GF_EXPORT GF_ModuleManager *gf_modules_new(const char *directory, GF_Config *config) { GF_ModuleManager *tmp; u32 loadedModules; const char *opt; u32 num_dirs = 0; if (!config) return NULL; /* Try to resolve directory from config file */ GF_SAFEALLOC(tmp, GF_ModuleManager); if (!tmp) return NULL; tmp->cfg = config; tmp->mutex = gf_mx_new("Module Manager"); gf_modules_get_module_directories(tmp, &num_dirs); /* Initialize module list */ tmp->plug_list = gf_list_new(); if (!tmp->plug_list) { GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("OUT OF MEMORY, cannot create list of modules !!!\n")); gf_free(tmp); return NULL; } tmp->plugin_registry = gf_list_new(); if (!tmp->plugin_registry) { GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("OUT OF MEMORY, cannot create list of static module registers !!!\n")); gf_list_del(tmp->plug_list); gf_free(tmp); return NULL; } opt = gf_cfg_get_key(config, "Systems", "ModuleUnload"); if (opt && !strcmp(opt, "no")) { tmp->no_unload = GF_TRUE; } #ifndef GPAC_MODULE_CUSTOM_LOAD load_all_modules(tmp); #endif loadedModules = gf_modules_refresh(tmp); GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("Loaded %d modules from directory %s.\n", loadedModules, directory)); return tmp; }
static void do_modrestart(struct Client *source_p) { int modnum; sendto_one_notice(source_p, ":Reloading all modules"); modnum = num_mods; while (num_mods) unload_one_module(modlist[0]->name, false); load_all_modules(false); load_core_modules(false); rehash(false); sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Module Restart: %d modules unloaded, %d modules loaded", modnum, num_mods); ilog(L_MAIN, "Module Restart: %d modules unloaded, %d modules loaded", modnum, num_mods); }
void parse_command_line(int argc, char *argv[], int spec) { const char *arg, *aispec; char tmpspec[100], tmpargbuf[CLIBUFSIZE], blurb[BLURBSIZE]; int i, n, numused, total_arg_space, tmpargbuflen = 0; /* This macro just checks that a required next argument is actually there. */ #define REQUIRE_ONE_ARG \ if (i + 1 >= argc) { \ fprintf(stderr, "Error: `%s' requires an argument, exiting now\n", argv[i]); \ had_error = TRUE; \ continue; \ } \ numused = 2; /* Each of these causes argument parsing to skip over the option if it's not the right time to look at it. */ #define GENERAL_OPTION if (spec != general_options) continue; #define VARIANT_OPTION if (spec != variant_options) continue; #define PLAYER_OPTION if (spec != player_options) continue; /* (should peel off any path stuff) */ program_name = argv[0]; if (spec == general_options) init_options(); total_arg_space = 0; for (i = 0; i < argc; ++i) { if (!empty_string(argv[i])) { strncpy(tmpargbuf, argv[i], CLIBUFSIZE); tmpargbuf[CLIBUFSIZE - 1] = 0; tmpargbuflen = strlen(tmpargbuf); total_arg_space += tmpargbuflen + 2; (argv[i])[tmpargbuflen] = 0; } } if (args_used == NULL) args_used = (char *)xmalloc (total_arg_space); for (i = 1; i < argc; ++i) { if (argv[i] == NULL || (argv[i])[0] == '\0') { /* Empty or already munched, nothing to do. */ } else if ((argv[i])[0] == '-') { arg = argv[i]; Dprintf("%s\n", arg); numused = 1; if (strcmp(arg, "-c") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; checkpoint_interval = atoi(argv[i+1]); } else if (strcmp(arg, "-design") == 0) { GENERAL_OPTION; #ifdef DESIGNERS allbedesigners = TRUE; #else fprintf(stderr, "No designing available, ignoring option `%s'\n", arg); #endif /* DESIGNERS */ } else if (strncmp(arg, "-D", 2) == 0) { GENERAL_OPTION; #ifdef DEBUGGING Debug = TRUE; if (strchr(arg+2, '-')) Debug = FALSE; if (strchr(arg+2, 'M')) DebugM = TRUE; if (strchr(arg+2, 'G')) DebugG = TRUE; #else fprintf(stderr, "No debugging available, ignoring option `%s'\n", arg); #endif /* DEBUGGING */ } else if (strncmp(arg, "-e", 2) == 0) { REQUIRE_ONE_ARG; PLAYER_OPTION; n = atoi(argv[i+1]); /* A comma indicates that the name of a particular desired AI type follows. */ if (strlen(arg) > 2) { aispec = arg + 2; if (*aispec != ',') { sprintf(tmpspec, "%s%s", default_ai_type, aispec); aispec = tmpspec; } } else { aispec = default_ai_type; } while (n-- > 0) add_a_raw_player_spec(aispec); } else if (strcmp(arg, "-f") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; add_a_module(NULL, argv[i+1]); } else if (strcmp(arg, "-g") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; add_a_module(copy_string(argv[i+1]), NULL); } else if (strcmp(arg, "-h") == 0) { REQUIRE_ONE_ARG; PLAYER_OPTION; n = atoi(argv[i+1]); option_num_to_wait_for += n; while (n-- > 0) add_a_raw_player_spec("?@"); } else if (strcmp(arg, "-help") == 0) { GENERAL_OPTION; help_wanted = TRUE; /* Will display help info later. */ } else if (strcmp(arg, "-host") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; option_game_to_host = copy_string(argv[i+1]); } else if (strcmp(arg, "-join") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; option_game_to_join = copy_string(argv[i+1]); } else if (strcmp(arg, "-L") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; if (strcmp(argv[i+1], "-") == 0) add_library_path(NULL); else add_library_path(argv[i+1]); } else if (strcmp(arg, "-M") == 0) { REQUIRE_ONE_ARG; VARIANT_OPTION; parse_world_option(argv[i+1]); } else if (strcmp(arg, "-noai") == 0) { PLAYER_OPTION; initially_no_ai = TRUE; } else if (strcmp(arg, "-r") == 0) { PLAYER_OPTION; option_add_default_player = FALSE; } else if (strcmp(arg, "-R") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; #ifdef DEBUGGING init_xrandom(atoi(argv[i+1])); #else fprintf(stderr, "No debugging available, ignoring option `%s'\n", arg); #endif /* DEBUGGING */ } else if (strcmp(arg, "-seq") == 0) { VARIANT_OPTION; push_key_int_binding(&variant_settings, K_SEQUENTIAL, 1); } else if (strcmp(arg, "-sim") == 0) { VARIANT_OPTION; push_key_int_binding(&variant_settings, K_SEQUENTIAL, 0); } else if (strncmp(arg, "-t", 2) == 0) { REQUIRE_ONE_ARG; VARIANT_OPTION; parse_realtime_option(arg, argv[i+1]); } else if (strncmp(arg, "-v", 2) == 0) { VARIANT_OPTION; parse_variant(arg + 2); } else if (strcmp(arg, "-V") == 0) { VARIANT_OPTION; push_key_int_binding(&variant_settings, K_SEE_ALL, 1); } else if (strcmp(arg, "-V0") == 0) { VARIANT_OPTION; push_key_int_binding(&variant_settings, K_SEE_ALL, 0); } else if (strcmp(arg, "-Vfalse") == 0) { VARIANT_OPTION; push_key_int_binding(&variant_settings, K_SEE_ALL, 0); } else if (strcmp(arg, "-w") == 0) { GENERAL_OPTION; warnings_suppressed = TRUE; } else if (strcmp(arg, "-x") == 0) { GENERAL_OPTION; option_popup_new_game_dialog = TRUE; } else if (strcmp(arg, "--help") == 0) { GENERAL_OPTION; help_wanted = TRUE; /* Will display help info later. */ } else if (strcmp(arg, "--version") == 0) { GENERAL_OPTION; version_wanted = TRUE; } else { numused = 0; /* Anything unrecognized during the last parse is an error. */ if (spec >= leftover_options) { fprintf(stderr, "Unrecognized option `%s'\n", arg); had_error = TRUE; } } if (numused >= 1) { strcat(args_used, " "); strcat(args_used, argv[i]); argv[i] = NULL; } if (numused >= 2) { strcat(args_used, " "); strcat(args_used, argv[i+1]); argv[i+1] = NULL; } if (numused >= 1) i += (numused - 1); } else { if (spec == player_options) { if (*(argv[i]) == '+' || *(argv[i]) == '@') { raw_default_player_spec = argv[i]; } else { add_a_raw_player_spec(argv[i]); } strcat(args_used, " "); strcat(args_used, argv[i]); argv[i] = NULL; } } } if (version_wanted) { version_info(); } if (had_error || help_wanted || variant_help_wanted) { /* If we want to get help about a particular game, have to load it first. */ if (help_wanted || variant_help_wanted) load_all_modules(); if (had_error || help_wanted) general_usage_info(); if (had_error || help_wanted) player_usage_info(); if (help_wanted && mainmodule != NULL) { printf("\nGame info:\n\n"); if (!empty_string(mainmodule->title)) printf("%s (%s)\n", mainmodule->title, mainmodule->name); else printf("%s\n", mainmodule->name); printf(" \n"); if (mainmodule->blurb != lispnil) { append_blurb_strings(blurb, mainmodule->blurb); printf("%s", blurb); } else { printf("(no description)"); } } /* Display variant info here so it comes after basic info about the game module. */ if (had_error || help_wanted || variant_help_wanted) game_usage_info(); } if (had_error || help_wanted || variant_help_wanted || version_wanted) { exit(had_error); } }
int main( int argc, char *argv[] ) { int c, items_to_show, debug, status; char item_name[ MXU_DRIVER_NAME_LENGTH + 1 ]; mx_bool_type show_all_fields, show_handles, show_link, start_debugger; unsigned long i, length, structures_to_show; static char usage_format[] = "Usage: %s [options]\n" "\n" " where options are\n" " -f'driver_name' Display record fields in record description\n" " -a'driver_name' Display all record fields\n" "\n" " -s Display available MX superclasses\n" " -c'superclass_name' Display available MX classes\n" " -t'class_name' Display available MX types\n" "\n" " -l Display all MX types\n" "\n" " -v Display the version of MX in use\n" "\n" " -m'module_name' Load the MX module named 'module_name'\n" " -M Load all MX modules in the default module directory\n" "\n" " -h Display array handles\n" " -d Turn on debugging output\n" "\n" " -D Start debugger\n" "\n" " LaTeX documentation generation options:\n" "\n" " -F'driver_name' Display record fields in description for LaTeX\n" " -A'driver_name' Display all record fields for LaTeX\n" "\n" " -L Show the field links for LaTeX\n" "\n" " -S[r][s][c][t] Specify structures to show in LaTeX\n" " r = record structures\n" " s = superclass structures\n" " c = class structures\n" " t = type structures\n" "\n"; /* Process the command line arguments, if any. */ items_to_show = 0; debug = FALSE; structures_to_show = 0xffffffff; show_all_fields = FALSE; show_handles = FALSE; show_link = FALSE; start_debugger = FALSE; strlcpy( item_name, "", sizeof(item_name) ); while ((c = getopt(argc, argv, "a:c:dDf:hlm:Mst:vA:F:LS:x")) != -1 ) { switch (c) { case 'a': items_to_show = MXDI_FIELDS; show_all_fields = TRUE; strlcpy( item_name, optarg, MXU_DRIVER_NAME_LENGTH ); break; case 'c': items_to_show = MXDI_CLASSES; strlcpy( item_name, optarg, MXU_DRIVER_NAME_LENGTH ); break; case 'd': debug = TRUE; break; case 'D': start_debugger = TRUE; break; case 'f': items_to_show = MXDI_FIELDS; show_all_fields = FALSE; strlcpy( item_name, optarg, MXU_DRIVER_NAME_LENGTH ); break; case 'h': show_handles = TRUE; break; case 'l': items_to_show = MXDI_DRIVERS; break; case 'm': load_module( optarg ); break; case 'M': load_all_modules(); break; case 's': items_to_show = MXDI_SUPERCLASSES; break; case 't': items_to_show = MXDI_TYPES; strlcpy( item_name, optarg, MXU_DRIVER_NAME_LENGTH ); break; case 'v': items_to_show = MXDI_VERSION; break; case 'x': putenv("MX_DEBUGGER=xterm -e gdbtui -p %lu"); break; case 'A': items_to_show = MXDI_LATEX_FIELDS; show_all_fields = TRUE; strlcpy( item_name, optarg, MXU_DRIVER_NAME_LENGTH ); break; case 'F': items_to_show = MXDI_LATEX_FIELDS; show_all_fields = FALSE; strlcpy( item_name, optarg, MXU_DRIVER_NAME_LENGTH ); break; case 'L': show_link = TRUE; break; case 'S': length = strlen(optarg); structures_to_show = 0; for ( i = 0; i < length; i++ ) { c = optarg[i]; switch(c) { case 'r': structures_to_show |= MXF_REC_RECORD_STRUCT; break; case 's': structures_to_show |= MXF_REC_SUPERCLASS_STRUCT; break; case 'c': structures_to_show |= MXF_REC_CLASS_STRUCT; break; case 't': structures_to_show |= MXF_REC_TYPE_STRUCT; break; } } break; case '?': fprintf(stderr, usage_format, program_name); exit(1); } } if ( start_debugger ) { mx_start_debugger(NULL); } if ( debug ) { fprintf(stderr,"items_to_show = %d\n", items_to_show); fprintf(stderr,"item_name = '%s'\n", item_name); } /* Initialize the MX device drivers. */ mx_initialize_drivers(); /* Select the function to run. */ switch (items_to_show) { case MXDI_DRIVERS: status = show_all_drivers( debug ); break; case MXDI_SUPERCLASSES: status = show_drivers( items_to_show, NULL, debug ); break; case MXDI_CLASSES: case MXDI_TYPES: status = show_drivers( items_to_show, item_name, debug ); break; case MXDI_FIELDS: status = show_field_list( item_name, show_all_fields, show_handles, debug ); break; case MXDI_VERSION: fprintf(stderr, "\nMX version %s\n\n", mx_get_version_full_string()); status = SUCCESS; break; case MXDI_LATEX_FIELDS: status = show_latex_field_table( item_name, structures_to_show, show_all_fields, show_link, debug ); break; default: fprintf(stderr, usage_format, program_name); exit(1); break; } if ( status != SUCCESS ) exit(1); return 0; }
int main(int argc, char *argv[]) { /* Check to see if the user is running us as root, which is a nono */ if (!geteuid()) { fprintf(stderr, "ERROR: This server won't run as root/superuser\n"); return -1; } /* Setup corefile size immediately after boot -kre */ setup_corefile(); /* Save server boot time right away, so getrusage works correctly */ set_time(); /* It's not random, but it ought to be a little harder to guess */ init_genrand(SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid() << 20))); dlinkAdd(&me, &me.node, &global_client_list); ConfigGeneral.dpath = DPATH; ConfigGeneral.spath = SPATH; ConfigGeneral.mpath = MPATH; ConfigGeneral.configfile = CPATH; /* Server configuration file */ ConfigGeneral.klinefile = KPATH; /* Server kline file */ ConfigGeneral.glinefile = GPATH; /* Server gline file */ ConfigGeneral.xlinefile = XPATH; /* Server xline file */ ConfigGeneral.dlinefile = DLPATH; /* dline file */ ConfigGeneral.resvfile = RESVPATH; /* resv file */ myargv = argv; umask(077); /* umask 077: u=rwx,g=,o= */ parseargs(&argc, &argv, myopts); if (printVersion) { printf("ircd: version %s(%s)\n", ircd_version, serno); exit(EXIT_SUCCESS); } if (chdir(ConfigGeneral.dpath)) { perror("chdir"); exit(EXIT_FAILURE); } ssl_init(); if (!server_state.foreground) { make_daemon(); close_standard_fds(); /* this needs to be before init_netio()! */ } else print_startup(getpid()); setup_signals(); /* We need this to initialise the fd array before anything else */ fdlist_init(); log_set_file(LOG_TYPE_IRCD, 0, logFileName); init_netio(); /* This needs to be setup early ! -- adrian */ /* Check if there is pidfile and daemon already running */ check_pidfile(pidFileName); mp_pool_init(); init_dlink_nodes(); init_isupport(); dbuf_init(); hash_init(); ipcache_init(); client_init(); class_init(); whowas_init(); watch_init(); auth_init(); /* Initialise the auth code */ init_resolver(); /* Needs to be setup before the io loop */ modules_init(); read_conf_files(1); /* cold start init conf files */ init_uid(); initialize_server_capabs(); /* Set up default_server_capabs */ initialize_global_set_options(); /* Has to be called after read_conf_files() */ channel_init(); read_links_file(); motd_init(); user_usermodes_init(); #ifdef HAVE_LIBGEOIP geoip_ctx = GeoIP_new(GEOIP_MEMORY_CACHE); #endif if (EmptyString(ConfigServerInfo.sid)) { ilog(LOG_TYPE_IRCD, "ERROR: No server id specified in serverinfo block."); exit(EXIT_FAILURE); } strlcpy(me.id, ConfigServerInfo.sid, sizeof(me.id)); if (EmptyString(ConfigServerInfo.name)) { ilog(LOG_TYPE_IRCD, "ERROR: No server name specified in serverinfo block."); exit(EXIT_FAILURE); } strlcpy(me.name, ConfigServerInfo.name, sizeof(me.name)); /* serverinfo{} description must exist. If not, error out.*/ if (EmptyString(ConfigServerInfo.description)) { ilog(LOG_TYPE_IRCD, "ERROR: No server description specified in serverinfo block."); exit(EXIT_FAILURE); } strlcpy(me.info, ConfigServerInfo.description, sizeof(me.info)); me.from = &me; me.servptr = &me; me.connection->lasttime = CurrentTime; me.connection->since = CurrentTime; me.connection->firsttime = CurrentTime; SetMe(&me); make_server(&me); hash_add_id(&me); hash_add_client(&me); dlinkAdd(&me, make_dlink_node(), &global_server_list); load_kline_database(); load_dline_database(); load_gline_database(); load_xline_database(); load_resv_database(); load_all_modules(1); load_conf_modules(); load_core_modules(1); write_pidfile(pidFileName); ilog(LOG_TYPE_IRCD, "Server Ready"); event_addish(&event_cleanup_glines, NULL); event_addish(&event_cleanup_tklines, NULL); /* We want try_connections to be called as soon as possible now! -- adrian */ /* No, 'cause after a restart it would cause all sorts of nick collides */ event_addish(&event_try_connections, NULL); /* Setup the timeout check. I'll shift it later :) -- adrian */ event_add(&event_comm_checktimeouts, NULL); event_addish(&event_save_all_databases, NULL); if (ConfigServerHide.links_delay > 0) { event_write_links_file.when = ConfigServerHide.links_delay; event_addish(&event_write_links_file, NULL); } else ConfigServerHide.links_disabled = 1; if (splitmode) event_addish(&splitmode_event, NULL); io_loop(); return 0; }
int main(int argc, char *argv[]) { #ifndef _WIN32 if (geteuid() == 0) { fprintf(stderr, "Running IRC services is root is not recommended."); return 1; } setup_corefile(); #endif memset(&ServicesInfo, 0, sizeof(ServicesInfo)); memset(&ServicesState, 0, sizeof(ServicesState)); ServicesState.configfile = CPATH; ServicesState.logfile = LPATH; ServicesState.pidfile = PPATH; ServicesState.fully_connected = 0; parseargs(&argc, &argv, myopts); if(ServicesState.printversion) { printf("oftc-ircservices: version: %s\n", VERSION); exit(EXIT_SUCCESS); } if(chdir(DPATH)) { perror("chdir"); exit(EXIT_FAILURE); } #ifndef _WIN32 if(!ServicesState.foreground) make_daemon(); else print_startup(getpid()); #endif setup_signals(); memset(&me, 0, sizeof(me)); libio_init(!ServicesState.foreground); init_events(); iorecv_cb = register_callback("iorecv", iorecv_default); connected_cb = register_callback("server connected", server_connected); iosend_cb = register_callback("iosend", iosend_default); OpenSSL_add_all_digests(); init_interface(); check_pidfile(ServicesState.pidfile); init_log(ServicesState.logfile); #ifdef HAVE_RUBY init_ruby(); signal(SIGSEGV, SIG_DFL); #endif init_channel(); init_conf(); init_client(); init_parser(); init_channel_modes(); init_mqueue(); init_tor(); me.from = me.servptr = &me; SetServer(&me); SetMe(&me); dlinkAdd(&me, &me.node, &global_client_list); read_services_conf(TRUE); init_db(); init_uid(); #ifdef HAVE_PYTHON init_python(); #endif init_kill(); write_pidfile(ServicesState.pidfile); ilog(L_NOTICE, "Services Ready"); db_load_driver(); #ifdef USE_SHARED_MODULES if(chdir(MODPATH)) { ilog(L_ERROR, "Could not load core modules from %s: %s", MODPATH, strerror(errno)); exit(EXIT_FAILURE); } /* Go back to DPATH after checking to see if we can chdir to MODPATH */ chdir(DPATH); #else load_all_modules(1); #endif boot_modules(1); connect_server(); for(;;) { while (eventNextTime() <= CurrentTime) eventRun(); execute_callback(do_event_cb); if(events_loop() == -1) { ilog(L_CRIT, "libevent returned error %d", errno); services_die("Libevent returned some sort of error", NO); break; } comm_select(); send_queued_all(); if(dorehash) { ilog(L_INFO, "Got SIGHUP, reloading configuration"); read_services_conf(NO); dorehash = 0; } } return 0; }
int main(int argc, char *argv[]) { int error, cntrlsfd, remotesfd; struct event cntrlev, remoteev; pid_t pid, sid; RHashTable *workers; error = 0; info("Starting the reactor..."); dbg("...freeing Mars.", NULL); // TODO root user check // TODO change ruid to euid (root) // TODO help // TODO version // TODO daemon lock file (?) // TODO trap signals /* daemonize */ #ifndef DEBUG pid = fork(); switch(pid) { case 0: /* child */ dbg("Forked child running.", NULL); break; case -1: err("Unable to daemonize"); fprintf(stderr, "Unable to daemonize\n"); default: /* parent */ goto exit; } #endif /* redirect standard files to /dev/null */ freopen( "/dev/null", "r", stdin); freopen( "/dev/null", "w", stdout); freopen( "/dev/null", "w", stderr); // TODO cancel child signals ? // sid = setsid(); // if (sid < 0) { // error = 1; // dbg_e("setsid() returned with errors.", NULL); // err("Unable to create a new session."); // goto exit; // } /* change current directory */ if ((chdir("/")) < 0) { error = 1; err("Unable to change current directory to '/'."); goto exit; } reactor.eventnotices = reactor_hash_table_new((RHashFunc) reactor_str_hash, (REqualFunc) str_eq); reactor.states = reactor_hash_table_new((RHashFunc) reactor_str_hash, (REqualFunc) str_eq); workers = reactor_hash_table_new((RHashFunc) reactor_str_hash, (REqualFunc) str_eq); init_rules(); /* sockets setup and poll */ event_init(); if((cntrlsfd = listen_cntrl()) == -1) { err("Unable to create the control socket and bind it to '%s'. Probably a permissions issue.", SOCK_PATH); goto exit; } if((remotesfd = listen_remote()) == -1) { err("Unable to create the remote socket."); goto exit; } load_all_modules(REACTORPLUGINDIR, workers); event_set(&cntrlev, cntrlsfd, EV_READ | EV_PERSIST, &attend_cntrl_msg, NULL); event_add(&cntrlev, NULL); event_set(&remoteev, remotesfd, EV_READ | EV_PERSIST, &attend_remote_events, NULL); event_add(&remoteev, NULL); event_dispatch(); exit: close_cntrl(cntrlsfd); close(remotesfd); return error; }
int main(int argc, char *argv[]) { /* Check to see if the user is running us as root, which is a nono */ if(geteuid() == 0) { fprintf(stderr, "Don't run ircd as root!!!\n"); return -1; } /* * save server boot time right away, so getrusage works correctly */ set_time(); /* * Setup corefile size immediately after boot -kre */ setup_corefile(); /* * set initialVMTop before we allocate any memory */ initialVMTop = get_vm_top(); ServerRunning = 0; /* It ain't random, but it ought to be a little harder to guess */ srand(SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid() << 20))); memset(&me, 0, sizeof(me)); memset(&meLocalUser, 0, sizeof(meLocalUser)); me.localClient = &meLocalUser; /* Make sure all lists are zeroed */ memset(&unknown_list, 0, sizeof(unknown_list)); memset(&lclient_list, 0, sizeof(lclient_list)); memset(&serv_list, 0, sizeof(serv_list)); memset(&global_serv_list, 0, sizeof(global_serv_list)); memset(&oper_list, 0, sizeof(oper_list)); dlinkAddTail(&me, &me.node, &global_client_list); memset((void *) &Count, 0, sizeof(Count)); memset((void *) &ServerInfo, 0, sizeof(ServerInfo)); memset((void *) &AdminInfo, 0, sizeof(AdminInfo)); /* Initialise the channel capability usage counts... */ init_chcap_usage_counts(); ConfigFileEntry.dpath = DPATH; ConfigFileEntry.configfile = CPATH; /* Server configuration file */ ConfigFileEntry.klinefile = KPATH; /* Server kline file */ ConfigFileEntry.dlinefile = DLPATH; /* dline file */ ConfigFileEntry.xlinefile = XPATH; ConfigFileEntry.resvfile = RESVPATH; ConfigFileEntry.connect_timeout = 30; /* Default to 30 */ myargv = argv; umask(077); /* better safe than sorry --SRB */ parseargs(&argc, &argv, myopts); if(printVersion) { printf("ircd: version %s\n", ircd_version); exit(EXIT_SUCCESS); } if(chdir(ConfigFileEntry.dpath)) { fprintf(stderr, "Unable to chdir to %s: %s\n", ConfigFileEntry.dpath, strerror(errno)); exit(EXIT_FAILURE); } setup_signals(); #ifdef __CYGWIN__ server_state_foreground = 1; #endif if (testing_conf) server_state_foreground = 1; /* We need this to initialise the fd array before anything else */ fdlist_init(); if(!server_state_foreground) { comm_close_all(); } /* Check if there is pidfile and daemon already running */ if(!testing_conf) { check_pidfile(pidFileName); if(!server_state_foreground) make_daemon(); else print_startup(getpid()); } init_netio(); /* This needs to be setup early ! -- adrian */ /* Init the event subsystem */ eventInit(); init_sys(); init_main_logfile(); initBlockHeap(); init_dlink_nodes(); init_patricia(); newconf_init(); init_s_conf(); init_s_newconf(); linebuf_init(); /* set up some linebuf stuff to control paging */ init_hash(); clear_scache_hash_table(); /* server cache name table */ init_host_hash(); clear_hash_parse(); init_client(); initUser(); init_channels(); initclass(); initwhowas(); init_stats(); init_hook(); init_reject(); init_cache(); init_monitor(); load_all_modules(1); #ifndef STATIC_MODULES load_core_modules(1); #endif init_auth(); /* Initialise the auth code */ init_resolver(); /* Needs to be setup before the io loop */ if (testing_conf) fprintf(stderr, "\nBeginning config test\n"); read_conf_files(YES); /* cold start init conf files */ rehash_bans(0); #ifndef STATIC_MODULES mod_add_path(MODULE_DIR); mod_add_path(MODULE_DIR "/autoload"); #endif initialize_server_capabs(); /* Set up default_server_capabs */ initialize_global_set_options(); if(ServerInfo.name == NULL) { fprintf(stderr, "ERROR: No server name specified in serverinfo block.\n"); ilog(L_MAIN, "No server name specified in serverinfo block."); exit(EXIT_FAILURE); } strlcpy(me.name, ServerInfo.name, sizeof(me.name)); if(ServerInfo.sid[0] == '\0') { fprintf(stderr, "ERROR: No server sid specified in serverinfo block.\n"); ilog(L_MAIN, "No server sid specified in serverinfo block."); exit(EXIT_FAILURE); } strcpy(me.id, ServerInfo.sid); init_uid(); /* serverinfo{} description must exist. If not, error out. */ if(ServerInfo.description == NULL) { fprintf(stderr, "ERROR: No server description specified in serverinfo block.\n"); ilog(L_MAIN, "ERROR: No server description specified in serverinfo block."); exit(EXIT_FAILURE); } strlcpy(me.info, ServerInfo.description, sizeof(me.info)); if (testing_conf) { fprintf(stderr, "\nConfig testing complete.\n"); fflush(stderr); exit(EXIT_SUCCESS); } me.from = &me; me.servptr = &me; SetMe(&me); make_server(&me); me.serv->up = me.name; startup_time = CurrentTime; add_to_client_hash(me.name, &me); add_to_id_hash(me.id, &me); dlinkAddAlloc(&me, &global_serv_list); check_class(); write_pidfile(pidFileName); load_help(); open_logfiles(); ilog(L_MAIN, "Server Ready"); eventAddIsh("cleanup_glines", cleanup_glines, NULL, CLEANUP_GLINES_TIME); /* We want try_connections to be called as soon as possible now! -- adrian */ /* No, 'cause after a restart it would cause all sorts of nick collides */ /* um. by waiting even longer, that just means we have even *more* * nick collisions. what a stupid idea. set an event for the IO loop --fl */ eventAddIsh("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME); eventAddOnce("try_connections_startup", try_connections, NULL, 0); eventAddIsh("collect_zipstats", collect_zipstats, NULL, ZIPSTATS_TIME); /* Setup the timeout check. I'll shift it later :) -- adrian */ eventAddIsh("comm_checktimeouts", comm_checktimeouts, NULL, 1); if(ConfigServerHide.links_delay > 0) eventAddIsh("cache_links", cache_links, NULL, ConfigServerHide.links_delay); else ConfigServerHide.links_disabled = 1; if(splitmode) eventAdd("check_splitmode", check_splitmode, NULL, 2); ServerRunning = 1; io_loop(); return 0; }
//========================================================================== // The 'main' function for the booter. Called by boot0 when booting // from a block device, or by the network booter. // // arguments: // biosdev - Value passed from boot1/NBP to specify the device // that the booter was loaded from. // // If biosdev is kBIOSDevNetwork, then this function will return if // booting was unsuccessful. This allows the PXE firmware to try the // next boot device on its list. void common_boot(int biosdev) { int status; char *bootFile; unsigned long adler32; bool quiet; bool firstRun = true; bool instantMenu; bool rescanPrompt = false; unsigned int allowBVFlags = kBVFlagSystemVolume|kBVFlagForeignBoot; unsigned int denyBVFlags = kBVFlagEFISystem; // Set reminder to unload the PXE base code. Neglect to unload // the base code will result in a hang or kernel panic. gUnloadPXEOnExit = true; // Record the device that the booter was loaded from. gBIOSDev = biosdev & kBIOSDevMask; // Initialize boot info structure. initKernBootStruct(); initBooterLog(); // Setup VGA text mode. // Not sure if it is safe to call setVideoMode() before the // config table has been loaded. Call video_mode() instead. #if DEBUG printf("before video_mode\n"); //Azi: this one is not printing... i remember it did.. check trunk. #endif video_mode( 2 ); // 80x25 mono text mode. #if DEBUG printf("after video_mode\n"); #endif // Scan and record the system's hardware information. scan_platform(); // First get info for boot volume. scanBootVolumes(gBIOSDev, 0); bvChain = getBVChainForBIOSDev(gBIOSDev); //Azi: initialising gBIOSBootVolume & gBootVolume (Startup volume) for the first time.. i think!? // also, kDefaultPartitionKey is checked here, on selectBootVolume. setBootGlobals(bvChain); msglog("setBootGlobals:\n Default: %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n", gBootVolume, gBootVolume->biosdev, gBootVolume->part_no, gBootVolume->flags); msglog(" bt(0,0): %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n", gBIOSBootVolume, gBIOSBootVolume->biosdev, gBIOSBootVolume->part_no, gBIOSBootVolume->flags); // Boot Volume is set as Root at this point so, pointing to Extra, /Extra or bt(0,0)/Extra // is exactly the same. Review bt(0,0)/bla bla paths...... (Reviewing...) //Azi: works as expected but... trying this because Kernel=mach_kernel doesn't work on a // override Boot.plist; this makes it impossible to override e.g. Kernel=bt(0,0)mach_kernel // on the main Boot.plist, when loading kernel from ramdisk btAliased. loadPrebootRAMDisk(); // Load boot.plist config file //Azi: on this first check, boot.plist acts as both "booter config file" // and bootargs/options "carrier".***** status = loadSystemConfig(&bootInfo->bootConfig); if (getBoolForKey(kQuietBootKey, &quiet, &bootInfo->bootConfig) && quiet) { gBootMode |= kBootModeQuiet; } // Override firstRun to get to the boot menu instantly by setting "Instant Menu"=y in system config if (getBoolForKey(kInstantMenuKey, &instantMenu, &bootInfo->bootConfig) && instantMenu) { firstRun = false; } // Loading preboot ramdisk if exists. // loadPrebootRAMDisk(); //Azi: this needs to be done before load_all_modules() // because of btAlias... (Reviewing...) // Intialize module system if (init_module_system()) { load_all_modules(); } // Disable rescan option by default gEnableCDROMRescan = false; // If we're loading the booter from optical media... (Reviewing...) if (biosDevIsCDROM(gBIOSDev)) { // ... ask the user for Rescan option by setting "Rescan Prompt"=y in system config... if (getBoolForKey(kRescanPromptKey, &rescanPrompt, &bootInfo->bootConfig) && rescanPrompt) { gEnableCDROMRescan = promptForRescanOption(); } else // ... or enable it with Rescan=y in system config. if (getBoolForKey(kRescanKey, &gEnableCDROMRescan, &bootInfo->bootConfig) && gEnableCDROMRescan) { gEnableCDROMRescan = true; } } //Azi: Is this a cdrom only thing? (Reviewing...) // Enable touching a single BIOS device only if "Scan Single Drive"=y is set in system config. if (getBoolForKey(kScanSingleDriveKey, &gScanSingleDrive, &bootInfo->bootConfig) && gScanSingleDrive) { scanBootVolumes(gBIOSDev, &bvCount); } else { //Azi: scanDisks uses scanBootVolumes. scanDisks(gBIOSDev, &bvCount); } // Create a separated bvr chain using the specified filters. bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount); gBootVolume = selectBootVolume(bvChain); //#if DEBUG //printf msglog(":something...???\n Default: %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n", gBootVolume, gBootVolume->biosdev, gBootVolume->part_no, gBootVolume->flags); msglog(" bt(0,0): %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n", gBIOSBootVolume, gBIOSBootVolume->biosdev, gBIOSBootVolume->part_no, gBIOSBootVolume->flags); // getchar(); //#endif useGUI = true; // Override useGUI default getBoolForKey(kGUIKey, &useGUI, &bootInfo->bootConfig); // AutoResolution - Azi: default to false // http://forum.voodooprojects.org/index.php/topic,1227.0.html gAutoResolution = false; // Check if user enabled AutoResolution on Boot.plist... getBoolForKey(kAutoResolutionKey, &gAutoResolution, &bootInfo->bootConfig); // Patch the Video Bios with the extracted resolution, before initGui. if (gAutoResolution == true) { initAutoRes(); } if (useGUI && initGUI()) { // initGUI() returned with an error, disabling GUI. useGUI = false; } setBootGlobals(bvChain); msglog("setBootGlobals:\n Default: %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n", gBootVolume, gBootVolume->biosdev, gBootVolume->part_no, gBootVolume->flags); msglog(" bt(0,0): %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n", gBIOSBootVolume, gBIOSBootVolume->biosdev, gBIOSBootVolume->part_no, gBIOSBootVolume->flags); // Parse args, load and start kernel. while (1) { const char *val; int len; int trycache; long flags, cachetime, kerneltime, exttime, sleeptime, time; int ret = -1; void *binary = (void *)kLoadAddr; bool tryresume; bool tryresumedefault; bool forceresume; bool ignoreKC = false; // additional variable for testing alternate kernel image locations on boot helper partitions. char bootFileSpec[512]; // Initialize globals. sysConfigValid = false; gErrors = false; status = getBootOptions(firstRun); firstRun = false; if (status == -1) continue; //Azi: test (gBootVolume == NULL) - so far Ok! // test with optical media again...? // Turn off any GUI elements, draw background and update VRAM. if ( bootArgs->Video.v_display == GRAPHICS_MODE ) { gui.devicelist.draw = false; gui.bootprompt.draw = false; gui.menu.draw = false; gui.infobox.draw = false; gui.logo.draw = false; drawBackground(); updateVRAM(); } status = processBootOptions(); //Azi: AutoResolution - closing Vbios here without restoring, causes an allocation error, // if the user tries to boot, after a e.g."Can't find bla_kernel" msg. // Doing it on execKernel() instead. // Status == 1 means to chainboot if ( status == 1 ) break; // Status == -1 means that gBootVolume is NULL. Config file is not mandatory anymore! if ( status == -1 ) { // gBootVolume == NULL usually means the user hit escape. (Reviewing...) if (gBootVolume == NULL) { freeFilteredBVChain(bvChain); if (gEnableCDROMRescan) rescanBIOSDevice(gBIOSDev); bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount); setBootGlobals(bvChain); setupDeviceList(&bootInfo->themeConfig); } continue; } // Other status (e.g. 0) means that we should proceed with boot. // If cpu handles 64 bit instructions... if (platformCPUFeature(CPU_FEATURE_EM64T)) { // use x86_64 kernel arch,... archCpuType = CPU_TYPE_X86_64; } else { // else use i386 kernel arch. archCpuType = CPU_TYPE_I386; } // If user override... if (getValueForKey(kArchKey, &val, &len, &bootInfo->bootConfig)) { // matches i386... if (strncmp(val, "i386", 4) == 0) { // use i386 kernel arch. archCpuType = CPU_TYPE_I386; } } if (!getBoolForKey (kWakeKey, &tryresume, &bootInfo->bootConfig)) { tryresume = true; tryresumedefault = true; } else { tryresumedefault = false; } if (!getBoolForKey (kForceWakeKey, &forceresume, &bootInfo->bootConfig)) { forceresume = false; } if (forceresume) { tryresume = true; tryresumedefault = false; } while (tryresume) { const char *tmp; BVRef bvr; if (!getValueForKey(kWakeKeyImageKey, &val, &len, &bootInfo->bootConfig)) val="/private/var/vm/sleepimage"; // Do this first to be sure that root volume is mounted ret = GetFileInfo(0, val, &flags, &sleeptime); if ((bvr = getBootVolumeRef(val, &tmp)) == NULL) break; // Can't check if it was hibernation Wake=y is required if (bvr->modTime == 0 && tryresumedefault) break; if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)) break; if (!forceresume && ((sleeptime+3)<bvr->modTime)) { //Azi: no need for printf at this point - reminder printf ("Hibernate image is too old by %d seconds. Use ForceWake=y to override.\n",bvr->modTime-sleeptime); break; } HibernateBoot((char *)val); break; } //Azi:kernelcache stuff bool patchKernel = false; getBoolForKey(kKPatcherKey, &patchKernel, &bootInfo->bootConfig); //Azi: avoiding having to use -f to ignore kernel cache //Azi: ignore kernel cache but still use kext cache (E/E.mkext & S/L/E.mkext). - explain... getBoolForKey(kUseKCKey, &ignoreKC, &bootInfo->bootConfig); // equivalent to UseKernelCache if (ignoreKC) { verbose("KC: cache ignored by user.\n"); // make sure the damn thing get's zeroed, just in case... :)* bzero(gBootKernelCacheFile, sizeof(gBootKernelCacheFile)); } else if (patchKernel) // to be moved..? { verbose("KC: kernel patcher enabled, ignore cache.\n"); bzero(gBootKernelCacheFile, sizeof(gBootKernelCacheFile)); } else if (getValueForKey(kKernelCacheKey, &val, &len, &bootInfo->bootConfig)) { strlcpy(gBootKernelCacheFile, val, len + 1); verbose("KC: path set by user = %s\n", gBootKernelCacheFile); //Azi: bypass time check when user sets path ??? // cache is still ignored if time doesn't match... (e.g. booter on usb stick) } else { // Reset cache name. bzero(gCacheNameAdler + 64, sizeof(gCacheNameAdler) - 64); // kextcache_main.c: Construct entry from UUID of boot volume...(reminder) // assemble ?string? to generate adler from... // sprintf(gCacheNameAdler + 64, "%s,%s", gRootDevice, bootInfo->bootFile); - OLD const char *ProductName = getStringForKey("SMproductname", &bootInfo->smbiosConfig); sprintf(gCacheNameAdler, ProductName); // well, at least the smbios.plist can be loaded this early... // to set/get "ProductName" this early, booter needs complete rewrite!! // see DHP's Revolution booter rework example! // verbose("KC: gCacheNameAdler 1 = %s\n", gCacheNameAdler); //Azi: check the validity of this, e.g. on Helper Partitions sprintf(gCacheNameAdler + 64, "%s", "\\System\\Library\\CoreServices\\boot.efi"); // verbose("KC: gCacheNameAdler 2 = %s\n", gCacheNameAdler + 64); sprintf(gCacheNameAdler + (64 + 38), "%s", bootInfo->bootFile); // verbose("KC: gCacheNameAdler 3 = %s\n", gCacheNameAdler + (64 + 38)); // generate adler adler32 = Adler32((unsigned char *)gCacheNameAdler, sizeof(gCacheNameAdler)); // verbose("KC: Adler32 = %08X\n", adler32); //Azi: no check for OS version here ?? - yes there is :) // append arch and/or adler (checksum) to kc path... if (gMacOSVersion[3] <= '5') { sprintf(gBootKernelCacheFile, "%s.%08lX", kCachePathTigerLeopard, adler32); // verbose("KC: adler added to path = %s\n", gBootKernelCacheFile); } else { sprintf(gBootKernelCacheFile, "%s_%s.%08X", kCachePathSnowLion, (archCpuType == CPU_TYPE_I386) ? "i386" : "x86_64", adler32); // verbose("KC: arch & adler added to path = %s\n", gBootKernelCacheFile); } } // Check for cache file. //Azi: trycache is done if... trycache = ( ( (gBootMode & kBootModeSafe) == 0) //... we're not booting in safe mode (-x arg), && !gOverrideKernel // we're not overriding default kernel "name", && (gBootFileType == kBlockDeviceType) // we're booting from local storage device, && (gMKextName[0] == '\0') // "MKext Cache" key IS NOT in use, and && (gBootKernelCacheFile[0] != '\0') ); // gBootKernelCacheFile is populated. // we could add the use of "kernelpatcher" to this bunch..?? // verbose("Loading Darwin %s\n", gMacOSVersion); //Azi: move?? to getOSVersion? :) if (trycache) do { verbose("KC: checking kernel cache (system prelinked kernel)...\n"); // if we haven't found the kernel yet, don't use the cache ret = GetFileInfo(NULL, bootInfo->bootFile, &flags, &kerneltime); if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)) { verbose("KC: no kernel found (shouldn't happen?!?)\n"); trycache = 0; // ignore kernel cache... break; } verbose("KC: kerneltime = %d\n", kerneltime); ret = GetFileInfo(NULL, gBootKernelCacheFile, &flags, &cachetime); if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat) || (cachetime < kerneltime)) { if (cachetime <= 100) // confirm: 100 = inexistent path, -xxxxxxxxx = wrong name // not confirming... i also get -xxxxxxxxx with inexisting prelinked kernel verbose("KC: cachetime = %d, kernel cache path/adler is incorrect, ignoring it. ??? \n", cachetime); else verbose("KC: cachetime = %d, kernel cache is older than the kernel, ignoring it.\n", cachetime); trycache = 0; break; } verbose("KC: cachetime = %d\n", cachetime); ret = GetFileInfo("/System/Library/", "Extensions", &flags, &exttime); if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory) && (cachetime < exttime)) { verbose("KC: exttime = %d, kernel cache is older than S/L/E, ignoring it.\n", exttime); trycache = 0; break; } verbose("KC: exttime = %d\n", exttime); if (kerneltime > exttime) // if S/L/E is older than the kernel... { verbose("KC: S/L/E is older than the kernel, matching exttime with kerneltime...\n"); exttime = kerneltime; } verbose("KC: exttime +1 = %d\n", exttime + 1); if (cachetime != (exttime + 1)) { verbose("KC: kernel cache time is diff from S/L/E time, ignoring it.\n"); trycache = 0; break; } verbose("KC: kernel cache found and up to date, will be used.\n"); } while (0); do { // Load kernel cache if not ignored. if (trycache) { bootFile = gBootKernelCacheFile; verbose("Loading kernel cache %s\n", bootFile); ret = LoadFile(bootFile); binary = (void *)kLoadAddr; if (ret >= 0) { break; } } bootFile = bootInfo->bootFile; // Try to load kernel image from alternate locations on boot helper partitions. sprintf(bootFileSpec, "com.apple.boot.P/%s", bootFile); ret = GetFileInfo(NULL, bootFileSpec, &flags, &time); if (ret == -1) { sprintf(bootFileSpec, "com.apple.boot.R/%s", bootFile); ret = GetFileInfo(NULL, bootFileSpec, &flags, &time); if (ret == -1) { sprintf(bootFileSpec, "com.apple.boot.S/%s", bootFile); ret = GetFileInfo(NULL, bootFileSpec, &flags, &time); if (ret == -1) { // No alternate location found, using the original kernel image path. strcpy(bootFileSpec, bootFile); } } } verbose("Loading kernel %s\n", bootFileSpec); ret = LoadThinFatFile(bootFileSpec, &binary); if (ret <= 0 && archCpuType == CPU_TYPE_X86_64) { archCpuType = CPU_TYPE_I386; ret = LoadThinFatFile(bootFileSpec, &binary); } } while (0); clearActivityIndicator(); /*#if DEBUG printf("Pausing..."); sleep(8); #endif Azi: annoying stuff :P */ if (ret <= 0) { printf("Can't find %s\n", bootFile); sleep(1); if (gBootFileType == kNetworkDeviceType) { // Return control back to PXE. Don't unload PXE base code. gUnloadPXEOnExit = false; break; } } else { // Won't return if successful. ret = ExecKernel(binary); } } // while (1) // chainboot if (status==1) { if (getVideoMode() == GRAPHICS_MODE) { // if we are already in graphics-mode, setVideoMode(VGA_TEXT_MODE, 0); // switch back to text mode } } if ((gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit) { nbpUnloadBaseCode(); } }
int main (int argc, char *argv[]) { /* Check to see if the user is running * us as root, which is a nono */ if (geteuid () == 0) { fprintf (stderr, "Don't run ircd as root!!!\n"); return (-1); } /* save server boot time right away, so getrusage works correctly */ set_time (); /* Setup corefile size immediately after boot -kre */ setup_corefile (); /* set initialVMTop before we allocate any memory */ initialVMTop = get_vm_top (); ServerRunning = 0; /* It ain't random, but it ought to be a little harder to guess */ srand (SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid () << 20))); memset (&me, 0, sizeof (me)); memset (&meLocalUser, 0, sizeof (meLocalUser)); me.localClient = &meLocalUser; dlinkAdd (&me, &me.node, &global_client_list); /* Pointer to beginning of Client list */ memset (&ServerInfo, 0, sizeof (ServerInfo)); /* Initialise the channel capability usage counts... */ init_chcap_usage_counts (); ConfigFileEntry.dpath = DPATH; ConfigFileEntry.configfile = CPATH; /* Server configuration file */ ConfigFileEntry.klinefile = KPATH; /* Server kline file */ ConfigFileEntry.xlinefile = XPATH; /* Server xline file */ ConfigFileEntry.dlinefile = DLPATH; /* dline file */ ConfigFileEntry.cresvfile = CRESVPATH; /* channel resv file */ ConfigFileEntry.nresvfile = NRESVPATH; /* nick resv file */ myargv = argv; umask (077); /* better safe than sorry --SRB */ parseargs (&argc, &argv, myopts); build_version (); if (printVersion) { printf ("ircd: version %s\n", ircd_version); exit (EXIT_SUCCESS); } if (chdir (ConfigFileEntry.dpath)) { perror ("chdir"); exit (EXIT_FAILURE); } if (!server_state.foreground) make_daemon (); else print_startup (getpid ()); #ifdef HAVE_LIBCRYPTO dh_init(); fprintf(stderr, "SSL: Initialize\n"); SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); ServerInfo.ctx = SSL_CTX_new(SSLv23_server_method()); if (!ServerInfo.ctx) { ERR_print_errors_fp(stderr); return 0; } fprintf(stderr, "SSL: Client based SSL connections are enabled.\n"); #endif setup_signals (); /* We need this to initialise the fd array before anything else */ fdlist_init (); if (!server_state.foreground) close_all_connections (); /* this needs to be before init_netio()! */ else check_can_use_v6 (); /* Done in close_all_connections normally */ init_log (logFileName); init_netio (); /* This needs to be setup early ! -- adrian */ /* Check if there is pidfile and daemon already running */ check_pidfile (pidFileName); /* Init the event subsystem */ eventInit (); init_sys (); #ifndef NOBALLOC initBlockHeap (); #endif init_dlink_nodes (); init_slink_nodes (); initialize_message_files (); dbuf_init (); init_hash (); init_ip_hash_table (); /* client host ip hash table */ init_host_hash (); /* Host-hashtable. */ clear_hash_parse (); init_client (); init_user (); init_channels (); init_class (); init_whowas (); init_stats (); init_hooks (); read_conf_files (1); /* cold start init conf files */ initServerMask (); init_uid (); init_auth (); /* Initialise the auth code */ init_resolver (); /* Needs to be setup before the io loop */ init_reject (); /* Set up the reject code. */ init_umodes (); /* Set up the usermode system. */ initialize_foundation_signals(); /* register things that modules need */ #ifdef HAVE_LIBCRYPTO bio_spare_fd = save_spare_fd ("SSL private key validation"); #endif /* HAVE_LIBCRYPTO */ initialize_server_capabs (); /* Set up default_server_capabs */ initialize_global_set_options (); if (ServerInfo.name == NULL) { fprintf (stderr, "ERROR: No server name specified in serverinfo block.\n"); ilog (L_CRIT, "No server name specified in serverinfo block."); exit (EXIT_FAILURE); } strlcpy (me.name, ServerInfo.name, sizeof (me.name)); /* serverinfo{} description must exist. If not, error out. */ if (ServerInfo.description == NULL) { fprintf (stderr, "ERROR: No server description specified in serverinfo block.\n"); ilog (L_CRIT, "ERROR: No server description specified in serverinfo block."); exit (EXIT_FAILURE); } strlcpy (me.info, ServerInfo.description, sizeof (me.info)); me.from = &me; me.servptr = &me; SetMe (&me); make_server (&me); strlcpy (me.serv->up, me.name, sizeof (me.serv->up)); me.lasttime = me.since = me.firsttime = CurrentTime; hash_add_client (&me); /* add ourselves to global_serv_list */ dlinkAdd (&me, make_dlink_node (), &global_serv_list); check_class (); #ifndef STATIC_MODULES if (chdir (MODPATH)) { ilog (L_CRIT, "Could not load core modules. Terminating!"); exit (EXIT_FAILURE); } mod_set_base (); load_all_modules (1); load_core_modules (1); /* Go back to DPATH after checking to see if we can chdir to MODPATH */ chdir (ConfigFileEntry.dpath); #else load_all_modules (1); #endif write_pidfile (pidFileName); ilog (L_NOTICE, "Server Ready"); eventAddIsh ("cleanup_tklines", cleanup_tklines, NULL, CLEANUP_TKLINES_TIME); /* We want try_connections to be called as soon as possible now! -- adrian */ /* No, 'cause after a restart it would cause all sorts of nick collides */ eventAddIsh ("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME); eventAddIsh ("collect_zipstats", collect_zipstats, NULL, ZIPSTATS_TIME); /* Setup the timeout check. I'll shift it later :) -- adrian */ eventAddIsh ("comm_checktimeouts", comm_checktimeouts, NULL, 1); if (splitmode) eventAddIsh ("check_splitmode", check_splitmode, NULL, 60); ServerRunning = 1; io_loop (); return (0); }