diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-26 20:13:52 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-26 20:13:52 +0000 |
commit | be048f21e62f18ddc5d1d135b8fe27f4e23d7bd2 (patch) | |
tree | 3e01e2e1be059589d8ac95cc10673a81600b0f26 | |
parent | 06aed4316e1f486f78c6487181c75cb22a70c639 (diff) | |
download | busybox-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.h | 26 | ||||
-rw-r--r-- | sysklogd/Config.in | 8 | ||||
-rw-r--r-- | sysklogd/syslogd.c | 41 |
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 | ||
45 | config 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 | |||
45 | config FEATURE_IPC_SYSLOG | 53 | config 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; | |||
538 | static void do_syslogd(void) | 541 | static 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 | } |