add .gitignore
[remotetop.git] / sendtop.c
index 8ab3269..9b41b22 100644 (file)
--- a/sendtop.c
+++ b/sendtop.c
@@ -33,6 +33,7 @@
 #include <unistd.h>
 #include <signal.h>
 #include <errno.h>
+#include <ctype.h>
 #include <sys/sysctl.h>
 
 #include "tlog.h"
 
 #include "top.h"
 
-#define NITEM   0
+#ifdef FreeBSD
 
 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,
+               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,
+               tlog(TL_ALARM, "sysctl(\"%s\", ...) expected %lu, got %lu\n", name,
                        (unsigned long)len, (unsigned long)nlen);
                return 1;
        }
@@ -63,25 +64,15 @@ getsysctl(char *name, void *ptr, size_t len) {
 #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
 
 static void
-fillMsgTop(TCMsgTop *m) {
-       double lll[3];
+getmeminfo(TCMsgTop *m) {
        int    memory_tmp;
+       long    memory_tmp1;
 
-       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
@@ -90,32 +81,125 @@ fillMsgTop(TCMsgTop *m) {
        if (  m->freemem>=0 )
                m->freemem *= getpagesize();
         
-       m->usermem =-1;
-       if ( GETSYSCTL("hw.usermem", memory_tmp) == 0 )
-               m->usermem = memory_tmp;
+       if ( GETSYSCTL("hw.physmem", memory_tmp1) == 0 )
+               m->physmem = memory_tmp1;
+}
+
+
+#elif defined  Linux /* end FreeBSD */
+
+#define MEMBUFSIZE 256
+
+/*
+ * if str mathes by pattern returns poineter to begin of value
+ * and NULL in opposite case
+ */
+static char*
+cmpPattern( char *str, char *pattern ) {
+       while( *str != '\0' && *str == *pattern ) {
+               str++;
+               pattern++;
+       }
+
+       if ( *pattern == '\0' ) {
+               if ( *str == '\0' )
+                       return NULL;
 
-       tlog( TL_DEBUG, "Sended topdata: %.2f load, %d free, %d total", m->load, m->freemem, m->usermem);
+               /*
+                * str matches by pattern, so skip leading spaces 
+                * before actual value
+                */
+               while( *str != '\0' ) {
+                       if ( isspace( *str ) )
+                               str++;
+                       else 
+                               return str;
+               }
+       }
+       
+       return NULL;
+}
+
+static void
+getmeminfo(TCMsgTop *m) {
+       FILE *fh;
+       static char buf[MEMBUFSIZE];
+       char *ptr;
+
+       fh=fopen("/proc/meminfo", "r");
+       if (fh == NULL) {
+               tlog(TL_ALARM, "fopen(\"/proc/meminfo\", ...) failed: %s", strerror(errno));
+               return;
+       }
+
+       while( fgets(buf, MEMBUFSIZE, fh) &&  (m->physmem == 0 || m->freemem == 0) ) {
+               if ( (ptr = cmpPattern(buf, "MemTotal:")) != NULL ) {
+                       m->physmem = atoll(ptr) * 1024; /* mem in Kb */ 
+               } else if ( (ptr = cmpPattern(buf, "MemFree:")) != NULL ) {
+                       m->freemem = atoll(ptr) * 1024; /* mem in Kb */ 
+               }
+       }
+
+       fclose(fh);
+}
+
+#else /* end Linux*/
+#error No memory stat for current OS
+#endif 
+
+#define NITEM   0
+
+static void
+fillMsgTop(TCMsgTop *m) {
+       double lll[3];
+
+       memset(m,0,sizeof(TCMsgTop));
+       if ( getloadavg(lll,3) >= NITEM+1 )
+               m->load=lll[NITEM];
+       else
+               m->load=-1.0;
+
+       m->freemem = 0;
+       m->physmem = 0;
+       getmeminfo(m);
+
+       tlog( TL_DEBUG, "Sended topdata: %.2f load, %lld free, %lld total", m->load, m->freemem, m->physmem);
 }
 
 static int
 sendTop(Msg *msg) {
        TCMsg *pmsg;
+       int msglen = TCMSGHDRSZ + sizeof(TCMsgTop);
 
        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;
        }
 
+       pmsg->len = msglen;
+       pmsg->type=TOPMSGTYPE;
        fillMsgTop( (TCMsgTop*)(pmsg->data) );
 
        return TC_sendMsg(msg);
 }
 
+void usage() {
+       fputs(
+               "Copyright (c) 2004-2007 Teodor Sigaev <teodor@sigaev.ru>. All rights reserved.\n"
+               "sendtop - small daemon to send load of box to server\n"
+               "Usage:\n"
+               "./sendtop [-D] -h HOST [-p PORT] [-s PERIOD]\n"
+               "  -D        - debug mode (do not daemonize, print to stderr instead of syslog)\n"
+               "  -h HOST   - server IP to send data\n"
+               "  -p PORT   - port number of server\n"
+               "  -s PERIOD - period of of send (in seconds)\n",
+               stdout
+       );
+
+       exit(1);
+}
 
 extern char *optarg;
 int
@@ -126,7 +210,7 @@ main( int argc, char *argv[] ) {
        int period=30;
 
        msg.port        = TOPD_SERVER_DEFAULT_PORT;
-       msg.host        = "127.0.0.1";
+       msg.host        = NULL;
        msg.msg = NULL;
        msg.sockfd =-1;
 
@@ -145,10 +229,14 @@ main( int argc, char *argv[] ) {
                                debug=1;
                                break;
                        default:
+                               usage();
                                return 1;
                }
        }
 
+       if (!msg.host)
+               usage();
+
        signal(SIGCHLD, SIG_IGN);
 
        if ( debug )