]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/ngircd.c
Introduce option to configure the maximum nick name lenth in ngircd.conf
[ngircd-alex.git] / src / ngircd / ngircd.c
index 6f965853777c32182aae4b7d316017a90bb8adee..d2a6d7ea8faae860f0df893edef82969acf80a3b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2005 by Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2007 Alexander Barton (alex@barton.de).
  *
  * 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
@@ -12,7 +12,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: ngircd.c,v 1.103 2005/07/07 18:37:36 fw Exp $";
+static char UNUSED id[] = "$Id: ngircd.c,v 1.117 2007/11/21 12:16:36 alex Exp $";
 
 /**
  * @file
@@ -48,7 +48,7 @@ static char UNUSED id[] = "$Id: ngircd.c,v 1.103 2005/07/07 18:37:36 fw Exp $";
 #include "parse.h"
 #include "irc.h"
 
-#ifdef RENDEZVOUS
+#ifdef ZEROCONF
 #include "rendezvous.h"
 #endif
 
@@ -56,20 +56,20 @@ static char UNUSED id[] = "$Id: ngircd.c,v 1.103 2005/07/07 18:37:36 fw Exp $";
 #include "ngircd.h"
 
 
-LOCAL void Initialize_Signal_Handler PARAMS(( void ));
-LOCAL void Signal_Handler PARAMS(( int Signal ));
+static void Initialize_Signal_Handler PARAMS(( void ));
+static void Signal_Handler PARAMS(( int Signal ));
 
-LOCAL void Show_Version PARAMS(( void ));
-LOCAL void Show_Help PARAMS(( void ));
+static void Show_Version PARAMS(( void ));
+static void Show_Help PARAMS(( void ));
 
-LOCAL void Pidfile_Create PARAMS(( long ));
-LOCAL void Pidfile_Delete PARAMS(( void ));
+static void Pidfile_Create PARAMS(( pid_t pid ));
+static void Pidfile_Delete PARAMS(( void ));
 
-LOCAL void Fill_Version PARAMS(( void ));
+static void Fill_Version PARAMS(( void ));
 
-LOCAL void Setup_FDStreams PARAMS(( void ));
+static void Setup_FDStreams PARAMS(( void ));
 
-LOCAL bool NGIRCd_Init PARAMS(( bool ));
+static bool NGIRCd_Init PARAMS(( bool ));
 
 /**
  * The main() function of ngIRCd.
@@ -262,17 +262,18 @@ main( int argc, const char *argv[] )
                Log_Init( ! NGIRCd_NoDaemon );
                Conf_Init( );
 
-               if (!NGIRCd_Init( NGIRCd_NoDaemon )) {
-                       Log(LOG_WARNING, "Fatal: Initialization failed");
+               /* Initialize the "main program": chroot environment, user and
+                * group ID, ... */
+               if (!NGIRCd_Init(NGIRCd_NoDaemon)) {
+                       Log(LOG_ALERT, "Fatal: Initialization failed");
                        exit(1);
                }
 
                /* Initialize modules, part II: these functions are eventually
                 * called with already dropped privileges ... */
-               Lists_Init( );
                Channel_Init( );
                Client_Init( );
-#ifdef RENDEZVOUS
+#ifdef ZEROCONF
                Rendezvous_Init( );
 #endif
                Conn_Init( );
@@ -321,12 +322,11 @@ main( int argc, const char *argv[] )
 
                /* Alles abmelden */
                Conn_Exit( );
-#ifdef RENDEZVOUS
+#ifdef ZEROCONF
                Rendezvous_Exit( );
 #endif
                Client_Exit( );
                Channel_Exit( );
-               Lists_Exit( );
                Log_Exit( );
        }
        Pidfile_Delete( );
@@ -341,7 +341,7 @@ main( int argc, const char *argv[] )
  * further usage, for example by the IRC command VERSION and the --version
  * command line switch.
  */
-LOCAL void
+static void
 Fill_Version( void )
 {
        NGIRCd_VersionAddition[0] = '\0';
@@ -361,11 +361,11 @@ Fill_Version( void )
 
        strlcat( NGIRCd_VersionAddition, "TCPWRAP", sizeof NGIRCd_VersionAddition );
 #endif
-#ifdef RENDEZVOUS
+#ifdef ZEROCONF
        if( NGIRCd_VersionAddition[0] )
                strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
 
-       strlcat( NGIRCd_VersionAddition, "RENDEZVOUS", sizeof NGIRCd_VersionAddition );
+       strlcat( NGIRCd_VersionAddition, "ZEROCONF", sizeof NGIRCd_VersionAddition );
 #endif
 #ifdef IDENTAUTH
        if( NGIRCd_VersionAddition[0] )
@@ -422,6 +422,7 @@ GLOBAL void
 NGIRCd_Rehash( void )
 {
        char old_name[CLIENT_ID_LEN];
+       unsigned old_nicklen;
 
        Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
        NGIRCd_SignalRehash = false;
@@ -429,17 +430,22 @@ NGIRCd_Rehash( void )
        /* Close down all listening sockets */
        Conn_ExitListeners( );
 
-       /* Remember old server name */
+       /* Remember old server name and nick name length */
        strlcpy( old_name, Conf_ServerName, sizeof old_name );
+       old_nicklen = Conf_MaxNickLength;
 
        /* Re-read configuration ... */
        Conf_Rehash( );
 
-       /* Recover old server name: it can't be changed during run-time */
-       if( strcmp( old_name, Conf_ServerName ) != 0 )
-       {
-               strcpy( Conf_ServerName, old_name );
-               Log( LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name." );
+       /* Recover old server name and nick name length: these values can't
+        * be changed during run-time */
+       if (strcmp(old_name, Conf_ServerName) != 0 ) {
+               strlcpy(Conf_ServerName, old_name, sizeof Conf_ServerName);
+               Log(LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name.");
+       }
+       if (old_nicklen != Conf_MaxNickLength) {
+               Conf_MaxNickLength = old_nicklen;
+               Log(LOG_ERR, "Can't change \"MaxNickLength\" on runtime! Ignored new value.");
        }
 
        /* Create new pre-defined channels */
@@ -458,7 +464,7 @@ NGIRCd_Rehash( void )
 /**
  * Initialize the signal handler.
  */
-LOCAL void
+static void
 Initialize_Signal_Handler( void )
 {
        /* Signal-Handler initialisieren: einige Signale
@@ -480,27 +486,27 @@ Initialize_Signal_Handler( void )
 #endif
 
        /* Signal-Handler einhaengen */
-       sigaction( SIGINT, &saction, NULL );
-       sigaction( SIGQUIT, &saction, NULL );
-       sigaction( SIGTERM, &saction, NULL);
-       sigaction( SIGHUP, &saction, NULL);
-       sigaction( SIGCHLD, &saction, NULL);
+       sigaction(SIGINT, &saction, NULL);
+       sigaction(SIGQUIT, &saction, NULL);
+       sigaction(SIGTERM, &saction, NULL);
+       sigaction(SIGHUP, &saction, NULL);
+       sigaction(SIGCHLD, &saction, NULL);
 
        /* einige Signale ignorieren */
        saction.sa_handler = SIG_IGN;
-       sigaction( SIGPIPE, &saction, NULL );
+       sigaction(SIGPIPE, &saction, NULL);
 #else
        /* kein sigaction() vorhanden */
 
        /* Signal-Handler einhaengen */
-       signal( SIGINT, Signal_Handler );
-       signal( SIGQUIT, Signal_Handler );
-       signal( SIGTERM, Signal_Handler );
-       signal( SIGHUP, Signal_Handler );
-       signal( SIGCHLD, Signal_Handler );
+       signal(SIGINT, Signal_Handler);
+       signal(SIGQUIT, Signal_Handler);
+       signal(SIGTERM, Signal_Handler);
+       signal(SIGHUP, Signal_Handler);
+       signal(SIGCHLD, Signal_Handler);
 
        /* einige Signale ignorieren */
-       signal( SIGPIPE, SIG_IGN );
+       signal(SIGPIPE, SIG_IGN);
 #endif
 } /* Initialize_Signal_Handler */
 
@@ -511,7 +517,7 @@ Initialize_Signal_Handler( void )
  * user and/or the system to it. For example SIGTERM and SIGHUP.
  * @param Signal Number of the signal to handle.
  */
-LOCAL void
+static void
 Signal_Handler( int Signal )
 {
        switch( Signal )
@@ -542,12 +548,12 @@ Signal_Handler( int Signal )
 /**
  * Display copyright and version information of ngIRCd on the console.
  */
-LOCAL void
+static void
 Show_Version( void )
 {
        puts( NGIRCd_Version );
-       puts( "Copyright (c)2001-2005 by Alexander Barton (<alex@barton.de>)." );
-       puts( "Homepage: <http://arthur.ath.cx/~alex/ngircd/>\n" );
+       puts( "Copyright (c)2001-2007 Alexander Barton (<alex@barton.de>) and Contributors." );
+       puts( "Homepage: <http://ngircd.barton.de/>\n" );
        puts( "This is free software; see the source for copying conditions. There is NO" );
        puts( "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." );
 } /* Show_Version */
@@ -558,7 +564,7 @@ Show_Version( void )
  * This help depends on the configuration of the executable and only shows
  * options that are actually enabled.
  */
-LOCAL void
+static void
 Show_Help( void )
 {
 #ifdef DEBUG
@@ -579,7 +585,7 @@ Show_Help( void )
 /**
  * Delete the file containing the process ID (PID).
  */
-LOCAL void
+static void
 Pidfile_Delete( void )
 {
        /* Pidfile configured? */
@@ -598,8 +604,8 @@ Pidfile_Delete( void )
  * Create the file containing the process ID of ngIRCd ("PID file").
  * @param pid The process ID to be stored in this file.
  */
-LOCAL void
-Pidfile_Create( long pid )
+static void
+Pidfile_Create(pid_t pid)
 {
        int pidfd;
        char pidbuf[64];
@@ -618,13 +624,13 @@ Pidfile_Create( long pid )
                return;
        }
 
-       len = snprintf( pidbuf, sizeof pidbuf, "%ld\n", pid );
-       if (len < 0|| len < (int)sizeof pid) {
+       len = snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);
+       if (len < 0 || len >= (int)sizeof pidbuf) {
                Log( LOG_ERR, "Error converting pid");
                return;
        }
        
-       if( write( pidfd, pidbuf, len) != len)
+       if (write(pidfd, pidbuf, (size_t)len) != (ssize_t)len)
                Log( LOG_ERR, "Can't write PID file (%s): %s", Conf_PidFile, strerror( errno ));
 
        if( close(pidfd) != 0 )
@@ -635,7 +641,7 @@ Pidfile_Create( long pid )
 /**
  * Redirect stdin, stdout and stderr to apropriate file handles.
  */
-LOCAL void
+static void
 Setup_FDStreams( void )
 {
        int fd;
@@ -660,8 +666,8 @@ Setup_FDStreams( void )
 } /* Setup_FDStreams */
 
 
-LOCAL bool
-NGIRCd_getNobodyID(unsigned int *uid, unsigned int *gid )
+static bool
+NGIRCd_getNobodyID(uid_t *uid, gid_t *gid )
 {
        struct passwd *pwd;
 
@@ -679,7 +685,7 @@ NGIRCd_getNobodyID(unsigned int *uid, unsigned int *gid )
 }
 
 
-LOCAL bool
+static bool
 NGIRCd_Init( bool NGIRCd_NoDaemon ) 
 {
        static bool initialized;
@@ -687,7 +693,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
        struct passwd *pwd;
        struct group *grp;
        int real_errno;
-       long pid;
+       pid_t pid;
 
        if (initialized)
                return true;
@@ -711,28 +717,34 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
                }
        }
 
-       if ( Conf_UID == 0 ) {
-               Log( LOG_INFO, "Conf_UID must not be 0, switching to user nobody", Conf_UID );
+       if (Conf_UID == 0) {
+               Log(LOG_INFO, "ServerUID must not be 0, using \"nobody\" instead.", Conf_UID);
 
-               if (!NGIRCd_getNobodyID(&Conf_UID, &Conf_GID )) {
-                       Log( LOG_WARNING, "Could not get uid/gid of user nobody: %s",
+               if (! NGIRCd_getNobodyID(&Conf_UID, &Conf_GID)) {
+                       Log(LOG_WARNING, "Could not get user/group ID of user \"nobody\": %s",
                                        errno ? strerror(errno) : "not found" );
                        return false;
                }
        }
 
-       if( setgid( Conf_GID ) != 0 ) {
-               real_errno = errno;
-               Log( LOG_ERR, "Can't change group ID to %u: %s", Conf_GID, strerror( errno ));
-               if (real_errno != EPERM) 
-                       return false;
+       if (getgid() != Conf_GID) {
+               /* Change group ID */
+               if (setgid(Conf_GID) != 0) {
+                       real_errno = errno;
+                       Log( LOG_ERR, "Can't change group ID to %u: %s", Conf_GID, strerror( errno ));
+                       if (real_errno != EPERM) 
+                               return false;
+               }
        }
 
-       if( setuid( Conf_UID ) != 0 ) {
-               real_errno = errno;
-               Log( LOG_ERR, "Can't change user ID to %u: %s", Conf_UID, strerror( errno ));
-               if (real_errno != EPERM) 
-                       return false;
+       if (getuid() != Conf_UID) {
+               /* Change user ID */
+               if (setuid(Conf_UID) != 0) {
+                       real_errno = errno;
+                       Log(LOG_ERR, "Can't change user ID to %u: %s", Conf_UID, strerror(errno));
+                       if (real_errno != EPERM) 
+                               return false;
+               }
        }
 
        initialized = true;
@@ -741,7 +753,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
         * connected to ther controlling terminal. Use "--nodaemon"
         * to disable this "daemon mode" (useful for debugging). */
        if ( ! NGIRCd_NoDaemon ) {
-               pid = (long)fork( );
+               pid = fork( );
                if( pid > 0 ) {
                        /* "Old" process: exit. */
                        exit( 0 );
@@ -764,16 +776,14 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 
        Pidfile_Create( pid );
 
-       /* check uid we are running as, can be different from values configured (e.g. if we were already
-       started with a uid > 0 */
+       /* Check UID/GID we are running as, can be different from values
+        * configured (e. g. if we were already started with a UID>0. */
        Conf_UID = getuid();
        Conf_GID = getgid();
 
-       assert( Conf_GID > 0);
-       assert( Conf_UID > 0);
-
        pwd = getpwuid( Conf_UID );
        grp = getgrgid( Conf_GID );
+
        Log( LOG_INFO, "Running as user %s(%ld), group %s(%ld), with PID %ld.",
                                pwd ? pwd->pw_name : "unknown", Conf_UID,
                                grp ? grp->gr_name : "unknown", Conf_GID, pid);
@@ -793,7 +803,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
                        if( chdir( pwd->pw_dir ) == 0 ) 
                                Log( LOG_DEBUG, "Changed working directory to \"%s\" ...", pwd->pw_dir );
                        else 
-                               Log( LOG_ERR, "Can't change working directory to \"%s\": %s",
+                               Log( LOG_INFO, "Notice: Can't change working directory to \"%s\": %s",
                                                                pwd->pw_dir, strerror( errno ));
                }
        } else {