]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-login.c
ngIRCd Release 27
[ngircd-alex.git] / src / ngircd / irc-login.c
index b7fe5feda3339b9659012f7352563a8c2af3b8cf..fb2219226d8c3654c3ebdb8029e96dd2a3ab1160 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2018 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
  * Login and logout
  */
 
-#include "imp.h"
 #include <assert.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
+#include <time.h>
 
 #include "conn-func.h"
-#include "class.h"
 #include "conf.h"
 #include "channel.h"
 #include "log.h"
 #include "messages.h"
 #include "parse.h"
 #include "irc.h"
-#include "irc-info.h"
 #include "irc-macros.h"
 #include "irc-write.h"
 
-#include "exp.h"
 #include "irc-login.h"
 
 static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, char *NewNick,
@@ -92,7 +89,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
 
        /* Protocol version */
        if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
-               int c2, c4;
+               char c2, c4;
 
                c2 = Req->argv[1][2];
                c4 = Req->argv[1][4];
@@ -175,6 +172,7 @@ GLOBAL bool
 IRC_NICK( CLIENT *Client, REQUEST *Req )
 {
        CLIENT *intr_c, *target, *c;
+       CHANNEL *chan;
        char *nick, *user, *hostname, *modes, *info;
        int token, hops;
 
@@ -198,6 +196,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 
                /* Search "target" client */
                if (Client_Type(Client) == CLIENT_SERVER) {
+                       _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
                        target = Client_Search(Req->prefix);
                        if (!target)
                                return IRC_WriteErrClient(Client,
@@ -246,7 +245,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 #else
                                Conn_SetAuthPing(Client_Conn(Client), rand());
 #endif
-                               IRC_WriteStrClient(Client, "PING :%ld",
+                               Conn_WriteStr(Client_Conn(Client), "PING :%ld",
                                        Conn_GetAuthPing(Client_Conn(Client)));
                                LogDebug("Connection %d: sent AUTH PING %ld ...",
                                        Client_Conn(Client),
@@ -262,6 +261,22 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
                                Client_SetType( Client, CLIENT_GOTNICK );
                } else {
                        /* Nickname change */
+
+                       /* Check that the user isn't on any channels set +N */
+                       if(Client_Type(Client) == CLIENT_USER &&
+                          !Client_HasMode(Client, 'o')) {
+                               chan = Channel_First();
+                               while (chan) {
+                                       if(Channel_HasMode(chan, 'N') &&
+                                          Channel_IsMemberOf(chan, Client))
+                                               return IRC_WriteErrClient(Client,
+                                                                         ERR_NONICKCHANGE_MSG,
+                                                                         Client_ID(Client),
+                                                                         Channel_Name(chan));
+                                       chan = Channel_Next(chan);
+                               }
+                       }
+
                        Change_Nick(Client, target, Req->argv[0],
                                    Client_Type(Client) == CLIENT_USER ? true : false);
                        IRC_SetPenalty(target, 2);
@@ -365,6 +380,8 @@ IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
        assert(Client != NULL);
        assert(Req != NULL);
 
+       _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
+
        /* Search the originator */
        from = Client_Search(Req->prefix);
        if (!from)
@@ -467,6 +484,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
                   Client_Type(Client) == CLIENT_SERVICE) {
                /* Server/service updating an user */
                _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 4)
+               _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
 
                c = Client_Search(Req->prefix);
                if (!c)
@@ -639,6 +657,8 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
 
        if (Client_Type(Client) == CLIENT_SERVER) {
                /* Server */
+               _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
+
                target = Client_Search(Req->prefix);
                if (!target) {
                        Log(LOG_WARNING,
@@ -727,9 +747,10 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
 
                if (target != Client_ThisServer()) {
                        /* Ok, we have to forward the PING */
-                       if (Client_Type(Client) == CLIENT_SERVER)
+                       if (Client_Type(Client) == CLIENT_SERVER) {
+                               _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
                                from = Client_Search(Req->prefix);
-                       else
+                       else
                                from = Client;
                        if (!from)
                                return IRC_WriteErrClient(Client,
@@ -753,7 +774,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
                return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG,
                                        Client_ID(Client), Req->prefix);
 
-       Log(LOG_DEBUG, "Connection %d: got PING, sending PONG ...",
+       LogDebug("Connection %d: got PING, sending PONG ...",
            Client_Conn(Client));
 
 #ifdef STRICT_RFC
@@ -801,6 +822,8 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
 
        /* Forward? */
        if (Req->argc == 2 && Client_Type(Client) == CLIENT_SERVER) {
+               _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
+
                target = Client_Search(Req->argv[0]);
                if (!target)
                        return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG,
@@ -835,14 +858,14 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
        if (auth_ping) {
                LogDebug("AUTH PONG: waiting for token \"%ld\", got \"%s\" ...",
                         auth_ping, Req->argv[0]);
-               if (auth_ping == atoi(Req->argv[0])) {
+               if (auth_ping == atol(Req->argv[0])) {
                        Conn_SetAuthPing(conn, 0);
                        if (Client_Type(Client) == CLIENT_WAITAUTHPING)
                                Login_User(Client);
                } else
                        if (!IRC_WriteStrClient(Client,
-                                       "To connect, type /QUOTE PONG %ld",
-                                       auth_ping))
+                                       "NOTICE %s :To connect, type /QUOTE PONG %ld",
+                                       Client_ID(Client), auth_ping))
                                return DISCONNECTED;
        }
 #endif
@@ -850,14 +873,21 @@ 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 second%s [%ld users, %ld channels].",
-                   Client_ID(Client), conn, time(NULL) - Conn_GetSignon(conn),
+                   Client_ID(Client), conn,
+                   (long)(time(NULL) - Conn_GetSignon(conn)),
                    time(NULL) - Conn_GetSignon(conn) == 1 ? "" : "s",
                    Client_UserCount(), Channel_CountVisible(NULL));
-               Conn_UpdatePing(conn);
-       } else
-               LogDebug("Connection %d: received PONG. Lag: %ld seconds.",
-                        conn, time(NULL) - Conn_LastPing(conn));
+       } else {
+               if (Conn_LastPing(conn) > 1)
+                       LogDebug("Connection %d: received PONG. Lag: %ld seconds.",
+                                conn, (long)(time(NULL) - Conn_LastPing(conn)));
+               else
+                       LogDebug("Got unexpected PONG on connection %d. Ignored.",
+                                conn);
+       }
 
+       /* We got a PONG, so signal that none is pending on this connection. */
+       Conn_UpdatePing(conn, 1);
        return CONNECTED;
 } /* IRC_PONG */