OSDN Git Service

Fix bug in accepting buffer size argument
[android-x86/external-busybox.git] / sysklogd / syslogd.c
index 3ba2398..8534c0a 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Mini syslogd implementation for busybox
  *
- * Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
  *
  * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org>
  *
@@ -35,6 +35,7 @@
 #include <paths.h>
 #include <signal.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <time.h>
 #include <string.h>
 #include <unistd.h>
@@ -58,6 +59,14 @@ static char lfile[MAXPATHLEN];
 
 static const char *logFilePath = __LOG_FILE;
 
+#ifdef CONFIG_FEATURE_ROTATE_LOGFILE
+/* max size of message file before being rotated */
+static int logFileSize = 200 * 1024;
+
+/* number of rotated message files */
+static int logFileRotate = 1;
+#endif
+
 /* interval between marks in seconds */
 static int MarkInterval = 20 * 60;
 
@@ -80,12 +89,21 @@ static int doRemoteLog = FALSE;
 static int local_logging = FALSE;
 #endif
 
+/* Make loging output smaller. */
+static bool small = false;
+
 
 #define MAXLINE         1024   /* maximum line length */
 
 
 /* circular buffer variables/structures */
 #ifdef CONFIG_FEATURE_IPC_SYSLOG
+
+#if CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE < 4
+#error Sorry, you must set the syslogd buffer size to at least 4KB.
+#error Please check CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE
+#endif
+
 #include <sys/ipc.h>
 #include <sys/sem.h>
 #include <sys/shm.h>
@@ -106,7 +124,7 @@ static struct sembuf SMwdn[3] = { {0, 0}, {1, 0}, {1, +1} };        // set SMwdn
 
 static int shmid = -1; // ipc shared memory id
 static int s_semid = -1;       // ipc semaphore id
-static int data_size = 16000;  // default data size
+static int shm_size = ((CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE)*1024);  // default shm size
 static int circular_logging = FALSE;
 
 /*
@@ -148,7 +166,7 @@ void ipcsyslog_cleanup(void)
 void ipcsyslog_init(void)
 {
        if (buf == NULL) {
-               if ((shmid = shmget(KEY_ID, data_size, IPC_CREAT | 1023)) == -1) {
+               if ((shmid = shmget(KEY_ID, shm_size, IPC_CREAT | 1023)) == -1) {
                        bb_perror_msg_and_die("shmget");
                }
 
@@ -156,7 +174,7 @@ void ipcsyslog_init(void)
                        bb_perror_msg_and_die("shmat");
                }
 
-               buf->size = data_size - sizeof(*buf);
+               buf->size = shm_size - sizeof(*buf);
                buf->head = buf->tail = 0;
 
                // we'll trust the OS to set initial semval to 0 (let's hope)
@@ -305,6 +323,36 @@ static void message(char *fmt, ...)
                                                         O_NONBLOCK)) >= 0) {
                fl.l_type = F_WRLCK;
                fcntl(fd, F_SETLKW, &fl);
+#ifdef CONFIG_FEATURE_ROTATE_LOGFILE
+               if ( logFileSize > 0 ) {
+                       struct stat statf;
+                       int r = fstat(fd, &statf);
+                       if( !r && (statf.st_mode & S_IFREG)
+                               && (lseek(fd,0,SEEK_END) > logFileSize) ) {
+                               if(logFileRotate > 0) {
+                                       int i;
+                                       char oldFile[(strlen(logFilePath)+3)], newFile[(strlen(logFilePath)+3)];
+                                       for(i=logFileRotate-1;i>0;i--) {
+                                               sprintf(oldFile, "%s.%d", logFilePath, i-1);
+                                               sprintf(newFile, "%s.%d", logFilePath, i);
+                                               rename(oldFile, newFile);
+                                       }
+                                       sprintf(newFile, "%s.%d", logFilePath, 0);
+                                       fl.l_type = F_UNLCK;
+                                       fcntl (fd, F_SETLKW, &fl);
+                                       close(fd);
+                                       rename(logFilePath, newFile);
+                                       fd = device_open (logFilePath,
+                                                  O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
+                                                  O_NONBLOCK);
+                                       fl.l_type = F_WRLCK;
+                                       fcntl (fd, F_SETLKW, &fl);
+                               } else {
+                                       ftruncate( fd, 0 );
+                               }
+                       }
+               }
+#endif
                va_start(arguments, fmt);
                vdprintf(fd, fmt, arguments);
                va_end(arguments);
@@ -384,8 +432,13 @@ static void logMessage(int pri, char *msg)
        }
        if (local_logging == TRUE)
 #endif
+       {
                /* now spew out the message to wherever it is supposed to go */
-               message("%s %s %s %s\n", timestamp, LocalHostName, res, msg);
+               if (small)
+                       message("%s %s\n", timestamp, msg);
+               else
+                       message("%s %s %s %s\n", timestamp, LocalHostName, res, msg);
+       }
 }
 
 static void quit_signal(int sig)
@@ -578,7 +631,7 @@ extern int syslogd_main(int argc, char **argv)
        char *p;
 
        /* do normal option parsing */
-       while ((opt = getopt(argc, argv, "m:nO:R:LC::")) > 0) {
+       while ((opt = getopt(argc, argv, "m:nO:s:Sb:R:LC:")) > 0) {
                switch (opt) {
                case 'm':
                        MarkInterval = atoi(optarg) * 60;
@@ -589,6 +642,15 @@ extern int syslogd_main(int argc, char **argv)
                case 'O':
                        logFilePath = optarg;
                        break;
+#ifdef CONFIG_FEATURE_ROTATE_LOGFILE
+               case 's':
+                       logFileSize = atoi(optarg) * 1024;
+                       break;
+               case 'b':
+                       logFileRotate = atoi(optarg);
+                       if( logFileRotate > 99 ) logFileRotate = 99;
+                       break;
+#endif
 #ifdef CONFIG_FEATURE_REMOTE_LOG
                case 'R':
                        RemoteHost = bb_xstrdup(optarg);
@@ -607,12 +669,15 @@ extern int syslogd_main(int argc, char **argv)
                        if (optarg) {
                                int buf_size = atoi(optarg);
                                if (buf_size >= 4) {
-                                       data_size = buf_size;
+                                       shm_size = buf_size * 1024;
                                }
                        }
                        circular_logging = TRUE;
                        break;
 #endif
+               case 'S':
+                       small = true;
+                       break;
                default:
                        bb_show_usage();
                }
@@ -634,11 +699,12 @@ extern int syslogd_main(int argc, char **argv)
        umask(0);
 
        if (doFork == TRUE) {
-               if(daemon(0, 1) < 0)
-               bb_perror_msg_and_die("daemon");
 #if defined(__uClinux__)
-               vfork_daemon_rexec(argc, argv, "-n");
-#endif
+               vfork_daemon_rexec(0, 1, argc, argv, "-n");
+#else /* __uClinux__ */
+               if(daemon(0, 1) < 0)
+                       bb_perror_msg_and_die("daemon");
+#endif /* __uClinux__ */
        }
        doSyslogd();