/[LeafOK_CVS]/pvpgn-1.7.4/src/bnetd/main.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/bnetd/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations)
Sat Jul 12 11:54:27 2008 UTC (17 years, 8 months ago) by sysadm
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +3 -0 lines
Content type: text/x-csrc
Update

1 /*
2 * Copyright (C) 1998 Mark Baysinger (mbaysing@ucsd.edu)
3 * Copyright (C) 1998,1999,2000 Ross Combs (rocombs@cs.nmsu.edu)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 #include "common/setup_before.h"
20 #include <stdio.h>
21 #ifdef HAVE_STDDEF_H
22 # include <stddef.h>
23 #else
24 # ifndef NULL
25 # define NULL ((void *)0)
26 # endif
27 #endif
28 #ifdef STDC_HEADERS
29 # include <stdlib.h>
30 #else
31 # ifdef HAVE_MALLOC_H
32 # include <malloc.h>
33 # endif
34 #endif
35 #include "compat/exitstatus.h"
36 #ifdef HAVE_STRING_H
37 # include <string.h>
38 #else
39 # ifdef HAVE_STRINGS_H
40 # include <strings.h>
41 # endif
42 #endif
43 #include "compat/strdup.h"
44 #include <errno.h>
45 #include "compat/strerror.h"
46 #ifdef HAVE_UNISTD_H
47 # include <unistd.h>
48 #endif
49 #include "compat/stdfileno.h"
50 #include "compat/psock.h"
51 #include "common/hexdump.h"
52 #include "channel.h"
53 #include "game.h"
54 #include "server.h"
55 #include "common/eventlog.h"
56 #include "account.h"
57 #include "connection.h"
58 #include "game.h"
59 #include "common/version.h"
60 #include "prefs.h"
61 #include "ladder.h"
62 #include "adbanner.h"
63 #include "ipban.h"
64 #include "autoupdate.h"
65 #include "helpfile.h"
66 #include "timer.h"
67 #include "watch.h"
68 #include "common/tracker.h"
69 #include "realm.h"
70 #include "character.h"
71 #include "common/give_up_root_privileges.h"
72 #include "versioncheck.h"
73 #include "storage.h"
74 #include "anongame.h"
75 //aaron
76 #include "command_groups.h"
77 #include "output.h"
78 #include "alias_command.h"
79 #include "anongame_infos.h"
80 #include "anongame_maplists.h"
81 #include "tournament.h"
82 #include "news.h"
83 #include "clan.h"
84 #include "team.h"
85 #include "topic.h"
86 #include "support.h"
87 #include "common/trans.h"
88 #include "common/xalloc.h"
89 #include "common/fdwatch.h"
90 #ifdef WIN32
91 # include "win32/service.h"
92 #endif
93 #ifdef WIN32_GUI
94 # include "win32/winmain.h"
95 # define printf gui_printf
96 #endif
97 #include "common/setup_after.h"
98
99 /* out of memory safety */
100 #define OOM_SAFE_MEM 1000000 /* 1 Mbyte of safety memory */
101
102 void *oom_buffer = NULL;
103
104 static int bnetd_oom_handler(void)
105 {
106 /* no safety buffer, sorry :( */
107 if (!oom_buffer) return 0;
108
109 /* free the safety buffer hoping next allocs will succeed */
110 free(oom_buffer);
111 oom_buffer = NULL;
112
113 eventlog(eventlog_level_fatal,__FUNCTION__,"out of memory, forcing immediate shutdown");
114
115 /* shutdown immediatly */
116 server_quit_delay(-1);
117
118 return 1; /* ask xalloc codes to retry the allocation request */
119 }
120
121 static int oom_setup(void)
122 {
123 oom_buffer = malloc(OOM_SAFE_MEM);
124 if (!oom_buffer) return -1;
125
126 xalloc_setcb(bnetd_oom_handler);
127 return 0;
128 }
129
130 static void oom_free(void)
131 {
132 if (oom_buffer) free(oom_buffer);
133 oom_buffer = NULL;
134 }
135
136 FILE *hexstrm = NULL;
137
138 char serviceLongName[] = "PvPGN service";
139 char serviceName[] = "pvpgn";
140 char serviceDescription[] = "Player vs. Player Gaming Network - Server";
141
142 // by quetzal. indicates service status
143 // -1 - not in service mode
144 // 0 - stopped
145 // 1 - running
146 // 2 - paused
147 int g_ServiceStatus = -1;
148
149 static void usage(char const * progname);
150
151 static void usage(char const * progname)
152 {
153 fprintf(stderr,
154 "usage: %s [<options>]\n"
155 " -c FILE, --config=FILE use FILE as configuration file (default is " BNETD_DEFAULT_CONF_FILE ")\n"
156 " -d FILE, --hexdump=FILE do hex dump of packets into FILE\n"
157 #ifdef DO_DAEMONIZE
158 " -f, --foreground don't daemonize\n"
159 #else
160 " -f, --foreground don't daemonize (default)\n"
161 #endif
162 " -D, --debug run in debug mode (run in foreground and log to stdout)\n"
163 " -h, --help, --usage show this information and exit\n"
164 " -v, --version print version number and exit\n"
165 #ifdef WIN32
166 " Running as service functions:\n"
167 " --service run as service\n"
168 " -s install install service\n"
169 " -s uninstall uninstall service\n"
170 #endif
171 ,progname);
172 }
173
174
175 // added some more exit status --> put in "compat/exitstatus.h" ???
176 #define STATUS_OOM_FAILURE 20
177 #define STATUS_STORAGE_FAILURE 30
178 #define STATUS_PSOCK_FAILURE 35
179 #define STATUS_MAPLISTS_FAILURE 40
180 #define STATUS_MATCHLISTS_FAILURE 50
181 #define STATUS_LADDERLIST_FAILURE 60
182 #define STATUS_WAR3XPTABLES_FAILURE 70
183 #define STATUS_SUPPORT_FAILURE 80
184 #define STATUS_FDWATCH_FAILURE 90
185
186 // new functions extracted from Fw()
187 int read_commandline(int argc, char * * argv, int *foreground, char const *preffile[], char *hexfile[]);
188 int pre_server_startup(void);
189 void post_server_shutdown(int status);
190 int eventlog_startup(void);
191 int fork_bnetd(int foreground);
192 char * write_to_pidfile(void);
193 void pvpgn_greeting(void);
194
195 // The functions
196 int read_commandline(int argc, char * * argv, int *foreground, char const *preffile[], char *hexfile[])
197 {
198 int a;
199
200 if (argc<1 || !argv || !argv[0]) {
201 fprintf(stderr,"bad arguments\n");
202 return -1;
203 }
204 #ifdef WIN32
205 if (argc > 1 && strncmp(argv[1], "--service", 9) == 0) {
206 Win32_ServiceRun();
207 return 0;
208 }
209 #endif
210 for (a=1; a<argc; a++) {
211 if (strncmp(argv[a],"--config=",9)==0) {
212 if (*preffile) {
213 fprintf(stderr,"%s: configuration file was already specified as \"%s\"\n",argv[0],preffile[0]);
214 usage(argv[0]);
215 return -1;
216 }
217 *preffile = &argv[a][9];
218 }
219 else if (strcmp(argv[a],"-c")==0) {
220 if (a+1>=argc) {
221 fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
222 usage(argv[0]);
223 return -1;
224 }
225 if (*preffile) {
226 fprintf(stderr,"%s: configuration file was already specified as \"%s\"\n",argv[0],preffile[0]);
227 usage(argv[0]);
228 return -1;
229 }
230 a++;
231 *preffile = argv[a];
232 }
233 else if (strncmp(argv[a],"--hexdump=",10)==0) {
234 if (*hexfile) {
235 fprintf(stderr,"%s: configuration file was already specified as \"%s\"\n",argv[0],hexfile[0]);
236 usage(argv[0]);
237 return -1;
238 }
239 *hexfile = &argv[a][10];
240 }
241 else if (strcmp(argv[a],"-d")==0) {
242 if (a+1>=argc) {
243 fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
244 usage(argv[0]);
245 return -1;
246 }
247 if (*hexfile) {
248 fprintf(stderr,"%s: configuration file was already specified as \"%s\"\n",argv[0],hexfile[0]);
249 usage(argv[0]);
250 return -1;
251 }
252 a++;
253 *hexfile = argv[a];
254 }
255 else if (strcmp(argv[a],"-f")==0 || strcmp(argv[a],"--foreground")==0)
256 *foreground = 1;
257 else if (strcmp(argv[a],"-D")==0 || strcmp(argv[a],"--debug")==0) {
258 eventlog_set_debugmode(1);
259 *foreground = 1;
260 }
261 #ifdef WIN32
262 else if (strcmp(argv[a],"-s") == 0) {
263 if (a < argc - 1) {
264 if (strcmp(argv[a+1], "install") == 0) {
265 fprintf(stderr, "Installing service");
266 Win32_ServiceInstall();
267 }
268 if (strcmp(argv[a+1], "uninstall") == 0) {
269 fprintf(stderr, "Uninstalling service");
270 Win32_ServiceUninstall();
271 }
272 }
273 return 0;
274 }
275 #endif
276 else if (strcmp(argv[a],"-v")==0 || strcmp(argv[a],"--version")==0) {
277 printf(PVPGN_SOFTWARE" version "PVPGN_VERSION"\n");
278 return 0;
279 }
280 else if (strcmp(argv[a],"-h")==0 || strcmp(argv[a],"--help")==0 || strcmp(argv[a],"--usage")==0) {
281 usage(argv[0]);
282 return 0;
283 }
284 else if (strcmp(argv[a],"--config")==0 || strcmp(argv[a],"--hexdump")==0) {
285 fprintf(stderr,"%s: option \"%s\" requires and argument.\n",argv[0],argv[a]);
286 usage(argv[0]);
287 return -1;
288 }
289 else {
290 fprintf(stderr,"%s: bad option \"%s\"\n",argv[0],argv[a]);
291 usage(argv[0]);
292 return -1;
293 }
294 }
295 return 1; // continue without exiting
296 }
297
298 int eventlog_startup(void)
299 {
300 char const * levels;
301 char * temp;
302 char const * tok;
303
304 eventlog_clear_level();
305 if ((levels = prefs_get_loglevels())) {
306 temp = xstrdup(levels);
307 tok = strtok(temp,","); /* strtok modifies the string it is passed */
308 while (tok) {
309 if (eventlog_add_level(tok)<0)
310 eventlog(eventlog_level_error,__FUNCTION__,"could not add log level \"%s\"",tok);
311 tok = strtok(NULL,",");
312 }
313 xfree(temp);
314 }
315 if (eventlog_open(prefs_get_logfile())<0) {
316 if (prefs_get_logfile()) {
317 eventlog(eventlog_level_fatal,__FUNCTION__,"could not use file \"%s\" for the eventlog (exiting)",prefs_get_logfile());
318 } else {
319 eventlog(eventlog_level_fatal,__FUNCTION__,"no logfile specified in configuration file \"%s\" (exiting)",preffile);
320 }
321 return -1;
322 }
323 eventlog(eventlog_level_info,__FUNCTION__,"logging event levels: %s",prefs_get_loglevels());
324 return 0;
325 }
326
327 int fork_bnetd(int foreground)
328 {
329 int pid;
330
331 #ifdef DO_DAEMONIZE
332 if (!foreground) {
333 if (chdir("/")<0) {
334 eventlog(eventlog_level_error,__FUNCTION__,"could not change working directory to / (chdir: %s)",pstrerror(errno));
335 return -1;
336 }
337
338 switch ((pid = fork())) {
339 case -1:
340 eventlog(eventlog_level_error,__FUNCTION__,"could not fork (fork: %s)",pstrerror(errno));
341 return -1;
342 case 0: /* child */
343 break;
344 default: /* parent */
345 return pid;
346 }
347 #ifndef WITH_D2
348 close(STDINFD);
349 close(STDOUTFD);
350 close(STDERRFD);
351 #endif
352 # ifdef HAVE_SETPGID
353 if (setpgid(0,0)<0) {
354 eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgid: %s)",pstrerror(errno));
355 return -1;
356 }
357 # else
358 # ifdef HAVE_SETPGRP
359 # ifdef SETPGRP_VOID
360 if (setpgrp()<0) {
361 eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgrp: %s)",pstrerror(errno));
362 return -1;
363 }
364 # else
365 if (setpgrp(0,0)<0) {
366 eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgrp: %s)",pstrerror(errno));
367 return -1;
368 }
369 # endif
370 # else
371 # ifdef HAVE_SETSID
372 if (setsid()<0) {
373 eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setsid: %s)",pstrerror(errno));
374 return -1;
375 }
376 # else
377 # error "One of setpgid(), setpgrp(), or setsid() is required"
378 # endif
379 # endif
380 # endif
381 }
382 return 0;
383 #endif
384 return 0;
385 }
386
387 char * write_to_pidfile(void)
388 {
389 char *pidfile = xstrdup(prefs_get_pidfile());
390
391 if (pidfile[0]=='\0') {
392 xfree((void *)pidfile); /* avoid warning */
393 return NULL;
394 }
395 if (pidfile) {
396 #ifdef HAVE_GETPID
397 FILE * fp;
398
399 if (!(fp = fopen(pidfile,"w"))) {
400 eventlog(eventlog_level_error,__FUNCTION__,"unable to open pid file \"%s\" for writing (fopen: %s)",pidfile,pstrerror(errno));
401 xfree((void *)pidfile); /* avoid warning */
402 return NULL;
403 } else {
404 fprintf(fp,"%u",(unsigned int)getpid());
405 if (fclose(fp)<0)
406 eventlog(eventlog_level_error,__FUNCTION__,"could not close pid file \"%s\" after writing (fclose: %s)",pidfile,pstrerror(errno));
407 }
408 #else
409 eventlog(eventlog_level_warn,__FUNCTION__,"no getpid() system call, disable pid file in bnetd.conf");
410 xfree((void *)pidfile); /* avoid warning */
411 return NULL;
412 #endif
413 }
414 return pidfile;
415 }
416
417 int pre_server_startup(void)
418 {
419 pvpgn_greeting();
420 if (oom_setup() < 0) {
421 eventlog(eventlog_level_error, __FUNCTION__, "OOM init failed");
422 return STATUS_OOM_FAILURE;
423 }
424 if (storage_init(prefs_get_storage_path()) < 0) {
425 eventlog(eventlog_level_error, "pre_server_startup", "storage init failed");
426 return STATUS_STORAGE_FAILURE;
427 }
428 if (psock_init() < 0) {
429 eventlog(eventlog_level_error, __FUNCTION__, "could not initialize socket functions");
430 return STATUS_PSOCK_FAILURE;
431 }
432 if (support_check_files(prefs_get_supportfile()) < 0) {
433 eventlog(eventlog_level_error, "pre_server_startup","some needed files are missing");
434 eventlog(eventlog_level_error, "pre_server_startup","please make sure you installed the supportfiles in %s",prefs_get_filedir());
435 return STATUS_SUPPORT_FAILURE;
436 }
437 if (anongame_maplists_create() < 0) {
438 eventlog(eventlog_level_error, "pre_server_startup", "could not load maps");
439 return STATUS_MAPLISTS_FAILURE;
440 }
441 if (anongame_matchlists_create() < 0) {
442 eventlog(eventlog_level_error, "pre_server_startup", "could not create matchlists");
443 return STATUS_MATCHLISTS_FAILURE;
444 }
445 if (fdwatch_init(prefs_get_max_connections())) {
446 eventlog(eventlog_level_error, __FUNCTION__, "error initilizing fdwatch");
447 return STATUS_FDWATCH_FAILURE;
448 }
449 connlist_create();
450 gamelist_create();
451 timerlist_create();
452 server_set_name();
453 channellist_create();
454 if (helpfile_init(prefs_get_helpfile())<0)
455 eventlog(eventlog_level_error,__FUNCTION__,"could not load helpfile");
456 ipbanlist_create();
457 if (ipbanlist_load(prefs_get_ipbanfile())<0)
458 eventlog(eventlog_level_error,__FUNCTION__,"could not load IP ban list");
459 if (adbannerlist_create(prefs_get_adfile())<0)
460 eventlog(eventlog_level_error,__FUNCTION__,"could not load adbanner list");
461 if (autoupdate_load(prefs_get_mpqfile())<0)
462 eventlog(eventlog_level_error,__FUNCTION__,"could not load autoupdate list");
463 if (versioncheck_load(prefs_get_versioncheck_file())<0)
464 eventlog(eventlog_level_error,__FUNCTION__,"could not load versioncheck list");
465 if (news_load(prefs_get_newsfile())<0)
466 eventlog(eventlog_level_error,__FUNCTION__,"could not load news list");
467 watchlist_create();
468 output_init();
469 accountlist_load_default();
470 accountlist_create();
471 if (ladder_createxptable(prefs_get_xplevel_file(),prefs_get_xpcalc_file())<0) {
472 eventlog(eventlog_level_error, "pre_server_startup", "could not load WAR3 xp calc tables");
473 return STATUS_WAR3XPTABLES_FAILURE;
474 }
475 ladders_init();
476 ladders_load_accounts_to_ladderlists();
477 ladder_update_all_accounts();
478 if (characterlist_create("")<0)
479 eventlog(eventlog_level_error,__FUNCTION__,"could not load character list");
480 if (prefs_get_track()) /* setup the tracking mechanism */
481 tracker_set_servers(prefs_get_trackserv_addrs());
482 if (command_groups_load(prefs_get_command_groups_file())<0)
483 eventlog(eventlog_level_error,__FUNCTION__,"could not load command_groups list");
484 aliasfile_load(prefs_get_aliasfile());
485 if (trans_load(prefs_get_transfile(),TRANS_BNETD)<0)
486 eventlog(eventlog_level_error,__FUNCTION__,"could not load trans list");
487 tournament_init(prefs_get_tournament_file());
488 anongame_infos_load(prefs_get_anongame_infos_file());
489 clanlist_load();
490 teamlist_load();
491 if (realmlist_create(prefs_get_realmfile())<0)
492 eventlog(eventlog_level_error,__FUNCTION__,"could not load realm list");
493 topiclist_load(prefs_get_topicfile());
494 return 0;
495 }
496
497 void post_server_shutdown(int status)
498 {
499 switch (status)
500 {
501 case 0:
502 topiclist_unload();
503 realmlist_destroy();
504 teamlist_unload();
505 clanlist_unload();
506 tournament_destroy();
507 anongame_infos_unload();
508 trans_unload();
509 aliasfile_unload();
510 command_groups_unload();
511 tracker_set_servers(NULL);
512 characterlist_destroy();
513 ladder_destroyxptable();
514 case STATUS_WAR3XPTABLES_FAILURE:
515
516 case STATUS_LADDERLIST_FAILURE:
517 ladder_update_all_accounts();
518 ladders_destroy();
519 output_dispose_filename();
520 accountlist_destroy();
521 accountlist_unload_default();
522 watchlist_destroy();
523 news_unload();
524 versioncheck_unload();
525 autoupdate_unload();
526 adbannerlist_destroy();
527 ipbanlist_save(prefs_get_ipbanfile());
528 ipbanlist_destroy();
529 helpfile_unload();
530 channellist_destroy();
531 server_clear_name();
532 timerlist_destroy();
533 gamelist_destroy();
534 connlist_destroy();
535 fdwatch_close();
536 case STATUS_FDWATCH_FAILURE:
537 anongame_matchlists_destroy();
538 case STATUS_MATCHLISTS_FAILURE:
539 anongame_maplists_destroy();
540 case STATUS_MAPLISTS_FAILURE:
541 case STATUS_SUPPORT_FAILURE:
542 if (psock_deinit())
543 eventlog(eventlog_level_error, __FUNCTION__, "got error from psock_deinit()");
544 case STATUS_PSOCK_FAILURE:
545 storage_close();
546 case STATUS_STORAGE_FAILURE:
547 oom_free();
548 case STATUS_OOM_FAILURE:
549 case -1:
550 break;
551 default:
552 eventlog(eventlog_level_error,__FUNCTION__,"got bad status \"%d\" during shutdown",status);
553 }
554 return;
555 }
556
557 void pvpgn_greeting(void)
558 {
559 #ifdef HAVE_GETPID
560 eventlog(eventlog_level_info,__FUNCTION__,PVPGN_SOFTWARE" version "PVPGN_VERSION" process %u",(unsigned int)getpid());
561 #else
562 eventlog(eventlog_level_info,__FUNCTION__,PVPGN_SOFTWARE" version "PVPGN_VERSION);
563 #endif
564
565 printf("You are currently Running "PVPGN_SOFTWARE" "PVPGN_VERSION"\n");
566 printf("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
567 printf("Make sure to visit:\n");
568 printf("http://www.pvpgn.org\n");
569 printf("We can also be found on: irc.pvpgn.org\n");
570 printf("Channel: #pvpgn\n");
571 printf("Server is now running.\n");
572 printf("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
573
574 return;
575 }
576
577 // MAIN STARTS HERE!!!
578 #ifdef WIN32_GUI
579 extern int server_main(int argc, char * * argv)
580 #else
581 extern int main(int argc, char * * argv)
582 #endif
583 {
584 int a;
585 int foreground = 0;
586 char *hexfile = NULL;
587 char *pidfile;
588
589 //Set umask
590 umask(2);
591
592 // Read the command line and set variables
593 if ((a = read_commandline(argc, argv, &foreground, &preffile, &hexfile)) != 1)
594 return a;
595
596 // Fork to child process if not set to foreground
597 if ((a = fork_bnetd(foreground)) != 0)
598 return a < 0 ? a : 0; /* dizzy: dont return code != 0 when things are OK! */
599
600 eventlog_set(stderr);
601 /* errors to eventlog from here on... */
602
603 // Load the prefs
604 if (preffile) {
605 if (prefs_load(preffile)<0) { // prefs are loaded here ...
606 eventlog(eventlog_level_fatal,__FUNCTION__,"could not parse specified configuration file (exiting)");
607 return -1;
608 }
609 } else {
610 if (prefs_load(BNETD_DEFAULT_CONF_FILE)<0) // or prefs are loaded here .. if not defined on command line ...
611 eventlog(eventlog_level_warn,__FUNCTION__,"using default configuration"); // or use defaults if default conf is not found
612 }
613
614 // Start logging to log file
615 if (eventlog_startup() == -1)
616 return -1;
617 /* eventlog goes to log file from here on... */
618
619 // Give up root privileges
620 /* Hakan: That's way too late to give up root privileges... Have to look for a better place */
621 if (give_up_root_privileges(prefs_get_effective_user(),prefs_get_effective_group())<0) {
622 eventlog(eventlog_level_fatal,__FUNCTION__,"could not give up privileges (exiting)");
623 return -1;
624 }
625
626 // Write the pidfile
627 pidfile = write_to_pidfile();
628
629 // Open the hexfile for writing
630 if (hexfile) {
631 if (!(hexstrm = fopen(hexfile,"w")))
632 eventlog(eventlog_level_error,__FUNCTION__,"could not open file \"%s\" for writing the hexdump (fopen: %s)",hexfile,pstrerror(errno));
633 else
634 fprintf(hexstrm,"# dump generated by "PVPGN_SOFTWARE" version "PVPGN_VERSION"\n");
635 }
636
637 // Run the pre server stuff
638 a = pre_server_startup();
639
640 // now process connections and network traffic
641 if (a == 0) {
642 if (server_process() < 0)
643 eventlog(eventlog_level_fatal,__FUNCTION__,"failed to initialize network (exiting)");
644 }
645
646 // run post server stuff and exit
647 post_server_shutdown(a);
648
649 // Close hexfile
650 if (hexstrm) {
651 fprintf(hexstrm,"# end of dump\n");
652 if (fclose(hexstrm)<0)
653 eventlog(eventlog_level_error,__FUNCTION__,"could not close hexdump file \"%s\" after writing (fclose: %s)",hexfile,pstrerror(errno));
654 }
655
656 // Delete pidfile
657 if (pidfile) {
658 if (remove(pidfile)<0)
659 eventlog(eventlog_level_error,__FUNCTION__,"could not remove pid file \"%s\" (remove: %s)",pidfile,pstrerror(errno));
660 xfree((void *)pidfile); /* avoid warning */
661 }
662
663 if (a == 0)
664 eventlog(eventlog_level_info,__FUNCTION__,"server has shut down");
665 prefs_unload();
666 eventlog_close();
667
668 if (a == 0)
669 return 0;
670
671 return -1;
672 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1