Send oplevels correctly during a burst.
[srvx.git] / src / hash.c
index 4fa1e913f11e93826aaddf309516464bf8b011a9..75769fa09706c6e4ebdf5962af50b6f0bb431c8c 100644 (file)
@@ -191,9 +191,11 @@ NickChange(struct userNode* user, const char *new_nick, int no_announce)
 #endif
 
     /* Make callbacks for nick changes.  Do this with new nick in
-     * place because that is slightly more useful.
+     * place because that is slightly more useful.  Stop if the user
+     * gets killed by any of the hooks, so that later hooks do not get
+     * confused by the user having disappeared.
      */
-    for (nn=0; nn<ncf2_used; nn++)
+    for (nn=0; (nn<ncf2_used) && !user->dead; nn++)
         ncf2_list[nn](user, old_nick);
     user->timestamp = now;
     if (IsLocal(user) && !no_announce)
@@ -219,7 +221,7 @@ reg_account_func(account_func_t handler)
 }
 
 void
-call_account_func(struct userNode *user, const char *stamp)
+call_account_func(struct userNode *user, const char *stamp, unsigned long timestamp, unsigned long serial)
 {
     /* We've received an account stamp for a user; notify
        NickServ, which registers the sole account_func
@@ -228,7 +230,7 @@ call_account_func(struct userNode *user, const char *stamp)
        P10 Protocol violation if (user->modes & FLAGS_STAMPED) here.
     */
     if (account_func)
-        account_func(user, stamp);
+        account_func(user, stamp, timestamp, serial);
 
 #ifdef WITH_PROTOCOL_P10
     /* Mark the user so we don't stamp it again. */
@@ -237,7 +239,7 @@ call_account_func(struct userNode *user, const char *stamp)
 }
 
 void
-StampUser(struct userNode *user, const char *stamp)
+StampUser(struct userNode *user, const char *stamp, unsigned long timestamp, unsigned long serial)
 {
 #ifdef WITH_PROTOCOL_P10
     /* The P10 protocol says we can't stamp users who already
@@ -246,7 +248,7 @@ StampUser(struct userNode *user, const char *stamp)
         return;
 #endif
 
-    irc_account(user, stamp);
+    irc_account(user, stamp, timestamp, serial);
     user->modes |= FLAGS_STAMPED;
 }
 
@@ -483,7 +485,7 @@ AddChannelUser(struct userNode *user, struct chanNode* channel)
         mNode->channel = channel;
         mNode->user = user;
         mNode->modes = 0;
-        mNode->oplevel = -1;
+        mNode->oplevel = MAXOPLEVEL;
         mNode->idle_since = now;
 
         /* Add modeNode to channel and to user.
@@ -498,16 +500,17 @@ AddChannelUser(struct userNode *user, struct chanNode* channel)
             && !(channel->modes & MODE_APASS))
             mNode->modes |= MODE_CHANOP;
 
-        for (n=0; n<jf_used; n++) {
+        if (IsLocal(user)) {
+            irc_join(user, channel);
+        }
+
+        for (n=0; (n<jf_used) && !user->dead; n++) {
             /* Callbacks return true if they kick or kill the user,
              * and we can continue without removing mNode. */
             if (jf_list[n](mNode))
                 return NULL;
         }
 
-        if (IsLocal(user))
-            irc_join(user, channel);
-
         return mNode;
 }
 
@@ -699,6 +702,10 @@ SetChannelTopic(struct chanNode *channel, struct userNode *user, const char *top
         irc_topic(user, channel, topic);
     } else {
         for (n=0; n<tf_used; n++)
+            /* A topic change handler can return non-zero to indicate
+             * that it has reverted the topic change, and that further
+             * hooks should not be called.
+             */
             if (tf_list[n](user, channel, old_topic))
                 break;
     }