]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/conn.c
Send "fake '*' key" in "MODE -k" replies
[ngircd-alex.git] / src / ngircd / conn.c
index 30dfd094467397ac958052fd41bfd5f33960ff14..fef568e4a17094b2513b9fbc9a722ed18a83f3d2 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-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
@@ -152,7 +152,9 @@ my_sd_listen_fds(void)
        if (!e || !*e)
                return -1;
        count = atoi(e);
+#ifdef HAVE_UNSETENV
        unsetenv("LISTEN_FDS");
+#endif
 
        return count;
 }
@@ -982,6 +984,7 @@ va_dcl
        size_t len;
        bool ok;
        va_list ap;
+       int r;
 
        assert( Idx > NONE );
        assert( Format != NULL );
@@ -991,7 +994,8 @@ va_dcl
 #else
        va_start( ap );
 #endif
-       if (vsnprintf( buffer, COMMAND_LEN - 2, Format, ap ) >= COMMAND_LEN - 2 ) {
+       r = vsnprintf(buffer, COMMAND_LEN - 2, Format, ap);
+       if (r >= COMMAND_LEN - 2 || r == -1) {
                /*
                 * The string that should be written to the socket is longer
                 * than the allowed size of COMMAND_LEN bytes (including both
@@ -1012,6 +1016,13 @@ va_dcl
                 * an other server only routing the message!), so the only
                 * option left is to shorten the string and to hope that the
                 * result is still somewhat useful ...
+                *
+                * Note:
+                * C99 states that vsnprintf() "returns the number of characters
+                * that would have been printed if the n were unlimited"; but
+                * according to the Linux manual page "glibc until 2.0.6 would
+                * return -1 when the output was truncated" -- so we have to
+                * handle both cases ...
                 *                                                   -alex-
                 */
 
@@ -1668,7 +1679,11 @@ Conn_StartLogin(CONN_ID Idx)
 #endif
                        (void)Conn_WriteStr(Idx,
                                "NOTICE AUTH :*** Looking up your hostname");
-               (void)Handle_Write(Idx);
+               /* Send buffered data to the client, but break on errors
+                * because Handle_Write() would have closed the connection
+                * again in this case! */
+               if (!Handle_Write(Idx))
+                       return;
        }
 
        Resolve_Addr(&My_Connections[Idx].proc_stat, &My_Connections[Idx].addr,
@@ -1909,7 +1924,7 @@ Handle_Buffer(CONN_ID Idx)
                ptr2 = strchr(array_start(&My_Connections[Idx].rbuf), '\n');
                if (ptr) {
                        /* Check if there is a single CR or LF _before_ the
-                        * corerct CR+LF line terminator:  */
+                        * correct CR+LF line terminator:  */
                        first_eol = ptr1 < ptr2 ? ptr1 : ptr2;
                        if (first_eol < ptr) {
                                /* Single CR or LF before CR+LF found */
@@ -2127,6 +2142,7 @@ New_Server( int Server , ng_ipaddr_t *dest)
 
        if (!ng_ipaddr_tostr_r(dest, ip_str)) {
                Log(LOG_WARNING, "New_Server: Could not convert IP to string");
+               Conf_Server[Server].conn_id = NONE;
                return;
        }
 
@@ -2141,11 +2157,14 @@ New_Server( int Server , ng_ipaddr_t *dest)
        if (new_sock < 0) {
                Log(LOG_CRIT, "Can't create socket (af %d): %s!",
                    af_dest, strerror(errno));
+               Conf_Server[Server].conn_id = NONE;
                return;
        }
 
-       if (!Init_Socket(new_sock))
+       if (!Init_Socket(new_sock)) {
+               Conf_Server[Server].conn_id = NONE;
                return;
+       }
 
        /* is a bind address configured? */
        res = ng_ipaddr_af(&Conf_Server[Server].bind_addr);
@@ -2161,6 +2180,7 @@ New_Server( int Server , ng_ipaddr_t *dest)
        if(( res != 0 ) && ( errno != EINPROGRESS )) {
                Log( LOG_CRIT, "Can't connect socket: %s!", strerror( errno ));
                close( new_sock );
+               Conf_Server[Server].conn_id = NONE;
                return;
        }
 
@@ -2169,12 +2189,14 @@ New_Server( int Server , ng_ipaddr_t *dest)
                    "Cannot allocate memory for server connection (socket %d)",
                    new_sock);
                close( new_sock );
+               Conf_Server[Server].conn_id = NONE;
                return;
        }
 
        if (!io_event_create( new_sock, IO_WANTWRITE, cb_connserver)) {
                Log(LOG_ALERT, "io_event_create(): could not add fd %d", strerror(errno));
                close(new_sock);
+               Conf_Server[Server].conn_id = NONE;
                return;
        }
 
@@ -2189,6 +2211,7 @@ New_Server( int Server , ng_ipaddr_t *dest)
        if (!c) {
                Log( LOG_ALERT, "Can't establish connection: can't create client structure!" );
                io_close(new_sock);
+               Conf_Server[Server].conn_id = NONE;
                return;
        }
 
@@ -2450,16 +2473,21 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
                                        *ptr ? "" : ": ",
                                        *ptr ? "" : identptr);
                        }
-               } else {
+               } else if(Conf_Ident) {
                        Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
-                       if (Conf_NoticeAuth && Conf_Ident)
+                       if (Conf_NoticeAuth)
                                (void)Conn_WriteStr(i,
                                        "NOTICE AUTH :*** No ident response");
                }
 #endif
 
-               if (Conf_NoticeAuth)
-                       (void)Handle_Write(i);
+               if (Conf_NoticeAuth) {
+                       /* Send buffered data to the client, but break on
+                        * errors because Handle_Write() would have closed
+                        * the connection again in this case! */
+                       if (!Handle_Write(i))
+                               return;
+               }
 
                Class_HandleServerBans(c);
        }