// Register some signal handlers. static void system_init(void) { struct sigaction act; fb_signal(SIGHUP, terminal_schedule_exit); #ifndef lint fb_signal(SIGINT, SIG_IGN); fb_signal(SIGQUIT, SIG_IGN); fb_signal(SIGPIPE, SIG_IGN); #ifdef DOTIMEOUT set_user_status(ST_LOGIN); alarm(LOGIN_TIMEOUT); #else fb_signal(SIGALRM, SIG_SIG); #endif fb_signal(SIGTERM, SIG_IGN); fb_signal(SIGURG, SIG_IGN); fb_signal(SIGTSTP, SIG_IGN); fb_signal(SIGTTIN, SIG_IGN); #endif sigemptyset(&act.sa_mask); act.sa_flags = SA_NODEFER; act.sa_handler = msg_handler; sigaction(SIGUSR2, &act, NULL); { struct itimerval itv; memset(&itv,0, sizeof(struct itimerval)); itv.it_value.tv_sec = 2 * 60; setitimer(ITIMER_PROF, &itv, NULL); fb_signal(SIGPROF, exit); } }
int main(int argc, char **argv) { const char *socket_path = getenv("FBBS_SOCKET_PATH"); server_path = getenv("FBBS_SERVER_PATH"); if (!socket_path || !server_path) return EXIT_FAILURE; start_daemon(); const char *fbbs_max_servers = getenv("FBBS_MAX_SERVERS"); if (fbbs_max_servers) max_servers = strtol(fbbs_max_servers, NULL, 10); if (max_servers <= 0) max_servers = DEFAULT_MAX_SERVERS; servers = malloc(sizeof(*servers) * max_servers); if (!servers) return EXIT_FAILURE; for (int i = 0; i < max_servers; ++i) { servers[i].pid = -1; servers[i].fd = -1; } int max_clients = 0; const char *fbbs_max_clients = getenv("FBBS_MAX_CLIENTS"); if (fbbs_max_clients) max_clients = strtol(fbbs_max_clients, NULL, 10); max_clients = check_max_clients(max_clients); if (max_clients <= 0) return EXIT_FAILURE; if (setgid(BBSGID) != 0) return EXIT_FAILURE; if (setuid(BBSUID) != 0) return EXIT_FAILURE; int fd = bind_unix_path(socket_path); if (fd < 0) return EXIT_FAILURE; fb_signal(SIGPIPE, SIG_IGN); fb_signal(SIGCHLD, reap_child); fb_signal(SIGTERM, shutdown_backend); for (int i = 0; i < max_servers; ++i) { if (!spawn_server(servers + i)) { kill_servers(); return EXIT_FAILURE; } } ev_run(EV_DEFAULT_ 0); return EXIT_SUCCESS; }
//#define MY_DEBUG // 执行命令cmdfile,参数为param1 static void exec_cmd(int umode, int pager, char *cmdfile, char *param1) { char buf[160]; char *my_argv[18], *ptr; fb_signal(SIGALRM, SIG_IGN); set_user_status(umode); screen_clear(); screen_move(2, 0); if (!dashf(cmdfile)) { //% prints("文件 [%s] 不存在!\n", cmdfile); prints("\xce\xc4\xbc\xfe [%s] \xb2\xbb\xb4\xe6\xd4\xda\xa3\xa1\n", cmdfile); pressreturn(); return; } sprintf(buf, "%s %s %s %d", cmdfile, param1, currentuser.userid, getpid()); report(buf, currentuser.userid); my_argv[0] = cmdfile; strcpy(buf, param1); if (buf[0] != '\0') ptr = strtok(buf, " \t"); else ptr = NULL; for (int i = 1; i < 18; i++) { if (ptr) { my_argv[i] = ptr; ptr = strtok(NULL, " \t"); } else { my_argv[i] = NULL; } } #ifdef MY_DEBUG for (i = 0; i < 18; i++) { if (my_argv[i] != NULL) prints ("my_argv[%d] = %s\n", i, my_argv[i]); else prints ("my_argv[%d] = (none)\n", i); } pressanykey (); #else child_pid = fork(); if (child_pid == -1) { //% prints("资源紧缺,fork() 失败,请稍后再使用"); prints("\xd7\xca\xd4\xb4\xbd\xf4\xc8\xb1\xa3\xac""fork() \xca\xa7\xb0\xdc\xa3\xac\xc7\xeb\xc9\xd4\xba\xf3\xd4\xd9\xca\xb9\xd3\xc3"); child_pid = 0; pressreturn(); return; } if (child_pid == 0) { execv(cmdfile, my_argv); exit(0); } else { waitpid(child_pid, NULL, 0); } #endif child_pid = 0; screen_clear(); }
// Save user info on exit. void u_exit(void) { // 这些信号的处理要关掉, 否则在离线时等候回车时出现 // 信号会导致重写名单, 这个导致的名单混乱比kick user更多 (ylsdd) fb_signal(SIGALRM, SIG_DFL); fb_signal(SIGPIPE, SIG_DFL); fb_signal(SIGTERM, SIG_DFL); fb_signal(SIGUSR1, SIG_IGN); fb_signal(SIGUSR2, SIG_IGN); if (HAS_PERM(PERM_LOGINCLOAK)) setflags(CLOAK_FLAG, !session_visible()); set_safe_record(); update_user_stay(¤tuser, false, false); substitut_record(PASSFILE, ¤tuser, sizeof(currentuser), usernum); uidshm->status[usernum - 1]--; session_destroy(session_id()); session_set_pid(0); }
/** * The main entrance of bbswebd. * @return 0 on success, 1 on initialization error. */ int main(void) { fb_signal(SIGTERM, exit_handler); fb_signal(SIGUSR1, exit_handler); if (initialize() < 0) return EXIT_FAILURE; initialize_environment(INIT_CONV | INIT_DB | INIT_MDB); while (FCGI_Accept() >= 0) { if (!web_ctx_init()) return EXIT_FAILURE; const web_handler_t *h = _get_handler(); int code = BBS_ENOURL; if (h) { get_client_ip(); session_validate(); brc_reset(); if (session_get_id()) { if (h->status != ST_IDLE) set_user_status(h->status); session_set_idle(session_get_id(), fb_time()); if (h->status != ST_READING) session_set_board(0); } code = execute(h); } if (code > 0) web_respond(code); else check_bbserr(code); web_ctx_destroy(); } return 0; }
/** * Daemonize the process. */ void start_daemon(void) { umask(0); int pid = fork(); if (pid < 0) { exit(1); } else if (pid != 0) { exit(0); } if (setsid() == -1) exit(1); if ((pid = fork()) < 0) { exit(1); } else if (pid != 0) { exit(0); } file_close_all(); for (int n = 1; n <= NSIG; n++) fb_signal(n, SIG_IGN); }