X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fngircd.c;h=7166640ba054288c08030f331ddf9c9724e0a073;hp=dfae3366d1f72655cc8cc0e51088b369d9218114;hb=HEAD;hpb=1f59821270e7298b380183778672e6db9c87971b diff --git a/src/ngircd/ngircd.c b/src/ngircd/ngircd.c index dfae3366..c2169c43 100644 --- a/src/ngircd/ngircd.c +++ b/src/ngircd/ngircd.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2024 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 @@ -9,6 +9,7 @@ * Please read the file COPYING, README and AUTHORS for more information. */ +#define GLOBAL_INIT #include "portab.h" /** @@ -17,12 +18,10 @@ * by the loader of the operating system. */ -#include "imp.h" #include #include #include #include -#include #include #include #include @@ -36,23 +35,16 @@ #include #endif -#include "defines.h" #include "conn.h" #include "class.h" -#include "conf-ssl.h" #include "channel.h" #include "conf.h" -#include "lists.h" #include "log.h" -#include "parse.h" #include "sighandlers.h" #include "io.h" -#include "irc.h" -#include "exp.h" #include "ngircd.h" - static void Show_Version PARAMS(( void )); static void Show_Help PARAMS(( void )); @@ -82,7 +74,7 @@ GLOBAL int main(int argc, const char *argv[]) { bool ok, configtest = false; - bool NGIRCd_NoDaemon = false; + bool NGIRCd_NoDaemon = false, NGIRCd_NoSyslog = false; int i; size_t n; @@ -96,14 +88,10 @@ main(int argc, const char *argv[]) NGIRCd_SignalQuit = NGIRCd_SignalRestart = false; NGIRCd_Passive = false; -#ifdef DEBUG NGIRCd_Debug = false; -#endif #ifdef SNIFFER NGIRCd_Sniffer = false; #endif - strlcpy(NGIRCd_ConfFile, SYSCONFDIR, sizeof(NGIRCd_ConfFile)); - strlcat(NGIRCd_ConfFile, CONFIG_FILE, sizeof(NGIRCd_ConfFile)); Fill_Version(); @@ -125,19 +113,18 @@ main(int argc, const char *argv[]) configtest = true; ok = true; } -#ifdef DEBUG if (strcmp(argv[i], "--debug") == 0) { NGIRCd_Debug = true; ok = true; } -#endif if (strcmp(argv[i], "--help") == 0) { Show_Version(); puts(""); Show_Help( ); puts( "" ); - exit(1); + exit(0); } if (strcmp(argv[i], "--nodaemon") == 0) { NGIRCd_NoDaemon = true; + NGIRCd_NoSyslog = true; ok = true; } if (strcmp(argv[i], "--passive") == 0) { @@ -149,22 +136,26 @@ main(int argc, const char *argv[]) NGIRCd_Sniffer = true; ok = true; } +#endif +#ifdef SYSLOG + if (strcmp(argv[i], "--syslog") == 0) { + NGIRCd_NoSyslog = false; + ok = true; + } #endif if (strcmp(argv[i], "--version") == 0) { Show_Version(); - exit(1); + exit(0); } } else if(argv[i][0] == '-' && argv[i][1] != '-') { /* short option */ for (n = 1; n < strlen(argv[i]); n++) { ok = false; -#ifdef DEBUG if (argv[i][n] == 'd') { NGIRCd_Debug = true; ok = true; } -#endif if (argv[i][n] == 'f') { if (!argv[i][n+1] && i+1 < argc) { /* Ok, next character is a blank */ @@ -186,6 +177,7 @@ main(int argc, const char *argv[]) if (argv[i][n] == 'n') { NGIRCd_NoDaemon = true; + NGIRCd_NoSyslog = true; ok = true; } if (argv[i][n] == 'p') { @@ -207,32 +199,38 @@ main(int argc, const char *argv[]) Show_Version(); exit(1); } +#ifdef SYSLOG + if (argv[i][n] == 'y') { + NGIRCd_NoSyslog = false; + ok = true; + } +#endif if (!ok) { - printf("%s: invalid option \"-%c\"!\n", - PACKAGE_NAME, argv[i][n]); - printf("Try \"%s --help\" for more information.\n", - PACKAGE_NAME); - exit(1); + fprintf(stderr, + "%s: invalid option \"-%c\"!\n", + PACKAGE_NAME, argv[i][n]); + fprintf(stderr, + "Try \"%s --help\" for more information.\n", + PACKAGE_NAME); + exit(2); } } } if (!ok) { - printf("%s: invalid option \"%s\"!\n", - PACKAGE_NAME, argv[i]); - printf("Try \"%s --help\" for more information.\n", - PACKAGE_NAME); - exit(1); + fprintf(stderr, "%s: invalid option \"%s\"!\n", + PACKAGE_NAME, argv[i]); + fprintf(stderr, "Try \"%s --help\" for more information.\n", + PACKAGE_NAME); + exit(2); } } /* Debug level for "VERSION" command */ NGIRCd_DebugLevel[0] = '\0'; -#ifdef DEBUG if (NGIRCd_Debug) strcpy(NGIRCd_DebugLevel, "1"); -#endif #ifdef SNIFFER if (NGIRCd_Sniffer) { NGIRCd_Debug = true; @@ -255,26 +253,18 @@ main(int argc, const char *argv[]) NGIRCd_SignalRestart = false; NGIRCd_SignalQuit = false; - /* Initialize modules, part I */ - Log_Init(!NGIRCd_NoDaemon); + Log_Init(!NGIRCd_NoSyslog); Random_Init(); Conf_Init(); Log_ReInit(); - /* Initialize the "main program": chroot environment, user and - * group ID, ... */ + /* Initialize the "main program": + * chroot environment, user and group ID, ... */ if (!NGIRCd_Init(NGIRCd_NoDaemon)) { - Log(LOG_ALERT, "Fatal: Initialization failed"); + Log(LOG_ALERT, "Fatal: Initialization failed, exiting!"); exit(1); } - /* Initialize modules, part II: these functions are eventually - * called with already dropped privileges ... */ - Channel_Init(); - Client_Init(); - Conn_Init(); - Class_Init(); - if (!io_library_init(CONNECTION_POOL)) { Log(LOG_ALERT, "Fatal: Could not initialize IO routines: %s", @@ -289,6 +279,11 @@ main(int argc, const char *argv[]) exit(1); } + Channel_Init(); + Conn_Init(); + Class_Init(); + Client_Init(); + /* Create protocol and server identification. The syntax * used by ngIRCd in PASS commands and the known "extended * flags" are described in doc/Protocol.txt. */ @@ -297,10 +292,10 @@ main(int argc, const char *argv[]) PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION, IRCPLUSFLAGS); #ifdef ZLIB - strcat(NGIRCd_ProtoID, "Z"); + strlcat(NGIRCd_ProtoID, "Z", sizeof NGIRCd_ProtoID); #endif if (Conf_OperCanMode) - strcat(NGIRCd_ProtoID, "o"); + strlcat(NGIRCd_ProtoID, "o", sizeof NGIRCd_ProtoID); #else /* IRCPLUS */ snprintf(NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s", PROTOVER, PROTOIRC, PACKAGE_NAME, PACKAGE_VERSION); @@ -460,7 +455,7 @@ static void Show_Version( void ) { puts( NGIRCd_Version ); - puts( "Copyright (c)2001-2013 Alexander Barton () and Contributors." ); + puts( "Copyright (c)2001-2024 Alexander Barton () and Contributors." ); puts( "Homepage: \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." ); @@ -475,9 +470,7 @@ Show_Version( void ) static void Show_Help( void ) { -#ifdef DEBUG puts( " -d, --debug log extra debug messages" ); -#endif puts( " -f, --config use file as configuration file" ); puts( " -n, --nodaemon don't fork and don't detach from controlling terminal" ); puts( " -p, --passive disable automatic connections to other servers" ); @@ -486,6 +479,9 @@ Show_Help( void ) #endif puts( " -t, --configtest read, validate and display configuration; then exit" ); puts( " -V, --version output version information and exit" ); +#ifdef SYSLOG + puts( " -y, --syslog log to syslog even when running in the foreground (-n)" ); +#endif puts( " -h, --help display this help and exit" ); } /* Show_Help */ @@ -499,9 +495,7 @@ Pidfile_Delete( void ) /* Pidfile configured? */ if( ! Conf_PidFile[0] ) return; -#ifdef DEBUG - Log( LOG_DEBUG, "Removing PID file (%s) ...", Conf_PidFile ); -#endif + LogDebug( "Removing PID file (%s) ...", Conf_PidFile ); if( unlink( Conf_PidFile )) Log( LOG_ERR, "Error unlinking PID file (%s): %s", Conf_PidFile, strerror( errno )); @@ -523,9 +517,7 @@ Pidfile_Create(pid_t pid) /* Pidfile configured? */ if( ! Conf_PidFile[0] ) return; -#ifdef DEBUG - Log( LOG_DEBUG, "Creating PID file (%s) ...", Conf_PidFile ); -#endif + LogDebug( "Creating PID file (%s) ...", Conf_PidFile ); pidfd = open( Conf_PidFile, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if ( pidfd < 0 ) { @@ -535,21 +527,23 @@ Pidfile_Create(pid_t pid) len = snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid); if (len < 0 || len >= (int)sizeof pidbuf) { - Log(LOG_ERR, "Error converting pid"); + Log(LOG_ERR, "Error converting process ID!"); close(pidfd); return; } - + if (write(pidfd, pidbuf, (size_t)len) != (ssize_t)len) - Log( LOG_ERR, "Can't write PID file (%s): %s", Conf_PidFile, strerror( errno )); + Log(LOG_ERR, "Can't write PID file (%s): %s!", Conf_PidFile, + strerror(errno)); - if( close(pidfd) != 0 ) - Log( LOG_ERR, "Error closing PID file (%s): %s", Conf_PidFile, strerror( errno )); + if (close(pidfd) != 0) + Log(LOG_ERR, "Error closing PID file (%s): %s!", Conf_PidFile, + strerror(errno)); } /* Pidfile_Create */ /** - * Redirect stdin, stdout and stderr to apropriate file handles. + * Redirect stdin, stdout and stderr to appropriate file handles. * * @param fd The file handle stdin, stdout and stderr should be redirected to. */ @@ -611,6 +605,13 @@ NGIRCd_getNobodyID(uid_t *uid, gid_t *gid ) #endif +#ifdef HAVE_ARC4RANDOM +static void +Random_Init(void) +{ + +} +#else static bool Random_Init_Kern(const char *file) { @@ -640,6 +641,7 @@ Random_Init(void) return; srand(rand() ^ (unsigned)getpid() ^ (unsigned)time(NULL)); } +#endif /** @@ -671,21 +673,22 @@ NGIRCd_Init(bool NGIRCd_NoDaemon) } /* SSL initialization */ - if (!ConnSSL_InitLibrary()) - Log(LOG_WARNING, - "Error during SSL initialization, continuing without SSL ..."); + if (!ConnSSL_InitLibrary()) { + Log(LOG_ERR, "Error during SSL initialization!"); + goto out; + } /* Change root */ if (Conf_Chroot[0]) { if (chdir(Conf_Chroot) != 0) { - Log(LOG_ERR, "Can't chdir() in ChrootDir (%s): %s", + Log(LOG_ERR, "Can't chdir() in ChrootDir (%s): %s!", Conf_Chroot, strerror(errno)); goto out; } if (chroot(Conf_Chroot) != 0) { Log(LOG_ERR, - "Can't change root directory to \"%s\": %s", + "Can't change root directory to \"%s\": %s!", Conf_Chroot, strerror(errno)); goto out; } else { @@ -716,12 +719,24 @@ NGIRCd_Init(bool NGIRCd_NoDaemon) if (setgid(Conf_GID) != 0) { real_errno = errno; grp = getgrgid(Conf_GID); - Log(LOG_ERR, "Can't change group ID to %s(%u): %s", + Log(LOG_ERR, "Can't change group ID to %s(%u): %s!", grp ? grp->gr_name : "?", Conf_GID, - strerror(errno)); - if (real_errno != EPERM) + strerror(real_errno)); + if (real_errno != EPERM && real_errno != EINVAL) + goto out; + } +#ifdef HAVE_SETGROUPS + if (setgroups(0, NULL) != 0) { + real_errno = errno; + Log(LOG_ERR, "Can't drop supplementary group IDs: %s!", + strerror(errno)); + if (real_errno != EPERM) goto out; } +#else + Log(LOG_WARNING, + "Can't drop supplementary group IDs: setgroups(3) missing!"); +#endif } #endif @@ -730,10 +745,10 @@ NGIRCd_Init(bool NGIRCd_NoDaemon) if (setuid(Conf_UID) != 0) { real_errno = errno; pwd = getpwuid(Conf_UID); - Log(LOG_ERR, "Can't change user ID to %s(%u): %s", + Log(LOG_ERR, "Can't change user ID to %s(%u): %s!", pwd ? pwd->pw_name : "?", Conf_UID, - strerror(errno)); - if (real_errno != EPERM) + strerror(real_errno)); + if (real_errno != EPERM && real_errno != EINVAL) goto out; } } @@ -741,7 +756,7 @@ NGIRCd_Init(bool NGIRCd_NoDaemon) initialized = true; /* Normally a child process is forked which isn't any longer - * connected to ther controlling terminal. Use "--nodaemon" + * connected to the controlling terminal. Use "--nodaemon" * to disable this "daemon mode" (useful for debugging). */ if (!NGIRCd_NoDaemon) { pid = fork(); @@ -764,7 +779,7 @@ NGIRCd_Init(bool NGIRCd_NoDaemon) setpgrp(0, getpid()); #endif if (chdir("/") != 0) - Log(LOG_ERR, "Can't change directory to '/': %s", + Log(LOG_ERR, "Can't change directory to '/': %s!", strerror(errno)); /* Detach stdin, stdout and stderr */ @@ -803,15 +818,15 @@ NGIRCd_Init(bool NGIRCd_NoDaemon) if (pwd) { if (chdir(pwd->pw_dir) == 0) - Log(LOG_DEBUG, + LogDebug( "Changed working directory to \"%s\" ...", pwd->pw_dir); else - Log(LOG_INFO, - "Notice: Can't change working directory to \"%s\": %s", + Log(LOG_ERR, + "Can't change working directory to \"%s\": %s!", pwd->pw_dir, strerror(errno)); } else - Log(LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID); + Log(LOG_ERR, "Can't get user information for UID %d!?", Conf_UID); return true; out: