/*refresh modules - note we don't check for deleted modules but since we've open them the OS should forbid delete*/ u32 gf_modules_refresh(GF_ModuleManager *pm) { u32 i; if (!pm) return 0; /*load all static modules*/ load_static_modules(pm); for (i =0; i < pm->num_dirs; i++){ #ifdef WIN32 gf_enum_directory(pm->dirs[i], GF_FALSE, enum_modules, pm, ".dll"); #elif defined(__APPLE__) #if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) /*we are in static build for modules by default*/ #else gf_enum_directory(pm->dirs[i], 0, enum_modules, pm, ".dylib"); #endif #else GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("Refreshing list of modules in directory %s...\n", pm->dirs[i])); gf_enum_directory(pm->dirs[i], 0, enum_modules, pm, ".so"); #endif } return gf_list_count(pm->plug_list); }
DAQ_LINKAGE int daq_load_modules(const char *directory_list[]) { static const char *extension = MODULE_EXT; #ifndef WIN32 char dirpath[NAME_SIZE]; DIR *dirp; struct dirent *de; char *p; int ret; #ifdef STATIC_MODULE_LIST load_static_modules(); #endif for (; directory_list && *directory_list; directory_list++) { if (!(**directory_list)) continue; if ((dirp = opendir(*directory_list)) == NULL) { fprintf(stderr,"Unable to open directory \"%s\"\n", *directory_list); continue; } DEBUG("Loading modules in: %s\n", *directory_list); while((de = readdir(dirp)) != NULL) { if (de->d_name == NULL) continue; p = strrchr(de->d_name, '.'); if (!p || strcmp(p, extension)) continue; snprintf(dirpath, sizeof(dirpath), "%s/%s", *directory_list, de->d_name); ret = daq_load_module(dirpath); if (ret == DAQ_SUCCESS) { DEBUG("Found module %s\n", de->d_name); } else if (ret == DAQ_ERROR_NOMEM) { closedir(dirp); return DAQ_ERROR_NOMEM; } } closedir(dirp); } #else /* Find all shared library files in path */ char path_buf[PATH_MAX]; char dyn_lib_name[PATH_MAX]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; HANDLE fSearch; WIN32_FIND_DATA FindFileData; int pathLen = 0; const char *directory; int useDrive = 0; #ifdef STATIC_MODULE_LIST load_static_modules(); #endif for (; directory_list && *directory_list; directory_list++) { if (!(**directory_list)) continue; if ((strncpy(path_buf, *directory_list, PATH_MAX) == NULL) || (strlen(path_buf) != strlen(*directory_list))) { fprintf(stderr, "Path is too long: %s\n", *directory_list); continue; } pathLen = strlen(path_buf); if ((path_buf[pathLen - 1] == '\\') || (path_buf[pathLen - 1] == '/')) { /* A directory was specified with trailing dir character */ _splitpath(path_buf, drive, dir, fname, ext); _makepath(path_buf, drive, dir, "*", MODULE_EXT); directory = &dir[0]; useDrive = 1; } else /* A directory was specified */ { _splitpath(path_buf, drive, dir, fname, ext); if (strcmp(extension, "")) { fprintf(stderr, "Improperly formatted directory name: %s\n", *directory_list); continue; } _makepath(path_buf, "", path_buf, "*", MODULE_EXT); directory = *directory_list; } fSearch = FindFirstFile(path_buf, &FindFileData); while (fSearch != NULL && fSearch != (HANDLE)-1) { if (useDrive) _makepath(dyn_lib_name, drive, directory, FindFileData.cFileName, NULL); else _makepath(dyn_lib_name, NULL, directory, FindFileData.cFileName, NULL); daq_load_module(dyn_lib_name); if (!FindNextFile(fSearch, &FindFileData)) { break; } } FindClose(fSearch); } #endif return DAQ_SUCCESS; }
int main(int argc, char *argv[], char *envp[]) { int c; int show_version = 0; const char *cmdopts = OPTION_COMMANDS; char SoftBotRoot[MAX_PATH_LEN], *tmp; // set gSoftBotRoot if ( realpath(argv[0], SoftBotRoot) ) { tmp = strstr( SoftBotRoot, "/bin/softbotd" ); if ( tmp ) { *tmp = '\0'; strcpy( gSoftBotRoot, SoftBotRoot ); } } info("server has started in [%s].", gSoftBotRoot ); #ifdef AIX5 { char *env = getenv("EXTSHM"); if (!env || strcmp(env, "ON")) { /* we need EXTSHM=ON in our environment to make the shmat and mmaps work */ setenv("EXTSHM", "ON", 1); fprintf(stderr, "re-executing self with EXTSHM=ON exported to fix AIX shmat problem.\n"); execv(argv[0], argv); fprintf(stderr, "re-execution failed - terminating.\n"); exit(1); } } #endif init_setproctitle(argc, argv, envp); set_static_modules(server_static_modules); /* getopt stuff */ opterr = 0; while ( (c = #ifdef HAVE_GETOPT_LONG getopt_long(argc, argv, cmdopts, opts, NULL) #elif HAVE_GETOPT getopt(argc, argv, cmdopts) #else # error at least one of getopt, getopt_long must exist. #endif /* HAVE_GETOPT_LONG */ ) != -1 ) { int i = 0; switch ( c ) { case 'n': nodaemon++; set_screen_log(); break; case 'p': clc_listen_port++; if (strcmp(optarg,"show")==0) { /* show using ports info */ clc_listen_port++; nodaemon++; log_setlevelstr("error"); clc_log_level++; break; } i=atoi(optarg); if (i<1024) gSoftBotListenPort += i; else gSoftBotListenPort = i; info("Setting gSoftBotListenPort to %d",gSoftBotListenPort); break; case 'g': if ( !optarg ) { error("Fatal: -g requires error log level argument."); exit(1); } if (log_setlevelstr(optarg) == SUCCESS) { clc_log_level++; } else { error("Invalid log level."); info(" arg for -d is like following"); for (i=0; gLogLevelStr[i]; i++) { info(" %s",gLogLevelStr[i]); } exit(1); } break; case 'm': if ( !optarg ) { error("Fatal: -m requires module name."); exit(1); } strncpy(debug_module, optarg, MAX_MODULE_NAME); debug_module[MAX_MODULE_NAME-1] = '\0'; /* nodaemon is on by default when debugging a module */ nodaemon++; set_screen_log(); debug("debugging module[%s]", debug_module); break; case 'u': if (unittest==0) { info("When doing unittest,"); info("always check that modules to be tested are loaded"); } nodaemon++; set_screen_log(); unittest++; break; case 'k': /* refer to hook.c, hook.h, modules.c */ debug_module_hooks++; break; case 'l': list_static_modules(stdout); exit(0); break; case 'c': if ( !optarg ) { error("Fatal: -c requires configuration path"); exit(1); } strncpy(mConfigFile, optarg, MAX_PATH_LEN); mConfigFile[MAX_PATH_LEN-1] = '\0'; debug("configuration file path set to %s",mConfigFile); break; case 't': check_config_syntax = 1; clc_log_level++; gLogLevel = LEVEL_INFO; set_screen_log(); // syntax checking 시 error를 화면으로.. printf("Checking syntax of configuration file\n"); fflush(stdout); break; case 'r': if ( !optarg ) { error("Fatal: -r requires server root path"); exit(1); } strncpy(gSoftBotRoot, optarg, MAX_PATH_LEN); gSoftBotRoot[MAX_PATH_LEN-1] = '\0'; clc_server_root++; debug("gSoftBotRoot is set to %s by -r option.",gSoftBotRoot); break; case 'v': show_version++; break; case 'h': show_usage(0); case '?': error("Unknown option: %c", (char)optopt); show_usage(1); } /* switch ( c ) */ } /* end of getopt stuff */ if ( show_version ) show_version_and_exit(); /* initializing */ /* we're only doing a syntax check of the configuration file. */ if ( check_config_syntax ) { int ret=FAIL; // TODO: is this enough? -aragorn debug("checking syntax"); debug("configuration file:%s",mConfigFile); load_static_modules(); ret = read_config(mConfigFile, NULL); printf("Syntax check completed.\n"); printf("Configuration module returned %d\n",ret); exit(0); } /* setuid, setgid stuff */ /* signal handler stuff */ set_signal_handlers(); /* resource limits */ if ( nodaemon == 0 ) detach(); /* RESTART:*/ /* set pid */ gRootPid = getpid(); server_main(); /* if ( restart ) goto RESTART; */ return 0; }
/* server_main() * -> sb_run_* APIs are enabled * -> all registries are enabled * -> all configs are enabled. config should follow and overwrite registry. */ int server_main() { module *mod=NULL; /*********************************************************************** * first-pass config */ set_proc_desc(NULL, "softbotd: master - loading static modules"); /* load_static_modules() * -> hooking APIs. we cannot call sb_run_* APIs before this */ load_static_modules(); /* FIXME why should i load kbo module?? */ //load_kbo_module(); if (read_config(mConfigFile, NULL) != SUCCESS) { crit("failed to read config file"); exit(1); } /* 1. load dynamic modules -> make linked list of whole modules * 2. setup each modules's configuration -> call each config function */ open_error_log(gErrorLogFile, gQueryLogFile); #ifdef USE_TIMELOG if(sb_tstat_log_init(mTimeLogFile) != SUCCESS) { exit(1); } #endif save_pid(mPidFile); load_dynamic_modules(); /*********************************************************************** * all the modules has been loaded. */ sb_sort_hook(); load_each_registry(); /* 1. register each module to registry * 2. do the shared memory related stuff... * 3. XXX registry module does not guarantee shared memory locking... */ restore_registry_file(gRegistryFile); /* TODO second-pass config */ /*********************************************************************** * runtime configuration is done. */ init_all_scoreboards(); /* method 3 of doc/README.init */ set_proc_desc(NULL, "softbotd: master - init each module"); if ( init_core_modules(first_module) != SUCCESS ) goto STOP; if ( init_standard_modules(first_module) != SUCCESS ) goto STOP; if (clc_listen_port >= 2) { /* show using ports */ show_portinfo(); goto STOP; } set_proc_desc(NULL, "softbotd: master - spawning child"); /* check debug_module */ if ( strlen(debug_module) > 0 ) { mod = find_module(debug_module); if ( mod == NULL ) { error("no such module [%s]", debug_module); return FAIL; } else { info("debugging module [%s]", debug_module); // XXX: in debugging mode, isn't it better not to fork? is it? if (mod->main) sb_run_spawn_process_for_module(scoreboard, mod); else { error("module[%s] has no main",debug_module); exit(1); } } } else if (unittest) { crit("unittesting started"); do_unittest(); crit("unittesting ended"); goto STOP; } else sb_run_spawn_processes_for_each_module(scoreboard, first_module); CRIT("*** master monitoring loop ***"); setproctitle("softbotd: master - monitoring"); set_proc_desc(NULL, "softbotd: master - monitoring"); scoreboard->period = CHILD_MONITORING_PERIOD; sb_run_monitor_processes_for_modules(scoreboard, first_module); /*********************************************************************** * stopping state. */ STOP: if ( save_registry_file(gRegistryFile) != SUCCESS ) error("save_registry_file(%s) failed: %s", gRegistryFile, strerror(errno)); free_ipcs(); /* release shared memory and semaphore */ close_error_log(); /* close error_log file and semaphore */ #ifdef USE_TIMELOG sb_tstat_log_destroy(); #endif return SUCCESS; }