add .gitignore
[remotetop.git] / topd.c
1 /*
2  * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *      notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *      notice, this list of conditions and the following disclaimer in the
12  *      documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the author nor the names of any co-contributors
14  *      may be used to endorse or promote products derived from this software
15  *      without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <signal.h>
34 #include <errno.h>
35 #include <sys/sysctl.h>
36
37 #include "tlog.h"
38 #include "connection.h"
39 #include "top.h"
40 #include "tmalloc.h"
41
42 TCServer cfg;
43 static int continueWork=1;
44
45 static void
46 inquireExit(int s) {
47         continueWork=0;
48 }
49                                 
50 extern char *optarg;
51 extern int optind;
52
53 void
54 usage() {
55         fputs(
56                 "Copyright (c) 2004-2007 Teodor Sigaev <teodor@sigaev.ru>. All rights reserved.\n"
57                 "topd - daemon to collect load data from clients\n"
58                 "Usage:\n"
59                 "./top [-D] -h IP [-p PORT] [-n NUMCLIENTS]\n"
60                 "  -D        - debug mode (do not daemonize, print to stderr instead of syslog)\n"
61                 "  -h HOST   - listen IP\n"
62                 "  -p PORT   - listen port\n"
63                 "  -n NUMCLIENTS - max number of clients\n",
64                 stdout
65         );
66         exit(1);
67 }
68 int
69 main( int argc, char *argv[] ) {
70         int ch;
71         int child=0, listenport = TOPD_SERVER_DEFAULT_PORT;
72         int n=1024;
73         char *host=NULL;
74
75         memset( &cfg, 0, sizeof(TCServer) );
76
77         while( (ch=getopt(argc, argv, "h:p:c:D"))!=-1) {
78                 switch(ch) {
79                         case 'D':
80                                 cfg.debug=1;
81                                 break;
82                         case 'h':
83                                 host=strdup(optarg);
84                                 break;
85                         case 'p':
86                                 listenport=atoi(optarg);
87                                 break;
88                         case 'n':
89                                 n=atoi(optarg);
90                                 break;
91                         default:
92                                 usage();
93                                 return 1;
94                 }
95         }
96
97         if (!host)
98                 usage();
99
100         signal(SIGCHLD, SIG_IGN);
101
102         if ( cfg.debug )
103                 opentlog( TL_OPEN_STDERR,  TL_DEBUG, NULL);
104         else
105                 opentlog( TL_OPEN_SYSLOG, TL_INFO, NULL);
106
107         if ( cfg.debug || (child = fork()) == 0 ) {
108                 /* child */
109                 if ( cfg.debug || (child = fork()) == 0 ) {
110                         /*child*/
111                         TC_Connection *newconn;
112                         int i;
113
114                         signal(SIGINT, inquireExit);
115                         signal(SIGHUP, inquireExit);
116
117                         if ( n <= 0 )
118                                 n=1024;
119
120                         cfg.mu = allocUnits(n);
121
122                         TC_addConnection( &cfg.pool, TC_fillConnection(NULL, NULL, listenport) );
123                         TC_ClientInitConnection( cfg.pool.conn[0], host, listenport);
124                         cfg.pool.conn[0]->state = CS_READ;
125
126                         TC_addConnection( &cfg.pool, TC_fillConnection(NULL, NULL, listenport) );
127                         cfg.pool.conn[1]->fd = TC_AcceptUdp( host, listenport );
128                         cfg.pool.conn[1]->state = CS_READ; 
129
130                         while(continueWork) {
131                                 if ( TC_ReadyIO(cfg.pool.conn, cfg.pool.number, 100 ) ) {
132                                         if ( cfg.pool.conn[1]->readyio ) 
133                                                 gotMsg( cfg.pool.conn[1] );
134                                         else 
135                                                 tlog(TL_DEBUG,"Ready connection...");
136                                 }
137                                 ConnectionWorks();
138                                 if ( cfg.pool.conn[0]->readyio && (newconn=TC_AcceptTcp( cfg.pool.conn[0] )) != NULL ) {
139                                         if ( newconn->state == CS_CONNECTED ) {
140                                                 tlog(TL_DEBUG,"Accept new connection...");
141                                                 newconn->state = CS_READ;
142                                                 TC_addConnection( &cfg.pool, newconn );
143                                         }
144                                 }
145                         }
146
147                         for(i=cfg.pool.number-1; i>=0; i--) 
148                                 TC_deleteConnectionByN(&cfg.pool,i);
149                 }
150         }
151         if (child == -1) 
152                 tlog(TL_CRIT,"Can't start child process");
153
154         return 0;
155 }
156