@@ -990,33 +990,30 @@ static void got_uninvite(struct chanset_t *chan, char *nick, char *from,
990990
991991static int gotmode (char * from , char * origmsg )
992992{
993- char * nick , * ch , * op , * chg , * msg ;
994- char s [UHOSTLEN ], buf [511 ];
995- char ms2 [3 ];
996- int z ;
993+ char * nick , * ch , * chg ;
994+ char s [UHOSTLEN ], buf [511 ], joinbuf [512 ];
995+ char ms2 [3 ], * arg ;
996+ int nextarg ;
997+ struct parsed_irc msg ;
997998 struct userrec * u ;
998999 memberlist * m ;
9991000 struct chanset_t * chan ;
10001001
10011002 strlcpy (buf , origmsg , sizeof buf );
1002- msg = buf ;
1003+ msg = parse_irc ( buf ) ;
10031004 /* Usermode changes? */
1004- if (msg [0 ] && (strchr (CHANMETA , msg [0 ]) != NULL )) {
1005- ch = newsplit (& msg );
1006- chg = newsplit (& msg );
1005+ if (msg .argc > 1 && (strchr (CHANMETA , msg .argv [0 ][0 ]) != NULL )) {
1006+ ch = msg .argv [0 ];
1007+ chg = msg .argv [1 ];
1008+ nextarg = 2 ;
10071009 reversing = 0 ;
10081010 chan = findchan (ch );
10091011 if (!chan ) {
10101012 putlog (LOG_MISC , "*" , CHAN_FORCEJOIN , ch );
10111013 dprintf (DP_SERVER , "PART %s\n" , ch );
10121014 } else if (channel_active (chan ) || channel_pending (chan )) {
1013- z = strlen (msg );
1014- if (msg [-- z ] == ' ' ) /* I hate cosmetic bugs :P -poptix */
1015- msg [z ] = 0 ;
1016- if (msg [0 ] == ':' )
1017- msg ++ ;
10181015 putlog (LOG_MODES , chan -> dname , "%s: mode change '%s %s' by %s" , ch , chg ,
1019- msg , from );
1016+ join_str_array ( msg . argv + 2 , msg . argc - 2 , " " , joinbuf , sizeof joinbuf ) , from );
10201017 nick = splitnick (& from );
10211018 m = ismember (chan , nick );
10221019 if (m ) {
@@ -1046,8 +1043,24 @@ static int gotmode(char *from, char *origmsg)
10461043 ms2 [0 ] = '+' ;
10471044 ms2 [2 ] = 0 ;
10481045 while ((ms2 [1 ] = * chg )) {
1046+ arg = NULL ;
10491047 int todo = 0 ;
10501048
1049+ if (* chg != '+' && * chg != '-' ) {
1050+ if ((ms2 [0 ] == '+' && MODE_HAS_SET_ARG (* chg )) || (ms2 [0 ] == '-' && MODE_HAS_UNSET_ARG (* chg ))) {
1051+ if (nextarg < msg .argc ) {
1052+ arg = msg .argv [nextarg ++ ];
1053+ } else {
1054+ putlog (LOG_MISC , "*" , "Error parsing modes in '%s', not enough arguments for %c%c" , origmsg , ms2 [0 ], * chg );
1055+ }
1056+ }
1057+ /* hardcoded assumptions in the existing old select code, SANITY CHECK */
1058+ if (((ms2 [0 ] == '+' && strchr ("behIklov" , * chg )) || (ms2 [0 ] == '-' && strchr ("behIkov" , * chg ))) && !arg ) {
1059+ arg = "" ;
1060+ putlog (LOG_MISC , "*" , "Error parsing modes in '%s', Eggdrop assumes mode change %c%c has a parameter but isupport says no" , origmsg , ms2 [0 ], * chg );
1061+ }
1062+ debug5 ("%s: split mode change '%s%s%s' by %s" , ch , ms2 , arg ? " " : "" , arg ? arg : "" , from );
1063+ }
10511064 switch (* chg ) {
10521065 case '+' :
10531066 ms2 [0 ] = '+' ;
@@ -1163,11 +1176,7 @@ static int gotmode(char *from, char *origmsg)
11631176 }
11641177 chan -> channel .maxmembers = 0 ;
11651178 } else {
1166- op = newsplit (& msg );
1167- fixcolon (op );
1168- if (* op == '\0' )
1169- break ;
1170- chan -> channel .maxmembers = atoi (op );
1179+ chan -> channel .maxmembers = atoi (arg );
11711180 check_tcl_mode (nick , from , u , chan -> dname , ms2 ,
11721181 int_to_base10 (chan -> channel .maxmembers ));
11731182 /* The Tcl proc might have modified/removed the chan or user */
@@ -1192,19 +1201,14 @@ static int gotmode(char *from, char *origmsg)
11921201 chan -> channel .mode |= CHANKEY ;
11931202 else
11941203 chan -> channel .mode &= ~CHANKEY ;
1195- op = newsplit (& msg );
1196- fixcolon (op );
1197- if (* op == '\0' ) {
1198- break ;
1199- }
1200- check_tcl_mode (nick , from , u , chan -> dname , ms2 , op );
1204+ check_tcl_mode (nick , from , u , chan -> dname , ms2 , arg );
12011205 /* The Tcl proc might have modified/removed the chan or user */
12021206 if (!(chan = modebind_refresh (ch , from , & user , NULL , NULL )))
12031207 return 0 ;
12041208 if (ms2 [0 ] == '+' ) {
1205- set_key (chan , op );
1209+ set_key (chan , arg );
12061210 if (channel_active (chan ))
1207- got_key (chan , nick , from , op );
1211+ got_key (chan , nick , from , arg );
12081212 } else {
12091213 if (channel_active (chan )) {
12101214 if (reversing && chan -> channel .key [0 ])
@@ -1217,29 +1221,23 @@ static int gotmode(char *from, char *origmsg)
12171221 }
12181222 break ;
12191223 case 'o' :
1220- op = newsplit (& msg );
1221- fixcolon (op );
12221224 if (ms2 [0 ] == '+' )
1223- got_op (chan , nick , from , op , u , & user );
1225+ got_op (chan , nick , from , arg , u , & user );
12241226 else
1225- got_deop (chan , nick , from , op , u );
1227+ got_deop (chan , nick , from , arg , u );
12261228 break ;
12271229 case 'h' :
1228- op = newsplit (& msg );
1229- fixcolon (op );
12301230 if (ms2 [0 ] == '+' )
1231- got_halfop (chan , nick , from , op , u , & user );
1231+ got_halfop (chan , nick , from , arg , u , & user );
12321232 else
1233- got_dehalfop (chan , nick , from , op , u );
1233+ got_dehalfop (chan , nick , from , arg , u );
12341234 break ;
12351235 case 'v' :
1236- op = newsplit (& msg );
1237- fixcolon (op );
1238- m = ismember (chan , op );
1236+ m = ismember (chan , arg );
12391237 if (!m ) {
12401238 if (channel_pending (chan ))
12411239 break ;
1242- putlog (LOG_MISC , chan -> dname , CHAN_BADCHANMODE , chan -> dname , op );
1240+ putlog (LOG_MISC , chan -> dname , CHAN_BADCHANMODE , chan -> dname , arg );
12431241 chan -> status |= CHAN_PEND ;
12441242 refresh_who_chan (chan -> name );
12451243 } else {
@@ -1248,21 +1246,21 @@ static int gotmode(char *from, char *origmsg)
12481246 if (ms2 [0 ] == '+' ) {
12491247 m -> flags &= ~SENTVOICE ;
12501248 m -> flags |= CHANVOICE ;
1251- check_tcl_mode (nick , from , u , chan -> dname , ms2 , op );
1249+ check_tcl_mode (nick , from , u , chan -> dname , ms2 , arg );
12521250 if (!(chan = modebind_refresh (ch , from , & user , s , & victim )))
12531251 return 0 ;
12541252 if (channel_active (chan ) && !glob_master (user ) &&
12551253 !chan_master (user ) && !match_my_nick (nick )) {
12561254 if (chan_quiet (victim ) ||
12571255 (glob_quiet (victim ) && !chan_voice (victim )))
1258- add_mode (chan , '-' , 'v' , op );
1256+ add_mode (chan , '-' , 'v' , arg );
12591257 else if (reversing )
1260- add_mode (chan , '-' , 'v' , op );
1258+ add_mode (chan , '-' , 'v' , arg );
12611259 }
12621260 } else {
12631261 m -> flags &= ~SENTDEVOICE ;
12641262 m -> flags &= ~CHANVOICE ;
1265- check_tcl_mode (nick , from , u , chan -> dname , ms2 , op );
1263+ check_tcl_mode (nick , from , u , chan -> dname , ms2 , arg );
12661264 if (!(chan = modebind_refresh (ch , from , & user , s , & victim )))
12671265 return 0 ;
12681266 if (channel_active (chan ) && !glob_master (user ) &&
@@ -1271,36 +1269,30 @@ static int gotmode(char *from, char *origmsg)
12711269 (chan_voice (victim ) || glob_voice (victim ))) ||
12721270 (!chan_quiet (victim ) && (glob_gvoice (victim ) ||
12731271 chan_gvoice (victim ))))
1274- add_mode (chan , '+' , 'v' , op );
1272+ add_mode (chan , '+' , 'v' , arg );
12751273 else if (reversing )
1276- add_mode (chan , '+' , 'v' , op );
1274+ add_mode (chan , '+' , 'v' , arg );
12771275 }
12781276 }
12791277 }
12801278 break ;
12811279 case 'b' :
1282- op = newsplit (& msg );
1283- fixcolon (op );
12841280 if (ms2 [0 ] == '+' )
1285- got_ban (chan , nick , from , op , ch , u );
1281+ got_ban (chan , nick , from , arg , ch , u );
12861282 else
1287- got_unban (chan , nick , from , op , ch , u );
1283+ got_unban (chan , nick , from , arg , ch , u );
12881284 break ;
12891285 case 'e' :
1290- op = newsplit (& msg );
1291- fixcolon (op );
12921286 if (ms2 [0 ] == '+' )
1293- got_exempt (chan , nick , from , op , ch , u );
1287+ got_exempt (chan , nick , from , arg , ch , u );
12941288 else
1295- got_unexempt (chan , nick , from , op , ch , u );
1289+ got_unexempt (chan , nick , from , arg , ch , u );
12961290 break ;
12971291 case 'I' :
1298- op = newsplit (& msg );
1299- fixcolon (op );
13001292 if (ms2 [0 ] == '+' )
1301- got_invite (chan , nick , from , op , ch , u );
1293+ got_invite (chan , nick , from , arg , ch , u );
13021294 else
1303- got_uninvite (chan , nick , from , op , ch , u );
1295+ got_uninvite (chan , nick , from , arg , ch , u );
13041296 break ;
13051297 }
13061298 if (todo ) {
0 commit comments