aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-02-26 20:13:52 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-02-26 20:13:52 +0000
commitbe048f21e62f18ddc5d1d135b8fe27f4e23d7bd2 (patch)
tree3e01e2e1be059589d8ac95cc10673a81600b0f26
parent06aed4316e1f486f78c6487181c75cb22a70c639 (diff)
downloadbusybox-w32-be048f21e62f18ddc5d1d135b8fe27f4e23d7bd2.tar.gz
busybox-w32-be048f21e62f18ddc5d1d135b8fe27f4e23d7bd2.tar.bz2
busybox-w32-be048f21e62f18ddc5d1d135b8fe27f4e23d7bd2.zip
syslogd: optional support for dropping dups. closes bug 436.
-rw-r--r--include/usage.h26
-rw-r--r--sysklogd/Config.in8
-rw-r--r--sysklogd/syslogd.c41
3 files changed, 54 insertions, 21 deletions
diff --git a/include/usage.h b/include/usage.h
index 3ef421197..6b54a1266 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -3686,22 +3686,24 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when
3686 "[OPTION]..." 3686 "[OPTION]..."
3687#define syslogd_full_usage \ 3687#define syslogd_full_usage \
3688 "System logging utility.\n" \ 3688 "System logging utility.\n" \
3689 "Note that this version of syslogd ignores /etc/syslog.conf." \ 3689 "Note that this version of syslogd ignores /etc/syslog.conf.\n" \
3690 "\n\nOptions:" \ 3690 "\nOptions:" \
3691 "\n -n Run in foreground" \ 3691 "\n -n Run in foreground" \
3692 "\n -O FILE Log to given file (default=/var/log/messages)" \ 3692 "\n -O FILE Log to given file (default=/var/log/messages)" \
3693 "\n -l n Set local log level" \ 3693 "\n -l n Set local log level" \
3694 "\n -S Smaller logging output" \ 3694 "\n -S Smaller logging output" \
3695 USE_FEATURE_ROTATE_LOGFILE( \ 3695 USE_FEATURE_ROTATE_LOGFILE( \
3696 "\n -s SIZE Max size (KB) before rotate (default=200KB, 0=off)" \ 3696 "\n -s SIZE Max size (KB) before rotate (default=200KB, 0=off)" \
3697 "\n -b NUM Number of rotated logs to keep (default=1, max=99, 0=purge)") \ 3697 "\n -b NUM Number of rotated logs to keep (default=1, max=99, 0=purge)") \
3698 USE_FEATURE_REMOTE_LOG( \ 3698 USE_FEATURE_REMOTE_LOG( \
3699 "\n -R HOST[:PORT] Log to IP or hostname on PORT (default PORT=514/UDP)" \ 3699 "\n -R HOST[:PORT] Log to IP or hostname on PORT (default PORT=514/UDP)" \
3700 "\n -L Log locally and via network (default is network only if -R)") \ 3700 "\n -L Log locally and via network (default is network only if -R)") \
3701 USE_FEATURE_SYSLOGD_DUP( \
3702 "\n -D Drop duplicates") \
3701 USE_FEATURE_IPC_SYSLOG( \ 3703 USE_FEATURE_IPC_SYSLOG( \
3702 "\n -C[size(KiB)] Log to shared mem buffer (read it using logread)") 3704 "\n -C[size(KiB)] Log to shared mem buffer (read it using logread)")
3703 /* NB: -Csize shouldn't have space (because size is optional) */ 3705 /* NB: -Csize shouldn't have space (because size is optional) */
3704/* "\n -m MIN Minutes between MARK lines (default=20, 0=off)" */ 3706/* "\n -m MIN Minutes between MARK lines (default=20, 0=off)" */
3705#define syslogd_example_usage \ 3707#define syslogd_example_usage \
3706 "$ syslogd -R masterlog:514\n" \ 3708 "$ syslogd -R masterlog:514\n" \
3707 "$ syslogd -R 192.168.1.1:601\n" 3709 "$ syslogd -R 192.168.1.1:601\n"
diff --git a/sysklogd/Config.in b/sysklogd/Config.in
index 78097eea1..45f86ed62 100644
--- a/sysklogd/Config.in
+++ b/sysklogd/Config.in
@@ -42,6 +42,14 @@ config FEATURE_REMOTE_LOG
42 measure to prevent system logs from being tampered with 42 measure to prevent system logs from being tampered with
43 by an intruder. 43 by an intruder.
44 44
45config FEATURE_SYSLOGD_DUP
46 bool "Support -D (drop dups) option"
47 default n
48 depends on SYSLOGD
49 help
50 Option -D instructs syslogd to drop consecutive messages
51 which are totally the same.
52
45config FEATURE_IPC_SYSLOG 53config FEATURE_IPC_SYSLOG
46 bool "Circular Buffer support" 54 bool "Circular Buffer support"
47 default n 55 default n
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 0d004bc27..e54ade7fd 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -101,7 +101,7 @@ struct globals {
101 char *hostname; 101 char *hostname;
102 102
103 /* We recv into recvbuf... */ 103 /* We recv into recvbuf... */
104 char recvbuf[MAX_READ]; 104 char recvbuf[MAX_READ * (1 + ENABLE_FEATURE_SYSLOGD_DUP)];
105 /* ...then copy to parsebuf, escaping control chars */ 105 /* ...then copy to parsebuf, escaping control chars */
106 /* (can grow x2 max) */ 106 /* (can grow x2 max) */
107 char parsebuf[MAX_READ*2]; 107 char parsebuf[MAX_READ*2];
@@ -152,6 +152,7 @@ enum {
152 USE_FEATURE_REMOTE_LOG( OPTBIT_remote ,) // -R 152 USE_FEATURE_REMOTE_LOG( OPTBIT_remote ,) // -R
153 USE_FEATURE_REMOTE_LOG( OPTBIT_locallog ,) // -L 153 USE_FEATURE_REMOTE_LOG( OPTBIT_locallog ,) // -L
154 USE_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C 154 USE_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C
155 USE_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D
155 156
156 OPT_mark = 1 << OPTBIT_mark , 157 OPT_mark = 1 << OPTBIT_mark ,
157 OPT_nofork = 1 << OPTBIT_nofork , 158 OPT_nofork = 1 << OPTBIT_nofork ,
@@ -163,13 +164,15 @@ enum {
163 OPT_remotelog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_remote )) + 0, 164 OPT_remotelog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_remote )) + 0,
164 OPT_locallog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_locallog )) + 0, 165 OPT_locallog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_locallog )) + 0,
165 OPT_circularlog = USE_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, 166 OPT_circularlog = USE_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0,
167 OPT_dup = USE_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0,
166}; 168};
167#define OPTION_STR "m:nO:l:S" \ 169#define OPTION_STR "m:nO:l:S" \
168 USE_FEATURE_ROTATE_LOGFILE("s:" ) \ 170 USE_FEATURE_ROTATE_LOGFILE("s:" ) \
169 USE_FEATURE_ROTATE_LOGFILE("b:" ) \ 171 USE_FEATURE_ROTATE_LOGFILE("b:" ) \
170 USE_FEATURE_REMOTE_LOG( "R:" ) \ 172 USE_FEATURE_REMOTE_LOG( "R:" ) \
171 USE_FEATURE_REMOTE_LOG( "L" ) \ 173 USE_FEATURE_REMOTE_LOG( "L" ) \
172 USE_FEATURE_IPC_SYSLOG( "C::") 174 USE_FEATURE_IPC_SYSLOG( "C::") \
175 USE_FEATURE_SYSLOGD_DUP( "D" )
173#define OPTION_DECL *opt_m, *opt_l \ 176#define OPTION_DECL *opt_m, *opt_l \
174 USE_FEATURE_ROTATE_LOGFILE(,*opt_s) \ 177 USE_FEATURE_ROTATE_LOGFILE(,*opt_s) \
175 USE_FEATURE_ROTATE_LOGFILE(,*opt_b) \ 178 USE_FEATURE_ROTATE_LOGFILE(,*opt_b) \
@@ -538,6 +541,13 @@ static void do_syslogd(void) ATTRIBUTE_NORETURN;
538static void do_syslogd(void) 541static void do_syslogd(void)
539{ 542{
540 int sock_fd; 543 int sock_fd;
544#if ENABLE_FEATURE_SYSLOGD_DUP
545 int last_sz = -1;
546 char *last_buf;
547 char *recvbuf = G.recvbuf;
548#else
549#define recvbuf (G.recvbuf)
550#endif
541 551
542 /* Set up signal handlers */ 552 /* Set up signal handlers */
543 bb_signals(0 553 bb_signals(0
@@ -561,8 +571,16 @@ static void do_syslogd(void)
561 571
562 for (;;) { 572 for (;;) {
563 size_t sz; 573 size_t sz;
574
575#if ENABLE_FEATURE_SYSLOGD_DUP
576 last_buf = recvbuf;
577 if (recvbuf == G.recvbuf)
578 recvbuf = G.recvbuf + MAX_READ;
579 else
580 recvbuf = G.recvbuf;
581#endif
564 read_again: 582 read_again:
565 sz = safe_read(sock_fd, G.recvbuf, MAX_READ - 1); 583 sz = safe_read(sock_fd, recvbuf, MAX_READ - 1);
566 if (sz < 0) 584 if (sz < 0)
567 bb_perror_msg_and_die("read from /dev/log"); 585 bb_perror_msg_and_die("read from /dev/log");
568 586
@@ -577,11 +595,16 @@ static void do_syslogd(void)
577 * IOW: newline is passed verbatim! 595 * IOW: newline is passed verbatim!
578 * I take it to mean that it's syslogd's job 596 * I take it to mean that it's syslogd's job
579 * to make those look identical in the log files. */ 597 * to make those look identical in the log files. */
580 if (G.recvbuf[sz-1] != '\0' && G.recvbuf[sz-1] != '\n') 598 if (recvbuf[sz-1] != '\0' && recvbuf[sz-1] != '\n')
581 break; 599 break;
582 sz--; 600 sz--;
583 } 601 }
584 /* TODO: maybe suppress duplicates? */ 602#if ENABLE_FEATURE_SYSLOGD_DUP
603 if ((option_mask32 & OPT_dup) && (sz == last_sz))
604 if (memcmp(last_buf, recvbuf, sz) == 0)
605 continue;
606 last_sz = sz;
607#endif
585#if ENABLE_FEATURE_REMOTE_LOG 608#if ENABLE_FEATURE_REMOTE_LOG
586 /* We are not modifying log messages in any way before send */ 609 /* We are not modifying log messages in any way before send */
587 /* Remote site cannot trust _us_ anyway and need to do validation again */ 610 /* Remote site cannot trust _us_ anyway and need to do validation again */
@@ -593,18 +616,18 @@ static void do_syslogd(void)
593 } 616 }
594 /* Stock syslogd sends it '\n'-terminated 617 /* Stock syslogd sends it '\n'-terminated
595 * over network, mimic that */ 618 * over network, mimic that */
596 G.recvbuf[sz] = '\n'; 619 recvbuf[sz] = '\n';
597 /* send message to remote logger, ignore possible error */ 620 /* send message to remote logger, ignore possible error */
598 /* TODO: on some errors, close and set G.remoteFD to -1 621 /* TODO: on some errors, close and set G.remoteFD to -1
599 * so that DNS resolution and connect is retried? */ 622 * so that DNS resolution and connect is retried? */
600 sendto(G.remoteFD, G.recvbuf, sz+1, MSG_DONTWAIT, 623 sendto(G.remoteFD, recvbuf, sz+1, MSG_DONTWAIT,
601 &G.remoteAddr->u.sa, G.remoteAddr->len); 624 &G.remoteAddr->u.sa, G.remoteAddr->len);
602 no_luck: ; 625 no_luck: ;
603 } 626 }
604#endif 627#endif
605 if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) { 628 if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
606 G.recvbuf[sz] = '\0'; /* ensure it *is* NUL terminated */ 629 recvbuf[sz] = '\0'; /* ensure it *is* NUL terminated */
607 split_escape_and_log(G.recvbuf, sz); 630 split_escape_and_log(recvbuf, sz);
608 } 631 }
609 } /* for (;;) */ 632 } /* for (;;) */
610} 633}