Remove empty +z channels when the +z is removed.
[srvx.git] / src / proto-p10.c
index ec517d142dae628744a441e2b373731ca9e5fca5..638913a77216142d3448c89fb42dcb0446cc2a9f 100644 (file)
@@ -291,6 +291,7 @@ static unsigned int num_notice_funcs;
 static struct dict *unbursted_channels;
 static const char *his_servername;
 static const char *his_servercomment;
+static struct channelList dead_channels;
 
 /* These correspond to 1 << X:      012345678901234567 */
 const char irc_user_mode_chars[] = "o iw dkgn        I";
@@ -683,7 +684,7 @@ irc_ungline(const char *mask)
  * Within those sets, ordering is arbitrary.
  */
 static int
-modeNode_sort(const void *pa, const void *pb)
+modeNode_sort_p10(const void *pa, const void *pb)
 {
         struct modeNode *a = *(struct modeNode**)pa;
         struct modeNode *b = *(struct modeNode**)pb;
@@ -724,7 +725,7 @@ irc_burst(struct chanNode *chan)
         burst_line[pos++] = ' ';
 
     /* sort the users for oplevel-sending purposes */
-    qsort(chan->members.list, chan->members.used, sizeof(chan->members.list[0]), modeNode_sort);
+    qsort(chan->members.list, chan->members.used, sizeof(chan->members.list[0]), modeNode_sort_p10);
 
     /* dump the users */
     for (n=0; n<chan->members.used; n++) {
@@ -1832,6 +1833,7 @@ init_parse(void)
     memset(notice_funcs, 0, sizeof(privmsg_func_t)*num_notice_funcs);
 
     userList_init(&dead_users);
+    channelList_init(&dead_channels);
     reg_del_channel_func(remove_unbursted_channel);
     reg_exit_func(parse_cleanup);
 }
@@ -1868,6 +1870,9 @@ parse_line(char *line, int recursive)
         for (i=0; i<dead_users.used; i++)
             free_user(dead_users.list[i]);
         dead_users.used = 0;
+        for (i=0; i<dead_channels.used; i++)
+            UnlockChannel(dead_channels.list[i]);
+        dead_channels.used = 0;
     }
     return res;
 }
@@ -2527,6 +2532,11 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
         change->modes_set &= ~(MODE_SECRET);
         change->modes_clear |= MODE_SECRET;
     }
+    if (change->modes_clear & MODE_REGISTERED) {
+        /* Horribly cheat by using the lock/unlock semantics. */
+        LockChannel(channel);
+        channelList_append(&dead_channels, channel);
+    }
     return change;
   error:
     mod_chanmode_free(change);
@@ -2878,8 +2888,8 @@ reg_notice_func(struct userNode *user, privmsg_func_t handler)
     if (numeric >= num_notice_funcs) {
         int newnum = numeric + 8, ii;
         notice_funcs = realloc(notice_funcs, newnum*sizeof(privmsg_func_t));
-        for (ii = num_privmsg_funcs; ii < newnum; ++ii)
-            privmsg_funcs[ii] = NULL;
+        for (ii = num_notice_funcs; ii < newnum; ++ii)
+            notice_funcs[ii] = NULL;
         num_notice_funcs = newnum;
     }
     if (notice_funcs[numeric])