diff options
Diffstat (limited to 'sysklogd/logread.c')
-rw-r--r-- | sysklogd/logread.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/sysklogd/logread.c b/sysklogd/logread.c new file mode 100644 index 0000000..9cc6561 --- /dev/null +++ b/sysklogd/logread.c @@ -0,0 +1,171 @@ +/* vi: set sw=4 ts=4: */ +/* + * circular buffer syslog implementation for busybox + * + * Copyright (C) 2000 by Gennady Feldman <gfeldman@gena01.com> + * + * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001 + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + + +#include "busybox.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ipc.h> +#include <sys/types.h> +#include <sys/sem.h> +#include <sys/shm.h> +#include <signal.h> +#include <setjmp.h> +#include <unistd.h> + +static const long KEY_ID = 0x414e4547; /*"GENA"*/ + +static struct shbuf_ds { + int size; // size of data written + int head; // start of message list + int tail; // end of message list + char data[1]; // data/messages +} *buf = NULL; // shared memory pointer + + +// Semaphore operation structures +static struct sembuf SMrup[1] = {{0, -1, IPC_NOWAIT | SEM_UNDO}}; // set SMrup +static struct sembuf SMrdn[2] = {{1, 0}, {0, +1, SEM_UNDO}}; // set SMrdn + +static int log_shmid = -1; // ipc shared memory id +static int log_semid = -1; // ipc semaphore id +static jmp_buf jmp_env; + +static void error_exit(const char *str); +static void interrupted(int sig); + +/* + * sem_up - up()'s a semaphore. + */ +static void sem_up(int semid) +{ + if ( semop(semid, SMrup, 1) == -1 ) + error_exit("semop[SMrup]"); +} + +/* + * sem_down - down()'s a semaphore + */ +static void sem_down(int semid) +{ + if ( semop(semid, SMrdn, 2) == -1 ) + error_exit("semop[SMrdn]"); +} + +int logread_main(int argc, char **argv) +{ + int i; + int follow=0; + + if (argc == 2 && argv[1][0]=='-' && argv[1][1]=='f') { + follow = 1; + } else { + /* no options, no getopt */ + if (argc > 1) + bb_show_usage(); + } + + // handle interrupt signal + if (setjmp(jmp_env)) goto output_end; + + // attempt to redefine ^C signal + signal(SIGINT, interrupted); + + if ( (log_shmid = shmget(KEY_ID, 0, 0)) == -1) + error_exit("Can't find circular buffer"); + + // Attach shared memory to our char* + if ( (buf = shmat(log_shmid, NULL, SHM_RDONLY)) == NULL) + error_exit("Can't get access to circular buffer from syslogd"); + + if ( (log_semid = semget(KEY_ID, 0, 0)) == -1) + error_exit("Can't get access to semaphore(s) for circular buffer from syslogd"); + + // Suppose atomic memory move + i = follow ? buf->tail : buf->head; + + do { +#ifdef CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING + 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"); + } + } + + // Read Memory +#ifdef CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING + log_len = buf->tail - i; + if (log_len < 0) + log_len += buf->size; + buf_data = (char *)xmalloc(log_len); + + 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 CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING + 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 + fflush(stdout); + } while (follow); + +output_end: + if (log_shmid != -1) + shmdt(buf); + + return EXIT_SUCCESS; +} + +static void interrupted(int sig){ + signal(SIGINT, SIG_IGN); + longjmp(jmp_env, 1); +} + +static void error_exit(const char *str){ + bb_perror_msg(str); + //release all acquired resources + if (log_shmid != -1) + shmdt(buf); + + exit(1); +} |