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

Annotation of /pvpgn-1.7.4/src/bntrackd/bntrackd.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Jun 6 03:41:37 2006 UTC (19 years, 9 months ago) by sysadm
CVS Tags: pvpgn_1-7-4-0_MIL
Branch point for: GNU, MAIN
Content type: text/x-csrc
Initial revision

1 sysadm 1.1 /*
2     * Copyright (C) 1999 Mark Baysinger (mbaysing@ucsd.edu)
3     * Copyright (C) 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     #define TRACKER_INTERNAL_ACCESS
20     #include "common/setup_before.h"
21     #include <stdio.h>
22     #ifdef HAVE_STDDEF_H
23     # include <stddef.h>
24     #else
25     # ifndef NULL
26     # define NULL ((void *)0)
27     # endif
28     #endif
29     #ifdef STDC_HEADERS
30     # include <stdlib.h>
31     #else
32     # ifdef HAVE_MALLOC_H
33     # include <malloc.h>
34     # endif
35     #endif
36     #include "compat/exitstatus.h"
37     #ifdef HAVE_STRING_H
38     # include <string.h>
39     #else
40     # ifdef HAVE_STRINGS_H
41     # include <strings.h>
42     # endif
43     #endif
44     #ifdef HAVE_MEMORY_H
45     # include <memory.h>
46     #endif
47     #include "compat/memset.h"
48     #ifdef HAVE_UNISTD_H
49     # include <unistd.h>
50     #endif
51     #include "compat/stdfileno.h"
52     #include <errno.h>
53     #include "compat/strerror.h"
54     #ifdef TIME_WITH_SYS_TIME
55     # include <sys/time.h>
56     # include <time.h>
57     #else
58     # ifdef HAVE_SYS_TIME_H
59     # include <sys/time.h>
60     # else
61     # include <time.h>
62     # endif
63     #endif
64     #ifdef HAVE_SYS_TYPES_H
65     # include <sys/types.h>
66     #endif
67     #ifdef HAVE_SYS_SOCKET_H
68     # include <sys/socket.h>
69     #endif
70     #include "compat/socket.h"
71     #include "compat/send.h"
72     #ifdef HAVE_SYS_PARAM_H
73     # include <sys/param.h>
74     #endif
75     #ifdef HAVE_NETINET_IN_H
76     # include <netinet/in.h>
77     #endif
78     #include "compat/netinet_in.h"
79     #ifdef HAVE_ARPA_INET_H
80     # include <arpa/inet.h>
81     #endif
82     #include "compat/inet_ntoa.h"
83     #include "compat/psock.h"
84     #include "common/list.h"
85     #include "common/version.h"
86     #include "common/eventlog.h"
87     #include "common/util.h"
88     #include "common/tracker.h"
89     #include "common/xalloc.h"
90     #include "common/setup_after.h"
91    
92    
93     /******************************************************************************
94     * TYPES
95     *****************************************************************************/
96     typedef struct
97     {
98     struct in_addr address;
99     time_t updated;
100     t_trackpacket info;
101     } t_server;
102    
103     typedef struct
104     {
105     int foreground;
106     int debug;
107     int XML_mode;
108     unsigned int expire;
109     unsigned int update;
110     unsigned short port;
111     char const * outfile;
112     char const * pidfile;
113     char const * logfile;
114     char const * process;
115     } t_prefs;
116    
117    
118     /******************************************************************************
119     * STATIC FUNCTION PROTOTYPES
120     *****************************************************************************/
121     static int server_process(int sockfd);
122     static void usage(char const * progname);
123     static void getprefs(int argc, char * argv[]);
124     static void fixup_str(char * str);
125    
126    
127     /******************************************************************************
128     * GLOBAL VARIABLES
129     *****************************************************************************/
130     static t_prefs prefs;
131    
132    
133     extern int main(int argc, char * argv[])
134     {
135     int sockfd;
136    
137     if (argc<1 || !argv || !argv[0])
138     {
139     fprintf(stderr,"bad arguments\n");
140     return STATUS_FAILURE;
141     }
142    
143     getprefs(argc,argv);
144    
145     if (!prefs.debug)
146     eventlog_del_level("debug");
147     if (prefs.logfile)
148     {
149     eventlog_set(stderr);
150     if (eventlog_open(prefs.logfile)<0)
151     {
152     eventlog(eventlog_level_fatal,__FUNCTION__,"could not use file \"%s\" for the eventlog (exiting)",prefs.logfile);
153     return STATUS_FAILURE;
154     }
155     }
156    
157     #ifdef DO_DAEMONIZE
158     if (!prefs.foreground)
159     {
160     switch (fork())
161     {
162     case -1:
163     eventlog(eventlog_level_error,__FUNCTION__,"could not fork (fork: %s)\n",pstrerror(errno));
164     return STATUS_FAILURE;
165     case 0: /* child */
166     break;
167     default: /* parent */
168     return STATUS_SUCCESS;
169     }
170    
171     close(STDINFD);
172     close(STDOUTFD);
173     close(STDERRFD);
174    
175     # ifdef HAVE_SETPGID
176     if (setpgid(0,0)<0)
177     {
178     eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgid: %s)\n",pstrerror(errno));
179     return STATUS_FAILURE;
180     }
181     # else
182     # ifdef HAVE_SETPGRP
183     # ifdef SETPGRP_VOID
184     if (setpgrp()<0)
185     {
186     eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgrp: %s)\n",pstrerror(errno));
187     return STATUS_FAILURE;
188     }
189     # else
190     if (setpgrp(0,0)<0)
191     {
192     eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgrp: %s)\n",pstrerror(errno));
193     return STATUS_FAILURE;
194     }
195     # endif
196     # else
197     # ifdef HAVE_SETSID
198     if (setsid()<0)
199     {
200     eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setsid: %s)\n",pstrerror(errno));
201     return STATUS_FAILURE;
202     }
203     # else
204     # error "One of setpgid(), setpgrp(), or setsid() is required"
205     # endif
206     # endif
207     # endif
208     }
209     #endif
210    
211     if (prefs.pidfile)
212     {
213     #ifdef HAVE_GETPID
214     FILE * fp;
215    
216     if (!(fp = fopen(prefs.pidfile,"w")))
217     {
218     eventlog(eventlog_level_error,__FUNCTION__,"unable to open pid file \"%s\" for writing (fopen: %s)",prefs.pidfile,pstrerror(errno));
219     prefs.pidfile = NULL;
220     }
221     else
222     {
223     fprintf(fp,"%u",(unsigned int)getpid());
224     if (fclose(fp)<0)
225     eventlog(eventlog_level_error,__FUNCTION__,"could not close pid file \"%s\" after writing (fclose: %s)",prefs.pidfile,pstrerror(errno));
226     }
227     #else
228     eventlog(eventlog_level_warn,__FUNCTION__,"no getpid() system call, do not use the -P or the --pidfile option");
229     prefs.pidfile = NULL;
230     #endif
231     }
232    
233     #ifdef HAVE_GETPID
234     eventlog(eventlog_level_info,__FUNCTION__,"bntrackd version "PVPGN_VERSION" process %u",(unsigned int)getpid());
235     #else
236     eventlog(eventlog_level_info,__FUNCTION__,"bntrackd version "PVPGN_VERSION);
237     #endif
238    
239     if (psock_init()<0)
240     {
241     eventlog(eventlog_level_error,__FUNCTION__,"could not initialize socket functions");
242     return STATUS_FAILURE;
243     }
244    
245     /* create the socket */
246     if ((sockfd = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_DGRAM,PSOCK_IPPROTO_UDP))<0)
247     {
248     eventlog(eventlog_level_error,__FUNCTION__,"could not create UDP listen socket (psock_socket: %s)\n",pstrerror(psock_errno()));
249     return STATUS_FAILURE;
250     }
251    
252     {
253     struct sockaddr_in servaddr;
254    
255     /* bind the socket to correct port and interface */
256     memset(&servaddr,0,sizeof(servaddr));
257     servaddr.sin_family = PSOCK_AF_INET;
258     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
259     servaddr.sin_port = htons(prefs.port);
260     if (psock_bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0)
261     {
262     eventlog(eventlog_level_error,__FUNCTION__,"could not bind to UDP port %hu (psock_bind: %s)\n",prefs.port,pstrerror(psock_errno()));
263     return STATUS_FAILURE;
264     }
265     }
266    
267     if (server_process(sockfd)<0)
268     return STATUS_FAILURE;
269     return STATUS_SUCCESS;
270     }
271    
272    
273     static int server_process(int sockfd)
274     {
275     t_list * serverlist_head;
276     t_elem * curr;
277     t_server * server;
278     struct sockaddr_in cliaddr;
279     t_psock_fd_set rfds;
280     struct timeval tv;
281     time_t last;
282     FILE * outfile;
283     psock_t_socklen len;
284     t_trackpacket packet;
285    
286     if (!(serverlist_head = list_create()))
287     {
288     eventlog(eventlog_level_error,__FUNCTION__,"could not create server list");
289     return -1;
290     }
291    
292     /* the main loop */
293     last = time(NULL) - prefs.update;
294     for (;;)
295     {
296     /* time to dump our list to disk and call the process command */
297     /* (I'm making the assumption that this won't take very long.) */
298     if (last+(signed)prefs.update<time(NULL))
299     {
300     last = time(NULL);
301    
302     if (!(outfile = fopen(prefs.outfile,"w")))
303     {
304     eventlog(eventlog_level_error,__FUNCTION__,"unable to open file \"%s\" for writing (fopen: %s)",prefs.outfile,pstrerror(errno));
305     continue;
306     }
307    
308     LIST_TRAVERSE(serverlist_head,curr)
309     {
310     server = elem_get_data(curr);
311    
312     if (server->updated+(signed)prefs.expire<last)
313     {
314     list_remove_elem(serverlist_head,&curr);
315     xfree(server);
316     }
317     else
318     {
319     if (prefs.XML_mode == 1)
320     {
321     fprintf(outfile,"<server>\n\t<address>%s</address>\n",inet_ntoa(server->address));
322     fprintf(outfile,"\t<port>%hu</port>\n",(unsigned short)ntohs(server->info.port));
323     fprintf(outfile,"\t<location>%s</location>\n",server->info.server_location);
324     fprintf(outfile,"\t<software>%s</software>\n",server->info.software);
325     fprintf(outfile,"\t<version>%s</version>\n",server->info.version);
326     fprintf(outfile,"\t<users>%lu</users>\n",(unsigned long)ntohl(server->info.users));
327     fprintf(outfile,"\t<channels>%lu</channels>\n",(unsigned long)ntohl(server->info.channels));
328     fprintf(outfile,"\t<games>%lu</games>\n",(unsigned long)ntohl(server->info.games));
329     fprintf(outfile,"\t<description>%s</description>\n",server->info.server_desc);
330     fprintf(outfile,"\t<platform>%s</platform>\n",server->info.platform);
331     fprintf(outfile,"\t<url>%s</url>\n",server->info.server_url);
332     fprintf(outfile,"\t<contact_name>%s</contact_name>\n",server->info.contact_name);
333     fprintf(outfile,"\t<contact_email>%s</contact_email>\n",server->info.contact_email);
334     fprintf(outfile,"\t<uptime>%lu</uptime>\n",(unsigned long)ntohl(server->info.uptime));
335     fprintf(outfile,"\t<total_games>%lu</total_games>\n",(unsigned long)ntohl(server->info.total_games));
336     fprintf(outfile,"\t<logins>%lu</logins>\n",(unsigned long)ntohl(server->info.total_logins));
337     fprintf(outfile,"</server>\n");
338     }
339     else
340     {
341     fprintf(outfile,"%s\n##\n",inet_ntoa(server->address));
342     fprintf(outfile,"%hu\n##\n",(unsigned short)ntohs(server->info.port));
343     fprintf(outfile,"%s\n##\n",server->info.server_location);
344     fprintf(outfile,"%s\n##\n",server->info.software);
345     fprintf(outfile,"%s\n##\n",server->info.version);
346     fprintf(outfile,"%lu\n##\n",(unsigned long)ntohl(server->info.users));
347     fprintf(outfile,"%lu\n##\n",(unsigned long)ntohl(server->info.channels));
348     fprintf(outfile,"%lu\n##\n",(unsigned long)ntohl(server->info.games));
349     fprintf(outfile,"%s\n##\n",server->info.server_desc);
350     fprintf(outfile,"%s\n##\n",server->info.platform);
351     fprintf(outfile,"%s\n##\n",server->info.server_url);
352     fprintf(outfile,"%s\n##\n",server->info.contact_name);
353     fprintf(outfile,"%s\n##\n",server->info.contact_email);
354     fprintf(outfile,"%lu\n##\n",(unsigned long)ntohl(server->info.uptime));
355     fprintf(outfile,"%lu\n##\n",(unsigned long)ntohl(server->info.total_games));
356     fprintf(outfile,"%lu\n##\n",(unsigned long)ntohl(server->info.total_logins));
357     fprintf(outfile,"###\n");
358     }
359     }
360     }
361     if (fclose(outfile)<0)
362     eventlog(eventlog_level_error,__FUNCTION__,"could not close output file \"%s\" after writing (fclose: %s)",prefs.outfile,pstrerror(errno));
363    
364     if (prefs.process[0]!='\0')
365     system(prefs.process);
366     }
367    
368     /* select socket to operate on */
369     PSOCK_FD_ZERO(&rfds);
370     PSOCK_FD_SET(sockfd,&rfds);
371     tv.tv_sec = BNTRACKD_GRANULARITY;
372     tv.tv_usec = 0;
373     switch (psock_select(sockfd+1,&rfds,NULL,NULL,&tv))
374     {
375     case -1: /* error */
376     if (
377     #ifdef PSOCK_EINTR
378     errno!=PSOCK_EINTR &&
379     #endif
380     1)
381     eventlog(eventlog_level_error,__FUNCTION__,"select failed (select: %s)",pstrerror(errno));
382     case 0: /* timeout and no sockets ready */
383     continue;
384     }
385    
386     /* New tracking packet */
387     if (PSOCK_FD_ISSET(sockfd,&rfds))
388     {
389    
390     len = sizeof(cliaddr);
391     if (psock_recvfrom(sockfd,&packet,sizeof(packet),0,(struct sockaddr *)&cliaddr,&len)>=0)
392     {
393    
394     if (ntohs(packet.packet_version)>=TRACK_VERSION)
395     {
396     packet.software[sizeof(packet.software)-1] = '\0';
397     if (strstr(packet.software,"##"))
398     fixup_str(packet.software);
399     packet.version[sizeof(packet.version)-1] = '\0';
400     if (strstr(packet.version,"##"))
401     fixup_str(packet.version);
402     packet.platform[sizeof(packet.platform)-1] = '\0';
403     if (strstr(packet.platform,"##"))
404     fixup_str(packet.platform);
405     packet.server_desc[sizeof(packet.server_desc)-1] = '\0';
406     if (strstr(packet.server_desc,"##"))
407     fixup_str(packet.server_desc);
408     packet.server_location[sizeof(packet.server_location)-1] = '\0';
409     if (strstr(packet.server_location,"##"))
410     fixup_str(packet.server_location);
411     packet.server_url[sizeof(packet.server_url)-1] = '\0';
412     if (strstr(packet.server_url,"##"))
413     fixup_str(packet.server_url);
414     packet.contact_name[sizeof(packet.contact_name)-1] = '\0';
415     if (strstr(packet.contact_name,"##"))
416     fixup_str(packet.contact_name);
417     packet.contact_email[sizeof(packet.contact_email)-1] = '\0';
418     if (strstr(packet.contact_email,"##"))
419     fixup_str(packet.contact_email);
420    
421     /* Find this server's slot */
422     LIST_TRAVERSE(serverlist_head,curr)
423     {
424     server = elem_get_data(curr);
425    
426     if (!memcmp(&server->address,&cliaddr.sin_addr,sizeof(struct in_addr)))
427     {
428     if (ntohl(packet.flags)&TF_SHUTDOWN)
429     {
430     list_remove_elem(serverlist_head,&curr);
431     xfree(server);
432     }
433     else
434     {
435     /* update in place */
436     server->info = packet;
437     server->updated = time(NULL);
438     }
439     break;
440     }
441     }
442    
443     /* Not found? Make a new slot */
444     if (!(ntohl(packet.flags)&TF_SHUTDOWN) && !curr)
445     {
446     server = xmalloc(sizeof(t_server));
447     server->address = cliaddr.sin_addr;
448     server->info = packet;
449     server->updated = time(NULL);
450    
451     list_append_data(serverlist_head,server);
452     }
453    
454     eventlog(eventlog_level_debug,__FUNCTION__,
455     "Packet received from %s:"
456     " packet_version=%u"
457     " flags=0x%08lx"
458     " port=%hu"
459     " software=\"%s\""
460     " version=\"%s\""
461     " platform=\"%s\""
462     " server_desc=\"%s\""
463     " server_location=\"%s\""
464     " server_url=\"%s\""
465     " contact_name=\"%s\""
466     " contact_email=\"%s\""
467     " uptime=%lu"
468     " total_games=%lu"
469     " total_logins=%lu",
470     inet_ntoa(cliaddr.sin_addr),
471     ntohs(packet.packet_version),
472     (unsigned long)ntohl(packet.flags),
473     ntohs(packet.port),
474     packet.software,
475     packet.version,
476     packet.platform,
477     packet.server_desc,
478     packet.server_location,
479     packet.server_url,
480     packet.contact_name,
481     packet.contact_email,
482     (unsigned long)ntohl(packet.uptime),
483     (unsigned long)ntohl(packet.total_games),
484     (unsigned long)ntohl(packet.total_logins));
485     }
486    
487     }
488     }
489    
490     }
491     }
492    
493    
494     static void usage(char const * progname)
495     {
496     fprintf(stderr,"usage: %s [<options>]\n",progname);
497     fprintf(stderr,
498     " -c COMMAND, --command=COMMAND execute COMMAND update\n"
499     " -d, --debug turn on debug mode\n"
500     " -e SECS, --expire SECS forget a list entry after SEC seconds\n"
501     #ifdef DO_DAEMONIZE
502     " -f, --foreground don't daemonize\n"
503     #else
504     " -f, --foreground don't daemonize (default)\n"
505     #endif
506     " -l FILE, --logfile=FILE write event messages to FILE\n"
507     " -o FILE, --outfile=FILE write server list to FILE\n");
508     fprintf(stderr,
509     " -p PORT, --port=PORT listen for announcments on UDP port PORT\n"
510     " -P FILE, --pidfile=FILE write pid to FILE\n"
511     " -u SECS, --update SECS write output file every SEC seconds\n"
512     " -x, --XML write output file in XML format\n"
513     " -h, --help, --usage show this information and exit\n"
514     " -v, --version print version number and exit\n");
515     exit(STATUS_FAILURE);
516     }
517    
518    
519     static void getprefs(int argc, char * argv[])
520     {
521     int a;
522    
523     prefs.foreground = 0;
524     prefs.debug = 0;
525     prefs.expire = 0;
526     prefs.update = 0;
527     prefs.port = 0;
528     prefs.XML_mode = 0;
529     prefs.outfile = NULL;
530     prefs.pidfile = NULL;
531     prefs.process = NULL;
532     prefs.logfile = NULL;
533    
534     for (a=1; a<argc; a++)
535     if (strncmp(argv[a],"--command=",10)==0)
536     {
537     if (prefs.process)
538     {
539     fprintf(stderr,"%s: processing command was already specified as \"%s\"\n",argv[0],prefs.process);
540     usage(argv[0]);
541     }
542     prefs.process = &argv[a][10];
543     }
544     else if (strcmp(argv[a],"-c")==0)
545     {
546     if (a+1>=argc)
547     {
548     fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
549     usage(argv[0]);
550     }
551     if (prefs.process)
552     {
553     fprintf(stderr,"%s: processing command was already specified as \"%s\"\n",argv[0],prefs.process);
554     usage(argv[0]);
555     }
556     a++;
557     prefs.process = argv[a];
558     }
559     else if (strcmp(argv[a],"-d")==0 || strcmp(argv[a],"--debug")==0)
560     prefs.debug = 1;
561     else if (strncmp(argv[a],"--expire=",9)==0)
562     {
563     if (prefs.expire)
564     {
565     fprintf(stderr,"%s: expiration period was already specified as \"%u\"\n",argv[0],prefs.expire);
566     usage(argv[0]);
567     }
568     if (str_to_uint(&argv[a][9],&prefs.expire)<0)
569     {
570     fprintf(stderr,"%s: \"%s\" should be a positive integer\n",argv[0],&argv[a][9]);
571     usage(argv[0]);
572     }
573     }
574     else if (strcmp(argv[a],"-e")==0)
575     {
576     if (a+1>=argc)
577     {
578     fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
579     usage(argv[0]);
580     }
581     if (prefs.expire)
582     {
583     fprintf(stderr,"%s: expiration period was already specified as \"%u\"\n",argv[0],prefs.expire);
584     usage(argv[0]);
585     }
586     a++;
587     if (str_to_uint(argv[a],&prefs.expire)<0)
588     {
589     fprintf(stderr,"%s: \"%s\" should be a positive integer\n",argv[0],argv[a]);
590     usage(argv[0]);
591     }
592     }
593     else if (strcmp(argv[a],"-f")==0 || strcmp(argv[a],"--foreground")==0)
594     prefs.foreground = 1;
595     else if (strcmp(argv[a],"-x")==0 || strcmp(argv[a],"--XML")==0)
596     prefs.XML_mode = 1;
597     else if (strncmp(argv[a],"--logfile=",10)==0)
598     {
599     if (prefs.logfile)
600     {
601     fprintf(stderr,"%s: eventlog file was already specified as \"%s\"\n",argv[0],prefs.logfile);
602     usage(argv[0]);
603     }
604     prefs.logfile = &argv[a][10];
605     }
606     else if (strcmp(argv[a],"-l")==0)
607     {
608     if (a+1>=argc)
609     {
610     fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
611     usage(argv[0]);
612     }
613     if (prefs.logfile)
614     {
615     fprintf(stderr,"%s: eventlog file was already specified as \"%s\"\n",argv[0],prefs.logfile);
616     usage(argv[0]);
617     }
618     a++;
619     prefs.logfile = argv[a];
620     }
621     else if (strncmp(argv[a],"--outfile=",10)==0)
622     {
623     if (prefs.outfile)
624     {
625     fprintf(stderr,"%s: output file was already specified as \"%s\"\n",argv[0],prefs.outfile);
626     usage(argv[0]);
627     }
628     prefs.outfile = &argv[a][10];
629     }
630     else if (strcmp(argv[a],"-o")==0)
631     {
632     if (a+1>=argc)
633     {
634     fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
635     usage(argv[0]);
636     }
637     if (prefs.outfile)
638     {
639     fprintf(stderr,"%s: output file was already specified as \"%s\"\n",argv[0],prefs.outfile);
640     usage(argv[0]);
641     }
642     a++;
643     prefs.outfile = argv[a];
644     }
645     else if (strncmp(argv[a],"--pidfile=",10)==0)
646     {
647     if (prefs.pidfile)
648     {
649     fprintf(stderr,"%s: pid file was already specified as \"%s\"\n",argv[0],prefs.pidfile);
650     usage(argv[0]);
651     }
652     prefs.pidfile = &argv[a][10];
653     }
654     else if (strncmp(argv[a],"--port=",7)==0)
655     {
656     if (prefs.port)
657     {
658     fprintf(stderr,"%s: port number was already specified as \"%hu\"\n",argv[0],prefs.port);
659     usage(argv[0]);
660     }
661     if (str_to_ushort(&argv[a][7],&prefs.port)<0)
662     {
663     fprintf(stderr,"%s: \"%s\" should be a positive integer\n",argv[0],&argv[a][7]);
664     usage(argv[0]);
665     }
666     }
667     else if (strcmp(argv[a],"-p")==0)
668     {
669     if (a+1>=argc)
670     {
671     fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
672     usage(argv[0]);
673     }
674     if (prefs.port)
675     {
676     fprintf(stderr,"%s: port number was already specified as \"%hu\"\n",argv[0],prefs.port);
677     usage(argv[0]);
678     }
679     a++;
680     if (str_to_ushort(argv[a],&prefs.port)<0)
681     {
682     fprintf(stderr,"%s: \"%s\" should be a positive integer\n",argv[0],argv[a]);
683     usage(argv[0]);
684     }
685     }
686     else if (strcmp(argv[a],"-P")==0)
687     {
688     if (a+1>=argc)
689     {
690     fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
691     usage(argv[0]);
692     }
693     if (prefs.pidfile)
694     {
695     fprintf(stderr,"%s: pid file was already specified as \"%s\"\n",argv[0],prefs.pidfile);
696     usage(argv[0]);
697     }
698     a++;
699     prefs.pidfile = argv[a];
700     }
701     else if (strncmp(argv[a],"--update=",9)==0)
702     {
703     if (prefs.update)
704     {
705     fprintf(stderr,"%s: update period was already specified as \"%u\"\n",argv[0],prefs.expire);
706     usage(argv[0]);
707     }
708     if (str_to_uint(&argv[a][9],&prefs.update)<0)
709     {
710     fprintf(stderr,"%s: \"%s\" should be a positive integer\n",argv[0],&argv[a][9]);
711     usage(argv[0]);
712     }
713     }
714     else if (strcmp(argv[a],"-u")==0)
715     {
716     if (a+1>=argc)
717     {
718     fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
719     usage(argv[0]);
720     }
721     if (prefs.update)
722     {
723     fprintf(stderr,"%s: update period was already specified as \"%u\"\n",argv[0],prefs.expire);
724     usage(argv[0]);
725     }
726     a++;
727     if (str_to_uint(argv[a],&prefs.update)<0)
728     {
729     fprintf(stderr,"%s: \"%s\" should be a positive integer\n",argv[0],argv[a]);
730     usage(argv[0]);
731     }
732     }
733     else if (strcmp(argv[a],"-h")==0 || strcmp(argv[a],"--help")==0 || strcmp(argv[a],"--usage")
734     ==0)
735     usage(argv[0]);
736     else if (strcmp(argv[a],"-v")==0 || strcmp(argv[a],"--version")==0)
737     {
738     printf("version "PVPGN_VERSION"\n");
739     exit(0);
740     }
741     else if (strcmp(argv[a],"--command")==0 || strcmp(argv[a],"--expire")==0 ||
742     strcmp(argv[a],"--logfile")==0 || strcmp(argv[a],"--outfile")==0 ||
743     strcmp(argv[a],"--port")==0 || strcmp(argv[a],"--pidfile")==0 ||
744     strcmp(argv[a],"--update")==0)
745     {
746     fprintf(stderr,"%s: option \"%s\" requires and argument.\n",argv[0],argv[a]);
747     usage(argv[0]);
748     }
749     else
750     {
751     fprintf(stderr,"%s: unknown option \"%s\"\n",argv[0],argv[a]);
752     usage(argv[0]);
753     }
754    
755     if (!prefs.process)
756     prefs.process = BNTRACKD_PROCESS;
757     if (prefs.expire==0)
758     prefs.expire = BNTRACKD_EXPIRE;
759     if (!prefs.logfile)
760     prefs.logfile = BNTRACKD_LOGFILE;
761     if (!prefs.outfile)
762     prefs.outfile = BNTRACKD_OUTFILE;
763     if (prefs.port==0)
764     prefs.port = BNTRACKD_SERVER_PORT;
765     if (!prefs.pidfile)
766     prefs.pidfile = BNTRACKD_PIDFILE;
767     if (prefs.expire==0)
768     prefs.update = BNTRACKD_UPDATE;
769    
770     if (prefs.logfile[0]=='\0')
771     prefs.logfile = NULL;
772     if (prefs.pidfile[0]=='\0')
773     prefs.pidfile = NULL;
774     }
775    
776    
777     static void fixup_str(char * str)
778     {
779     char prev;
780     unsigned int i;
781    
782     for (prev='\0',i=0; i<strlen(str); prev=str[i],i++)
783     if (prev=='#' && str[i]=='#')
784     str[i] = '%';
785     }

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