📄 server.c
字号:
eventlog(eventlog_level_error,__FUNCTION__,"could not set SIGUSR1 signal handler (sigaction: %s)",pstrerror(errno)); if (sigaction(SIGPIPE,&pipe_action,NULL)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not set SIGPIPE signal handler (sigaction: %s)",pstrerror(errno));#ifdef HAVE_SETITIMER /* setup asynchronus timestamp update timer */ if (sigaction(SIGALRM,&timer_action,NULL)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not set SIGALRM signal handler (sigaction: %s)",pstrerror(errno)); { struct itimerval it; it.it_interval.tv_sec = BNETD_JIFFIES / 1000; it.it_interval.tv_usec = BNETD_JIFFIES % 1000; it.it_value.tv_sec = BNETD_JIFFIES / 1000; it.it_value.tv_usec = BNETD_JIFFIES % 1000; if (setitimer(ITIMER_REAL, &it, NULL)) { eventlog(eventlog_level_fatal, __FUNCTION__, "failed to set timers (setitimer(): %s)", pstrerror(errno)); return -1; } }#endif if (sigaction(SIGQUIT,&forced_quit_action,NULL)<0) /* immediate shutdown */ eventlog(eventlog_level_error,__FUNCTION__,"could not set SIGQUIT signal handler (sigaction: %s)",pstrerror(errno)); } return 0;}#endifstatic time_t prev_exittime;static void _server_mainloop(t_addrlist *laddrs){ time_t next_savetime, next_flushtime, track_time; time_t war3_ladder_updatetime; time_t output_updatetime; unsigned int count; int savestep, flushstep; starttime = time(NULL); track_time = starttime - prefs_get_track(); next_savetime = starttime + prefs_get_user_sync_timer(); next_flushtime = starttime + prefs_get_user_flush_timer(); war3_ladder_updatetime = starttime - prefs_get_war3_ladder_update_secs(); output_updatetime = starttime - prefs_get_output_update_secs(); savestep = flushstep = 0; count = 0; for (;;) {#ifdef WIN32# ifndef WIN32_GUI if (g_ServiceStatus<0 && kbhit() && getch()=='q') server_quit_wraper();# endif if (g_ServiceStatus == 0) server_quit_wraper(); while (g_ServiceStatus == 2) Sleep(1000);#endif #ifdef DO_POSIXSIG if (sigprocmask(SIG_SETMASK,&save_set,NULL)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not unblock signals"); /* receive signals here */ if (sigprocmask(SIG_SETMASK,&block_set,NULL)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not block signals");#endif if (got_epipe) { got_epipe = 0; eventlog(eventlog_level_info,__FUNCTION__,"handled SIGPIPE"); } #if !defined(DO_POSIXSIG) || !defined(HAVE_SETITIMER)/* if no DO_POSIXSIG or no HAVE_SETITIMER so we must read timestamp each loop */ time(&now);#endif curr_exittime = sigexittime; if (curr_exittime && (curr_exittime<=now || connlist_login_get_length()<1)) { eventlog(eventlog_level_info,__FUNCTION__,"the server is shutting down (%d connections left)",connlist_get_length()); clanlist_save(); /* no need for accountlist_save() when using "force" */ accountlist_save(FS_FORCE | FS_ALL); accountlist_flush(FS_FORCE | FS_ALL); break; } if (prev_exittime!=curr_exittime) { t_message * message; char const * tstr; if (curr_exittime!=0) { char text[29+256+2+32+24+1]; /* "The ... in " + time + " (" num + " connection ...)." + NUL */ tstr = seconds_to_timestr(curr_exittime-now); sprintf(text,"The server will shut down in %s (%d connections remaining).",tstr,connlist_get_length()); if ((message = message_create(message_type_error,NULL,NULL,text))) { message_send_all(message); message_destroy(message); } eventlog(eventlog_level_info,__FUNCTION__,"the server will shut down in %s (%d connections remaining)",tstr,connlist_get_length()); } else { if ((message = message_create(message_type_error,NULL,NULL,"Server shutdown has been canceled."))) { message_send_all(message); message_destroy(message); } eventlog(eventlog_level_info,__FUNCTION__,"server shutdown canceled"); } } prev_exittime = curr_exittime; if (next_savetime <=now) { if (!savestep) { /* do this stuff only first step of save */ clanlist_save(); gamelist_check_voidgame(); } savestep = accountlist_save(FS_NONE); if (!savestep) /* saving finished */ next_savetime += prefs_get_user_sync_timer(); } if (next_flushtime <=now) { if (!flushstep) { /* do this stuff only first step of save */ clanlist_save(); gamelist_check_voidgame(); } flushstep = accountlist_flush(FS_NONE); if (!flushstep) /* flushing finished */ next_flushtime += prefs_get_user_flush_timer(); } if (prefs_get_track() && track_time+(time_t)prefs_get_track()<=now) { track_time = now; tracker_send_report(laddrs); } if (prefs_get_war3_ladder_update_secs() && war3_ladder_updatetime+(time_t)prefs_get_war3_ladder_update_secs()<=now) { war3_ladder_updatetime = now; ladders_write_to_file(); } if (prefs_get_output_update_secs() && output_updatetime+(time_t)prefs_get_output_update_secs()<=now) { output_updatetime = now; output_write_to_file(); } if (do_save) { eventlog(eventlog_level_info,__FUNCTION__,"saving accounts due to signal"); clanlist_save(); savestep = accountlist_save(FS_NONE); if (!savestep) /* saving finished */ next_savetime += prefs_get_user_sync_timer(); do_save = 0; } if (do_restart) { eventlog(eventlog_level_info,__FUNCTION__,"reading configuration files"); if (cmdline_get_preffile()) { if (prefs_load(cmdline_get_preffile())<0) eventlog(eventlog_level_error,__FUNCTION__,"could not parse configuration file"); } else if (prefs_load(BNETD_DEFAULT_CONF_FILE)<0) eventlog(eventlog_level_error,__FUNCTION__,"using default configuration"); if (eventlog_open(prefs_get_logfile())<0) eventlog(eventlog_level_error,__FUNCTION__,"could not use the file \"%s\" for the eventlog",prefs_get_logfile()); /* FIXME: load new network settings */ /* reload server name */ server_set_hostname(); attrlayer_load_default(); channellist_reload(); if (realmlist_reload(prefs_get_realmfile())<0) eventlog(eventlog_level_error,__FUNCTION__,"could not reload realm list"); autoupdate_unload(); if (autoupdate_load(prefs_get_mpqfile())<0) eventlog(eventlog_level_error,__FUNCTION__,"could not load autoupdate list"); news_unload(); if (news_load(prefs_get_newsfile())<0) eventlog(eventlog_level_error,__FUNCTION__,"could not load news list"); versioncheck_unload(); if (versioncheck_load(prefs_get_versioncheck_file())<0) eventlog(eventlog_level_error,__FUNCTION__,"could not load versioncheck list"); if (ipbanlist_destroy()<0) eventlog(eventlog_level_error,__FUNCTION__,"could not unload old IP ban list"); ipbanlist_create(); if (ipbanlist_load(prefs_get_ipbanfile())<0) eventlog(eventlog_level_error,__FUNCTION__,"could not load new IP ban list"); helpfile_unload(); if (helpfile_init(prefs_get_helpfile())<0) eventlog(eventlog_level_error,__FUNCTION__,"could not load the helpfile"); if (adbannerlist_destroy()<0) eventlog(eventlog_level_error,__FUNCTION__,"could not unload old adbanner list"); if (adbannerlist_create(prefs_get_adfile())<0) eventlog(eventlog_level_error,__FUNCTION__,"could not load new adbanner list"); ladder_reload_conf(); if (prefs_get_track()) tracker_set_servers(prefs_get_trackserv_addrs()); if (command_groups_reload(prefs_get_command_groups_file())<0) eventlog(eventlog_level_error,__FUNCTION__,"could not load new command_groups list"); aliasfile_unload(); aliasfile_load(prefs_get_aliasfile()); if(trans_reload(prefs_get_transfile(),TRANS_BNETD)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not reload trans list"); tournament_reload(prefs_get_tournament_file()); anongame_infos_unload(); anongame_infos_load(prefs_get_anongame_infos_file()); topiclist_unload(); if (topiclist_load(prefs_get_topicfile())<0) eventlog(eventlog_level_error,__FUNCTION__,"could not load new topic list"); eventlog(eventlog_level_info,__FUNCTION__,"done reconfiguring"); do_restart = 0; } count += BNETD_POLL_INTERVAL; if (count>=1000) /* only check timers once a second */ { timerlist_check_timers(now); count = 0; }/* no need to populate the fdwatch structures as they are populated on the fly * by sd_accept, conn_push_outqueue, conn_pull_outqueue, conn_destory */ /* find which sockets need servicing */ switch (fdwatch(BNETD_POLL_INTERVAL)) { case -1: /* error */ if (#ifdef PSOCK_EINTR psock_errno()!=PSOCK_EINTR &&#endif 1) eventlog(eventlog_level_error,__FUNCTION__,"fdwatch() failed (errno: %s)",pstrerror(psock_errno())); case 0: /* timeout... no sockets need checking */ continue; } /* cycle through the ready sockets and handle them */ fdwatch_handle(); /* reap dead connections */ connlist_reap(); }}static void _shutdown_conns(void){ t_elem *ccurr; t_connection *c; LIST_TRAVERSE(connlist(),ccurr) { c = (t_connection *)elem_get_data(ccurr); conn_destroy(c,&ccurr,DESTROY_FROM_CONNLIST); }}static void _shutdown_addrs(t_addrlist *laddrs){ t_addr * curr_laddr; t_laddr_info * laddr_info; t_elem const * acurr; LIST_TRAVERSE_CONST(laddrs,acurr) { curr_laddr = elem_get_data(acurr); if ((laddr_info = addr_get_data(curr_laddr).p)) { if (laddr_info->usocket!=-1) psock_close(laddr_info->usocket); if (laddr_info->ssocket!=-1) psock_close(laddr_info->ssocket); xfree(laddr_info); } } addrlist_destroy(laddrs);}extern int server_process(void){ t_addrlist * laddrs; laddrs = NULL; /* Start with the Battle.net address list */ if (_setup_add_addrs(&laddrs, prefs_get_bnetdserv_addrs(),INADDR_ANY,BNETD_SERV_PORT,laddr_type_bnet)) { eventlog(eventlog_level_error,__FUNCTION__,"could not create %s server address list from \"%s\"",laddr_type_get_str(laddr_type_bnet),prefs_get_bnetdserv_addrs()); return -1; } /* Append list of addresses to listen for IRC connections */ if (_setup_add_addrs(&laddrs, prefs_get_irc_addrs(),INADDR_ANY,BNETD_IRC_PORT, laddr_type_irc)) { eventlog(eventlog_level_error,__FUNCTION__,"could not create %s server address list from \"%s\"",laddr_type_get_str(laddr_type_irc),prefs_get_irc_addrs()); _shutdown_addrs(laddrs); return -1; } /* Append list of addresses to listen for WOL IRC connections */ if (_setup_add_addrs(&laddrs, prefs_get_wol_addrs(),INADDR_ANY,BNETD_WOL_PORT, laddr_type_wol)) { eventlog(eventlog_level_error,__FUNCTION__,"could not create %s server address list from \"%s\"",laddr_type_get_str(laddr_type_wol),prefs_get_wol_addrs()); _shutdown_addrs(laddrs); return -1; } /* Append list of addresses to listen for W3ROUTE connections */ if (_setup_add_addrs(&laddrs,prefs_get_w3route_addr(),INADDR_ANY,BNETD_W3ROUTE_PORT, laddr_type_w3route)) { eventlog(eventlog_level_error,__FUNCTION__,"could not create %s server address list from \"%s\"",laddr_type_get_str(laddr_type_w3route),prefs_get_w3route_addr()); _shutdown_addrs(laddrs); return -1; } /* Append list of addresses to listen for telnet connections */ if (_setup_add_addrs(&laddrs,prefs_get_telnet_addrs(),INADDR_ANY,BNETD_TELNET_PORT,laddr_type_telnet)) { eventlog(eventlog_level_error,__FUNCTION__,"could not create %s server address list from \"%s\"",laddr_type_get_str(laddr_type_telnet),prefs_get_telnet_addrs()); _shutdown_addrs(laddrs); return -1; } if (_setup_listensock(laddrs)) { _shutdown_addrs(laddrs); return -1; } /* setup signal handlers */ prev_exittime = sigexittime;#ifdef DO_POSIXSIG _setup_posixsig();#endif _server_mainloop(laddrs); /* cleanup for server shutdown */ _shutdown_conns(); _shutdown_addrs(laddrs); return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -