예제 #1
0
/**
 * Reload the server configuration file.
 */
static void
Rehash(void)
{
	char old_name[CLIENT_ID_LEN];
	unsigned old_nicklen;

	Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );

	/* Remember old server name and nickname length */
	strlcpy( old_name, Conf_ServerName, sizeof old_name );
	old_nicklen = Conf_MaxNickLength;

	/* Re-read configuration ... */
	if (!Conf_Rehash( ))
		return;

	/* Close down all listening sockets */
	Conn_ExitListeners( );

	/* Recover old server name and nickname 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 */
	Channel_InitPredefined( );

	if (!ConnSSL_InitLibrary())
		Log(LOG_WARNING,
		    "Re-Initializing of SSL failed, using old keys!");

	/* Start listening on sockets */
	Conn_InitListeners( );

	/* Sync configuration with established connections */
	Conn_SyncServerStruct( );

	Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." );
} /* Rehash */
예제 #2
0
/**
 * The main() function of ngIRCd.
 *
 * Here all starts: this function is called by the operating system loader,
 * it is the first portion of code executed of ngIRCd.
 *
 * @param argc The number of arguments passed to ngIRCd on the command line.
 * @param argv An array containing all the arguments passed to ngIRCd.
 * @return Global exit code of ngIRCd, zero on success.
 */
GLOBAL int
main(int argc, const char *argv[])
{
	bool ok, configtest = false;
	bool NGIRCd_NoDaemon = false;
	int i;
	size_t n;

#if defined(DEBUG) && defined(HAVE_MTRACE)
	/* enable GNU libc memory tracing when running in debug mode
	 * and functionality available */
	mtrace();
#endif

	umask(0077);

	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();

	/* parse conmmand line */
	for (i = 1; i < argc; i++) {
		ok = false;
		if (argv[i][0] == '-' && argv[i][1] == '-') {
			/* long option */
			if (strcmp(argv[i], "--config") == 0) {
				if (i + 1 < argc) {
					/* Ok, there's an parameter left */
					strlcpy(NGIRCd_ConfFile, argv[i+1],
						sizeof(NGIRCd_ConfFile));
					/* next parameter */
					i++; ok = true;
				}
			}
			if (strcmp(argv[i], "--configtest") == 0) {
				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);
			}
			if (strcmp(argv[i], "--nodaemon") == 0) {
				NGIRCd_NoDaemon = true;
				ok = true;
			}
			if (strcmp(argv[i], "--passive") == 0) {
				NGIRCd_Passive = true;
				ok = true;
			}
#ifdef SNIFFER
			if (strcmp(argv[i], "--sniffer") == 0) {
				NGIRCd_Sniffer = true;
				ok = true;
			}
#endif
			if (strcmp(argv[i], "--version") == 0) {
				Show_Version();
				exit(1);
			}
		}
		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 */
						strlcpy(NGIRCd_ConfFile, argv[i+1],
							sizeof(NGIRCd_ConfFile));

						/* go to the following parameter */
						i++;
						n = strlen(argv[i]);
						ok = true;
					}
				}

				if (argv[i][n] == 'h') {
					Show_Version();
					puts(""); Show_Help(); puts("");
					exit(1);
				}

				if (argv[i][n] == 'n') {
					NGIRCd_NoDaemon = true;
					ok = true;
				}
				if (argv[i][n] == 'p') {
					NGIRCd_Passive = true;
					ok = true;
				}
#ifdef SNIFFER
				if (argv[i][n] == 's') {
					NGIRCd_Sniffer = true;
					ok = true;
				}
#endif
				if (argv[i][n] == 't') {
					configtest = true;
					ok = true;
				}

				if (argv[i][n] == 'V') {
					Show_Version();
					exit(1);
				}

				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);
				}
			}

		}
		if (!ok) {
			printf("%s: invalid option \"%s\"!\n",
			       PACKAGE_NAME, argv[i]);
			printf("Try \"%s --help\" for more information.\n",
			       PACKAGE_NAME);
			exit(1);
		}
	}

	/* 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;
		strcpy(NGIRCd_DebugLevel, "2");
	}
#endif

	if (configtest) {
		Show_Version(); puts("");
		exit(Conf_Test());
	}

	while (!NGIRCd_SignalQuit) {
		/* Initialize global variables */
		NGIRCd_Start = time(NULL);
		(void)strftime(NGIRCd_StartStr, 64,
			       "%a %b %d %Y at %H:%M:%S (%Z)",
			       localtime(&NGIRCd_Start));

		NGIRCd_SignalRestart = false;
		NGIRCd_SignalQuit = false;

		/* Initialize modules, part I */
		Log_Init(!NGIRCd_NoDaemon);
		Random_Init();
		Conf_Init();
		Log_ReInit();

		/* 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 ... */
		Channel_Init();
		Client_Init();
		Conn_Init();
		Class_Init();

		if (!io_library_init(CONNECTION_POOL)) {
			Log(LOG_ALERT,
			    "Fatal: Could not initialize IO routines: %s",
			    strerror(errno));
			exit(1);
		}

		if (!Signals_Init()) {
			Log(LOG_ALERT,
			    "Fatal: Could not set up signal handlers: %s",
			    strerror(errno));
			exit(1);
		}

		/* Create protocol and server identification. The syntax
		 * used by ngIRCd in PASS commands and the known "extended
		 * flags" are described in doc/Protocol.txt. */
#ifdef IRCPLUS
		snprintf(NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s:%s",
			 PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION,
			 IRCPLUSFLAGS);
#ifdef ZLIB
		strcat(NGIRCd_ProtoID, "Z");
#endif
		if (Conf_OperCanMode)
			strcat(NGIRCd_ProtoID, "o");
#else /* IRCPLUS */
		snprintf(NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s",
			 PROTOVER, PROTOIRC, PACKAGE_NAME, PACKAGE_VERSION);
#endif /* IRCPLUS */
		strlcat(NGIRCd_ProtoID, " P", sizeof NGIRCd_ProtoID);
#ifdef ZLIB
		strlcat(NGIRCd_ProtoID, "Z", sizeof NGIRCd_ProtoID);
#endif
		LogDebug("Protocol and server ID is \"%s\".", NGIRCd_ProtoID);

		Channel_InitPredefined();

		if (Conn_InitListeners() < 1) {
			Log(LOG_ALERT,
			    "Server isn't listening on a single port!" );
			Log(LOG_ALERT,
			    "%s exiting due to fatal errors!", PACKAGE_NAME);
			Pidfile_Delete();
			exit(1);
		}

		/* Main Run Loop */
		Conn_Handler();

		Conn_Exit();
		Client_Exit();
		Channel_Exit();
		Class_Exit();
		Log_Exit();
	}
	Pidfile_Delete();

	return 0;
} /* main */