]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-login.c
Make configure[.ng] compatible with autoconf 1.10 again
[ngircd-alex.git] / src / ngircd / irc-login.c
index c3f32b7e8b2516fe383b6482341817ce668269a6..6969fa338c22018643c5b08aa976bb0b2257fb7c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2012 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
@@ -39,8 +39,8 @@
 #include "irc-login.h"
 
 static void Kill_Nick PARAMS((char *Nick, char *Reason));
-static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target,
-                               char *NewNick, bool RegisterWhowas));
+static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, char *NewNick,
+                               bool InformClient));
 
 
 /**
@@ -146,7 +146,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
                        } else
                                flags = "";
                        Log(LOG_INFO,
-                           "Peer on conenction %d announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").",
+                           "Peer on connection %d announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").",
                            Client_Conn(Client), impl, serverver,
                            protohigh, protolow, flags);
                } else {
@@ -278,7 +278,8 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
                                Client_SetType( Client, CLIENT_GOTNICK );
                } else {
                        /* Nickname change */
-                       Change_Nick(Client, target, Req->argv[0], true);
+                       Change_Nick(Client, target, Req->argv[0],
+                                   Client_Type(Client) == CLIENT_USER ? true : false);
                        IRC_SetPenalty(target, 2);
                }
 
@@ -359,6 +360,54 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 } /* IRC_NICK */
 
 
+/**
+ * Handler for the IRC "SVSNICK" command.
+ *
+ * @param Client The client from which this command has been received.
+ * @param Req Request structure with prefix and all parameters.
+ * @return CONNECTED or DISCONNECTED.
+ */
+GLOBAL bool
+IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
+{
+       CLIENT *from, *target;
+
+       assert(Client != NULL);
+       assert(Req != NULL);
+
+       if (Req->argc != 2)
+               return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+                                         Client_ID(Client), Req->command);
+
+       /* Search the originator */
+       from = Client_Search(Req->prefix);
+       if (!from)
+               from = Client;
+
+       /* Search the target */
+       target = Client_Search(Req->argv[0]);
+       if (!target || Client_Type(target) != CLIENT_USER) {
+               return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+                                         Client_ID(Client), Req->argv[0]);
+       }
+
+       if (Client_Conn(target) <= NONE) {
+               /* We have to forward the message to the server handling
+                * this user; this is required to make sure all servers
+                * in the network do follow the nick name change! */
+               return IRC_WriteStrClientPrefix(Client_NextHop(target), from,
+                                               "SVSNICK %s %s",
+                                               Req->argv[0], Req->argv[1]);
+       }
+
+       /* Make sure that the new nickname is valid */
+       if (!Client_CheckNick(from, Req->argv[1]))
+               return CONNECTED;
+
+       Change_Nick(from, target, Req->argv[1], true);
+       return CONNECTED;
+}
+
 /**
  * Handler for the IRC "USER" command.
  *
@@ -394,8 +443,8 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
                   punctuation is allowed.*/
                ptr = Req->argv[0];
                while (*ptr) {
-                       if (!isalnum(*ptr) &&
-                           *ptr != '+' && *ptr != '-' &&
+                       if (!isalnum((int)*ptr) &&
+                           *ptr != '+' && *ptr != '-' && *ptr != '@' &&
                            *ptr != '.' && *ptr != '_') {
                                Conn_Close(Client_Conn(Client), NULL,
                                           "Invalid user name", true);
@@ -404,6 +453,13 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
                        ptr++;
                }
 
+               /* Save the received username for authentication, and use
+                * it up to the first '@' as default user name (like ircd2.11,
+                * bahamut, ircd-seven, ...), prefixed with '~', if needed: */
+               Client_SetOrigUser(Client, Req->argv[0]);
+               ptr = strchr(Req->argv[0], '@');
+               if (ptr)
+                       *ptr = '\0';
 #ifdef IDENTAUTH
                ptr = Client_User(Client);
                if (!ptr || !*ptr || *ptr == '~')
@@ -411,7 +467,6 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
 #else
                Client_SetUser(Client, Req->argv[0], false);
 #endif
-               Client_SetOrigUser(Client, Req->argv[0]);
 
                /* "Real name" or user info text: Don't set it to the empty
                 * string, the original ircd can't deal with such "real names"
@@ -642,11 +697,11 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
                }
 
                if (target != Client) {
-                       Client_Destroy(target, "Got QUIT command.",
+                       Client_Destroy(target, "Got QUIT command",
                                       Req->argc == 1 ? quitmsg : NULL, true);
                        return CONNECTED;
                } else {
-                       Conn_Close(Client_Conn(Client), "Got QUIT command.",
+                       Conn_Close(Client_Conn(Client), "Got QUIT command",
                                   Req->argc == 1 ? quitmsg : NULL, true);
                        return DISCONNECTED;
                }
@@ -659,7 +714,7 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
                }
 
                /* User, Service, or not yet registered */
-               Conn_Close(Client_Conn(Client), "Got QUIT command.",
+               Conn_Close(Client_Conn(Client), "Got QUIT command",
                           Req->argc == 1 ? quitmsg : NULL, true);
 
                return DISCONNECTED;
@@ -858,8 +913,9 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
 
        if (Client_Type(Client) == CLIENT_SERVER && Conn_LastPing(conn) == 0) {
                Log(LOG_INFO,
-                   "Synchronization with \"%s\" done (connection %d): %ld seconds [%ld users, %ld channels]",
+                   "Synchronization with \"%s\" done (connection %d): %ld second%s [%ld users, %ld channels].",
                    Client_ID(Client), conn, time(NULL) - Conn_GetSignon(conn),
+                   time(NULL) - Conn_GetSignon(conn) == 1 ? "" : "s",
                    Client_UserCount(), Channel_CountVisible(NULL));
                Conn_UpdatePing(conn);
        } else
@@ -889,7 +945,7 @@ Kill_Nick(char *Nick, char *Reason)
        r.argv[1] = Reason;
        r.argc = 2;
 
-       Log(LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s",
+       Log(LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s!",
            Nick, Reason);
 
        IRC_KILL(Client_ThisServer(), &r);
@@ -904,7 +960,7 @@ Kill_Nick(char *Nick, char *Reason)
  * @param NewNick The new nickname.
  */
 static void
-Change_Nick(CLIENT *Origin, CLIENT *Target, char *NewNick, bool RegisterWhowas)
+Change_Nick(CLIENT *Origin, CLIENT *Target, char *NewNick, bool InformClient)
 {
        if (Client_Conn(Target) > NONE) {
                /* Local client */
@@ -921,14 +977,15 @@ Change_Nick(CLIENT *Origin, CLIENT *Target, char *NewNick, bool RegisterWhowas)
        }
 
        /* Inform all servers and users (which have to know) of the new name */
-       if (Client_Type(Origin) == CLIENT_USER)
-               IRC_WriteStrClientPrefix(Origin, Origin, "NICK :%s", NewNick);
-       IRC_WriteStrServersPrefix(Origin, Target, "NICK :%s", NewNick);
+       if (InformClient) {
+               IRC_WriteStrClientPrefix(Target, Target, "NICK :%s", NewNick);
+               IRC_WriteStrServersPrefix(NULL, Target, "NICK :%s", NewNick);
+       } else
+               IRC_WriteStrServersPrefix(Origin, Target, "NICK :%s", NewNick);
        IRC_WriteStrRelatedPrefix(Target, Target, false, "NICK :%s", NewNick);
 
-       /* Register old nickname for WHOWAS queries, if required */
-       if (RegisterWhowas)
-               Client_RegisterWhowas(Target);
+       /* Register old nickname for WHOWAS queries */
+       Client_RegisterWhowas(Target);
 
        /* Save new nickname */
        Client_SetID(Target, NewNick);