--- /dev/null
+CC=gcc
+AR=ar rcv
+RANLIB=ranlib
+LD=ld -x -shared
+
+INCLUDE=-I. -I../tedtools
+CFLAGS=-Wall -g -O2 -pedantic -ansi -DASSERT_CORE -D_GNU_SOURCE -DHAVE_POLL_H -DHAVE_SYS_POLL_H -DHAVE_HSTRERROR
+LIB=-L../tedtools -ltedtools
+
+PROGS=sendtop topd rtop
+
+.SUFFIXES: .o.c
+
+all: $(PROGS)
+
+rtop: rtop.o
+ $(CC) -o $@ $< $(LIB)
+
+sendtop: sendtop.o
+ $(CC) -o $@ $< $(LIB)
+
+topd: topd.o td_unit.o td_smsg.o td_lmsg.o
+ $(CC) -o $@ topd.o td_unit.o td_smsg.o td_lmsg.o $(LIB)
+
+.c.o:
+ $(CC) $(CFLAGS) $(INCLUDE) -c $<
+
+
+clean:
+ rm -rf $(PROGS) *.o
+ rm -rf *core *gmon* nohup.out
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "tlog.h"
+#include "connection.h"
+#include "tmalloc.h"
+#include "top.h"
+
+int
+main( int argc, char *argv[] ) {
+ int ch;
+ int debug=0;
+ char *host="127.0.0.1";
+ int port=TOPD_SERVER_DEFAULT_PORT;
+ int i;
+
+ MassiveUnit *mu;
+ TCMsg *pmsg = (TCMsg*)malloc( TCMSGHDRSZ );
+ TC_Connection cs;
+
+ pmsg->type = TOPGETTYPE;
+ pmsg->len = TCMSGHDRSZ;
+
+ while( (ch=getopt(argc, argv, "Dh:p:"))!=-1) {
+ switch(ch) {
+ case 'D':
+ debug=1;
+ break;
+ case 'h':
+ host=strdup(optarg);
+ break;
+ case 'p':
+ port=atoi(optarg);
+ break;
+ default:
+ return 1;
+ }
+ }
+
+ if ( debug )
+ opentlog( TL_OPEN_STDERR, TL_DEBUG, NULL);
+ else
+ opentlog( TL_OPEN_SYSLOG, TL_INFO, NULL);
+
+ TC_fillConnection(&cs, host, port);
+ cs.buf = (char*)pmsg;
+ cs.len = pmsg->len;
+ if ( TC_Talk(&cs) == CS_OK ) {
+ pmsg = (TCMsg*) cs.buf;
+ mu = (MassiveUnit*)pmsg->data;
+
+ printf("\tIP\tLoad\tFree\tTotal\tData\n");
+ for(i=0; i<mu->number; i++)
+ printf("%s\t%.2f\t%.1fM\t%.1fM\t%s",
+ inet_ntoa(mu->units[i].ip),
+ mu->units[i].top.load,
+ ((float) mu->units[i].top.freemem)/( 1024*1024.0 ),
+ ((float) mu->units[i].top.usermem)/( 1024*1024.0 ),
+ ctime( &(mu->units[i].stamp) )
+ );
+ }
+
+ TC_FreeConnection(&cs);
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/sysctl.h>
+
+#include "tlog.h"
+#include "tmalloc.h"
+#include "connection.h"
+
+#include "top.h"
+
+#define NITEM 0
+
+static int
+getsysctl(char *name, void *ptr, size_t len) {
+ size_t nlen = len;
+ if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) {
+ tlog(TL_ALARM, "sysctl(%s...) failed: %s\n", name,
+ strerror(errno));
+ return 1;
+ }
+ if (nlen != len) {
+ tlog(TL_ALARM, "sysctl(%s...) expected %lu, got %lu\n", name,
+ (unsigned long)len, (unsigned long)nlen);
+ return 1;
+ }
+ return 0;
+}
+
+
+#define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
+
+static void
+fillMsgTop(TCMsgTop *m) {
+ double lll[3];
+ int memory_tmp;
+
+ memset(m,0,sizeof(TCMsgTop));
+ if ( getloadavg(lll,3) >= NITEM+1 )
+ m->load=lll[NITEM];
+ else
+ m->load=-1.0;
+
+ m->freemem = 0;
+ if ( GETSYSCTL("vm.stats.vm.v_inactive_count", memory_tmp) == 0 )
+ m->freemem += memory_tmp;
+ else
+ m->freemem = -1;
+ if ( m->freemem>=0 && GETSYSCTL("vm.stats.vm.v_cache_count", memory_tmp) == 0 )
+ m->freemem += memory_tmp;
+ else
+ m->freemem = -1;
+ if ( m->freemem>=0 && GETSYSCTL("vm.stats.vm.v_free_count", memory_tmp) == 0 )
+ m->freemem += memory_tmp;
+ else
+ m->freemem = -1;
+
+ if ( m->freemem>=0 )
+ m->freemem *= getpagesize();
+
+ m->usermem =-1;
+ if ( GETSYSCTL("hw.usermem", memory_tmp) == 0 )
+ m->usermem = memory_tmp;
+
+ tlog( TL_DEBUG, "Sended topdata: %.2f load, %d free, %d total", m->load, m->freemem, m->usermem);
+}
+
+static int
+sendTop(Msg *msg) {
+ TCMsg *pmsg;
+
+ if ( !msg->msg ) {
+ int msglen = TCMSGHDRSZ + sizeof(TCMsgTop);
+ pmsg = (TCMsg*)tmalloc(msglen);
+ pmsg->len = msglen;
+ pmsg->type=TOPMSGTYPE;
+ msg->msg = pmsg;
+ } else {
+ pmsg = msg->msg;
+ }
+
+ fillMsgTop( (TCMsgTop*)(pmsg->data) );
+
+ return TC_sendMsg(msg);
+}
+
+
+extern char *optarg;
+int
+main( int argc, char *argv[] ) {
+ int ch;
+ Msg msg;
+ int debug=0, child=0;
+ int period=30;
+
+ msg.port = TOPD_SERVER_DEFAULT_PORT;
+ msg.host = "127.0.0.1";
+ msg.msg = NULL;
+ msg.sockfd =-1;
+
+ while( (ch=getopt(argc, argv, "h:p:s:D"))!=-1) {
+ switch(ch) {
+ case 'h':
+ msg.host = strdup(optarg);
+ break;
+ case 'p':
+ msg.port = atoi(optarg);
+ break;
+ case 's':
+ period = atoi(optarg);
+ break;
+ case 'D':
+ debug=1;
+ break;
+ default:
+ return 1;
+ }
+ }
+
+ signal(SIGCHLD, SIG_IGN);
+
+ if ( debug )
+ opentlog( TL_OPEN_STDERR, TL_DEBUG, NULL);
+ else
+ opentlog( TL_OPEN_SYSLOG, TL_INFO, NULL);
+
+ if ( debug || (child = fork()) == 0 ) {
+ while(1) {
+ sendTop(&msg);
+ sleep(period);
+ }
+ TC_closefd(&msg);
+ }
+
+ if (child == -1)
+ tlog(TL_CRIT|TL_EXIT, "Can't start child process: %s", strerror(errno));
+
+ return (0);
+}
--- /dev/null
+/*
+ * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include "tlog.h"
+#include "connection.h"
+#include "top.h"
+#include "tmalloc.h"
+
+static void
+getTopData(TC_Connection *conn) {
+ TCMsg *pmsg;
+ conn->len = TCMSGHDRSZ + MUHDRSZ + cfg.mu->number * sizeof(UnitInfo);
+ conn->buf = trealloc( conn->buf, conn->len );
+ pmsg = (TCMsg*) conn->buf;
+
+ pmsg->len = conn->len;
+ pmsg->type = TOPGETTYPE;
+ memcpy( pmsg->data, cfg.mu, pmsg->len - TCMSGHDRSZ );
+ ((MassiveUnit*)pmsg->data)->maxnumber = cfg.mu->number;
+ TC_Send(conn);
+}
+
+static void
+gotLongMessage( TC_Connection *conn ) {
+ TCMsg *pmsg = (TCMsg*) conn->buf;
+
+ if ( conn->ptr - conn->buf < TCMSGHDRSZ ) {
+ tlog(TL_ALARM,"Wrong size of long message (%d bytes)", conn->ptr - conn->buf);
+ conn->state = CS_ERROR;
+ return;
+ }
+
+ switch(pmsg->type) {
+ case TOPGETTYPE:
+ getTopData(conn);
+ break;
+ default:
+ tlog(TL_ALARM,"Got unknown packet type: %d", pmsg->type);
+ conn->state = CS_ERROR;
+ }
+}
+
+static void
+sendedLongMessage( TC_Connection *conn ) {
+ TCMsg *pmsg = (TCMsg*) conn->buf;
+ switch(pmsg->type) {
+ case TOPGETTYPE:
+ conn->state = CS_FINISH;
+ break;
+ default:
+ tlog(TL_ALARM,"Send unknown packet type: %d", pmsg->type);
+ conn->state = CS_ERROR;
+ }
+}
+
+void
+ConnectionWorks() {
+ int i;
+ TC_Connection *conn;
+ for(i=TC_SERVER_CONN_START; i<cfg.pool.number; i++) {
+ conn = cfg.pool.conn[i];
+ switch( conn->state ) {
+ case CS_INPROCESS:
+ TC_ServerConnect( conn );
+ break;
+ case CS_CONNECTED: /* we have connected to remote host */
+ TC_Send( conn );
+ break;
+ case CS_FINISHSEND:
+ sendedLongMessage( conn );
+ break;
+ case CS_FINISHREAD:
+ gotLongMessage( conn );
+ break;
+ case CS_READ:
+ if ( conn->readyio ) {
+ TC_Read( conn );
+ if ( conn->state != CS_READ ) i--; /* check it one more time */
+ }
+ break;
+ case CS_SEND:
+ if ( conn->readyio ) {
+ TC_Send( conn );
+ if ( conn->state != CS_SEND ) i--; /* check it one more time */
+ }
+ break;
+ /* ignore */
+ case CS_OK:
+ case CS_AGAIN:
+ case CS_WAIT: /* ??? */
+ break;
+ /* out */
+ case CS_TIMEOUT:
+ case CS_CLOSED:
+ case CS_NOTINITED:
+ case CS_FINISH:
+ case CS_ERROR:
+ default:
+ tlog(TL_DEBUG, "Clear N%d connection", i);
+ TC_deleteConnectionByN(&cfg.pool,i);
+ i--;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
+ * 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 <string.h>
+
+#include "tlog.h"
+#include "connection.h"
+#include "top.h"
+#include "tmalloc.h"
+
+
+static void
+addMsgTop( MassiveUnit *mu, TCMsgTop *tmsg, struct in_addr *client ) {
+ UnitInfo unit;
+
+ memcpy( &(unit.top), tmsg, sizeof( TCMsgTop ));
+ unit.stamp=time(NULL);
+ memcpy( &(unit.ip), client, sizeof(struct in_addr) );
+ unit.flag = 0;
+
+ fillUnit(mu, &unit);
+}
+
+
+void
+gotMsg(TC_Connection *msgconn) {
+ Msg gmsg;
+ TCMsg *pmsg;
+
+ if ( TC_getMsg( msgconn->fd, &gmsg ) )
+ return;
+
+ pmsg = gmsg.msg;
+
+ if ( cfg.debug )
+ tlog(TL_DEBUG, "Got %d bytes %08x type from %s:%d",
+ pmsg->len,
+ pmsg->type,
+ inet_ntoa(gmsg.host_addr.sin_addr),
+ ntohs(gmsg.host_addr.sin_port)
+ );
+
+ switch( pmsg->type ) {
+ case TOPMSGTYPE:
+ addMsgTop( cfg.mu, (TCMsgTop*)(pmsg->data), &(gmsg.host_addr.sin_addr) );
+ break;
+ default:
+ tlog(TL_ALARM, "Unknown message type: %d from %s",
+ pmsg->type, inet_ntoa(gmsg.host_addr.sin_addr));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include "tlog.h"
+#include "connection.h"
+#include "top.h"
+#include "tmalloc.h"
+
+
+MassiveUnit*
+allocUnits(int n ) {
+ MassiveUnit *ptr = NULL;
+
+ ptr = (MassiveUnit*)malloc( MUHDRSZ + n * sizeof(UnitInfo) );
+ if ( !ptr )
+ tlog(TL_CRIT|TL_EXIT, "allocUnits: no memoru for %d units", n);
+ ptr->maxnumber = n;
+ ptr->number=0;
+
+ return ptr;
+}
+
+static int
+cmpUnit(const void *a, const void *b) {
+ if ( ((UnitInfo*)a)->ip.s_addr == ((UnitInfo*)b)->ip.s_addr )
+ return 0;
+ return ( ((UnitInfo*)a)->ip.s_addr > ((UnitInfo*)b)->ip.s_addr ) ? 1 : -1;
+}
+
+void
+fillUnit( MassiveUnit* mu, UnitInfo *unit ) {
+ if ( mu->number==0 || ( mu->number==1 && unit->ip.s_addr == mu->units->ip.s_addr ) ) {
+ memcpy( mu->units, unit, sizeof(UnitInfo) );
+ mu->number=1;
+ } else {
+ UnitInfo *ptr = bsearch(unit, mu->units, mu->number, sizeof(UnitInfo), cmpUnit);
+ if ( ptr )
+ memcpy( ptr, unit, sizeof(UnitInfo) );
+ else {
+ if ( mu->number == mu->maxnumber )
+ tlog(TL_ALARM, "Can't add new unit");
+ else {
+ ptr = mu->units + mu->number;
+ memcpy( ptr, unit, sizeof(UnitInfo) );
+ mu->number++;
+ qsort(mu->units, mu->number, sizeof(UnitInfo), cmpUnit);
+ }
+ }
+ }
+}
+
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
+ * 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.
+ */
+
+#ifndef __TOP_H__
+#define __TOP_H__
+
+#include <sys/types.h>
+#include "connection.h"
+
+#define TOPD_SERVER_DEFAULT_PORT 6543
+#define TOPMSGTYPE 0x10AD10AD
+#define TOPGETTYPE 0x06ED10AD
+
+typedef struct {
+ double load;
+ int freemem;
+ int usermem;
+} TCMsgTop;
+
+typedef struct {
+ TCMsgTop top;
+ time_t stamp;
+ struct in_addr ip;
+ u_int32_t flag;
+} UnitInfo;
+
+typedef struct {
+ u_int32_t maxnumber;
+ u_int32_t number;
+ UnitInfo units[1];
+} MassiveUnit;
+
+#define MUHDRSZ (2*sizeof(u_int32_t))
+
+MassiveUnit *allocUnits(int n);
+void fillUnit( MassiveUnit* mu, UnitInfo *unit );
+
+void gotMsg(TC_Connection *msgconn);
+void ConnectionWorks();
+
+typedef struct {
+ MassiveUnit *mu;
+ u_int32_t
+ debug:1,
+ unused:31;
+ PoolConnection pool;
+} TCServer;
+
+extern TCServer cfg;
+
+#define TC_SERVER_CONN_START 2
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/sysctl.h>
+
+#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;
+
+int
+main( int argc, char *argv[] ) {
+ int ch;
+ int child=0, listenport = TOPD_SERVER_DEFAULT_PORT;
+ int n=1024;
+ char *host="127.0.0.1";
+
+ memset( &cfg, 0, sizeof(TCServer) );
+
+ while( (ch=getopt(argc, argv, "h:p:c:s: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:
+ return 1;
+ }
+ }
+
+ 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], NULL, 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 );
+ }
+ }
+ }
+ TC_deleteConnectionByN(&cfg.pool, 0);
+ close( cfg.pool.conn[1]->fd );
+ for(i=TC_SERVER_CONN_START; i<cfg.pool.number; i++)
+ TC_deleteConnectionByN(&cfg.pool,i);
+ }
+ }
+ if (child == -1)
+ tlog(TL_CRIT,"Can't start child process");
+
+ return 0;
+}
+