X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=sysklogd%2Fsyslogd.c;h=ab50f4a28e701daba3e85aed3165781ca4d66b19;hb=fb957125d8aa83c9df6e54292327983a51ee7ffd;hp=0799038e94439f4f03bedd17ba17c694d1e36cb3;hpb=e9c8bed4d3b157097e89ee2611ca731e37ce8d7d;p=oweals%2Fbusybox.git diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 0799038e9..ab50f4a28 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -12,29 +12,150 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config SYSLOGD +//config: bool "syslogd (13 kb)" +//config: default y +//config: help +//config: The syslogd utility is used to record logs of all the +//config: significant events that occur on a system. Every +//config: message that is logged records the date and time of the +//config: event, and will generally also record the name of the +//config: application that generated the message. When used in +//config: conjunction with klogd, messages from the Linux kernel +//config: can also be recorded. This is terribly useful, +//config: especially for finding what happened when something goes +//config: wrong. And something almost always will go wrong if +//config: you wait long enough.... +//config: +//config:config FEATURE_ROTATE_LOGFILE +//config: bool "Rotate message files" +//config: default y +//config: depends on SYSLOGD +//config: help +//config: This enables syslogd to rotate the message files +//config: on his own. No need to use an external rotate script. +//config: +//config:config FEATURE_REMOTE_LOG +//config: bool "Remote Log support" +//config: default y +//config: depends on SYSLOGD +//config: help +//config: When you enable this feature, the syslogd utility can +//config: be used to send system log messages to another system +//config: connected via a network. This allows the remote +//config: machine to log all the system messages, which can be +//config: terribly useful for reducing the number of serial +//config: cables you use. It can also be a very good security +//config: measure to prevent system logs from being tampered with +//config: by an intruder. +//config: +//config:config FEATURE_SYSLOGD_DUP +//config: bool "Support -D (drop dups) option" +//config: default y +//config: depends on SYSLOGD +//config: help +//config: Option -D instructs syslogd to drop consecutive messages +//config: which are totally the same. +//config: +//config:config FEATURE_SYSLOGD_CFG +//config: bool "Support syslog.conf" +//config: default y +//config: depends on SYSLOGD +//config: help +//config: Supports restricted syslogd config. See docs/syslog.conf.txt +//config: +//config:config FEATURE_SYSLOGD_PRECISE_TIMESTAMPS +//config: bool "Include milliseconds in timestamps" +//config: default n +//config: depends on SYSLOGD +//config: help +//config: Includes milliseconds (HH:MM:SS.mmm) in timestamp when +//config: timestamps are added. +//config: +//config:config FEATURE_SYSLOGD_READ_BUFFER_SIZE +//config: int "Read buffer size in bytes" +//config: default 256 +//config: range 256 20000 +//config: depends on SYSLOGD +//config: help +//config: This option sets the size of the syslog read buffer. +//config: Actual memory usage increases around five times the +//config: change done here. +//config: +//config:config FEATURE_IPC_SYSLOG +//config: bool "Circular Buffer support" +//config: default y +//config: depends on SYSLOGD +//config: help +//config: When you enable this feature, the syslogd utility will +//config: use a circular buffer to record system log messages. +//config: When the buffer is filled it will continue to overwrite +//config: the oldest messages. This can be very useful for +//config: systems with little or no permanent storage, since +//config: otherwise system logs can eventually fill up your +//config: entire filesystem, which may cause your system to +//config: break badly. +//config: +//config:config FEATURE_IPC_SYSLOG_BUFFER_SIZE +//config: int "Circular buffer size in Kbytes (minimum 4KB)" +//config: default 16 +//config: range 4 2147483647 +//config: depends on FEATURE_IPC_SYSLOG +//config: help +//config: This option sets the size of the circular buffer +//config: used to record system log messages. +//config: +//config:config FEATURE_KMSG_SYSLOG +//config: bool "Linux kernel printk buffer support" +//config: default y +//config: depends on SYSLOGD +//config: select PLATFORM_LINUX +//config: help +//config: When you enable this feature, the syslogd utility will +//config: write system log message to the Linux kernel's printk buffer. +//config: This can be used as a smaller alternative to the syslogd IPC +//config: support, as klogd and logread aren't needed. +//config: +//config: NOTICE: Syslog facilities in log entries needs kernel 3.5+. + +//applet:IF_SYSLOGD(APPLET(syslogd, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SYSLOGD) += syslogd_and_logger.o //usage:#define syslogd_trivial_usage //usage: "[OPTIONS]" //usage:#define syslogd_full_usage "\n\n" -//usage: "System logging utility.\n" -//usage: "This version of syslogd ignores /etc/syslog.conf\n" -//usage: "\nOptions:" +//usage: "System logging utility\n" +//usage: IF_NOT_FEATURE_SYSLOGD_CFG( +//usage: "(this version of syslogd ignores /etc/syslog.conf)\n" +//usage: ) //usage: "\n -n Run in foreground" -//usage: "\n -O FILE Log to given file (default:/var/log/messages)" -//usage: "\n -l N Set local log level" -//usage: "\n -S Smaller logging output" -//usage: IF_FEATURE_ROTATE_LOGFILE( -//usage: "\n -s SIZE Max size (KB) before rotate (default:200KB, 0=off)" -//usage: "\n -b N N rotated logs to keep (default:1, max=99, 0=purge)") //usage: IF_FEATURE_REMOTE_LOG( -//usage: "\n -R HOST[:PORT] Log to IP or hostname on PORT (default PORT=514/UDP)" -//usage: "\n -L Log locally and via network (default is network only if -R)") -//usage: IF_FEATURE_SYSLOGD_DUP( -//usage: "\n -D Drop duplicates") +//usage: "\n -R HOST[:PORT] Log to HOST:PORT (default PORT:514)" +//usage: "\n -L Log locally and via network (default is network only if -R)" +//usage: ) //usage: IF_FEATURE_IPC_SYSLOG( -//usage: "\n -C[size(KiB)] Log to shared mem buffer (read it using logread)") /* NB: -Csize shouldn't have space (because size is optional) */ -/* //usage: "\n -m MIN Minutes between MARK lines (default:20, 0=off)" */ +//usage: "\n -C[size_kb] Log to shared mem buffer (use logread to read it)" +//usage: ) +//usage: IF_FEATURE_KMSG_SYSLOG( +//usage: "\n -K Log to kernel printk buffer (use dmesg to read it)" +//usage: ) +//usage: "\n -O FILE Log to FILE (default: /var/log/messages, stdout if -)" +//usage: IF_FEATURE_ROTATE_LOGFILE( +//usage: "\n -s SIZE Max size (KB) before rotation (default 200KB, 0=off)" +//usage: "\n -b N N rotated logs to keep (default 1, max 99, 0=purge)" +//usage: ) +//usage: "\n -l N Log only messages more urgent than prio N (1-8)" +//usage: "\n -S Smaller output" +//usage: "\n -t Strip client-generated timestamps" +//usage: IF_FEATURE_SYSLOGD_DUP( +//usage: "\n -D Drop duplicates" +//usage: ) +//usage: IF_FEATURE_SYSLOGD_CFG( +//usage: "\n -f FILE Use FILE as config (default:/etc/syslog.conf)" +//usage: ) +/* //usage: "\n -m MIN Minutes between MARK lines (default 20, 0=off)" */ //usage: //usage:#define syslogd_example_usage //usage: "$ syslogd -R masterlog:514\n" @@ -47,6 +168,9 @@ #define SYSLOG_NAMES_CONST #include */ +#ifndef _PATH_LOG +#define _PATH_LOG "/dev/log" +#endif #include #include @@ -96,6 +220,7 @@ typedef struct { typedef struct logFile_t { const char *path; int fd; + time_t last_log_time; #if ENABLE_FEATURE_ROTATE_LOGFILE unsigned size; uint8_t isRegular; @@ -132,6 +257,10 @@ IF_FEATURE_IPC_SYSLOG( \ ) \ IF_FEATURE_SYSLOGD_CFG( \ logRule_t *log_rules; \ +) \ +IF_FEATURE_KMSG_SYSLOG( \ + int kmsgfd; \ + int primask; \ ) struct init_globals { @@ -147,7 +276,6 @@ struct globals { #if ENABLE_FEATURE_IPC_SYSLOG struct shbuf_ds *shbuf; #endif - time_t last_log_time; /* localhost's name. We print only first 64 chars */ char *hostname; @@ -156,7 +284,7 @@ struct globals { /* ...then copy to parsebuf, escaping control chars */ /* (can grow x2 max) */ char parsebuf[MAX_READ*2]; - /* ...then sprintf into printbuf, adding timestamp (15 chars), + /* ...then sprintf into printbuf, adding timestamp (15 or 19 chars), * host (64), fac.prio (20) to the message */ /* (growth by: 15 + 64 + 20 + delims = ~110) */ char printbuf[MAX_READ*2 + 128]; @@ -197,6 +325,7 @@ enum { OPTBIT_outfile, // -O OPTBIT_loglevel, // -l OPTBIT_small, // -S + OPTBIT_timestamp, // -t IF_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize ,) // -s IF_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt ,) // -b IF_FEATURE_REMOTE_LOG( OPTBIT_remotelog ,) // -R @@ -204,12 +333,14 @@ enum { IF_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C IF_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D IF_FEATURE_SYSLOGD_CFG( OPTBIT_cfg ,) // -f + IF_FEATURE_KMSG_SYSLOG( OPTBIT_kmsg ,) // -K OPT_mark = 1 << OPTBIT_mark , OPT_nofork = 1 << OPTBIT_nofork , OPT_outfile = 1 << OPTBIT_outfile , OPT_loglevel = 1 << OPTBIT_loglevel, OPT_small = 1 << OPTBIT_small , + OPT_timestamp = 1 << OPTBIT_timestamp, OPT_filesize = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize )) + 0, OPT_rotatecnt = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt )) + 0, OPT_remotelog = IF_FEATURE_REMOTE_LOG( (1 << OPTBIT_remotelog )) + 0, @@ -217,15 +348,17 @@ enum { OPT_circularlog = IF_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, OPT_dup = IF_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0, OPT_cfg = IF_FEATURE_SYSLOGD_CFG( (1 << OPTBIT_cfg )) + 0, + OPT_kmsg = IF_FEATURE_KMSG_SYSLOG( (1 << OPTBIT_kmsg )) + 0, }; -#define OPTION_STR "m:nO:l:S" \ +#define OPTION_STR "m:nO:l:St" \ IF_FEATURE_ROTATE_LOGFILE("s:" ) \ IF_FEATURE_ROTATE_LOGFILE("b:" ) \ - IF_FEATURE_REMOTE_LOG( "R:" ) \ + IF_FEATURE_REMOTE_LOG( "R:*") \ IF_FEATURE_REMOTE_LOG( "L" ) \ IF_FEATURE_IPC_SYSLOG( "C::") \ IF_FEATURE_SYSLOGD_DUP( "D" ) \ - IF_FEATURE_SYSLOGD_CFG( "f:" ) + IF_FEATURE_SYSLOGD_CFG( "f:" ) \ + IF_FEATURE_KMSG_SYSLOG( "K" ) #define OPTION_DECL *opt_m, *opt_l \ IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \ IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \ @@ -234,7 +367,7 @@ enum { #define OPTION_PARAM &opt_m, &(G.logFile.path), &opt_l \ IF_FEATURE_ROTATE_LOGFILE(,&opt_s) \ IF_FEATURE_ROTATE_LOGFILE(,&opt_b) \ - IF_FEATURE_REMOTE_LOG( ,&remoteAddrList) \ + IF_FEATURE_REMOTE_LOG( ,&remoteAddrList) \ IF_FEATURE_IPC_SYSLOG( ,&opt_C) \ IF_FEATURE_SYSLOGD_CFG( ,&opt_f) @@ -270,7 +403,7 @@ static void parse_syslogdcfg(const char *file) parser_t *parser; parser = config_open2(file ? file : "/etc/syslog.conf", - file ? xfopen_for_read : fopen_or_warn_stdin); + file ? xfopen_for_read : fopen_for_read); if (!parser) /* didn't find default /etc/syslog.conf */ /* proceed as if we built busybox without config support */ @@ -284,10 +417,8 @@ static void parse_syslogdcfg(const char *file) logRule_t *cur_rule; /* unexpected trailing token? */ - if (tok[2]) { - t = tok[2]; + if (tok[2]) goto cfgerr; - } cur_rule = *pp_rule = xzalloc(sizeof(*cur_rule)); @@ -307,10 +438,8 @@ static void parse_syslogdcfg(const char *file) *next_selector++ = '\0'; t = strchr(cur_selector, '.'); - if (!t) { - t = cur_selector; + if (!t) goto cfgerr; - } *t++ = '\0'; /* separate facility from priority */ negated_prio = 0; @@ -329,7 +458,7 @@ static void parse_syslogdcfg(const char *file) primap = 0xff; /* all 8 log levels enabled */ else { uint8_t priority; - code = find_by_name(t, prioritynames); + code = find_by_name(t, bb_prioritynames); if (!code) goto cfgerr; primap = 0; @@ -362,7 +491,7 @@ static void parse_syslogdcfg(const char *file) next_facility = strchr(t, ','); if (next_facility) *next_facility++ = '\0'; - code = find_by_name(t, facilitynames); + code = find_by_name(t, bb_facilitynames); if (!code) goto cfgerr; /* "mark" is not a real facility, skip it */ @@ -414,7 +543,9 @@ static void parse_syslogdcfg(const char *file) return; cfgerr: - bb_error_msg_and_die("bad line %d: wrong token '%s'", parser->lineno, t); + bb_error_msg_and_die("error in '%s' at line %d", + file ? file : "/etc/syslog.conf", + parser->lineno); } #endif @@ -449,12 +580,12 @@ static void ipcsyslog_init(void) G.shmid = shmget(KEY_ID, G.shm_size, IPC_CREAT | 0644); if (G.shmid == -1) { - bb_perror_msg_and_die("shmget"); + bb_simple_perror_msg_and_die("shmget"); } G.shbuf = shmat(G.shmid, NULL, 0); if (G.shbuf == (void*) -1L) { /* shmat has bizarre error return */ - bb_perror_msg_and_die("shmat"); + bb_simple_perror_msg_and_die("shmat"); } memset(G.shbuf, 0, G.shm_size); @@ -469,7 +600,7 @@ static void ipcsyslog_init(void) if (G.s_semid != -1) return; } - bb_perror_msg_and_die("semget"); + bb_simple_perror_msg_and_die("semget"); } } @@ -480,7 +611,7 @@ static void log_to_shmem(const char *msg) int len; if (semop(G.s_semid, G.SMwdn, 3) == -1) { - bb_perror_msg_and_die("SMwdn"); + bb_simple_perror_msg_and_die("SMwdn"); } /* Circular Buffer Algorithm: @@ -508,17 +639,55 @@ static void log_to_shmem(const char *msg) goto again; } if (semop(G.s_semid, G.SMwup, 1) == -1) { - bb_perror_msg_and_die("SMwup"); + bb_simple_perror_msg_and_die("SMwup"); } if (DEBUG) printf("tail:%d\n", G.shbuf->tail); } #else -void ipcsyslog_cleanup(void); -void ipcsyslog_init(void); +static void ipcsyslog_cleanup(void) {} +static void ipcsyslog_init(void) {} void log_to_shmem(const char *msg); #endif /* FEATURE_IPC_SYSLOG */ +#if ENABLE_FEATURE_KMSG_SYSLOG +static void kmsg_init(void) +{ + G.kmsgfd = xopen("/dev/kmsg", O_WRONLY); + + /* + * kernel < 3.5 expects single char printk KERN_* priority prefix, + * from 3.5 onwards the full syslog facility/priority format is supported + */ + if (get_linux_version_code() < KERNEL_VERSION(3,5,0)) + G.primask = LOG_PRIMASK; + else + G.primask = -1; +} + +static void kmsg_cleanup(void) +{ + if (ENABLE_FEATURE_CLEAN_UP) + close(G.kmsgfd); +} + +/* Write message to /dev/kmsg */ +static void log_to_kmsg(int pri, const char *msg) +{ + /* + * kernel < 3.5 expects single char printk KERN_* priority prefix, + * from 3.5 onwards the full syslog facility/priority format is supported + */ + pri &= G.primask; + + full_write(G.kmsgfd, G.printbuf, sprintf(G.printbuf, "<%d>%s\n", pri, msg)); +} +#else +static void kmsg_init(void) {} +static void kmsg_cleanup(void) {} +static void log_to_kmsg(int pri UNUSED_PARAM, const char *msg UNUSED_PARAM) {} +#endif /* FEATURE_KMSG_SYSLOG */ + /* Print a message to the log file. */ static void log_locally(time_t now, char *msg, logFile_t *log_file) { @@ -527,42 +696,54 @@ static void log_locally(time_t now, char *msg, logFile_t *log_file) #endif int len = strlen(msg); - if (log_file->fd >= 0) { - /* Reopen log file every second. This allows admin - * to delete the file and not worry about restarting us. + /* fd can't be 0 (we connect fd 0 to /dev/log socket) */ + /* fd is 1 if "-O -" is in use */ + if (log_file->fd > 1) { + /* Reopen log files every second. This allows admin + * to delete the files and not worry about restarting us. * This costs almost nothing since it happens - * _at most_ once a second. + * _at most_ once a second for each file, and happens + * only when each file is actually written. */ if (!now) now = time(NULL); - if (G.last_log_time != now) { - G.last_log_time = now; + if (log_file->last_log_time != now) { + log_file->last_log_time = now; close(log_file->fd); goto reopen; } - } else { + } + else if (log_file->fd == 1) { + /* We are logging to stdout: do nothing */ + } + else { + if (LONE_DASH(log_file->path)) { + log_file->fd = 1; + /* log_file->isRegular = 0; - already is */ + } else { reopen: - log_file->fd = open(log_file->path, O_WRONLY | O_CREAT + log_file->fd = open(log_file->path, O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND | O_NONBLOCK, 0666); - if (log_file->fd < 0) { - /* cannot open logfile? - print to /dev/console then */ - int fd = device_open(DEV_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK); - if (fd < 0) - fd = 2; /* then stderr, dammit */ - full_write(fd, msg, len); - if (fd != 2) - close(fd); - return; - } + if (log_file->fd < 0) { + /* cannot open logfile? - print to /dev/console then */ + int fd = device_open(DEV_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK); + if (fd < 0) + fd = 2; /* then stderr, dammit */ + full_write(fd, msg, len); + if (fd != 2) + close(fd); + return; + } #if ENABLE_FEATURE_ROTATE_LOGFILE - { - struct stat statf; - log_file->isRegular = (fstat(log_file->fd, &statf) == 0 && S_ISREG(statf.st_mode)); - /* bug (mostly harmless): can wrap around if file > 4gb */ - log_file->size = statf.st_size; - } + { + struct stat statf; + log_file->isRegular = (fstat(log_file->fd, &statf) == 0 && S_ISREG(statf.st_mode)); + /* bug (mostly harmless): can wrap around if file > 4gb */ + log_file->size = statf.st_size; + } #endif + } } #ifdef SYSLOGD_WRLOCK @@ -590,18 +771,33 @@ static void log_locally(time_t now, char *msg, logFile_t *log_file) } /* newFile == "f.0" now */ rename(log_file->path, newFile); + } + + /* We may or may not have just renamed the file away; + * if we didn't rename because we aren't keeping any backlog, + * then it's time to clobber the file. If we did rename it..., + * incredibly, if F and F.0 are hardlinks, POSIX _demands_ + * that rename returns 0 but does not remove F!!! + * (hardlinked F/F.0 pair was observed after + * power failure during rename()). + * So ensure old file is gone in any case: + */ + unlink(log_file->path); #ifdef SYSLOGD_WRLOCK - fl.l_type = F_UNLCK; - fcntl(log_file->fd, F_SETLKW, &fl); + fl.l_type = F_UNLCK; + fcntl(log_file->fd, F_SETLKW, &fl); #endif - close(log_file->fd); - goto reopen; - } - ftruncate(log_file->fd, 0); + close(log_file->fd); + goto reopen; } - log_file->size += +/* TODO: what to do on write errors ("disk full")? */ + len = full_write(log_file->fd, msg, len); + if (len > 0) + log_file->size += len; +#else + full_write(log_file->fd, msg, len); #endif - full_write(log_file->fd, msg, len); + #ifdef SYSLOGD_WRLOCK fl.l_type = F_UNLCK; fcntl(log_file->fd, F_SETLKW, &fl); @@ -612,9 +808,9 @@ static void parse_fac_prio_20(int pri, char *res20) { const CODE *c_pri, *c_fac; - c_fac = find_by_val(LOG_FAC(pri) << 3, facilitynames); + c_fac = find_by_val(LOG_FAC(pri) << 3, bb_facilitynames); if (c_fac) { - c_pri = find_by_val(LOG_PRI(pri), prioritynames); + c_pri = find_by_val(LOG_PRI(pri), bb_prioritynames); if (c_pri) { snprintf(res20, 20, "%s.%s", c_fac->c_name, c_pri->c_name); return; @@ -628,22 +824,45 @@ static void parse_fac_prio_20(int pri, char *res20) * that there is no timestamp, short-circuiting the test. */ static void timestamp_and_log(int pri, char *msg, int len) { - char *timestamp; + char *timestamp = NULL; time_t now; /* Jan 18 00:11:22 msg... */ /* 01234567890123456 */ - if (len < 16 || msg[3] != ' ' || msg[6] != ' ' - || msg[9] != ':' || msg[12] != ':' || msg[15] != ' ' + if (len >= 16 && msg[3] == ' ' && msg[6] == ' ' + && msg[9] == ':' && msg[12] == ':' && msg[15] == ' ' ) { - time(&now); + if (!(option_mask32 & OPT_timestamp)) { + /* use message timestamp */ + timestamp = msg; + now = 0; + } + msg += 16; + } + +#if ENABLE_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS + if (!timestamp) { + struct timeval tv; + gettimeofday(&tv, NULL); + now = tv.tv_sec; timestamp = ctime(&now) + 4; /* skip day of week */ + /* overwrite year by milliseconds, zero terminate */ + sprintf(timestamp + 15, ".%03u", (unsigned)tv.tv_usec / 1000u); } else { - now = 0; - timestamp = msg; - msg += 16; + timestamp[15] = '\0'; + } +#else + if (!timestamp) { + time(&now); + timestamp = ctime(&now) + 4; /* skip day of week */ } timestamp[15] = '\0'; +#endif + + if (option_mask32 & OPT_kmsg) { + log_to_kmsg(pri, msg); + return; + } if (option_mask32 & OPT_small) sprintf(G.printbuf, "%s %s\n", timestamp, msg); @@ -674,7 +893,7 @@ static void timestamp_and_log(int pri, char *msg, int len) if (LOG_PRI(pri) < G.logLevel) { #if ENABLE_FEATURE_IPC_SYSLOG if ((option_mask32 & OPT_circularlog) && G.shbuf) { - log_to_shmem(msg); + log_to_shmem(G.printbuf); return; } #endif @@ -746,18 +965,13 @@ static NOINLINE int create_socket(void) int sock_fd; char *dev_log_name; -#if ENABLE_FEATURE_SYSTEMD - if (sd_listen_fds() == 1) - return SD_LISTEN_FDS_START; -#endif - memset(&sunx, 0, sizeof(sunx)); sunx.sun_family = AF_UNIX; /* Unlink old /dev/log or object it points to. */ /* (if it exists, bind will fail) */ - strcpy(sunx.sun_path, "/dev/log"); - dev_log_name = xmalloc_follow_symlinks("/dev/log"); + strcpy(sunx.sun_path, _PATH_LOG); + dev_log_name = xmalloc_follow_symlinks(_PATH_LOG); if (dev_log_name) { safe_strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path)); free(dev_log_name); @@ -766,7 +980,7 @@ static NOINLINE int create_socket(void) sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0); xbind(sock_fd, (struct sockaddr *) &sunx, sizeof(sunx)); - chmod("/dev/log", 0666); + chmod(_PATH_LOG, 0666); return sock_fd; } @@ -792,7 +1006,6 @@ static int try_to_resolve_remote(remoteHost_t *rh) static void do_syslogd(void) NORETURN; static void do_syslogd(void) { - int sock_fd; #if ENABLE_FEATURE_REMOTE_LOG llist_t *item; #endif @@ -813,11 +1026,13 @@ static void do_syslogd(void) signal(SIGALRM, do_mark); alarm(G.markInterval); #endif - sock_fd = create_socket(); + xmove_fd(create_socket(), STDIN_FILENO); - if (ENABLE_FEATURE_IPC_SYSLOG && (option_mask32 & OPT_circularlog)) { + if (option_mask32 & OPT_circularlog) ipcsyslog_init(); - } + + if (option_mask32 & OPT_kmsg) + kmsg_init(); timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER); @@ -832,10 +1047,10 @@ static void do_syslogd(void) recvbuf = G.recvbuf; #endif read_again: - sz = read(sock_fd, recvbuf, MAX_READ - 1); + sz = read(STDIN_FILENO, recvbuf, MAX_READ - 1); if (sz < 0) { if (!bb_got_signal) - bb_perror_msg("read from /dev/log"); + bb_perror_msg("read from %s", _PATH_LOG); break; } @@ -903,9 +1118,10 @@ static void do_syslogd(void) } /* while (!bb_got_signal) */ timestamp_and_log_internal("syslogd exiting"); - puts("syslogd exiting"); - if (ENABLE_FEATURE_IPC_SYSLOG) - ipcsyslog_cleanup(); + remove_pidfile_std_path_and_ext("syslogd"); + ipcsyslog_cleanup(); + if (option_mask32 & OPT_kmsg) + kmsg_cleanup(); kill_myself_with_sig(bb_got_signal); #undef recvbuf } @@ -921,9 +1137,8 @@ int syslogd_main(int argc UNUSED_PARAM, char **argv) INIT_G(); - /* No non-option params, -R can occur multiple times */ - opt_complementary = "=0" IF_FEATURE_REMOTE_LOG(":R::"); - opts = getopt32(argv, OPTION_STR, OPTION_PARAM); + /* No non-option params */ + opts = getopt32(argv, "^"OPTION_STR"\0""=0", OPTION_PARAM); #if ENABLE_FEATURE_REMOTE_LOG while (remoteAddrList) { remoteHost_t *rh = xzalloc(sizeof(*rh)); @@ -967,8 +1182,10 @@ int syslogd_main(int argc UNUSED_PARAM, char **argv) if (!(opts & OPT_nofork)) { bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); } + //umask(0); - why?? - write_pidfile("/var/run/syslogd.pid"); + write_pidfile_std_path_and_ext("syslogd"); + do_syslogd(); /* return EXIT_SUCCESS; */ }