21 |
#include <syslog.h> |
#include <syslog.h> |
22 |
*/ |
*/ |
23 |
|
|
|
#include <paths.h> |
|
24 |
#include <sys/un.h> |
#include <sys/un.h> |
25 |
#include <sys/uio.h> |
#include <sys/uio.h> |
26 |
|
|
42 |
* (semaphores are down but do_mark routine tries to down them again) */ |
* (semaphores are down but do_mark routine tries to down them again) */ |
43 |
#undef SYSLOGD_MARK |
#undef SYSLOGD_MARK |
44 |
|
|
45 |
|
/* Write locking does not seem to be useful either */ |
46 |
|
#undef SYSLOGD_WRLOCK |
47 |
|
|
48 |
enum { |
enum { |
49 |
MAX_READ = 256, |
MAX_READ = 256, |
50 |
DNS_WAIT_SEC = 2 * 60, |
DNS_WAIT_SEC = 2 * 60, |
65 |
/*int markInterval;*/ \ |
/*int markInterval;*/ \ |
66 |
/* level of messages to be logged */ \ |
/* level of messages to be logged */ \ |
67 |
int logLevel; \ |
int logLevel; \ |
68 |
USE_FEATURE_ROTATE_LOGFILE( \ |
IF_FEATURE_ROTATE_LOGFILE( \ |
69 |
/* max size of file before rotation */ \ |
/* max size of file before rotation */ \ |
70 |
unsigned logFileSize; \ |
unsigned logFileSize; \ |
71 |
/* number of rotated message files */ \ |
/* number of rotated message files */ \ |
73 |
unsigned curFileSize; \ |
unsigned curFileSize; \ |
74 |
smallint isRegular; \ |
smallint isRegular; \ |
75 |
) \ |
) \ |
76 |
USE_FEATURE_REMOTE_LOG( \ |
IF_FEATURE_REMOTE_LOG( \ |
77 |
/* udp socket for remote logging */ \ |
/* udp socket for remote logging */ \ |
78 |
int remoteFD; \ |
int remoteFD; \ |
79 |
len_and_sockaddr* remoteAddr; \ |
len_and_sockaddr* remoteAddr; \ |
80 |
) \ |
) \ |
81 |
USE_FEATURE_IPC_SYSLOG( \ |
IF_FEATURE_IPC_SYSLOG( \ |
82 |
int shmid; /* ipc shared memory id */ \ |
int shmid; /* ipc shared memory id */ \ |
83 |
int s_semid; /* ipc semaphore id */ \ |
int s_semid; /* ipc semaphore id */ \ |
84 |
int shm_size; \ |
int shm_size; \ |
152 |
OPTBIT_outfile, // -O |
OPTBIT_outfile, // -O |
153 |
OPTBIT_loglevel, // -l |
OPTBIT_loglevel, // -l |
154 |
OPTBIT_small, // -S |
OPTBIT_small, // -S |
155 |
USE_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize ,) // -s |
IF_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize ,) // -s |
156 |
USE_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt ,) // -b |
IF_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt ,) // -b |
157 |
USE_FEATURE_REMOTE_LOG( OPTBIT_remote ,) // -R |
IF_FEATURE_REMOTE_LOG( OPTBIT_remotelog ,) // -R |
158 |
USE_FEATURE_REMOTE_LOG( OPTBIT_locallog ,) // -L |
IF_FEATURE_REMOTE_LOG( OPTBIT_locallog ,) // -L |
159 |
USE_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C |
IF_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C |
160 |
USE_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D |
IF_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D |
161 |
|
|
162 |
OPT_mark = 1 << OPTBIT_mark , |
OPT_mark = 1 << OPTBIT_mark , |
163 |
OPT_nofork = 1 << OPTBIT_nofork , |
OPT_nofork = 1 << OPTBIT_nofork , |
164 |
OPT_outfile = 1 << OPTBIT_outfile , |
OPT_outfile = 1 << OPTBIT_outfile , |
165 |
OPT_loglevel = 1 << OPTBIT_loglevel, |
OPT_loglevel = 1 << OPTBIT_loglevel, |
166 |
OPT_small = 1 << OPTBIT_small , |
OPT_small = 1 << OPTBIT_small , |
167 |
OPT_filesize = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize )) + 0, |
OPT_filesize = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize )) + 0, |
168 |
OPT_rotatecnt = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt )) + 0, |
OPT_rotatecnt = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt )) + 0, |
169 |
OPT_remotelog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_remote )) + 0, |
OPT_remotelog = IF_FEATURE_REMOTE_LOG( (1 << OPTBIT_remotelog )) + 0, |
170 |
OPT_locallog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_locallog )) + 0, |
OPT_locallog = IF_FEATURE_REMOTE_LOG( (1 << OPTBIT_locallog )) + 0, |
171 |
OPT_circularlog = USE_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, |
OPT_circularlog = IF_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, |
172 |
OPT_dup = USE_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0, |
OPT_dup = IF_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0, |
173 |
}; |
}; |
174 |
#define OPTION_STR "m:nO:l:S" \ |
#define OPTION_STR "m:nO:l:S" \ |
175 |
USE_FEATURE_ROTATE_LOGFILE("s:" ) \ |
IF_FEATURE_ROTATE_LOGFILE("s:" ) \ |
176 |
USE_FEATURE_ROTATE_LOGFILE("b:" ) \ |
IF_FEATURE_ROTATE_LOGFILE("b:" ) \ |
177 |
USE_FEATURE_REMOTE_LOG( "R:" ) \ |
IF_FEATURE_REMOTE_LOG( "R:" ) \ |
178 |
USE_FEATURE_REMOTE_LOG( "L" ) \ |
IF_FEATURE_REMOTE_LOG( "L" ) \ |
179 |
USE_FEATURE_IPC_SYSLOG( "C::") \ |
IF_FEATURE_IPC_SYSLOG( "C::") \ |
180 |
USE_FEATURE_SYSLOGD_DUP( "D" ) |
IF_FEATURE_SYSLOGD_DUP( "D" ) |
181 |
#define OPTION_DECL *opt_m, *opt_l \ |
#define OPTION_DECL *opt_m, *opt_l \ |
182 |
USE_FEATURE_ROTATE_LOGFILE(,*opt_s) \ |
IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \ |
183 |
USE_FEATURE_ROTATE_LOGFILE(,*opt_b) \ |
IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \ |
184 |
USE_FEATURE_IPC_SYSLOG( ,*opt_C = NULL) |
IF_FEATURE_IPC_SYSLOG( ,*opt_C = NULL) |
185 |
#define OPTION_PARAM &opt_m, &G.logFilePath, &opt_l \ |
#define OPTION_PARAM &opt_m, &G.logFilePath, &opt_l \ |
186 |
USE_FEATURE_ROTATE_LOGFILE(,&opt_s) \ |
IF_FEATURE_ROTATE_LOGFILE(,&opt_s) \ |
187 |
USE_FEATURE_ROTATE_LOGFILE(,&opt_b) \ |
IF_FEATURE_ROTATE_LOGFILE(,&opt_b) \ |
188 |
USE_FEATURE_REMOTE_LOG( ,&G.remoteAddrStr) \ |
IF_FEATURE_REMOTE_LOG( ,&G.remoteAddrStr) \ |
189 |
USE_FEATURE_IPC_SYSLOG( ,&opt_C) |
IF_FEATURE_IPC_SYSLOG( ,&opt_C) |
190 |
|
|
191 |
|
|
192 |
/* circular buffer variables/structures */ |
/* circular buffer variables/structures */ |
293 |
/* Print a message to the log file. */ |
/* Print a message to the log file. */ |
294 |
static void log_locally(time_t now, char *msg) |
static void log_locally(time_t now, char *msg) |
295 |
{ |
{ |
296 |
|
#ifdef SYSLOGD_WRLOCK |
297 |
struct flock fl; |
struct flock fl; |
298 |
|
#endif |
299 |
int len = strlen(msg); |
int len = strlen(msg); |
300 |
|
|
301 |
#if ENABLE_FEATURE_IPC_SYSLOG |
#if ENABLE_FEATURE_IPC_SYSLOG |
342 |
#endif |
#endif |
343 |
} |
} |
344 |
|
|
345 |
|
#ifdef SYSLOGD_WRLOCK |
346 |
fl.l_whence = SEEK_SET; |
fl.l_whence = SEEK_SET; |
347 |
fl.l_start = 0; |
fl.l_start = 0; |
348 |
fl.l_len = 1; |
fl.l_len = 1; |
349 |
fl.l_type = F_WRLCK; |
fl.l_type = F_WRLCK; |
350 |
fcntl(G.logFD, F_SETLKW, &fl); |
fcntl(G.logFD, F_SETLKW, &fl); |
351 |
|
#endif |
352 |
|
|
353 |
#if ENABLE_FEATURE_ROTATE_LOGFILE |
#if ENABLE_FEATURE_ROTATE_LOGFILE |
354 |
if (G.logFileSize && G.isRegular && G.curFileSize > G.logFileSize) { |
if (G.logFileSize && G.isRegular && G.curFileSize > G.logFileSize) { |
367 |
} |
} |
368 |
/* newFile == "f.0" now */ |
/* newFile == "f.0" now */ |
369 |
rename(G.logFilePath, newFile); |
rename(G.logFilePath, newFile); |
370 |
|
#ifdef SYSLOGD_WRLOCK |
371 |
fl.l_type = F_UNLCK; |
fl.l_type = F_UNLCK; |
372 |
fcntl(G.logFD, F_SETLKW, &fl); |
fcntl(G.logFD, F_SETLKW, &fl); |
373 |
|
#endif |
374 |
close(G.logFD); |
close(G.logFD); |
375 |
goto reopen; |
goto reopen; |
376 |
} |
} |
379 |
G.curFileSize += |
G.curFileSize += |
380 |
#endif |
#endif |
381 |
full_write(G.logFD, msg, len); |
full_write(G.logFD, msg, len); |
382 |
|
#ifdef SYSLOGD_WRLOCK |
383 |
fl.l_type = F_UNLCK; |
fl.l_type = F_UNLCK; |
384 |
fcntl(G.logFD, F_SETLKW, &fl); |
fcntl(G.logFD, F_SETLKW, &fl); |
385 |
|
#endif |
386 |
} |
} |
387 |
|
|
388 |
static void parse_fac_prio_20(int pri, char *res20) |
static void parse_fac_prio_20(int pri, char *res20) |
422 |
char *timestamp; |
char *timestamp; |
423 |
time_t now; |
time_t now; |
424 |
|
|
425 |
|
/* Jan 18 00:11:22 msg... */ |
426 |
|
/* 01234567890123456 */ |
427 |
if (len < 16 || msg[3] != ' ' || msg[6] != ' ' |
if (len < 16 || msg[3] != ' ' || msg[6] != ' ' |
428 |
|| msg[9] != ':' || msg[12] != ':' || msg[15] != ' ' |
|| msg[9] != ':' || msg[12] != ':' || msg[15] != ' ' |
429 |
) { |
) { |
450 |
|
|
451 |
static void timestamp_and_log_internal(const char *msg) |
static void timestamp_and_log_internal(const char *msg) |
452 |
{ |
{ |
453 |
|
/* -L, or no -R */ |
454 |
if (ENABLE_FEATURE_REMOTE_LOG && !(option_mask32 & OPT_locallog)) |
if (ENABLE_FEATURE_REMOTE_LOG && !(option_mask32 & OPT_locallog)) |
455 |
return; |
return; |
456 |
timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)msg, 0); |
timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)msg, 0); |
495 |
} |
} |
496 |
} |
} |
497 |
|
|
|
static void quit_signal(int sig) |
|
|
{ |
|
|
timestamp_and_log_internal("syslogd exiting"); |
|
|
puts("syslogd exiting"); |
|
|
if (ENABLE_FEATURE_IPC_SYSLOG) |
|
|
ipcsyslog_cleanup(); |
|
|
kill_myself_with_sig(sig); |
|
|
} |
|
|
|
|
498 |
#ifdef SYSLOGD_MARK |
#ifdef SYSLOGD_MARK |
499 |
static void do_mark(int sig) |
static void do_mark(int sig) |
500 |
{ |
{ |
563 |
#define recvbuf (G.recvbuf) |
#define recvbuf (G.recvbuf) |
564 |
#endif |
#endif |
565 |
|
|
566 |
/* Set up signal handlers */ |
/* Set up signal handlers (so that they interrupt read()) */ |
567 |
bb_signals(0 |
signal_no_SA_RESTART_empty_mask(SIGTERM, record_signo); |
568 |
+ (1 << SIGINT) |
signal_no_SA_RESTART_empty_mask(SIGINT, record_signo); |
569 |
+ (1 << SIGTERM) |
//signal_no_SA_RESTART_empty_mask(SIGQUIT, record_signo); |
|
+ (1 << SIGQUIT) |
|
|
, quit_signal); |
|
570 |
signal(SIGHUP, SIG_IGN); |
signal(SIGHUP, SIG_IGN); |
|
/* signal(SIGCHLD, SIG_IGN); - why? */ |
|
571 |
#ifdef SYSLOGD_MARK |
#ifdef SYSLOGD_MARK |
572 |
signal(SIGALRM, do_mark); |
signal(SIGALRM, do_mark); |
573 |
alarm(G.markInterval); |
alarm(G.markInterval); |
580 |
|
|
581 |
timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER); |
timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER); |
582 |
|
|
583 |
for (;;) { |
while (!bb_got_signal) { |
584 |
ssize_t sz; |
ssize_t sz; |
585 |
|
|
586 |
#if ENABLE_FEATURE_SYSLOGD_DUP |
#if ENABLE_FEATURE_SYSLOGD_DUP |
591 |
recvbuf = G.recvbuf; |
recvbuf = G.recvbuf; |
592 |
#endif |
#endif |
593 |
read_again: |
read_again: |
594 |
sz = safe_read(sock_fd, recvbuf, MAX_READ - 1); |
sz = read(sock_fd, recvbuf, MAX_READ - 1); |
595 |
if (sz < 0) |
if (sz < 0) { |
596 |
bb_perror_msg_and_die("read from /dev/log"); |
if (!bb_got_signal) |
597 |
|
bb_perror_msg("read from /dev/log"); |
598 |
|
break; |
599 |
|
} |
600 |
|
|
601 |
/* Drop trailing '\n' and NULs (typically there is one NUL) */ |
/* Drop trailing '\n' and NULs (typically there is one NUL) */ |
602 |
while (1) { |
while (1) { |
643 |
recvbuf[sz] = '\0'; /* ensure it *is* NUL terminated */ |
recvbuf[sz] = '\0'; /* ensure it *is* NUL terminated */ |
644 |
split_escape_and_log(recvbuf, sz); |
split_escape_and_log(recvbuf, sz); |
645 |
} |
} |
646 |
} /* for (;;) */ |
} /* while (!bb_got_signal) */ |
647 |
|
|
648 |
|
timestamp_and_log_internal("syslogd exiting"); |
649 |
|
puts("syslogd exiting"); |
650 |
|
if (ENABLE_FEATURE_IPC_SYSLOG) |
651 |
|
ipcsyslog_cleanup(); |
652 |
|
kill_myself_with_sig(bb_got_signal); |
653 |
#undef recvbuf |
#undef recvbuf |
654 |
} |
} |
655 |
|
|
657 |
int syslogd_main(int argc UNUSED_PARAM, char **argv) |
int syslogd_main(int argc UNUSED_PARAM, char **argv) |
658 |
{ |
{ |
659 |
char OPTION_DECL; |
char OPTION_DECL; |
660 |
|
int opts; |
661 |
|
|
662 |
INIT_G(); |
INIT_G(); |
663 |
#if ENABLE_FEATURE_REMOTE_LOG |
#if ENABLE_FEATURE_REMOTE_LOG |
666 |
|
|
667 |
/* do normal option parsing */ |
/* do normal option parsing */ |
668 |
opt_complementary = "=0"; /* no non-option params */ |
opt_complementary = "=0"; /* no non-option params */ |
669 |
getopt32(argv, OPTION_STR, OPTION_PARAM); |
opts = getopt32(argv, OPTION_STR, OPTION_PARAM); |
670 |
#ifdef SYSLOGD_MARK |
#ifdef SYSLOGD_MARK |
671 |
if (option_mask32 & OPT_mark) // -m |
if (opts & OPT_mark) // -m |
672 |
G.markInterval = xatou_range(opt_m, 0, INT_MAX/60) * 60; |
G.markInterval = xatou_range(opt_m, 0, INT_MAX/60) * 60; |
673 |
#endif |
#endif |
674 |
//if (option_mask32 & OPT_nofork) // -n |
//if (opts & OPT_nofork) // -n |
675 |
//if (option_mask32 & OPT_outfile) // -O |
//if (opts & OPT_outfile) // -O |
676 |
if (option_mask32 & OPT_loglevel) // -l |
if (opts & OPT_loglevel) // -l |
677 |
G.logLevel = xatou_range(opt_l, 1, 8); |
G.logLevel = xatou_range(opt_l, 1, 8); |
678 |
//if (option_mask32 & OPT_small) // -S |
//if (opts & OPT_small) // -S |
679 |
#if ENABLE_FEATURE_ROTATE_LOGFILE |
#if ENABLE_FEATURE_ROTATE_LOGFILE |
680 |
if (option_mask32 & OPT_filesize) // -s |
if (opts & OPT_filesize) // -s |
681 |
G.logFileSize = xatou_range(opt_s, 0, INT_MAX/1024) * 1024; |
G.logFileSize = xatou_range(opt_s, 0, INT_MAX/1024) * 1024; |
682 |
if (option_mask32 & OPT_rotatecnt) // -b |
if (opts & OPT_rotatecnt) // -b |
683 |
G.logFileRotate = xatou_range(opt_b, 0, 99); |
G.logFileRotate = xatou_range(opt_b, 0, 99); |
684 |
#endif |
#endif |
685 |
#if ENABLE_FEATURE_IPC_SYSLOG |
#if ENABLE_FEATURE_IPC_SYSLOG |
688 |
#endif |
#endif |
689 |
|
|
690 |
/* If they have not specified remote logging, then log locally */ |
/* If they have not specified remote logging, then log locally */ |
691 |
if (ENABLE_FEATURE_REMOTE_LOG && !(option_mask32 & OPT_remotelog)) |
if (ENABLE_FEATURE_REMOTE_LOG && !(opts & OPT_remotelog)) // -R |
692 |
option_mask32 |= OPT_locallog; |
option_mask32 |= OPT_locallog; |
693 |
|
|
694 |
/* Store away localhost's name before the fork */ |
/* Store away localhost's name before the fork */ |
695 |
G.hostname = safe_gethostname(); |
G.hostname = safe_gethostname(); |
696 |
*strchrnul(G.hostname, '.') = '\0'; |
*strchrnul(G.hostname, '.') = '\0'; |
697 |
|
|
698 |
if (!(option_mask32 & OPT_nofork)) { |
if (!(opts & OPT_nofork)) { |
699 |
bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); |
bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); |
700 |
} |
} |
701 |
umask(0); |
//umask(0); - why?? |
702 |
write_pidfile("/var/run/syslogd.pid"); |
write_pidfile("/var/run/syslogd.pid"); |
703 |
do_syslogd(); |
do_syslogd(); |
704 |
/* return EXIT_SUCCESS; */ |
/* return EXIT_SUCCESS; */ |
705 |
} |
} |
706 |
|
|
707 |
/* Clean up. Needed because we are included from syslogd_and_logger.c */ |
/* Clean up. Needed because we are included from syslogd_and_logger.c */ |
708 |
|
#undef DEBUG |
709 |
|
#undef SYSLOGD_MARK |
710 |
|
#undef SYSLOGD_WRLOCK |
711 |
#undef G |
#undef G |
712 |
#undef GLOBALS |
#undef GLOBALS |
713 |
#undef INIT_G |
#undef INIT_G |