+static void *main_tread(void *empty);
+static TIMEQ_CALLBACK(clear_cache);
+static TIMEQ_CALLBACK(main_checkauths);
+static void check_firstrun();
+
+
+static void main_parse_arguments() {
+ int c;
+ struct option options[] = {
+ {"show", 1, 0, 's'},
+ {"foreground", 0, 0, 'f'},
+ {"config", 1, 0, 'c'},
+ {"pid", 1, 0, 'p'},
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 'v'},
+ {0, 0, 0, 0}
+ };
+ while ((c = getopt_long(process_state.argc, process_state.argv, "s:fvh", options, NULL)) != -1) {
+ switch (c) {
+ case 'c':
+ strncpy(process_state.config, optarg, MAXLEN-1);
+ break;
+ case 'p':
+ strncpy(process_state.pidfile, optarg, MAXLEN-1);
+ break;
+ case 's':
+ process_state.loglevel = atoi(optarg);
+ break;
+ case 'f':
+ process_state.run_as_daemon = 0;
+ break;
+ case 'v':
+ printf("Version: %s.%d (%s)\n", NEONSERV_VERSION, patchlevel, (strcmp(revision, "") ? revision : "-"));
+ printf("Build: #%s %s (%s lines, " COMPILER ")\n", compilation, creation, codelines);
+ exit(0);
+ break;
+ case 'h':
+ printf("Usage: ./neonserv [-c neonserv.conf] [-p neonserv.pid] [-s loglevel] [-f] [-h|-v]\n");
+ printf(" -c, --config use this configuration file.\n");
+ printf(" -f, --foreground run NeonServ in the foreground.\n");
+ printf(" -h, --help prints this usage message.\n");
+ printf(" -p, --pid use this pid file.\n");
+ printf(" -s, --show show log lines matching loglevel in stdout.\n");
+ printf(" -v, --version prints this program's version.\n");
+ exit(0);
+ break;
+ }
+ }
+}
+
+static void main_daemon_exit() {
+ remove(process_state.pidfile);
+}
+
+static void main_daemonize() {
+ #ifndef WIN32
+ /* Attempt to fork into the background if daemon mode is on. */
+ pid_t pid = fork();
+ if (pid < 0) {
+ fprintf(stderr, "Unable to fork: %s\n", strerror(errno));
+ } else if (pid > 0) {
+ printf("Forking into the background (pid: %d)...\n", pid);
+ printf_log("main", LOG_INFO, "Forking into the background (pid: %d)...\n", pid);
+ exit(0);
+ }
+ setsid();
+ process_state.daemonized = 1;
+ atexit(main_daemon_exit);
+ FILE *pidfile = fopen(process_state.pidfile, "w");
+ if (pidfile == NULL) {
+ fprintf(stderr, "Unable to create PID file: %s\n", strerror(errno));
+ printf_log("main", LOG_ERROR, "Unable to create PID file: %s\n", strerror(errno));
+ } else {
+ fprintf(pidfile, "%i\n", (int)getpid());
+ fclose(pidfile);
+ }
+ FILE *retn;
+ fclose(stdin); retn = fopen("/dev/null", "r");
+ fclose(stdout); retn = fopen("/dev/null", "w");
+ fclose(stderr); retn = fopen("/dev/null", "w");
+ #endif
+}
+
+static int reload_configuration() {
+ printf_log("main", LOG_DEBUG, "reloading configuration file: %s", process_state.config);
+ if(!loadConfig(process_state.config)) {
+ printf_log("main", LOG_ERROR, "could not reload configuration file: %s", process_state.config);
+ return 1;
+ }
+ if(process_state.loaded_config) {
+ if(!reload_mysql())
+ return 2;
+ char **modulelist = get_all_fieldnames("modules");
+ if(!modulelist || !modulelist[0]) {
+ free(modulelist);
+ return 3;
+ }
+ free(modulelist);
+ event_reload(0);
+ }
+ process_state.loaded_config = 1;
+ return 0;
+}
+
+
+/* INITIALISATION OF SUBSYSTEMS */
+void initialize_subsystems() {
+ init_bind();
+ init_log();
+ printf_log("main", LOG_INFO, "starting up NeonServ %s subsystems...", NEONSERV_VERSION);
+ init_lang();
+ init_parser();
+ init_UserNode();
+ init_ChanNode();
+ init_ModeNode();
+ init_modcmd();
+ register_module_commands();
+ init_handleinfohandler();
+ init_tools();
+ init_modulefunctions();
+ loadModules();
+ init_bots();
+ init_DBHelper();
+ qserver_init();
+ load_languages();
+ init_statistics();
+}
+
+void shutdown_subsystems() {
+ printf_log("main", LOG_INFO, "stopping NeonServ subsystems...");
+ free_sockets(1);
+ //wait 50ms (run iohandler)
+ {
+ struct timeval timeout, ctime1, ctime2;
+ gettimeofday(&ctime1, NULL);
+ ctime1.tv_usec += 50000;
+ if(ctime1.tv_usec > 1000000) {
+ ctime1.tv_usec -= 1000000;
+ ctime1.tv_sec++;
+ }
+ do {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 10000;
+ iohandler_poll_timeout(timeout);
+ gettimeofday(&ctime2, NULL);
+ } while(timeval_is_bigger(ctime1, ctime2));
+ }
+ stop_modules();
+ free_sockets(0);