Try to make indent formatting less horrible
[oweals/busybox.git] / sysklogd / logread.c
index d3349625caadcbc01ba386a3e280f2fd74dcb87e..524178fe8243df513af6e0083fb3f2db1d5764dc 100644 (file)
@@ -2,9 +2,9 @@
 /*
  * circular buffer syslog implementation for busybox
  *
- * Copyright (C) 2000 by Gennady Feldman <gfeldman@cachier.com>
+ * Copyright (C) 2000 by Gennady Feldman <gfeldman@gena01.com>
  *
- * Maintainer: Gennady Feldman <gena01@cachier.com> as of Mar 12, 2001
+ * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <sys/shm.h>
 #include <signal.h>
 #include <setjmp.h>
+#include <unistd.h>
 #include "busybox.h"
 
-#if __GNU_LIBRARY__ < 5
-#error Sorry.  Looks like you are using libc5.  
-#error libc5 shm support isnt good enough.
-#error Please disable BB_FEATURE_IPC_SYSLOG 
-#endif 
-
-
 static const long KEY_ID = 0x414e4547; /*"GENA"*/
 
 static struct shbuf_ds {
@@ -84,10 +78,15 @@ static inline void sem_down(int semid)
 extern int logread_main(int argc, char **argv)
 {
        int i;
+       int follow=0;
        
-       /* no options, no getopt */
-       if (argc > 1)
-               show_usage();
+       if (argc == 2 && strcmp(argv[1],"-f")==0) {
+               follow = 1;
+       } else {
+               /* no options, no getopt */
+               if (argc > 1)
+                       bb_show_usage();
+       }
        
        // handle intrrupt signal
        if (setjmp(jmp_env)) goto output_end;
@@ -105,22 +104,66 @@ extern int logread_main(int argc, char **argv)
        if ( (log_semid = semget(KEY_ID, 0, 0)) == -1)
                error_exit("Can't get access to semaphone(s) for circular buffer from syslogd");
 
-       sem_down(log_semid);    
-       // Read Memory 
-       i=buf->head;
-
-       //printf("head: %i tail: %i size: %i\n",buf->head,buf->tail,buf->size);
-       if (buf->head == buf->tail) {
-               printf("<empty syslog>\n");
-       }
+       // Suppose atomic memory move
+       i = follow ? buf->tail : buf->head;
+
+       do {
+#undef RC_LOGREAD
+#ifdef RC_LOGREAD
+               char *buf_data;
+               int log_len,j;
+#endif
+
+               sem_down(log_semid);    
+
+               //printf("head: %i tail: %i size: %i\n",buf->head,buf->tail,buf->size);
+               if (buf->head == buf->tail || i==buf->tail) {
+                       if (follow) {
+                               sem_up(log_semid);
+                               sleep(1);       /* TODO: replace me with a sleep_on */
+                               continue;
+                       } else {
+                               printf("<empty syslog>\n");
+                       }
+               }
        
-       while ( i != buf->tail) {
-               printf("%s", buf->data+i);
-               i+= strlen(buf->data+i) + 1;
-               if (i >= buf->size )
-                       i=0;
-       }
-       sem_up(log_semid);
+               // Read Memory 
+#ifdef RC_LOGREAD
+               log_len = buf->tail - i;
+               if (log_len < 0)
+                       log_len += buf->size;
+               buf_data = (char *)malloc(log_len);
+               if (!buf_data)
+                       error_exit("malloc failed");
+
+               if (buf->tail < i) {
+                       memcpy(buf_data, buf->data+i, buf->size-i);
+                       memcpy(buf_data+buf->size-i, buf->data, buf->tail);
+               } else {
+                       memcpy(buf_data, buf->data+i, buf->tail-i);
+               }
+               i = buf->tail;
+
+#else
+               while ( i != buf->tail) {
+                       printf("%s", buf->data+i);
+                       i+= strlen(buf->data+i) + 1;
+                       if (i >= buf->size )
+                               i=0;
+               }
+#endif
+               // release the lock on the log chain
+               sem_up(log_semid);
+
+#ifdef RC_LOGREAD
+               for (j=0; j < log_len; j+=strlen(buf_data+j)+1) {
+                       printf("%s", buf_data+j);
+                       if (follow)
+                               fflush(stdout);
+               }
+               free(buf_data);
+#endif
+       } while (follow);
 
 output_end:
        if (log_shmid != -1)