fixed possible crash in cmd_NeonServ.mod/cmd_neonserv_mode.c
[NeonServV5.git] / src / modules / NeonServ.mod / event_neonserv_mode.c
index f0794a906b7aa30db06ba1fb9e5e62360cedb239..b6d06527e1ca04fdd4ad9470355d726158515159 100644 (file)
@@ -1,4 +1,4 @@
-/* event_neonserv_mode.c - NeonServ v5.3
+/* event_neonserv_mode.c - NeonServ v5.6
  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
  * 
  * This program is free software: you can redistribute it and/or modify
@@ -38,7 +38,7 @@ static void neonserv_event_mode(struct UserNode *user, struct ChanNode *chan, ch
     if(argc) 
         temp_argv = malloc(argc*sizeof(*temp_argv));
     if (!cache || (argc && !temp_argv)) {
-        perror("malloc() failed");
+        printf_log("neonserv", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
         return;
     }
     if(argc) {
@@ -52,7 +52,7 @@ static void neonserv_event_mode(struct UserNode *user, struct ChanNode *chan, ch
     cache->modes = strdup(modes);
     cache->argv = temp_argv;
     cache->argc = argc;
-    get_userlist_with_invisible(chan, neonserv_event_mode_userlist_lookup, cache);
+    get_userlist_with_invisible(chan, module_id, neonserv_event_mode_userlist_lookup, cache);
 }
 
 static USERLIST_CALLBACK(neonserv_event_mode_userlist_lookup) {
@@ -131,6 +131,10 @@ static void neonserv_event_mode_async1(struct ClientSocket *client, struct UserN
                     //someone deopped the bot???
                     if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
                                                requestOp(client->user, chan);
+                } else if(modes[i] == 'o' && add && isBot(cuser)) {
+                    //someone opped a bot
+                    if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+                                               module_neonbackup_recover_chan(chan);
                 }
                 if((modes[i] == 'o' || (modes[i] == 'h' && !with_halfops)) && !(add && isBot(cuser))) {
                     if(uaccess < db_canop) {
@@ -197,16 +201,30 @@ static void neonserv_event_mode_async1(struct ClientSocket *client, struct UserN
                     reply(textclient, user, "NS_MODE_CANBAN", chan->name);
                     db_canban = -1;
                 }
+                char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
+                char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+                int match_count = 0;
                 if(db_canban == -1) {
-                    if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+                    if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed)) {
+                        if(!add) {
+                            //check if a user just removed a bot ban
+                            for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+                                cuser = chanuser->user;
+                                sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+                                if(!match(carg, usermask) && isBot(cuser)) {
+                                    skip = 1;
+                                    break;
+                                }
+                            }
+                            if(skip)
+                                break;
+                        }
                         modeBufferSet(modeBuf, !add, modes[i], carg);
+                    }
                     if(uaccess < db_getop)
                         deop_user = 1;
                     break;
                 }
-                char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
-                char usermask[NICKLEN+USERLEN+HOSTLEN+3];
-                int match_count = 0;
                 carg = make_banmask(carg, hostmask_buffer);
                 if(add) {
                     for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {