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 | } |
