]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/numeric.c
Sync "except lists" between servers
[ngircd-alex.git] / src / ngircd / numeric.c
index f2c61e8a8cb46ea0b7b7649ad73b76c7f9db438a..b0ceeef815e3d4cf91a8501801f36e983121e208 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Handlers for IRC numerics sent to the server
  */
 
-#include "imp.h"
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 
-#include "defines.h"
-#include "conn.h"
-#include "conf.h"
-#include "conn.h"
 #include "conn-func.h"
+#include "conf.h"
 #include "channel.h"
 #include "class.h"
 #include "irc-write.h"
 #include "lists.h"
 #include "log.h"
-#include "messages.h"
 #include "parse.h"
 
-#include "exp.h"
 #include "numeric.h"
 
-
 /**
  * Announce a channel and its users in the network.
  */
@@ -47,7 +41,7 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
 {
        CL2CHAN *cl2chan;
        CLIENT *cl;
-       char str[LINE_LEN], *ptr;
+       char str[COMMAND_LEN], *ptr;
        bool njoin, xop;
 
        /* Check features of remote server */
@@ -68,21 +62,21 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
                                strlcat(str, ",", sizeof(str));
 
                        /* Prepare user prefix (ChanOp, voiced, ...) */
-                       if (xop && strchr(Channel_UserModes(Chan, cl), 'q'))
+                       if (xop && Channel_UserHasMode(Chan, cl, 'q'))
                                strlcat(str, "~", sizeof(str));
-                       if (xop && strchr(Channel_UserModes(Chan, cl), 'a'))
+                       if (xop && Channel_UserHasMode(Chan, cl, 'a'))
                                strlcat(str, "&", sizeof(str));
-                       if (strchr(Channel_UserModes(Chan, cl), 'o'))
+                       if (Channel_UserHasMode(Chan, cl, 'o'))
                                strlcat(str, "@", sizeof(str));
-                       if (xop && strchr(Channel_UserModes(Chan, cl), 'h'))
+                       if (xop && Channel_UserHasMode(Chan, cl, 'h'))
                                strlcat(str, "%", sizeof(str));
-                       if (strchr(Channel_UserModes(Chan, cl), 'v'))
+                       if (Channel_UserHasMode(Chan, cl, 'v'))
                                strlcat(str, "+", sizeof(str));
 
                        strlcat(str, Client_ID(cl), sizeof(str));
 
                        /* Send the data if the buffer is "full" */
-                       if (strlen(str) > (LINE_LEN - CLIENT_NICK_LEN - 8)) {
+                       if (strlen(str) > (sizeof(str) - CLIENT_NICK_LEN - 8)) {
                                if (!IRC_WriteStrClient(Client, "%s", str))
                                        return DISCONNECTED;
                                snprintf(str, sizeof(str), "NJOIN %s :",
@@ -117,7 +111,6 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
        return CONNECTED;
 } /* Announce_Channel */
 
-
 /**
  * Announce new server in the network
  * @param Client New server
@@ -149,11 +142,30 @@ Announce_Server(CLIENT * Client, CLIENT * Server)
                Client_MyToken(Server), Client_Info(Server));
 } /* Announce_Server */
 
-
 #ifdef IRCPLUS
 
 /**
- * Synchronize invite, ban, G- and K-Line lists between servers.
+ * Send a specific list to a remote server.
+ */
+static bool
+Send_List(CLIENT *Client, CHANNEL *Chan, struct list_head *Head, char Type)
+{
+       struct list_elem *elem;
+
+       elem = Lists_GetFirst(Head);
+       while (elem) {
+               if (!IRC_WriteStrClient(Client, "MODE %s +%c %s",
+                                       Channel_Name(Chan), Type,
+                                       Lists_GetMask(elem))) {
+                       return DISCONNECTED;
+               }
+               elem = Lists_GetNext(elem);
+       }
+       return CONNECTED;
+}
+
+/**
+ * Synchronize invite, ban, except, and G-Line lists between servers.
  *
  * @param Client New server.
  * @return CONNECTED or DISCONNECTED.
@@ -181,36 +193,17 @@ Synchronize_Lists(CLIENT * Client)
 
        c = Channel_First();
        while (c) {
-               /* ban list */
-               head = Channel_GetListBans(c);
-               elem = Lists_GetFirst(head);
-               while (elem) {
-                       if (!IRC_WriteStrClient(Client, "MODE %s +b %s",
-                                               Channel_Name(c),
-                                               Lists_GetMask(elem))) {
-                               return DISCONNECTED;
-                       }
-                       elem = Lists_GetNext(elem);
-               }
-
-               /* invite list */
-               head = Channel_GetListInvites(c);
-               elem = Lists_GetFirst(head);
-               while (elem) {
-                       if (!IRC_WriteStrClient(Client, "MODE %s +I %s",
-                                               Channel_Name(c),
-                                               Lists_GetMask(elem))) {
-                               return DISCONNECTED;
-                       }
-                       elem = Lists_GetNext(elem);
-               }
-
+               if (!Send_List(Client, c, Channel_GetListExcepts(c), 'e'))
+                       return DISCONNECTED;
+               if (!Send_List(Client, c, Channel_GetListBans(c), 'b'))
+                       return DISCONNECTED;
+               if (!Send_List(Client, c, Channel_GetListInvites(c), 'I'))
+                       return DISCONNECTED;
                c = Channel_Next(c);
        }
        return CONNECTED;
 }
 
-
 /**
  * Send CHANINFO commands to a new server (inform it about existing channels).
  * @param Client New server
@@ -232,8 +225,8 @@ Send_CHANINFO(CLIENT * Client, CHANNEL * Chan)
        if (!*modes && !*topic)
                return CONNECTED;
 
-       has_k = strchr(modes, 'k') != NULL;
-       has_l = strchr(modes, 'l') != NULL;
+       has_k = Channel_HasMode(Chan, 'k');
+       has_l = Channel_HasMode(Chan, 'l');
 
        /* send CHANINFO */
        if (!has_k && !has_l) {
@@ -255,7 +248,6 @@ Send_CHANINFO(CLIENT * Client, CHANNEL * Chan)
 
 #endif /* IRCPLUS */
 
-
 /**
  * Handle ENDOFMOTD (376) numeric and login remote server.
  * The peer is either an IRC server (no IRC+ protocol), or we got the
@@ -349,7 +341,6 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
        return CONNECTED;
 } /* IRC_Num_ENDOFMOTD */
 
-
 /**
  * Handle ISUPPORT (005) numeric.
  */
@@ -385,5 +376,4 @@ IRC_Num_ISUPPORT(CLIENT * Client, REQUEST * Req)
        return CONNECTED;
 } /* IRC_Num_ISUPPORT */
 
-
 /* -eof- */