wbt_status wbt_conf_reload() { /* TODO 清理已保存的配置信息 */ /* 尝试读取配置文件 */ wbt_file_t wbt_config_file; wbt_config_file.fd = wbt_open_file(wbt_config_file_name.str); if( wbt_config_file.fd <= 0 ) { /* 找不到配置文件 */ wbt_log_print("Can't find config file: %.*s\n", wbt_config_file_name.len, wbt_config_file_name.str); return WBT_ERROR; } #ifndef WIN32 int len = wbt_get_file_path_by_fd(wbt_config_file.fd, wbt_config_file_path.str, wbt_config_file_path.len); if( len <= 0 ) { return WBT_ERROR; } wbt_config_file_path.str[len] = '\0'; #endif struct stat statbuff; if(stat(wbt_config_file_name.str, &statbuff) < 0){ return WBT_ERROR; } wbt_config_file.size = statbuff.st_size; wbt_config_file_content.len = wbt_config_file.size; wbt_config_file_content.str = wbt_malloc( wbt_config_file_content.len ); if( wbt_config_file_content.str == NULL ) { return WBT_ERROR; } if( wbt_read_file( wbt_config_file.fd, wbt_config_file_content.str, wbt_config_file_content.len, 0) != wbt_config_file_content.len ) { wbt_log_print("Read config file failed\n"); return WBT_ERROR; } /* 关闭配置文件 */ wbt_close_file(wbt_config_file.fd); /* 解析配置文件 */ if( wbt_conf_parse(&wbt_config_file_content) == WBT_OK ) { //wbt_rbtree_print(wbt_config_rbtree.root); wbt_free(wbt_config_file_content.str); #ifndef WIN32 char tmp[1024]; snprintf(tmp, sizeof(tmp), "bmq: master process (%.*s)", len, wbt_config_file_path.str ); wbt_set_proc_title(tmp); #endif return WBT_OK; } else { wbt_free(wbt_config_file_content.str); wbt_log_print("Syntax error on config file: line %d, charactor %d\n", wbt_conf_line, wbt_conf_charactor); return WBT_ERROR; } }
wbt_status wbt_module_exit() { /* 卸载所有模块 */ int i, size = sizeof(wbt_modules)/sizeof(wbt_module_t *) - 1; for( i = size - 1 ; i >= 0 ; i-- ) { wbt_log_print( "\nFinalize module %-12.*s [ ]", wbt_modules[i]->name.len, wbt_modules[i]->name.str ); if( wbt_modules[i]->exit && wbt_modules[i]->exit(/*cycle*/) != WBT_OK ) { /* fatal */ wbt_log_print( "\rFinalize module %-12.*s [ \033[31;49;1mFAILED\033[0m ]", wbt_modules[i]->name.len, wbt_modules[i]->name.str ); } else { wbt_log_print( "\rFinalize module %-12.*s [ \033[32;49;1mOK\033[0m ]", wbt_modules[i]->name.len, wbt_modules[i]->name.str ); } } return WBT_OK; }
wbt_status wbt_module_init() { /* 初始化模块 */ int i , size = sizeof(wbt_modules)/sizeof(wbt_module_t *) - 1; for( i = 0 ; i < size ; i++ ) { wbt_log_print( "\nInitialize module %-10.*s [ ]", wbt_modules[i]->name.len, wbt_modules[i]->name.str ); if( wbt_modules[i]->init && wbt_modules[i]->init(/*cycle*/) != WBT_OK ) { /* fatal */ wbt_log_print( "\rInitialize module %-10.*s [ \033[31;49;1mFAILED\033[0m ]", wbt_modules[i]->name.len, wbt_modules[i]->name.str ); return WBT_ERROR; } else { wbt_log_print( "\rInitialize module %-10.*s [ \033[32;49;1mOK\033[0m ]", wbt_modules[i]->name.len, wbt_modules[i]->name.str ); } } return WBT_OK; }
void wbt_exit(int exit_code) { wbt_wating_to_exit = 1; /* 卸载所有模块 */ wbt_module_exit(); wbt_log_add("Webit exit (pid: %d)\n", getpid()); wbt_log_print("\n\nWebit exit (pid: %d)\n", getpid()); exit(exit_code); }
int main(int argc, char** argv) { /* 保存传入参数 */ if( wbt_save_argv(argc, argv) != WBT_OK ) { return 1; } /* 初始化日至输出缓冲 */ if( wbt_malloc( &wbt_log_buf, 1024 ) != WBT_OK ) { return 1; } /* 更新终端尺寸 */ wbt_term_update_size(); /* 解析传入参数 */ int ch; opterr = 0; while( ( ch = wbt_getopt(argc,argv,"c:hs:tv") ) != -1 ) { switch(ch) { case 'v': wbt_log_print( "webit version: webit/" WBT_VERSION "\n" ); return 0; case 'h': wbt_log_print( "\nOptions:\n" " -h : this help\n" " -v : show version and exit\n" " -s [stop|reload] : send signal to a master process\n" " -t [config-file] : test configuration and exit\n" " -c [config-file] : use the specified configuration\n\n"); return 0; case 'c': if( wbt_conf_set_file(optarg) != WBT_OK ) { return 1; } break; case '?': if( optopt == 'c' || optopt == 's' || optopt == 't' ) { wbt_log_print("option: -%c required parameters\n",optopt); } else { wbt_log_print("invalid option: -%c\n",optopt); } return 1; default: wbt_log_print("option: -%c not yet implemented\n",ch); return 1; } } wbt_init_proc_title(); /* 初始化所有组件 */ wbt_log_print( "webit version: webit/" WBT_VERSION "\n" ); if( wbt_module_init() != WBT_OK ) { wbt_log_print( "\n\n" ); return 1; } /* 设置程序允许打开的最大文件句柄数 */ struct rlimit rlim; rlim.rlim_cur = wbt_conf.max_open_files; rlim.rlim_max = 65535; setrlimit(RLIMIT_NOFILE, &rlim); /* 设置程序允许生成的 core dump 文件大小 */ if( wbt_conf.max_core_file_size < 0 ) { rlim.rlim_cur = RLIM_INFINITY; } else { rlim.rlim_cur = wbt_conf.max_core_file_size; } rlim.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &rlim); /* 屏蔽 umask */ umask(0); /* 接下来的 chroot 会导致程序无法访问 /etc/timezone * TODO 读取 /etc/timezone 的内容并保存 */ if( setenv("TZ", "Asia/Shanghai", 1) != 0 ) { perror("setenv"); return 1; } tzset(); if( !wbt_conf.run_mode ) { wbt_log_print( "\n\nwebit is now running in the background.\n\n" ); /* 转入后台运行 */ if( daemon(1,0) < 0 ) { perror("error daemon"); return 1; } } else { wbt_log_print( "\n\nwebit is now running.\n\n" ); } /* 限制可以访问的目录 * 这个操作会导致 daemon() 不能正常运行 * 只有 root 用户才能执行该操作,为了使非 root 用户也能运行 webit,必须放弃使用 chroot */ //const char * wwwroot = wbt_stdstr(&wbt_conf.root); /* if( chroot( wwwroot ) != 0 ) { wbt_log_add("%s not exists.\n", wwwroot); return; } else { wbt_log_add("Root path: %s\n", wwwroot); }*/ if( !wbt_conf.run_mode ) { wbt_master_process(); } else { wbt_worker_process(); } return 0; }
wbt_status wbt_conf_init() { wbt_rb_init(&wbt_config_rbtree, WBT_RB_KEY_STRING); wbt_config_file_path.len = 64; wbt_config_file_path.str = wbt_malloc( wbt_config_file_path.len ); if( wbt_config_file_path.str == NULL ) { return WBT_ERROR; } if( wbt_conf_reload() != WBT_OK ) { return WBT_ERROR; } /* 初始化 wbt_conf */ const char * value; wbt_str_t * m_value; wbt_conf.listen_port = 80; if( ( value = wbt_conf_get("listen") ) != NULL ) { wbt_conf.listen_port = atoi(value); if( wbt_conf.listen_port < 0 || wbt_conf.listen_port > 65535 ) { wbt_log_print("listen port out of range ( expect 0 - 65535 )\n"); return WBT_ERROR; } } wbt_conf.process = 1; if( ( value = wbt_conf_get("process") ) != NULL ) { wbt_conf.process = atoi(value); if( wbt_conf.process < 1 || wbt_conf.process > 128 ) { wbt_log_print("worker process number out of range ( expect 1 - 128 )\n"); return WBT_ERROR; } } wbt_conf.secure = 0; if( ( m_value = wbt_conf_get_v("secure") ) != NULL ) { if( wbt_strcmp( m_value, &wbt_conf_option_on ) == 0 ) { wbt_conf.secure = 1; } } wbt_conf.secure_port = 443; if( ( value = wbt_conf_get("secure_port") ) != NULL ) { wbt_conf.secure_port = atoi(value); if( wbt_conf.secure_port < 0 || wbt_conf.secure_port > 65535 ) { wbt_log_print("secure port out of range ( expect 0 - 65535 )\n"); return WBT_ERROR; } } wbt_str_set_null(wbt_conf.secure_key); wbt_str_set_null(wbt_conf.secure_crt); if( wbt_conf.secure ) { if( ( m_value = wbt_conf_get_v("secure_key") ) != NULL ) { wbt_conf.secure_key = *m_value; } else { wbt_log_print("option secure_key is required\n"); return WBT_ERROR; } if( ( m_value = wbt_conf_get_v("secure_crt") ) != NULL ) { wbt_conf.secure_crt = *m_value; } else { wbt_log_print("option secure_crt is required\n"); return WBT_ERROR; } } wbt_conf.sendfile = 0; if( !wbt_conf.secure ) { if( ( m_value = wbt_conf_get_v("sendfile") ) != NULL ) { if( wbt_strcmp( (wbt_str_t *)m_value, &wbt_conf_option_on ) == 0 ) { wbt_conf.sendfile = 1; } } } wbt_conf.gzip = 0; if( ( m_value = wbt_conf_get_v("gzip") ) != NULL ) { if( wbt_strcmp( (wbt_str_t *)m_value, &wbt_conf_option_on ) == 0 ) { wbt_conf.gzip = 1; } } wbt_conf.aof = 1; if( ( m_value = wbt_conf_get_v("aof") ) != NULL ) { if( wbt_strcmp( (wbt_str_t *)m_value, &wbt_conf_option_off ) == 0 ) { wbt_conf.aof = 0; } } wbt_conf.aof_crc = 0; if( ( m_value = wbt_conf_get_v("aof_crc") ) != NULL ) { if( wbt_strcmp( (wbt_str_t *)m_value, &wbt_conf_option_on ) == 0 ) { wbt_conf.aof_crc = 1; } } wbt_conf.aof_fsync = AOF_FSYNC_EVERYSEC; if( ( m_value = wbt_conf_get_v("aof_fsync") ) != NULL ) { if( wbt_strcmp( (wbt_str_t *)m_value, &wbt_conf_option_off ) == 0 ) { wbt_conf.aof_fsync = AOF_FSYNC_NO; } else if( wbt_strcmp( (wbt_str_t *)m_value, &wbt_conf_option_always ) == 0 ) { wbt_conf.aof_fsync = AOF_FSYNC_ALWAYS; } else if( wbt_strcmp( (wbt_str_t *)m_value, &wbt_conf_option_everysec ) == 0 ) { wbt_conf.aof_fsync = AOF_FSYNC_EVERYSEC; } else { wbt_log_print("option aof_fsync is illegal ( expect off / always / everysec )\n"); return WBT_ERROR; } } wbt_conf.aof_fast_boot = 1; if( ( m_value = wbt_conf_get_v("aof_fast_boot") ) != NULL ) { if( wbt_strcmp( (wbt_str_t *)m_value, &wbt_conf_option_off ) == 0 ) { wbt_conf.aof_fast_boot = 0; } } wbt_conf.auth = 0; if( ( m_value = wbt_conf_get_v("auth") ) != NULL ) { if( wbt_strcmp( (wbt_str_t *)m_value, &wbt_conf_option_none ) == 0 ) { wbt_conf.auth = 0; } else if( wbt_strcmp( (wbt_str_t *)m_value, &wbt_conf_option_basic ) == 0 ) { wbt_conf.auth = 1; } else if( wbt_strcmp( (wbt_str_t *)m_value, &wbt_conf_option_standard ) == 0 ) { wbt_conf.auth = 2; } else { wbt_log_print("option auth is illegal ( expect none / baisc / standard )\n"); return WBT_ERROR; } } if( wbt_conf.auth == 1 ) { wbt_str_set_null(wbt_conf.auth_password); if( ( m_value = wbt_conf_get_v("auth_password") ) != NULL ) { wbt_conf.auth_key = *m_value; } else { wbt_log_print("option auth_password is required\n"); return WBT_ERROR; } } else if( wbt_conf.auth == 2 ) { wbt_str_set_null(wbt_conf.auth_key); if( ( m_value = wbt_conf_get_v("auth_key") ) != NULL ) { wbt_conf.auth_key = *m_value; } else { wbt_log_print("option auth_key is required\n"); return WBT_ERROR; } } wbt_str_set_null(wbt_conf.auth_anonymous); if( ( m_value = wbt_conf_get_v("auth_anonymous") ) != NULL ) { wbt_conf.auth_anonymous = *m_value; } wbt_conf.keep_alive_timeout = 600000; if( ( value = wbt_conf_get("keep_alive_timeout") ) != NULL ) { wbt_conf.keep_alive_timeout = atoi(value); } wbt_conf.event_timeout = 150000; if( ( value = wbt_conf_get("event_timeout") ) != NULL ) { wbt_conf.event_timeout = atoi(value); } wbt_conf.max_open_files = 65535; if( ( value = wbt_conf_get("max_open_files") ) != NULL ) { wbt_conf.max_open_files = atoi(value); } wbt_conf.max_core_file_size = 0; if( ( value = wbt_conf_get("max_core_file_size") ) != NULL ) { wbt_conf.max_core_file_size = atoi(value); } wbt_conf.max_memory_usage = 0; if( ( value = wbt_conf_get("max_memory_usage") ) != NULL ) { wbt_conf.max_memory_usage = 1024*1024*atoll(value); } wbt_conf.master_port = 1039; if( ( value = wbt_conf_get("master_port") ) != NULL ) { wbt_conf.master_port = atoi(value); } wbt_str_set_null(wbt_conf.root); if( ( m_value = wbt_conf_get_v("root") ) != NULL ) { wbt_conf.root = *m_value; // TODO 检查 root 是否存在 } else { wbt_log_print("option root is required\n"); return WBT_ERROR; } wbt_str_set_null(wbt_conf.index); if( ( m_value = wbt_conf_get_v("default") ) != NULL ) { wbt_conf.index = *m_value; } wbt_str_set_null(wbt_conf.admin); if( ( m_value = wbt_conf_get_v("server_admin") ) != NULL ) { wbt_conf.admin = *m_value; } wbt_str_set_null(wbt_conf.user); if( ( m_value = wbt_conf_get_v("user") ) != NULL ) { wbt_conf.user = *m_value; } wbt_str_set_null(wbt_conf.data); if( ( m_value = wbt_conf_get_v("data") ) != NULL ) { wbt_conf.data = *m_value; } else { wbt_log_print("option data is required\n"); return WBT_ERROR; } wbt_str_set_null(wbt_conf.logs); if( ( m_value = wbt_conf_get_v("logs") ) != NULL ) { wbt_conf.logs = *m_value; } else { wbt_log_print("option logs is required\n"); return WBT_ERROR; } wbt_str_set_null(wbt_conf.master_host); if( ( m_value = wbt_conf_get_v("master_host") ) != NULL ) { wbt_conf.master_host = *m_value; } wbt_conf.worker_id = 0; if( ( value = wbt_conf_get("worker_id") ) != NULL ) { wbt_conf.worker_id = atoi(value); if( wbt_conf.worker_id < 0 || wbt_conf.worker_id > SF_MAX_WORKER_ID ) { wbt_log_print("worker_id out of range ( expect 0 - %d )\n", SF_MAX_WORKER_ID); return WBT_ERROR; } } return WBT_OK; }