]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/numeric.c
Enhance debug messages while sending CHANINFO commands
[ngircd-alex.git] / src / ngircd / numeric.c
index 3fc8c461bf73f1455731bf21f818a63455cd619d..7d32ddc933fd5fd132e4efbf74defa1c961d3fd3 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,13 +41,12 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
 {
        CL2CHAN *cl2chan;
        CLIENT *cl;
-       char str[LINE_LEN], *ptr;
-       bool njoin;
+       char str[COMMAND_LEN], *ptr;
+       bool njoin, xop;
 
-       if (Conn_Options(Client_Conn(Client)) & CONN_RFC1459)
-               njoin = false;
-       else
-               njoin = true;
+       /* Check features of remote server */
+       njoin = Conn_Options(Client_Conn(Client)) & CONN_RFC1459 ? false : true;
+       xop = Client_HasFlag(Client, 'X') ? true : false;
 
        /* Get all the members of this channel */
        cl2chan = Channel_FirstMember(Chan);
@@ -67,21 +60,23 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
                         * (if user is channel operator or has voice) */
                        if (str[strlen(str) - 1] != ':')
                                strlcat(str, ",", sizeof(str));
-                       if (strchr(Channel_UserModes(Chan, cl), 'q'))
+
+                       /* Prepare user prefix (ChanOp, voiced, ...) */
+                       if (xop && Channel_UserHasMode(Chan, cl, 'q'))
                                strlcat(str, "~", sizeof(str));
-                       if (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 (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 :",
@@ -116,7 +111,6 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
        return CONNECTED;
 } /* Announce_Channel */
 
-
 /**
  * Announce new server in the network
  * @param Client New server
@@ -148,61 +142,30 @@ Announce_Server(CLIENT * Client, CLIENT * Server)
                Client_MyToken(Server), Client_Info(Server));
 } /* Announce_Server */
 
+#ifdef IRCPLUS
 
 /**
- * Announce existing user to a new server
- * @param Client New server
- * @param User Existing user in the network
+ * Send a specific list to a remote server.
  */
 static bool
-Announce_User(CLIENT * Client, CLIENT * User)
+Send_List(CLIENT *Client, CHANNEL *Chan, struct list_head *Head, char Type)
 {
-       CONN_ID conn;
-       char *modes;
-
-       conn = Client_Conn(Client);
-       if (Conn_Options(conn) & CONN_RFC1459) {
-               /* RFC 1459 mode: separate NICK and USER commands */
-               if (! Conn_WriteStr(conn, "NICK %s :%d",
-                                   Client_ID(User), Client_Hops(User) + 1))
-                       return DISCONNECTED;
-               if (! Conn_WriteStr(conn, ":%s USER %s %s %s :%s",
-                                    Client_ID(User), Client_User(User),
-                                    Client_Hostname(User),
-                                    Client_ID(Client_Introducer(User)),
-                                    Client_Info(User)))
+       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;
-               modes = Client_Modes(User);
-               if (modes[0]) {
-                       return Conn_WriteStr(conn, ":%s MODE %s +%s",
-                                    Client_ID(User), Client_ID(User),
-                                    modes);
                }
-               return CONNECTED;
-       } else {
-               /* RFC 2813 mode: one combined NICK or SERVICE command */
-               if (Client_Type(User) == CLIENT_SERVICE
-                   && strchr(Client_Flags(Client), 'S'))
-                       return IRC_WriteStrClient(Client,
-                               "SERVICE %s %d * +%s %d :%s", Client_Mask(User),
-                               Client_MyToken(Client_Introducer(User)),
-                               Client_Modes(User), Client_Hops(User) + 1,
-                               Client_Info(User));
-               else
-                       return IRC_WriteStrClient(Client,
-                               "NICK %s %d %s %s %d +%s :%s",
-                               Client_ID(User), Client_Hops(User) + 1,
-                               Client_User(User), Client_Hostname(User),
-                               Client_MyToken(Client_Introducer(User)),
-                               Client_Modes(User), Client_Info(User));
+               elem = Lists_GetNext(elem);
        }
-} /* Announce_User */
-
-
-#ifdef IRCPLUS
+       return CONNECTED;
+}
 
 /**
- * Synchronize invite, ban, G- and K-Line lists between servers.
+ * Synchronize invite, ban, except, and G-Line lists between servers.
  *
  * @param Client New server.
  * @return CONNECTED or DISCONNECTED.
@@ -230,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
@@ -272,7 +216,8 @@ Send_CHANINFO(CLIENT * Client, CHANNEL * Chan)
        bool has_k, has_l;
 
 #ifdef DEBUG
-       Log(LOG_DEBUG, "Sending CHANINFO commands ...");
+       Log(LOG_DEBUG, "Sending CHANINFO commands for \"%s\" ...",
+           Channel_Name(Chan));
 #endif
 
        modes = Channel_Modes(Chan);
@@ -281,8 +226,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) {
@@ -304,7 +249,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
@@ -355,7 +299,7 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
        while (c) {
                if (Client_Type(c) == CLIENT_USER ||
                    Client_Type(c) == CLIENT_SERVICE) {
-                       if (!Announce_User(Client, c))
+                       if (!Client_Announce(Client, Client_ThisServer(), c))
                                return DISCONNECTED;
                }
                c = Client_Next(c);
@@ -370,7 +314,7 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
                }
 #ifdef IRCPLUS
                /* Send CHANINFO if the peer supports it */
-               if (strchr(Client_Flags(Client), 'C')) {
+               if (Client_HasFlag(Client, 'C')) {
                        if (!Send_CHANINFO(Client, chan))
                                return DISCONNECTED;
                }
@@ -384,7 +328,7 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
        }
 
 #ifdef IRCPLUS
-       if (strchr(Client_Flags(Client), 'L')) {
+       if (Client_HasFlag(Client, 'L')) {
                LogDebug("Synchronizing INVITE- and BAN-lists ...");
                if (!Synchronize_Lists(Client))
                        return DISCONNECTED;
@@ -398,7 +342,6 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
        return CONNECTED;
 } /* IRC_Num_ENDOFMOTD */
 
-
 /**
  * Handle ISUPPORT (005) numeric.
  */
@@ -434,5 +377,4 @@ IRC_Num_ISUPPORT(CLIENT * Client, REQUEST * Req)
        return CONNECTED;
 } /* IRC_Num_ISUPPORT */
 
-
 /* -eof- */