Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/sysklogd
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- Location:
- branches/2.2.9/mindi-busybox/sysklogd
- Files:
-
- 3 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/sysklogd/Config.in
r1765 r2725 1 # DO NOT EDIT. This file is generated from Config.src 1 2 # 2 3 # For a description of the syntax of this configuration file, … … 6 7 menu "System Logging Utilities" 7 8 9 10 8 11 config SYSLOGD 9 12 bool "syslogd" 10 default n13 default y 11 14 help 12 15 The syslogd utility is used to record logs of all the 13 significant events that occur on a system. 16 significant events that occur on a system. Every 14 17 message that is logged records the date and time of the 15 18 event, and will generally also record the name of the 16 application that generated the message. 19 application that generated the message. When used in 17 20 conjunction with klogd, messages from the Linux kernel 18 can also be recorded. 21 can also be recorded. This is terribly useful, 19 22 especially for finding what happened when something goes 20 wrong. 23 wrong. And something almost always will go wrong if 21 24 you wait long enough.... 22 25 23 26 config FEATURE_ROTATE_LOGFILE 24 27 bool "Rotate message files" 25 default n28 default y 26 29 depends on SYSLOGD 27 30 help … … 31 34 config FEATURE_REMOTE_LOG 32 35 bool "Remote Log support" 33 default n36 default y 34 37 depends on SYSLOGD 35 38 help 36 39 When you enable this feature, the syslogd utility can 37 40 be used to send system log messages to another system 38 connected via a network. 41 connected via a network. This allows the remote 39 42 machine to log all the system messages, which can be 40 43 terribly useful for reducing the number of serial 41 cables you use. 44 cables you use. It can also be a very good security 42 45 measure to prevent system logs from being tampered with 43 46 by an intruder. 44 47 48 config FEATURE_SYSLOGD_DUP 49 bool "Support -D (drop dups) option" 50 default y 51 depends on SYSLOGD 52 help 53 Option -D instructs syslogd to drop consecutive messages 54 which are totally the same. 55 56 config FEATURE_SYSLOGD_READ_BUFFER_SIZE 57 int "Read buffer size in bytes" 58 default 256 59 range 256 20000 60 depends on SYSLOGD 61 help 62 This option sets the size of the syslog read buffer. 63 Actual memory usage increases around five times the 64 change done here. 65 45 66 config FEATURE_IPC_SYSLOG 46 67 bool "Circular Buffer support" 47 default n68 default y 48 69 depends on SYSLOGD 49 70 help … … 51 72 use a circular buffer to record system log messages. 52 73 When the buffer is filled it will continue to overwrite 53 the oldest messages. 74 the oldest messages. This can be very useful for 54 75 systems with little or no permanent storage, since 55 76 otherwise system logs can eventually fill up your … … 58 79 59 80 config FEATURE_IPC_SYSLOG_BUFFER_SIZE 60 int " 81 int "Circular buffer size in Kbytes (minimum 4KB)" 61 82 default 16 62 83 range 4 2147483647 … … 72 93 help 73 94 If you enabled Circular Buffer support, you almost 74 certainly want to enable this feature as well. 95 certainly want to enable this feature as well. This 75 96 utility will allow you to read the messages that are 76 97 stored in the syslogd circular buffer. 77 98 78 99 config FEATURE_LOGREAD_REDUCED_LOCKING 79 bool " logread double buffering"80 default n100 bool "Double buffering" 101 default y 81 102 depends on LOGREAD 82 103 help … … 89 110 config KLOGD 90 111 bool "klogd" 91 default n112 default y 92 113 help 93 114 klogd is a utility which intercepts and logs all 94 115 messages from the Linux kernel and sends the messages 95 out to the 'syslogd' utility so they can be logged. 116 out to the 'syslogd' utility so they can be logged. If 96 117 you wish to record the messages produced by the kernel, 97 118 you should enable this option. 98 119 120 config FEATURE_KLOGD_KLOGCTL 121 bool "Use the klogctl() interface" 122 default y 123 depends on KLOGD && PLATFORM_LINUX 124 help 125 The klogd applet supports two interfaces for reading 126 kernel messages. Linux provides the klogctl() interface 127 which allows reading messages from the kernel ring buffer 128 independently from the file system. 129 130 If you answer 'N' here, klogd will use the more portable 131 approach of reading them from /proc or a device node. 132 However, this method requires the file to be available. 133 134 If in doubt, say 'Y'. 135 99 136 config LOGGER 100 137 bool "logger" 101 default n138 default y 102 139 select FEATURE_SYSLOG 103 140 help 104 141 The logger utility allows you to send arbitrary text 105 142 messages to the system log (i.e. the 'syslogd' utility) so 106 they can be logged. 143 they can be logged. This is generally used to help locate 107 144 problems that occur within programs and scripts. 108 145 109 146 endmenu 110 -
branches/2.2.9/mindi-busybox/sysklogd/Kbuild
r1765 r2725 1 # DO NOT EDIT. This file is generated from Kbuild.src 1 2 # Makefile for busybox 2 3 # 3 4 # Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> 4 5 # 5 # Licensed under the GPL v2, see the file LICENSE in this tarball.6 # Licensed under GPLv2, see file LICENSE in this source tree. 6 7 7 8 lib-y:= 9 10 8 11 lib-$(CONFIG_KLOGD) += klogd.o 9 lib-$(CONFIG_LOGGER) += logger.o12 lib-$(CONFIG_LOGGER) += syslogd_and_logger.o 10 13 lib-$(CONFIG_LOGREAD) += logread.o 11 lib-$(CONFIG_SYSLOGD) += syslogd .o14 lib-$(CONFIG_SYSLOGD) += syslogd_and_logger.o -
branches/2.2.9/mindi-busybox/sysklogd/klogd.c
r1765 r2725 5 5 * Copyright (C) 2001 by Gennady Feldman <gfeldman@gena01.com>. 6 6 * Changes: Made this a standalone busybox module which uses standalone 7 * 7 * syslog() client interface. 8 8 * 9 9 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> … … 15 15 * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001 16 16 * 17 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.17 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 18 18 */ 19 19 20 20 #include "libbb.h" 21 #include <sys/syslog.h> 22 #include <sys/klog.h> 23 24 static void klogd_signal(int sig ATTRIBUTE_UNUSED) 25 { 26 klogctl(7, NULL, 0); 27 klogctl(0, 0, 0); 28 syslog(LOG_NOTICE, "Kernel log daemon exiting"); 29 exit(EXIT_SUCCESS); 30 } 31 32 #define OPT_LEVEL 1 33 #define OPT_FOREGROUND 2 34 35 #define KLOGD_LOGBUF_SIZE BUFSIZ 21 #include <syslog.h> 22 23 24 /* The Linux-specific klogctl(3) interface does not rely on the filesystem and 25 * allows us to change the console loglevel. Alternatively, we read the 26 * messages from _PATH_KLOG. */ 27 28 #if ENABLE_FEATURE_KLOGD_KLOGCTL 29 30 # include <sys/klog.h> 31 32 static void klogd_open(void) 33 { 34 /* "Open the log. Currently a NOP" */ 35 klogctl(1, NULL, 0); 36 } 37 38 static void klogd_setloglevel(int lvl) 39 { 40 /* "printk() prints a message on the console only if it has a loglevel 41 * less than console_loglevel". Here we set console_loglevel = lvl. */ 42 klogctl(8, NULL, lvl); 43 } 44 45 static int klogd_read(char *bufp, int len) 46 { 47 return klogctl(2, bufp, len); 48 } 49 # define READ_ERROR "klogctl(2) error" 50 51 static void klogd_close(void) 52 { 53 /* FYI: cmd 7 is equivalent to setting console_loglevel to 7 54 * via klogctl(8, NULL, 7). */ 55 klogctl(7, NULL, 0); /* "7 -- Enable printk's to console" */ 56 klogctl(0, NULL, 0); /* "0 -- Close the log. Currently a NOP" */ 57 } 58 59 #else 60 61 # include <paths.h> 62 # ifndef _PATH_KLOG 63 # ifdef __GNU__ 64 # define _PATH_KLOG "/dev/klog" 65 # else 66 # error "your system's _PATH_KLOG is unknown" 67 # endif 68 # endif 69 # define PATH_PRINTK "/proc/sys/kernel/printk" 70 71 enum { klogfd = 3 }; 72 73 static void klogd_open(void) 74 { 75 int fd = xopen(_PATH_KLOG, O_RDONLY); 76 xmove_fd(fd, klogfd); 77 } 78 79 static void klogd_setloglevel(int lvl) 80 { 81 FILE *fp = fopen_or_warn(PATH_PRINTK, "w"); 82 if (fp) { 83 /* This changes only first value: 84 * "messages with a higher priority than this 85 * [that is, with numerically lower value] 86 * will be printed to the console". 87 * The other three values in this pseudo-file aren't changed. 88 */ 89 fprintf(fp, "%u\n", lvl); 90 fclose(fp); 91 } 92 } 93 94 static int klogd_read(char *bufp, int len) 95 { 96 return read(klogfd, bufp, len); 97 } 98 # define READ_ERROR "read error" 99 100 static void klogd_close(void) 101 { 102 klogd_setloglevel(7); 103 if (ENABLE_FEATURE_CLEAN_UP) 104 close(klogfd); 105 } 106 107 #endif 108 36 109 #define log_buffer bb_common_bufsiz1 37 38 int klogd_main(int argc, char **argv); 39 int klogd_main(int argc, char **argv) 40 { 41 int i = i; /* silence gcc */ 42 char *start; 43 44 /* do normal option parsing */ 45 getopt32(argv, "c:n", &start); 46 47 if (option_mask32 & OPT_LEVEL) { 110 enum { 111 KLOGD_LOGBUF_SIZE = sizeof(log_buffer), 112 OPT_LEVEL = (1 << 0), 113 OPT_FOREGROUND = (1 << 1), 114 }; 115 116 /* TODO: glibc openlog(LOG_KERN) reverts to LOG_USER instead, 117 * because that's how they interpret word "default" 118 * in the openlog() manpage: 119 * LOG_USER (default) 120 * generic user-level messages 121 * and the fact that LOG_KERN is a constant 0. 122 * glibc interprets it as "0 in openlog() call means 'use default'". 123 * I think it means "if openlog wasn't called before syslog() is called, 124 * use default". 125 * Convincing glibc maintainers otherwise is, as usual, nearly impossible. 126 * Should we open-code syslog() here to use correct facility? 127 */ 128 129 int klogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 130 int klogd_main(int argc UNUSED_PARAM, char **argv) 131 { 132 int i = 0; 133 char *opt_c; 134 int opt; 135 int used; 136 137 opt = getopt32(argv, "c:n", &opt_c); 138 if (opt & OPT_LEVEL) { 48 139 /* Valid levels are between 1 and 8 */ 49 i = xatoul_range(start, 1, 8); 50 } 51 52 if (!(option_mask32 & OPT_FOREGROUND)) { 140 i = xatou_range(opt_c, 1, 8); 141 } 142 if (!(opt & OPT_FOREGROUND)) { 53 143 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); 54 144 } 55 145 146 logmode = LOGMODE_SYSLOG; 147 148 /* klogd_open() before openlog(), since it might use fixed fd 3, 149 * and openlog() also may use the same fd 3 if we swap them: 150 */ 151 klogd_open(); 56 152 openlog("kernel", 0, LOG_KERN); 57 153 58 /* Set up sig handlers */59 signal(SIGINT, klogd_signal);60 signal(SIGKILL, klogd_signal); 61 signal(SIGTERM, klogd_signal);154 if (i) 155 klogd_setloglevel(i); 156 157 bb_signals(BB_FATAL_SIGS, record_signo); 62 158 signal(SIGHUP, SIG_IGN); 63 159 64 /* "Open the log. Currently a NOP." */65 klogctl(1, NULL, 0);66 67 /* Set level of kernel console messaging. */68 if (option_mask32 & OPT_LEVEL)69 klogctl(8, NULL, i);70 71 160 syslog(LOG_NOTICE, "klogd started: %s", bb_banner); 72 161 73 /* Note: this code does not detect incomplete messages 74 * (messages not ending with '\n' or just when kernel 75 * generates too many messages for us to keep up) 76 * and will split them in two separate lines */ 77 while (1) { 162 used = 0; 163 while (!bb_got_signal) { 78 164 int n; 79 165 int priority; 80 81 n = klogctl(2, log_buffer, KLOGD_LOGBUF_SIZE - 1); 166 char *start; 167 168 /* "2 -- Read from the log." */ 169 start = log_buffer + used; 170 n = klogd_read(start, KLOGD_LOGBUF_SIZE-1 - used); 82 171 if (n < 0) { 83 172 if (errno == EINTR) 84 173 continue; 85 syslog(LOG_ERR, "klogd: error from klogctl(2): %d - %m", 86 errno); 174 bb_perror_msg(READ_ERROR); 87 175 break; 88 176 } 89 log_buffer[n] = '\n'; 90 i = 0; 91 while (i < n) { 177 start[n] = '\0'; 178 179 /* Process each newline-terminated line in the buffer */ 180 start = log_buffer; 181 while (1) { 182 char *newline = strchrnul(start, '\n'); 183 184 if (*newline == '\0') { 185 /* This line is incomplete */ 186 187 /* move it to the front of the buffer */ 188 overlapping_strcpy(log_buffer, start); 189 used = newline - start; 190 if (used < KLOGD_LOGBUF_SIZE-1) { 191 /* buffer isn't full */ 192 break; 193 } 194 /* buffer is full, log it anyway */ 195 used = 0; 196 newline = NULL; 197 } else { 198 *newline++ = '\0'; 199 } 200 201 /* Extract the priority */ 92 202 priority = LOG_INFO; 93 start = &log_buffer[i]; 94 if (log_buffer[i] == '<') { 95 i++; 96 // kernel never ganerates multi-digit prios 97 //priority = 0; 98 //while (log_buffer[i] >= '0' && log_buffer[i] <= '9') { 99 // priority = priority * 10 + (log_buffer[i] - '0'); 100 // i++; 101 //} 102 if (isdigit(log_buffer[i])) { 103 priority = (log_buffer[i] - '0'); 104 i++; 203 if (*start == '<') { 204 start++; 205 if (*start) { 206 /* kernel never generates multi-digit prios */ 207 priority = (*start - '0'); 208 start++; 105 209 } 106 if (log_buffer[i] == '>') 107 i++; 108 start = &log_buffer[i]; 210 if (*start == '>') 211 start++; 109 212 } 110 while (log_buffer[i] != '\n') 111 i++; 112 log_buffer[i] = '\0'; 113 syslog(priority, "%s", start); 114 i++; 213 /* Log (only non-empty lines) */ 214 if (*start) 215 syslog(priority, "%s", start); 216 217 if (!newline) 218 break; 219 start = newline; 115 220 } 116 221 } 117 222 223 klogd_close(); 224 syslog(LOG_NOTICE, "klogd: exiting"); 225 if (bb_got_signal) 226 kill_myself_with_sig(bb_got_signal); 118 227 return EXIT_FAILURE; 119 228 } -
branches/2.2.9/mindi-busybox/sysklogd/logger.c
r1772 r2725 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 9 10 /* 11 * Done in syslogd_and_logger.c: 10 12 #include "libbb.h" 11 12 #if !defined CONFIG_SYSLOGD13 14 13 #define SYSLOG_NAMES 15 #include <sys/syslog.h> 16 17 #else 18 #include <sys/syslog.h> 19 # ifndef __dietlibc__ 20 /* We have to do this since the header file defines static 21 * structures. Argh.... bad libc, bad, bad... 22 */ 23 typedef struct _code { 24 char *c_name; 25 int c_val; 26 } CODE; 27 extern CODE prioritynames[]; 28 extern CODE facilitynames[]; 29 # endif 30 #endif 14 #define SYSLOG_NAMES_CONST 15 #include <syslog.h> 16 */ 31 17 32 18 /* Decode a symbolic name to a numeric value … … 37 23 * Original copyright notice is retained at the end of this file. 38 24 */ 39 static int decode(char *name, CODE *codetab)25 static int decode(char *name, const CODE *codetab) 40 26 { 41 CODE *c;27 const CODE *c; 42 28 43 29 if (isdigit(*name)) … … 81 67 } 82 68 69 #define strbuf bb_common_bufsiz1 83 70 84 int logger_main(int argc, char **argv) ;85 int logger_main(int argc , char **argv)71 int logger_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 72 int logger_main(int argc UNUSED_PARAM, char **argv) 86 73 { 87 74 char *str_p, *str_t; 75 int opt; 88 76 int i = 0; 89 char name[80];90 77 91 78 /* Fill out the name string early (may be overwritten later) */ 92 bb_getpwuid(name, sizeof(name), geteuid()); 93 str_t = name; 79 str_t = uid2uname_utoa(geteuid()); 94 80 95 81 /* Parse any options */ 96 getopt32(argv, "p:st:", &str_p, &str_t);82 opt = getopt32(argv, "p:st:", &str_p, &str_t); 97 83 98 if (opt ion_mask32& 0x2) /* -s */84 if (opt & 0x2) /* -s */ 99 85 i |= LOG_PERROR; 100 //if (opt ion_mask32& 0x4) /* -t */86 //if (opt & 0x4) /* -t */ 101 87 openlog(str_t, i, 0); 102 88 i = LOG_USER | LOG_NOTICE; 103 if (opt ion_mask32& 0x1) /* -p */89 if (opt & 0x1) /* -p */ 104 90 i = pencode(str_p); 105 91 106 argc -= optind;107 92 argv += optind; 108 if (!argc) { 109 #define strbuf bb_common_bufsiz1 93 if (!argv[0]) { 110 94 while (fgets(strbuf, COMMON_BUFSIZE, stdin)) { 111 95 if (strbuf[0] … … 133 117 } 134 118 119 /* Clean up. Needed because we are included from syslogd_and_logger.c */ 120 #undef strbuf 135 121 136 122 /*- 137 123 * Copyright (c) 1983, 1993 138 * 124 * The Regents of the University of California. All rights reserved. 139 125 * 140 126 * This is the original license statement for the decode and pencode functions. … … 149 135 * documentation and/or other materials provided with the distribution. 150 136 * 151 * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change152 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>137 * 3. BSD Advertising Clause omitted per the July 22, 1999 licensing change 138 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change 153 139 * 154 140 * 4. Neither the name of the University nor the names of its contributors -
branches/2.2.9/mindi-busybox/sysklogd/logread.c
r1765 r2725 7 7 * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001 8 8 * 9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.9 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 10 10 */ 11 11 … … 17 17 #define DEBUG 0 18 18 19 /* our shared key (syslogd.c and logread.c must be in sync) */ 19 20 enum { KEY_ID = 0x414e4547 }; /* "GENA" */ 20 21 21 st atic struct shbuf_ds {22 struct shbuf_ds { 22 23 int32_t size; // size of data - 1 23 24 int32_t tail; // end of message list 24 25 char data[1]; // messages 25 } *shbuf;26 }; 26 27 27 // Semaphore operation structures 28 static struct sembuf SMrup[1] = {{0, -1, IPC_NOWAIT | SEM_UNDO}}; // set SMrup 29 static struct sembuf SMrdn[2] = {{1, 0}, {0, +1, SEM_UNDO}}; // set SMrdn 28 static const struct sembuf init_sem[3] = { 29 {0, -1, IPC_NOWAIT | SEM_UNDO}, 30 {1, 0}, {0, +1, SEM_UNDO} 31 }; 30 32 33 struct globals { 34 struct sembuf SMrup[1]; // {0, -1, IPC_NOWAIT | SEM_UNDO}, 35 struct sembuf SMrdn[2]; // {1, 0}, {0, +1, SEM_UNDO} 36 struct shbuf_ds *shbuf; 37 } FIX_ALIASING; 38 #define G (*(struct globals*)&bb_common_bufsiz1) 39 #define SMrup (G.SMrup) 40 #define SMrdn (G.SMrdn) 41 #define shbuf (G.shbuf) 42 #define INIT_G() do { \ 43 memcpy(SMrup, init_sem, sizeof(init_sem)); \ 44 } while (0) 31 45 32 static void error_exit(const char *str) ATTRIBUTE_NORETURN;46 static void error_exit(const char *str) NORETURN; 33 47 static void error_exit(const char *str) 34 48 { … … 47 61 } 48 62 49 static void interrupted(int sig ATTRIBUTE_UNUSED)63 static void interrupted(int sig UNUSED_PARAM) 50 64 { 51 65 signal(SIGINT, SIG_IGN); 52 66 shmdt(shbuf); 53 exit( 0);67 exit(EXIT_SUCCESS); 54 68 } 55 69 56 int logread_main(int argc, char **argv) ;57 int logread_main(int argc , char **argv)70 int logread_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 71 int logread_main(int argc UNUSED_PARAM, char **argv) 58 72 { 59 intcur;73 unsigned cur; 60 74 int log_semid; /* ipc semaphore id */ 61 75 int log_shmid; /* ipc shared memory id */ 62 76 smallint follow = getopt32(argv, "f"); 77 78 INIT_G(); 63 79 64 80 log_shmid = shmget(KEY_ID, 0, 0); … … 120 136 if (cur == shbuf_tail) { 121 137 sem_up(log_semid); 122 fflush (stdout);138 fflush_all(); 123 139 sleep(1); /* TODO: replace me with a sleep_on */ 124 140 continue; -
branches/2.2.9/mindi-busybox/sysklogd/syslogd.c
r1765 r2725 11 11 * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001 12 12 * 13 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.13 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 14 14 */ 15 15 16 /* 17 * Done in syslogd_and_logger.c: 16 18 #include "libbb.h" 17 #include <paths.h> 19 #define SYSLOG_NAMES 20 #define SYSLOG_NAMES_CONST 21 #include <syslog.h> 22 */ 23 18 24 #include <sys/un.h> 19 20 /* SYSLOG_NAMES defined to pull prioritynames[] and facilitynames[]21 * from syslog.h. Grrrr - glibc puts those in _rwdata_! :( */22 #define SYSLOG_NAMES23 #define SYSLOG_NAMES_CONST /* uclibc is saner :) */24 #include <sys/syslog.h>25 25 #include <sys/uio.h> 26 26 … … 43 43 #undef SYSLOGD_MARK 44 44 45 enum { MAX_READ = 256 }; 45 /* Write locking does not seem to be useful either */ 46 #undef SYSLOGD_WRLOCK 47 48 enum { 49 MAX_READ = CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE, 50 DNS_WAIT_SEC = 2 * 60, 51 }; 46 52 47 53 /* Semaphore operation structures */ … … 51 57 char data[1]; /* data/messages */ 52 58 }; 59 60 #if ENABLE_FEATURE_REMOTE_LOG 61 typedef struct { 62 int remoteFD; 63 unsigned last_dns_resolve; 64 len_and_sockaddr *remoteAddr; 65 const char *remoteHostname; 66 } remoteHost_t; 67 #endif 53 68 54 69 /* Allows us to have smaller initializer. Ugly. */ … … 60 75 /* level of messages to be logged */ \ 61 76 int logLevel; \ 62 USE_FEATURE_ROTATE_LOGFILE( \77 IF_FEATURE_ROTATE_LOGFILE( \ 63 78 /* max size of file before rotation */ \ 64 79 unsigned logFileSize; \ … … 68 83 smallint isRegular; \ 69 84 ) \ 70 USE_FEATURE_REMOTE_LOG( \ 71 /* udp socket for remote logging */ \ 72 int remoteFD; \ 73 len_and_sockaddr* remoteAddr; \ 74 ) \ 75 USE_FEATURE_IPC_SYSLOG( \ 85 IF_FEATURE_IPC_SYSLOG( \ 76 86 int shmid; /* ipc shared memory id */ \ 77 87 int s_semid; /* ipc semaphore id */ \ … … 87 97 struct globals { 88 98 GLOBALS 99 100 #if ENABLE_FEATURE_REMOTE_LOG 101 llist_t *remoteHosts; 102 #endif 89 103 #if ENABLE_FEATURE_IPC_SYSLOG 90 104 struct shbuf_ds *shbuf; 91 105 #endif 92 106 time_t last_log_time; 93 /* localhost's name */94 char localHostName[64];107 /* localhost's name. We print only first 64 chars */ 108 char *hostname; 95 109 96 110 /* We recv into recvbuf... */ 97 char recvbuf[MAX_READ ];111 char recvbuf[MAX_READ * (1 + ENABLE_FEATURE_SYSLOGD_DUP)]; 98 112 /* ...then copy to parsebuf, escaping control chars */ 99 113 /* (can grow x2 max) */ … … 116 130 .logFileRotate = 1, 117 131 #endif 118 #if ENABLE_FEATURE_REMOTE_LOG119 .remoteFD = -1,120 #endif121 132 #if ENABLE_FEATURE_IPC_SYSLOG 122 133 .shmid = -1, … … 129 140 130 141 #define G (*ptr_to_globals) 142 #define INIT_G() do { \ 143 SET_PTR_TO_GLOBALS(memcpy(xzalloc(sizeof(G)), &init_data, sizeof(init_data))); \ 144 } while (0) 131 145 132 146 … … 138 152 OPTBIT_loglevel, // -l 139 153 OPTBIT_small, // -S 140 USE_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize ,) // -s 141 USE_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt ,) // -b 142 USE_FEATURE_REMOTE_LOG( OPTBIT_remote ,) // -R 143 USE_FEATURE_REMOTE_LOG( OPTBIT_localtoo ,) // -L 144 USE_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C 154 IF_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize ,) // -s 155 IF_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt ,) // -b 156 IF_FEATURE_REMOTE_LOG( OPTBIT_remotelog ,) // -R 157 IF_FEATURE_REMOTE_LOG( OPTBIT_locallog ,) // -L 158 IF_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C 159 IF_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D 145 160 146 161 OPT_mark = 1 << OPTBIT_mark , … … 149 164 OPT_loglevel = 1 << OPTBIT_loglevel, 150 165 OPT_small = 1 << OPTBIT_small , 151 OPT_filesize = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize )) + 0, 152 OPT_rotatecnt = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt )) + 0, 153 OPT_remotelog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_remote )) + 0, 154 OPT_locallog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_localtoo )) + 0, 155 OPT_circularlog = USE_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, 166 OPT_filesize = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize )) + 0, 167 OPT_rotatecnt = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt )) + 0, 168 OPT_remotelog = IF_FEATURE_REMOTE_LOG( (1 << OPTBIT_remotelog )) + 0, 169 OPT_locallog = IF_FEATURE_REMOTE_LOG( (1 << OPTBIT_locallog )) + 0, 170 OPT_circularlog = IF_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, 171 OPT_dup = IF_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0, 156 172 }; 157 173 #define OPTION_STR "m:nO:l:S" \ 158 USE_FEATURE_ROTATE_LOGFILE("s:" ) \ 159 USE_FEATURE_ROTATE_LOGFILE("b:" ) \ 160 USE_FEATURE_REMOTE_LOG( "R:" ) \ 161 USE_FEATURE_REMOTE_LOG( "L" ) \ 162 USE_FEATURE_IPC_SYSLOG( "C::") 174 IF_FEATURE_ROTATE_LOGFILE("s:" ) \ 175 IF_FEATURE_ROTATE_LOGFILE("b:" ) \ 176 IF_FEATURE_REMOTE_LOG( "R:" ) \ 177 IF_FEATURE_REMOTE_LOG( "L" ) \ 178 IF_FEATURE_IPC_SYSLOG( "C::") \ 179 IF_FEATURE_SYSLOGD_DUP( "D" ) 163 180 #define OPTION_DECL *opt_m, *opt_l \ 164 USE_FEATURE_ROTATE_LOGFILE(,*opt_s) \ 165 USE_FEATURE_ROTATE_LOGFILE(,*opt_b) \ 166 USE_FEATURE_REMOTE_LOG( ,*opt_R) \ 167 USE_FEATURE_IPC_SYSLOG( ,*opt_C = NULL) 181 IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \ 182 IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \ 183 IF_FEATURE_IPC_SYSLOG( ,*opt_C = NULL) 168 184 #define OPTION_PARAM &opt_m, &G.logFilePath, &opt_l \ 169 USE_FEATURE_ROTATE_LOGFILE(,&opt_s) \170 USE_FEATURE_ROTATE_LOGFILE(,&opt_b) \171 USE_FEATURE_REMOTE_LOG( ,&opt_R) \172 USE_FEATURE_IPC_SYSLOG( ,&opt_C)185 IF_FEATURE_ROTATE_LOGFILE(,&opt_s) \ 186 IF_FEATURE_ROTATE_LOGFILE(,&opt_b) \ 187 IF_FEATURE_REMOTE_LOG( ,&remoteAddrList) \ 188 IF_FEATURE_IPC_SYSLOG( ,&opt_C) 173 189 174 190 … … 181 197 #endif 182 198 183 /* our shared key */184 #define KEY_ID ((long)0x414e4547)/* "GENA" */199 /* our shared key (syslogd.c and logread.c must be in sync) */ 200 enum { KEY_ID = 0x414e4547 }; /* "GENA" */ 185 201 186 202 static void ipcsyslog_cleanup(void) … … 200 216 { 201 217 if (DEBUG) 202 printf("shmget(% lx, %d,...)\n",KEY_ID, G.shm_size);218 printf("shmget(%x, %d,...)\n", (int)KEY_ID, G.shm_size); 203 219 204 220 G.shmid = shmget(KEY_ID, G.shm_size, IPC_CREAT | 0644); … … 208 224 209 225 G.shbuf = shmat(G.shmid, NULL, 0); 210 if ( !G.shbuf) {226 if (G.shbuf == (void*) -1L) { /* shmat has bizarre error return */ 211 227 bb_perror_msg_and_die("shmat"); 212 228 } … … 275 291 276 292 /* Print a message to the log file. */ 277 static void log_locally(char *msg) 278 { 293 static void log_locally(time_t now, char *msg) 294 { 295 #ifdef SYSLOGD_WRLOCK 279 296 struct flock fl; 297 #endif 280 298 int len = strlen(msg); 281 299 … … 287 305 #endif 288 306 if (G.logFD >= 0) { 289 time_t cur; 290 time(&cur); 291 if (G.last_log_time != cur) { 292 G.last_log_time = cur; /* reopen log file every second */ 307 /* Reopen log file every second. This allows admin 308 * to delete the file and not worry about restarting us. 309 * This costs almost nothing since it happens 310 * _at most_ once a second. 311 */ 312 if (!now) 313 now = time(NULL); 314 if (G.last_log_time != now) { 315 G.last_log_time = now; 293 316 close(G.logFD); 294 317 goto reopen; … … 296 319 } else { 297 320 reopen: 298 G.logFD = device_open(G.logFilePath, O_WRONLY | O_CREAT 299 | O_NOCTTY | O_APPEND | O_NONBLOCK); 321 G.logFD = open(G.logFilePath, O_WRONLY | O_CREAT 322 | O_NOCTTY | O_APPEND | O_NONBLOCK, 323 0666); 300 324 if (G.logFD < 0) { 301 325 /* cannot open logfile? - print to /dev/console then */ 302 int fd = device_open( _PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK);326 int fd = device_open(DEV_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK); 303 327 if (fd < 0) 304 328 fd = 2; /* then stderr, dammit */ … … 318 342 } 319 343 344 #ifdef SYSLOGD_WRLOCK 320 345 fl.l_whence = SEEK_SET; 321 346 fl.l_start = 0; … … 323 348 fl.l_type = F_WRLCK; 324 349 fcntl(G.logFD, F_SETLKW, &fl); 350 #endif 325 351 326 352 #if ENABLE_FEATURE_ROTATE_LOGFILE … … 336 362 if (i == 0) break; 337 363 sprintf(oldFile, "%s.%d", G.logFilePath, --i); 364 /* ignore errors - file might be missing */ 338 365 rename(oldFile, newFile); 339 366 } 340 367 /* newFile == "f.0" now */ 341 368 rename(G.logFilePath, newFile); 369 #ifdef SYSLOGD_WRLOCK 342 370 fl.l_type = F_UNLCK; 343 371 fcntl(G.logFD, F_SETLKW, &fl); 372 #endif 344 373 close(G.logFD); 345 374 goto reopen; … … 349 378 G.curFileSize += 350 379 #endif 351 full_write(G.logFD, msg, len); 380 full_write(G.logFD, msg, len); 381 #ifdef SYSLOGD_WRLOCK 352 382 fl.l_type = F_UNLCK; 353 383 fcntl(G.logFD, F_SETLKW, &fl); 384 #endif 354 385 } 355 386 … … 362 393 while (c_fac->c_name) { 363 394 if (c_fac->c_val != (LOG_FAC(pri) << 3)) { 364 c_fac++; continue; 395 c_fac++; 396 continue; 365 397 } 366 398 /* facility is found, look for prio */ … … 368 400 while (c_pri->c_name) { 369 401 if (c_pri->c_val != LOG_PRI(pri)) { 370 c_pri++; continue; 402 c_pri++; 403 continue; 371 404 } 372 405 snprintf(res20, 20, "%s.%s", … … 382 415 383 416 /* len parameter is used only for "is there a timestamp?" check. 384 * NB: some callers cheat and supply 0 when they know385 * that there is no timestamp, short-c utting the test. */417 * NB: some callers cheat and supply len==0 when they know 418 * that there is no timestamp, short-circuiting the test. */ 386 419 static void timestamp_and_log(int pri, char *msg, int len) 387 420 { 388 421 char *timestamp; 389 422 time_t now; 423 424 /* Jan 18 00:11:22 msg... */ 425 /* 01234567890123456 */ 390 426 if (len < 16 || msg[3] != ' ' || msg[6] != ' ' 391 427 || msg[9] != ':' || msg[12] != ':' || msg[15] != ' ' 392 428 ) { 393 time_t now;394 429 time(&now); 395 timestamp = ctime(&now) + 4; 430 timestamp = ctime(&now) + 4; /* skip day of week */ 396 431 } else { 432 now = 0; 397 433 timestamp = msg; 398 434 msg += 16; … … 400 436 timestamp[15] = '\0'; 401 437 438 if (option_mask32 & OPT_small) 439 sprintf(G.printbuf, "%s %s\n", timestamp, msg); 440 else { 441 char res[20]; 442 parse_fac_prio_20(pri, res); 443 sprintf(G.printbuf, "%s %.64s %s %s\n", timestamp, G.hostname, res, msg); 444 } 445 402 446 /* Log message locally (to file or shared mem) */ 403 if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {404 if (LOG_PRI(pri) < G.logLevel) { 405 if (option_mask32 & OPT_small) 406 sprintf(G.printbuf, "%s %s\n", timestamp, msg); 407 else{408 char res[20];409 parse_fac_prio_20(pri, res);410 sprintf(G.printbuf, "%s %s %s %s\n", timestamp, G.localHostName, res, msg);411 }412 log_locally(G.printbuf); 413 } 414 } 415 } 416 447 log_locally(now, G.printbuf); 448 } 449 450 static void timestamp_and_log_internal(const char *msg) 451 { 452 /* -L, or no -R */ 453 if (ENABLE_FEATURE_REMOTE_LOG && !(option_mask32 & OPT_locallog)) 454 return; 455 timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)msg, 0); 456 } 457 458 /* tmpbuf[len] is a NUL byte (set by caller), but there can be other, 459 * embedded NULs. Split messages on each of these NULs, parse prio, 460 * escape control chars and log each locally. */ 417 461 static void split_escape_and_log(char *tmpbuf, int len) 418 462 { … … 428 472 /* Parse the magic priority number */ 429 473 pri = bb_strtou(p + 1, &p, 10); 430 if (*p == '>') p++; 431 if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) { 474 if (*p == '>') 475 p++; 476 if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) 432 477 pri = (LOG_USER | LOG_NOTICE); 433 }434 478 } 435 479 … … 444 488 } 445 489 *q = '\0'; 490 446 491 /* Now log it */ 447 timestamp_and_log(pri, G.parsebuf, q - G.parsebuf); 448 } 449 } 450 451 static void quit_signal(int sig) 452 { 453 timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)"syslogd exiting", 0); 492 if (LOG_PRI(pri) < G.logLevel) 493 timestamp_and_log(pri, G.parsebuf, q - G.parsebuf); 494 } 495 } 496 497 #ifdef SYSLOGD_MARK 498 static void do_mark(int sig) 499 { 500 if (G.markInterval) { 501 timestamp_and_log_internal("-- MARK --"); 502 alarm(G.markInterval); 503 } 504 } 505 #endif 506 507 /* Don't inline: prevent struct sockaddr_un to take up space on stack 508 * permanently */ 509 static NOINLINE int create_socket(void) 510 { 511 struct sockaddr_un sunx; 512 int sock_fd; 513 char *dev_log_name; 514 515 memset(&sunx, 0, sizeof(sunx)); 516 sunx.sun_family = AF_UNIX; 517 518 /* Unlink old /dev/log or object it points to. */ 519 /* (if it exists, bind will fail) */ 520 strcpy(sunx.sun_path, "/dev/log"); 521 dev_log_name = xmalloc_follow_symlinks("/dev/log"); 522 if (dev_log_name) { 523 safe_strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path)); 524 free(dev_log_name); 525 } 526 unlink(sunx.sun_path); 527 528 sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0); 529 xbind(sock_fd, (struct sockaddr *) &sunx, sizeof(sunx)); 530 chmod("/dev/log", 0666); 531 532 return sock_fd; 533 } 534 535 #if ENABLE_FEATURE_REMOTE_LOG 536 static int try_to_resolve_remote(remoteHost_t *rh) 537 { 538 if (!rh->remoteAddr) { 539 unsigned now = monotonic_sec(); 540 541 /* Don't resolve name too often - DNS timeouts can be big */ 542 if ((now - rh->last_dns_resolve) < DNS_WAIT_SEC) 543 return -1; 544 rh->last_dns_resolve = now; 545 rh->remoteAddr = host2sockaddr(rh->remoteHostname, 514); 546 if (!rh->remoteAddr) 547 return -1; 548 } 549 return xsocket(rh->remoteAddr->u.sa.sa_family, SOCK_DGRAM, 0); 550 } 551 #endif 552 553 static void do_syslogd(void) NORETURN; 554 static void do_syslogd(void) 555 { 556 int sock_fd; 557 #if ENABLE_FEATURE_REMOTE_LOG 558 llist_t *item; 559 #endif 560 #if ENABLE_FEATURE_SYSLOGD_DUP 561 int last_sz = -1; 562 char *last_buf; 563 char *recvbuf = G.recvbuf; 564 #else 565 #define recvbuf (G.recvbuf) 566 #endif 567 568 /* Set up signal handlers (so that they interrupt read()) */ 569 signal_no_SA_RESTART_empty_mask(SIGTERM, record_signo); 570 signal_no_SA_RESTART_empty_mask(SIGINT, record_signo); 571 //signal_no_SA_RESTART_empty_mask(SIGQUIT, record_signo); 572 signal(SIGHUP, SIG_IGN); 573 #ifdef SYSLOGD_MARK 574 signal(SIGALRM, do_mark); 575 alarm(G.markInterval); 576 #endif 577 sock_fd = create_socket(); 578 579 if (ENABLE_FEATURE_IPC_SYSLOG && (option_mask32 & OPT_circularlog)) { 580 ipcsyslog_init(); 581 } 582 583 timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER); 584 585 while (!bb_got_signal) { 586 ssize_t sz; 587 588 #if ENABLE_FEATURE_SYSLOGD_DUP 589 last_buf = recvbuf; 590 if (recvbuf == G.recvbuf) 591 recvbuf = G.recvbuf + MAX_READ; 592 else 593 recvbuf = G.recvbuf; 594 #endif 595 read_again: 596 sz = read(sock_fd, recvbuf, MAX_READ - 1); 597 if (sz < 0) { 598 if (!bb_got_signal) 599 bb_perror_msg("read from /dev/log"); 600 break; 601 } 602 603 /* Drop trailing '\n' and NULs (typically there is one NUL) */ 604 while (1) { 605 if (sz == 0) 606 goto read_again; 607 /* man 3 syslog says: "A trailing newline is added when needed". 608 * However, neither glibc nor uclibc do this: 609 * syslog(prio, "test") sends "test\0" to /dev/log, 610 * syslog(prio, "test\n") sends "test\n\0". 611 * IOW: newline is passed verbatim! 612 * I take it to mean that it's syslogd's job 613 * to make those look identical in the log files. */ 614 if (recvbuf[sz-1] != '\0' && recvbuf[sz-1] != '\n') 615 break; 616 sz--; 617 } 618 #if ENABLE_FEATURE_SYSLOGD_DUP 619 if ((option_mask32 & OPT_dup) && (sz == last_sz)) 620 if (memcmp(last_buf, recvbuf, sz) == 0) 621 continue; 622 last_sz = sz; 623 #endif 624 #if ENABLE_FEATURE_REMOTE_LOG 625 /* Stock syslogd sends it '\n'-terminated 626 * over network, mimic that */ 627 recvbuf[sz] = '\n'; 628 629 /* We are not modifying log messages in any way before send */ 630 /* Remote site cannot trust _us_ anyway and need to do validation again */ 631 for (item = G.remoteHosts; item != NULL; item = item->link) { 632 remoteHost_t *rh = (remoteHost_t *)item->data; 633 634 if (rh->remoteFD == -1) { 635 rh->remoteFD = try_to_resolve_remote(rh); 636 if (rh->remoteFD == -1) 637 continue; 638 } 639 640 /* Send message to remote logger. 641 * On some errors, close and set remoteFD to -1 642 * so that DNS resolution is retried. 643 */ 644 if (sendto(rh->remoteFD, recvbuf, sz+1, 645 MSG_DONTWAIT | MSG_NOSIGNAL, 646 &(rh->remoteAddr->u.sa), rh->remoteAddr->len) == -1 647 ) { 648 switch (errno) { 649 case ECONNRESET: 650 case ENOTCONN: /* paranoia */ 651 case EPIPE: 652 close(rh->remoteFD); 653 rh->remoteFD = -1; 654 free(rh->remoteAddr); 655 rh->remoteAddr = NULL; 656 } 657 } 658 } 659 #endif 660 if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) { 661 recvbuf[sz] = '\0'; /* ensure it *is* NUL terminated */ 662 split_escape_and_log(recvbuf, sz); 663 } 664 } /* while (!bb_got_signal) */ 665 666 timestamp_and_log_internal("syslogd exiting"); 454 667 puts("syslogd exiting"); 455 668 if (ENABLE_FEATURE_IPC_SYSLOG) 456 669 ipcsyslog_cleanup(); 457 exit(1); 458 } 670 kill_myself_with_sig(bb_got_signal); 671 #undef recvbuf 672 } 673 674 int syslogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 675 int syslogd_main(int argc UNUSED_PARAM, char **argv) 676 { 677 int opts; 678 char OPTION_DECL; 679 #if ENABLE_FEATURE_REMOTE_LOG 680 llist_t *remoteAddrList = NULL; 681 #endif 682 683 INIT_G(); 684 685 /* No non-option params, -R can occur multiple times */ 686 opt_complementary = "=0" IF_FEATURE_REMOTE_LOG(":R::"); 687 opts = getopt32(argv, OPTION_STR, OPTION_PARAM); 688 #if ENABLE_FEATURE_REMOTE_LOG 689 while (remoteAddrList) { 690 remoteHost_t *rh = xzalloc(sizeof(*rh)); 691 rh->remoteHostname = llist_pop(&remoteAddrList); 692 rh->remoteFD = -1; 693 rh->last_dns_resolve = monotonic_sec() - DNS_WAIT_SEC - 1; 694 llist_add_to(&G.remoteHosts, rh); 695 } 696 #endif 459 697 460 698 #ifdef SYSLOGD_MARK 461 static void do_mark(int sig) 462 { 463 if (G.markInterval) { 464 timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)"-- MARK --", 0); 465 alarm(G.markInterval); 466 } 467 } 468 #endif 469 470 static void do_syslogd(void) ATTRIBUTE_NORETURN; 471 static void do_syslogd(void) 472 { 473 struct sockaddr_un sunx; 474 int sock_fd; 475 fd_set fds; 476 char *dev_log_name; 477 478 /* Set up signal handlers */ 479 signal(SIGINT, quit_signal); 480 signal(SIGTERM, quit_signal); 481 signal(SIGQUIT, quit_signal); 482 signal(SIGHUP, SIG_IGN); 483 signal(SIGCHLD, SIG_IGN); 484 #ifdef SIGCLD 485 signal(SIGCLD, SIG_IGN); 486 #endif 487 #ifdef SYSLOGD_MARK 488 signal(SIGALRM, do_mark); 489 alarm(G.markInterval); 490 #endif 491 remove_pidfile("/var/run/syslogd.pid"); 492 493 memset(&sunx, 0, sizeof(sunx)); 494 sunx.sun_family = AF_UNIX; 495 strcpy(sunx.sun_path, "/dev/log"); 496 497 /* Unlink old /dev/log or object it points to. */ 498 /* (if it exists, bind will fail) */ 499 logmode = LOGMODE_NONE; 500 dev_log_name = xmalloc_readlink_or_warn("/dev/log"); 501 logmode = LOGMODE_STDIO; 502 if (dev_log_name) { 503 int fd = xopen(".", O_NONBLOCK); 504 xchdir("/dev"); 505 /* we do not check whether this is a link also */ 506 unlink(dev_log_name); 507 fchdir(fd); 508 close(fd); 509 safe_strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path)); 510 free(dev_log_name); 511 } else { 512 unlink("/dev/log"); 513 } 514 515 sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0); 516 xbind(sock_fd, (struct sockaddr *) &sunx, sizeof(sunx)); 517 518 if (chmod("/dev/log", 0666) < 0) { 519 bb_perror_msg_and_die("cannot set permission on /dev/log"); 520 } 521 if (ENABLE_FEATURE_IPC_SYSLOG && (option_mask32 & OPT_circularlog)) { 522 ipcsyslog_init(); 523 } 524 525 timestamp_and_log(LOG_SYSLOG | LOG_INFO, 526 (char*)"syslogd started: BusyBox v" BB_VER, 0); 527 528 for (;;) { 529 FD_ZERO(&fds); 530 FD_SET(sock_fd, &fds); 531 532 if (select(sock_fd + 1, &fds, NULL, NULL, NULL) < 0) { 533 if (errno == EINTR) { 534 /* alarm may have happened */ 535 continue; 536 } 537 bb_perror_msg_and_die("select"); 538 } 539 540 if (FD_ISSET(sock_fd, &fds)) { 541 int i; 542 i = recv(sock_fd, G.recvbuf, MAX_READ - 1, 0); 543 if (i <= 0) 544 bb_perror_msg_and_die("UNIX socket error"); 545 /* TODO: maybe suppress duplicates? */ 546 #if ENABLE_FEATURE_REMOTE_LOG 547 /* We are not modifying log messages in any way before send */ 548 /* Remote site cannot trust _us_ anyway and need to do validation again */ 549 if (G.remoteAddr) { 550 if (-1 == G.remoteFD) { 551 G.remoteFD = socket(G.remoteAddr->sa.sa_family, SOCK_DGRAM, 0); 552 } 553 if (-1 != G.remoteFD) { 554 /* send message to remote logger, ignore possible error */ 555 sendto(G.remoteFD, G.recvbuf, i, MSG_DONTWAIT, 556 &G.remoteAddr->sa, G.remoteAddr->len); 557 } 558 } 559 #endif 560 G.recvbuf[i] = '\0'; 561 split_escape_and_log(G.recvbuf, i); 562 } /* FD_ISSET() */ 563 } /* for */ 564 } 565 566 int syslogd_main(int argc, char **argv); 567 int syslogd_main(int argc, char **argv) 568 { 569 char OPTION_DECL; 570 char *p; 571 572 PTR_TO_GLOBALS = memcpy(xzalloc(sizeof(G)), &init_data, sizeof(init_data)); 573 574 /* do normal option parsing */ 575 opt_complementary = "=0"; /* no non-option params */ 576 getopt32(argv, OPTION_STR, OPTION_PARAM); 577 #ifdef SYSLOGD_MARK 578 if (option_mask32 & OPT_mark) // -m 699 if (opts & OPT_mark) // -m 579 700 G.markInterval = xatou_range(opt_m, 0, INT_MAX/60) * 60; 580 701 #endif 581 //if (opt ion_mask32& OPT_nofork) // -n582 //if (opt ion_mask32& OPT_outfile) // -O583 if (opt ion_mask32& OPT_loglevel) // -l702 //if (opts & OPT_nofork) // -n 703 //if (opts & OPT_outfile) // -O 704 if (opts & OPT_loglevel) // -l 584 705 G.logLevel = xatou_range(opt_l, 1, 8); 585 //if (opt ion_mask32& OPT_small) // -S706 //if (opts & OPT_small) // -S 586 707 #if ENABLE_FEATURE_ROTATE_LOGFILE 587 if (opt ion_mask32& OPT_filesize) // -s708 if (opts & OPT_filesize) // -s 588 709 G.logFileSize = xatou_range(opt_s, 0, INT_MAX/1024) * 1024; 589 if (opt ion_mask32& OPT_rotatecnt) // -b710 if (opts & OPT_rotatecnt) // -b 590 711 G.logFileRotate = xatou_range(opt_b, 0, 99); 591 #endif592 #if ENABLE_FEATURE_REMOTE_LOG593 if (option_mask32 & OPT_remotelog) { // -R594 G.remoteAddr = xhost2sockaddr(opt_R, 514);595 }596 //if (option_mask32 & OPT_locallog) // -L597 712 #endif 598 713 #if ENABLE_FEATURE_IPC_SYSLOG … … 602 717 603 718 /* If they have not specified remote logging, then log locally */ 604 if (ENABLE_FEATURE_REMOTE_LOG && !(opt ion_mask32 & OPT_remotelog))719 if (ENABLE_FEATURE_REMOTE_LOG && !(opts & OPT_remotelog)) // -R 605 720 option_mask32 |= OPT_locallog; 606 721 607 722 /* Store away localhost's name before the fork */ 608 gethostname(G.localHostName, sizeof(G.localHostName)); 609 p = strchr(G.localHostName, '.'); 610 if (p) { 611 *p = '\0'; 612 } 613 614 if (!(option_mask32 & OPT_nofork)) { 723 G.hostname = safe_gethostname(); 724 *strchrnul(G.hostname, '.') = '\0'; 725 726 if (!(opts & OPT_nofork)) { 615 727 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); 616 728 } 617 umask(0);729 //umask(0); - why?? 618 730 write_pidfile("/var/run/syslogd.pid"); 619 731 do_syslogd(); 620 732 /* return EXIT_SUCCESS; */ 621 733 } 734 735 /* Clean up. Needed because we are included from syslogd_and_logger.c */ 736 #undef DEBUG 737 #undef SYSLOGD_MARK 738 #undef SYSLOGD_WRLOCK 739 #undef G 740 #undef GLOBALS 741 #undef INIT_G 742 #undef OPTION_STR 743 #undef OPTION_DECL 744 #undef OPTION_PARAM
Note:
See TracChangeset
for help on using the changeset viewer.