/* * Copyright (c) 2004 Teodor Sigaev * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "tlog.h" #include "connection.h" #include "top.h" #include "tmalloc.h" TCServer cfg; static int continueWork=1; static void inquireExit(int s) { continueWork=0; } extern char *optarg; extern int optind; void usage() { fputs( "Copyright (c) 2004-2007 Teodor Sigaev . All rights reserved.\n" "topd - daemon to collect load data from clients\n" "Usage:\n" "./top [-D] -h IP [-p PORT] [-n NUMCLIENTS]\n" " -D - debug mode (do not daemonize, print to stderr instead of syslog)\n" " -h HOST - listen IP\n" " -p PORT - listen port\n" " -n NUMCLIENTS - max number of clients\n", stdout ); exit(1); } int main( int argc, char *argv[] ) { int ch; int child=0, listenport = TOPD_SERVER_DEFAULT_PORT; int n=1024; char *host=NULL; memset( &cfg, 0, sizeof(TCServer) ); while( (ch=getopt(argc, argv, "h:p:c:D"))!=-1) { switch(ch) { case 'D': cfg.debug=1; break; case 'h': host=strdup(optarg); break; case 'p': listenport=atoi(optarg); break; case 'n': n=atoi(optarg); break; default: usage(); return 1; } } if (!host) usage(); signal(SIGCHLD, SIG_IGN); if ( cfg.debug ) opentlog( TL_OPEN_STDERR, TL_DEBUG, NULL); else opentlog( TL_OPEN_SYSLOG, TL_INFO, NULL); if ( cfg.debug || (child = fork()) == 0 ) { /* child */ if ( cfg.debug || (child = fork()) == 0 ) { /*child*/ TC_Connection *newconn; int i; signal(SIGINT, inquireExit); signal(SIGHUP, inquireExit); if ( n <= 0 ) n=1024; cfg.mu = allocUnits(n); TC_addConnection( &cfg.pool, TC_fillConnection(NULL, NULL, listenport) ); TC_ClientInitConnection( cfg.pool.conn[0], host, listenport); cfg.pool.conn[0]->state = CS_READ; TC_addConnection( &cfg.pool, TC_fillConnection(NULL, NULL, listenport) ); cfg.pool.conn[1]->fd = TC_AcceptUdp( host, listenport ); cfg.pool.conn[1]->state = CS_READ; while(continueWork) { if ( TC_ReadyIO(cfg.pool.conn, cfg.pool.number, 100 ) ) { if ( cfg.pool.conn[1]->readyio ) gotMsg( cfg.pool.conn[1] ); else tlog(TL_DEBUG,"Ready connection..."); } ConnectionWorks(); if ( cfg.pool.conn[0]->readyio && (newconn=TC_AcceptTcp( cfg.pool.conn[0] )) != NULL ) { if ( newconn->state == CS_CONNECTED ) { tlog(TL_DEBUG,"Accept new connection..."); newconn->state = CS_READ; TC_addConnection( &cfg.pool, newconn ); } } } for(i=cfg.pool.number-1; i>=0; i--) TC_deleteConnectionByN(&cfg.pool,i); } } if (child == -1) tlog(TL_CRIT,"Can't start child process"); return 0; }