diff options
author | Mark Whitley <markw@lineo.com> | 2001-03-12 22:51:50 +0000 |
---|---|---|
committer | Mark Whitley <markw@lineo.com> | 2001-03-12 22:51:50 +0000 |
commit | 6317c4baf79c25d7f77897b064eb4f0b7d9f070e (patch) | |
tree | 5fc8fe65a4903f6224925a72b53a4f46e2b0b1d3 | |
parent | 4987bbf97924044c88007c45ee2674d97b93ad92 (diff) | |
download | busybox-w32-6317c4baf79c25d7f77897b064eb4f0b7d9f070e.tar.gz busybox-w32-6317c4baf79c25d7f77897b064eb4f0b7d9f070e.tar.bz2 busybox-w32-6317c4baf79c25d7f77897b064eb4f0b7d9f070e.zip |
Applied patch from Gennady Feldman to split up syslogd.c into syslogd and
klogd (as it should be).
-rw-r--r-- | Config.h | 2 | ||||
-rw-r--r-- | applets.h | 6 | ||||
-rw-r--r-- | applets/usage.h | 23 | ||||
-rw-r--r-- | busybox.h | 5 | ||||
-rw-r--r-- | include/applets.h | 6 | ||||
-rw-r--r-- | include/busybox.h | 5 | ||||
-rw-r--r-- | include/usage.h | 23 | ||||
-rw-r--r-- | klogd.c | 171 | ||||
-rw-r--r-- | logger.c | 5 | ||||
-rw-r--r-- | logread.c | 135 | ||||
-rw-r--r-- | sysklogd/klogd.c | 171 | ||||
-rw-r--r-- | sysklogd/logger.c | 5 | ||||
-rw-r--r-- | sysklogd/logread.c | 135 | ||||
-rw-r--r-- | sysklogd/syslogd.c | 318 | ||||
-rw-r--r-- | syslogd.c | 318 | ||||
-rw-r--r-- | usage.h | 23 | ||||
-rw-r--r-- | utility.c | 18 |
17 files changed, 1115 insertions, 254 deletions
@@ -52,6 +52,7 @@ | |||
52 | //#define BB_INSMOD | 52 | //#define BB_INSMOD |
53 | #define BB_KILL | 53 | #define BB_KILL |
54 | #define BB_KILLALL | 54 | #define BB_KILLALL |
55 | #define BB_KLOGD | ||
55 | //#define BB_LENGTH | 56 | //#define BB_LENGTH |
56 | #define BB_LN | 57 | #define BB_LN |
57 | //#define BB_LOADACM | 58 | //#define BB_LOADACM |
@@ -59,6 +60,7 @@ | |||
59 | //#define BB_LOADKMAP | 60 | //#define BB_LOADKMAP |
60 | #define BB_LOGGER | 61 | #define BB_LOGGER |
61 | //#define BB_LOGNAME | 62 | //#define BB_LOGNAME |
63 | #define BB_LOGREAD | ||
62 | #define BB_LS | 64 | #define BB_LS |
63 | #define BB_LSMOD | 65 | #define BB_LSMOD |
64 | //#define BB_MAKEDEVS | 66 | //#define BB_MAKEDEVS |
@@ -191,6 +191,9 @@ | |||
191 | #ifdef BB_KILLALL | 191 | #ifdef BB_KILLALL |
192 | APPLET(killall, kill_main, _BB_DIR_USR_BIN) | 192 | APPLET(killall, kill_main, _BB_DIR_USR_BIN) |
193 | #endif | 193 | #endif |
194 | #ifdef BB_KLOGD | ||
195 | APPLET(klogd, klogd_main, _BB_DIR_SBIN) | ||
196 | #endif | ||
194 | #ifdef BB_LENGTH | 197 | #ifdef BB_LENGTH |
195 | APPLET(length, length_main, _BB_DIR_USR_BIN) | 198 | APPLET(length, length_main, _BB_DIR_USR_BIN) |
196 | #endif | 199 | #endif |
@@ -215,6 +218,9 @@ | |||
215 | #ifdef BB_LOGNAME | 218 | #ifdef BB_LOGNAME |
216 | APPLET(logname, logname_main, _BB_DIR_USR_BIN) | 219 | APPLET(logname, logname_main, _BB_DIR_USR_BIN) |
217 | #endif | 220 | #endif |
221 | #ifdef BB_LOGREAD | ||
222 | APPLET(logread, logread_main, _BB_DIR_SBIN) | ||
223 | #endif | ||
218 | #ifdef BB_LS | 224 | #ifdef BB_LS |
219 | APPLET(ls, ls_main, _BB_DIR_BIN) | 225 | APPLET(ls, ls_main, _BB_DIR_BIN) |
220 | #endif | 226 | #endif |
diff --git a/applets/usage.h b/applets/usage.h index 8ba86d569..f241d3a04 100644 --- a/applets/usage.h +++ b/applets/usage.h | |||
@@ -468,6 +468,13 @@ | |||
468 | "Options:\n" \ | 468 | "Options:\n" \ |
469 | "\t-l\tList all signal names and numbers." | 469 | "\t-l\tList all signal names and numbers." |
470 | 470 | ||
471 | #define klogd_trivial_usage \ | ||
472 | "-n" | ||
473 | #define klogd_full_usage \ | ||
474 | "Kernel logger.\n"\ | ||
475 | "Options:\n"\ | ||
476 | "\t-n\tRun as a foreground process." | ||
477 | |||
471 | #define length_trivial_usage \ | 478 | #define length_trivial_usage \ |
472 | "STRING" | 479 | "STRING" |
473 | #define length_full_usage \ | 480 | #define length_full_usage \ |
@@ -513,6 +520,12 @@ | |||
513 | #define logname_full_usage \ | 520 | #define logname_full_usage \ |
514 | "Print the name of the current user." | 521 | "Print the name of the current user." |
515 | 522 | ||
523 | #define logread_trivial_usage \ | ||
524 | "" | ||
525 | |||
526 | #define logread_full_usage \ | ||
527 | "Shows the messages from syslogd (using circular buffer)." | ||
528 | |||
516 | #ifdef BB_FEATURE_LS_TIMESTAMPS | 529 | #ifdef BB_FEATURE_LS_TIMESTAMPS |
517 | #define USAGE_LS_TIMESTAMPS(a) a | 530 | #define USAGE_LS_TIMESTAMPS(a) a |
518 | #else | 531 | #else |
@@ -913,11 +926,6 @@ | |||
913 | "Write all buffered filesystem blocks to disk." | 926 | "Write all buffered filesystem blocks to disk." |
914 | 927 | ||
915 | 928 | ||
916 | #ifdef BB_FEATURE_KLOGD | ||
917 | #define USAGE_KLOGD(a) a | ||
918 | #else | ||
919 | #define USAGE_KLOGD(a) | ||
920 | #endif | ||
921 | #ifdef BB_FEATURE_REMOTE_LOG | 929 | #ifdef BB_FEATURE_REMOTE_LOG |
922 | #define USAGE_REMOTE_LOG(a) a | 930 | #define USAGE_REMOTE_LOG(a) a |
923 | #else | 931 | #else |
@@ -926,12 +934,11 @@ | |||
926 | #define syslogd_trivial_usage \ | 934 | #define syslogd_trivial_usage \ |
927 | "[OPTION]..." | 935 | "[OPTION]..." |
928 | #define syslogd_full_usage \ | 936 | #define syslogd_full_usage \ |
929 | "Linux system and kernel (provides klogd) logging utility.\n" \ | 937 | "Linux system and kernel logging utility.\n" \ |
930 | "Note that this version of syslogd/klogd ignores /etc/syslog.conf.\n\n" \ | 938 | "Note that this version of syslogd ignores /etc/syslog.conf.\n\n" \ |
931 | "Options:\n" \ | 939 | "Options:\n" \ |
932 | "\t-m NUM\t\tInterval between MARK lines (default=20min, 0=off)\n" \ | 940 | "\t-m NUM\t\tInterval between MARK lines (default=20min, 0=off)\n" \ |
933 | "\t-n\t\tRun as a foreground process\n" \ | 941 | "\t-n\t\tRun as a foreground process\n" \ |
934 | USAGE_KLOGD("\t-K\t\tDo not start up the klogd process\n") \ | ||
935 | "\t-O FILE\t\tUse an alternate log file (default=/var/log/messages)" \ | 942 | "\t-O FILE\t\tUse an alternate log file (default=/var/log/messages)" \ |
936 | USAGE_REMOTE_LOG( \ | 943 | USAGE_REMOTE_LOG( \ |
937 | "\n\t-R HOST[:PORT]\tLog to IP or hostname on PORT (default PORT=514/UDP)\n" \ | 944 | "\n\t-R HOST[:PORT]\tLog to IP or hostname on PORT (default PORT=514/UDP)\n" \ |
@@ -205,6 +205,11 @@ int nfsmount(const char *spec, const char *node, int *flags, | |||
205 | #define RB_POWER_OFF 0x4321fedc | 205 | #define RB_POWER_OFF 0x4321fedc |
206 | #endif | 206 | #endif |
207 | 207 | ||
208 | #if defined(BB_KLOGD) || defined(BB_LOGGER) | ||
209 | void syslog_msg_with_name(const char *name, int facility, int pri, const char *msg); | ||
210 | void syslog_msg(int facility, int pri, const char *msg); | ||
211 | #endif | ||
212 | |||
208 | /* Include our own copy of struct sysinfo to avoid binary compatability | 213 | /* Include our own copy of struct sysinfo to avoid binary compatability |
209 | * problems with Linux 2.4, which changed things. Grumble, grumble. */ | 214 | * problems with Linux 2.4, which changed things. Grumble, grumble. */ |
210 | struct sysinfo { | 215 | struct sysinfo { |
diff --git a/include/applets.h b/include/applets.h index 36817fef7..b3fb291d7 100644 --- a/include/applets.h +++ b/include/applets.h | |||
@@ -191,6 +191,9 @@ | |||
191 | #ifdef BB_KILLALL | 191 | #ifdef BB_KILLALL |
192 | APPLET(killall, kill_main, _BB_DIR_USR_BIN) | 192 | APPLET(killall, kill_main, _BB_DIR_USR_BIN) |
193 | #endif | 193 | #endif |
194 | #ifdef BB_KLOGD | ||
195 | APPLET(klogd, klogd_main, _BB_DIR_SBIN) | ||
196 | #endif | ||
194 | #ifdef BB_LENGTH | 197 | #ifdef BB_LENGTH |
195 | APPLET(length, length_main, _BB_DIR_USR_BIN) | 198 | APPLET(length, length_main, _BB_DIR_USR_BIN) |
196 | #endif | 199 | #endif |
@@ -215,6 +218,9 @@ | |||
215 | #ifdef BB_LOGNAME | 218 | #ifdef BB_LOGNAME |
216 | APPLET(logname, logname_main, _BB_DIR_USR_BIN) | 219 | APPLET(logname, logname_main, _BB_DIR_USR_BIN) |
217 | #endif | 220 | #endif |
221 | #ifdef BB_LOGREAD | ||
222 | APPLET(logread, logread_main, _BB_DIR_SBIN) | ||
223 | #endif | ||
218 | #ifdef BB_LS | 224 | #ifdef BB_LS |
219 | APPLET(ls, ls_main, _BB_DIR_BIN) | 225 | APPLET(ls, ls_main, _BB_DIR_BIN) |
220 | #endif | 226 | #endif |
diff --git a/include/busybox.h b/include/busybox.h index d9362b58b..abf62410f 100644 --- a/include/busybox.h +++ b/include/busybox.h | |||
@@ -205,6 +205,11 @@ int nfsmount(const char *spec, const char *node, int *flags, | |||
205 | #define RB_POWER_OFF 0x4321fedc | 205 | #define RB_POWER_OFF 0x4321fedc |
206 | #endif | 206 | #endif |
207 | 207 | ||
208 | #if defined(BB_KLOGD) || defined(BB_LOGGER) | ||
209 | void syslog_msg_with_name(const char *name, int facility, int pri, const char *msg); | ||
210 | void syslog_msg(int facility, int pri, const char *msg); | ||
211 | #endif | ||
212 | |||
208 | /* Include our own copy of struct sysinfo to avoid binary compatability | 213 | /* Include our own copy of struct sysinfo to avoid binary compatability |
209 | * problems with Linux 2.4, which changed things. Grumble, grumble. */ | 214 | * problems with Linux 2.4, which changed things. Grumble, grumble. */ |
210 | struct sysinfo { | 215 | struct sysinfo { |
diff --git a/include/usage.h b/include/usage.h index 8ba86d569..f241d3a04 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -468,6 +468,13 @@ | |||
468 | "Options:\n" \ | 468 | "Options:\n" \ |
469 | "\t-l\tList all signal names and numbers." | 469 | "\t-l\tList all signal names and numbers." |
470 | 470 | ||
471 | #define klogd_trivial_usage \ | ||
472 | "-n" | ||
473 | #define klogd_full_usage \ | ||
474 | "Kernel logger.\n"\ | ||
475 | "Options:\n"\ | ||
476 | "\t-n\tRun as a foreground process." | ||
477 | |||
471 | #define length_trivial_usage \ | 478 | #define length_trivial_usage \ |
472 | "STRING" | 479 | "STRING" |
473 | #define length_full_usage \ | 480 | #define length_full_usage \ |
@@ -513,6 +520,12 @@ | |||
513 | #define logname_full_usage \ | 520 | #define logname_full_usage \ |
514 | "Print the name of the current user." | 521 | "Print the name of the current user." |
515 | 522 | ||
523 | #define logread_trivial_usage \ | ||
524 | "" | ||
525 | |||
526 | #define logread_full_usage \ | ||
527 | "Shows the messages from syslogd (using circular buffer)." | ||
528 | |||
516 | #ifdef BB_FEATURE_LS_TIMESTAMPS | 529 | #ifdef BB_FEATURE_LS_TIMESTAMPS |
517 | #define USAGE_LS_TIMESTAMPS(a) a | 530 | #define USAGE_LS_TIMESTAMPS(a) a |
518 | #else | 531 | #else |
@@ -913,11 +926,6 @@ | |||
913 | "Write all buffered filesystem blocks to disk." | 926 | "Write all buffered filesystem blocks to disk." |
914 | 927 | ||
915 | 928 | ||
916 | #ifdef BB_FEATURE_KLOGD | ||
917 | #define USAGE_KLOGD(a) a | ||
918 | #else | ||
919 | #define USAGE_KLOGD(a) | ||
920 | #endif | ||
921 | #ifdef BB_FEATURE_REMOTE_LOG | 929 | #ifdef BB_FEATURE_REMOTE_LOG |
922 | #define USAGE_REMOTE_LOG(a) a | 930 | #define USAGE_REMOTE_LOG(a) a |
923 | #else | 931 | #else |
@@ -926,12 +934,11 @@ | |||
926 | #define syslogd_trivial_usage \ | 934 | #define syslogd_trivial_usage \ |
927 | "[OPTION]..." | 935 | "[OPTION]..." |
928 | #define syslogd_full_usage \ | 936 | #define syslogd_full_usage \ |
929 | "Linux system and kernel (provides klogd) logging utility.\n" \ | 937 | "Linux system and kernel logging utility.\n" \ |
930 | "Note that this version of syslogd/klogd ignores /etc/syslog.conf.\n\n" \ | 938 | "Note that this version of syslogd ignores /etc/syslog.conf.\n\n" \ |
931 | "Options:\n" \ | 939 | "Options:\n" \ |
932 | "\t-m NUM\t\tInterval between MARK lines (default=20min, 0=off)\n" \ | 940 | "\t-m NUM\t\tInterval between MARK lines (default=20min, 0=off)\n" \ |
933 | "\t-n\t\tRun as a foreground process\n" \ | 941 | "\t-n\t\tRun as a foreground process\n" \ |
934 | USAGE_KLOGD("\t-K\t\tDo not start up the klogd process\n") \ | ||
935 | "\t-O FILE\t\tUse an alternate log file (default=/var/log/messages)" \ | 942 | "\t-O FILE\t\tUse an alternate log file (default=/var/log/messages)" \ |
936 | USAGE_REMOTE_LOG( \ | 943 | USAGE_REMOTE_LOG( \ |
937 | "\n\t-R HOST[:PORT]\tLog to IP or hostname on PORT (default PORT=514/UDP)\n" \ | 944 | "\n\t-R HOST[:PORT]\tLog to IP or hostname on PORT (default PORT=514/UDP)\n" \ |
diff --git a/klogd.c b/klogd.c new file mode 100644 index 000000000..f44383637 --- /dev/null +++ b/klogd.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Mini klogd implementation for busybox | ||
4 | * | ||
5 | * Copyright (C) 2001 by Gennady Feldman <gfeldman@cachier.com>. | ||
6 | * Changes: Made this a standalone busybox module which uses standalone | ||
7 | * syslog() client interface. | ||
8 | * | ||
9 | * Copyright (C) 1999,2000,2001 by Lineo, inc. | ||
10 | * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> | ||
11 | * | ||
12 | * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org> | ||
13 | * | ||
14 | * "circular buffer" Copyright (C) 2000 by Gennady Feldman <gfeldman@mail.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or | ||
19 | * (at your option) any later version. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
24 | * General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, write to the Free Software | ||
28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <stdlib.h> | ||
34 | #include <signal.h> /* for our signal() handlers */ | ||
35 | #include <string.h> /* strncpy() */ | ||
36 | #include <errno.h> /* errno and friends */ | ||
37 | #include <unistd.h> | ||
38 | #include <ctype.h> | ||
39 | #include <sys/syslog.h> | ||
40 | |||
41 | #if ! defined __GLIBC__ && ! defined __UCLIBC__ | ||
42 | #include <sys/syscall.h> | ||
43 | #include <linux/unistd.h> | ||
44 | typedef unsigned int socklen_t; | ||
45 | |||
46 | #ifndef __alpha__ | ||
47 | # define __NR_klogctl __NR_syslog | ||
48 | static inline _syscall3(int, klogctl, int, type, char *, b, int, len); | ||
49 | #else /* __alpha__ */ | ||
50 | #define klogctl syslog | ||
51 | #endif | ||
52 | |||
53 | #else | ||
54 | # include <sys/klog.h> | ||
55 | #endif | ||
56 | #include "busybox.h" | ||
57 | |||
58 | static void klogd_signal(int sig) | ||
59 | { | ||
60 | klogctl(7, NULL, 0); | ||
61 | klogctl(0, 0, 0); | ||
62 | //logMessage(0, "Kernel log daemon exiting."); | ||
63 | syslog_msg(LOG_DAEMON, 0, "Kernel log daemon exiting."); | ||
64 | exit(TRUE); | ||
65 | } | ||
66 | |||
67 | static void doKlogd (void) __attribute__ ((noreturn)); | ||
68 | static void doKlogd (void) | ||
69 | { | ||
70 | int priority = LOG_INFO; | ||
71 | char log_buffer[4096]; | ||
72 | int i, n, lastc; | ||
73 | char *start; | ||
74 | |||
75 | /* Set up sig handlers */ | ||
76 | signal(SIGINT, klogd_signal); | ||
77 | signal(SIGKILL, klogd_signal); | ||
78 | signal(SIGTERM, klogd_signal); | ||
79 | signal(SIGHUP, SIG_IGN); | ||
80 | |||
81 | /* "Open the log. Currently a NOP." */ | ||
82 | klogctl(1, NULL, 0); | ||
83 | |||
84 | syslog_msg(LOG_DAEMON, 0, "klogd started: BusyBox v" BB_VER " (" BB_BT ")"); | ||
85 | |||
86 | while (1) { | ||
87 | /* Use kernel syscalls */ | ||
88 | memset(log_buffer, '\0', sizeof(log_buffer)); | ||
89 | n = klogctl(2, log_buffer, sizeof(log_buffer)); | ||
90 | if (n < 0) { | ||
91 | char message[80]; | ||
92 | |||
93 | if (errno == EINTR) | ||
94 | continue; | ||
95 | snprintf(message, 79, "klogd: Error return from sys_sycall: %d - %s.\n", | ||
96 | errno, strerror(errno)); | ||
97 | syslog_msg(LOG_DAEMON, LOG_SYSLOG | LOG_ERR, message); | ||
98 | exit(1); | ||
99 | } | ||
100 | |||
101 | /* klogctl buffer parsing modelled after code in dmesg.c */ | ||
102 | start=&log_buffer[0]; | ||
103 | lastc='\0'; | ||
104 | for (i=0; i<n; i++) { | ||
105 | if (lastc == '\0' && log_buffer[i] == '<') { | ||
106 | priority = 0; | ||
107 | i++; | ||
108 | while (isdigit(log_buffer[i])) { | ||
109 | priority = priority*10+(log_buffer[i]-'0'); | ||
110 | i++; | ||
111 | } | ||
112 | if (log_buffer[i] == '>') i++; | ||
113 | start = &log_buffer[i]; | ||
114 | } | ||
115 | if (log_buffer[i] == '\n') { | ||
116 | log_buffer[i] = '\0'; /* zero terminate this message */ | ||
117 | syslog_msg(LOG_DAEMON, LOG_KERN | priority, start); | ||
118 | start = &log_buffer[i+1]; | ||
119 | priority = LOG_INFO; | ||
120 | } | ||
121 | lastc = log_buffer[i]; | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | |||
126 | static void daemon_init (char **argv, char *dz, void fn (void)) | ||
127 | { | ||
128 | setsid(); /* start a new session? */ | ||
129 | strncpy(argv[0], dz, strlen(argv[0])); | ||
130 | fn(); | ||
131 | exit(0); | ||
132 | } | ||
133 | |||
134 | extern int klogd_main(int argc, char **argv) | ||
135 | { | ||
136 | /* no options, no getopt */ | ||
137 | int opt, pid; | ||
138 | int doFork = TRUE; | ||
139 | |||
140 | /* do normal option parsing */ | ||
141 | while ((opt = getopt(argc, argv, "n")) > 0) { | ||
142 | switch (opt) { | ||
143 | case 'n': | ||
144 | doFork = FALSE; | ||
145 | break; | ||
146 | default: | ||
147 | show_usage(); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | if (doFork == TRUE) { | ||
152 | pid = fork(); | ||
153 | if (pid < 0) | ||
154 | exit(pid); | ||
155 | else if (pid == 0) { | ||
156 | daemon_init (argv, "klogd", doKlogd); | ||
157 | } | ||
158 | } else { | ||
159 | doKlogd(); | ||
160 | } | ||
161 | |||
162 | return EXIT_SUCCESS; | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | Local Variables | ||
167 | c-file-style: "linux" | ||
168 | c-basic-offset: 4 | ||
169 | tab-width: 4 | ||
170 | End: | ||
171 | */ | ||
@@ -148,9 +148,10 @@ extern int logger_main(int argc, char **argv) | |||
148 | message[strlen(message)-1] = '\0'; | 148 | message[strlen(message)-1] = '\0'; |
149 | } | 149 | } |
150 | 150 | ||
151 | openlog(name, option, (pri | LOG_FACMASK)); | 151 | /*openlog(name, option, (pri | LOG_FACMASK)); |
152 | syslog(pri, "%s", message); | 152 | syslog(pri, "%s", message); |
153 | closelog(); | 153 | closelog();*/ |
154 | syslog_msg_with_name(name,(pri | LOG_FACMASK),pri,message); | ||
154 | return EXIT_SUCCESS; | 155 | return EXIT_SUCCESS; |
155 | } | 156 | } |
156 | 157 | ||
diff --git a/logread.c b/logread.c new file mode 100644 index 000000000..3bf4c541e --- /dev/null +++ b/logread.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * circular buffer syslog implementation for busybox | ||
4 | * | ||
5 | * Copyright (C) 2000 by Gennady Feldman <gfeldman@cachier.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
20 | * 02111-1307 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <stdio.h> | ||
25 | #include <stdlib.h> | ||
26 | #include <string.h> | ||
27 | #include <sys/ipc.h> | ||
28 | #include <sys/types.h> | ||
29 | #include <sys/sem.h> | ||
30 | #include <sys/shm.h> | ||
31 | #include <signal.h> | ||
32 | #include <setjmp.h> | ||
33 | #include "busybox.h" | ||
34 | |||
35 | static const long KEY_ID = 0x414e4547; /*"GENA"*/ | ||
36 | |||
37 | static struct shbuf_ds { | ||
38 | int size; // size of data written | ||
39 | int head; // start of message list | ||
40 | int tail; // end of message list | ||
41 | char data[1]; // data/messages | ||
42 | } *buf = NULL; // shared memory pointer | ||
43 | |||
44 | |||
45 | // Semaphore operation structures | ||
46 | static struct sembuf SMrup[1] = {{0, -1, IPC_NOWAIT | SEM_UNDO}}; // set SMrup | ||
47 | static struct sembuf SMrdn[2] = {{1, 0}, {0, +1, SEM_UNDO}}; // set SMrdn | ||
48 | |||
49 | static int shmid = -1; // ipc shared memory id | ||
50 | static int semid = -1; // ipc semaphore id | ||
51 | static jmp_buf jmp_env; | ||
52 | |||
53 | static void error_exit(const char *str); | ||
54 | static void interrupted(int sig); | ||
55 | |||
56 | /* | ||
57 | * sem_up - up()'s a semaphore. | ||
58 | */ | ||
59 | static inline void sem_up(int semid) | ||
60 | { | ||
61 | if ( semop(semid, SMrup, 1) == -1 ) | ||
62 | error_exit("semop[SMrup]"); | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * sem_down - down()'s a semaphore | ||
67 | */ | ||
68 | static inline void sem_down(int semid) | ||
69 | { | ||
70 | if ( semop(semid, SMrdn, 2) == -1 ) | ||
71 | error_exit("semop[SMrdn]"); | ||
72 | } | ||
73 | |||
74 | extern int logread_main(int argc, char **argv) | ||
75 | { | ||
76 | int i; | ||
77 | |||
78 | /* no options, no getopt */ | ||
79 | if (argc > 1) | ||
80 | show_usage(); | ||
81 | |||
82 | // handle intrrupt signal | ||
83 | if (setjmp(jmp_env)) goto output_end; | ||
84 | |||
85 | // attempt to redefine ^C signal | ||
86 | signal(SIGINT, interrupted); | ||
87 | |||
88 | if ( (shmid = shmget(KEY_ID, 0, 0)) == -1) | ||
89 | error_exit("Can't find circular buffer"); | ||
90 | |||
91 | // Attach shared memory to our char* | ||
92 | if ( (buf = shmat(shmid, NULL, SHM_RDONLY)) == NULL) | ||
93 | error_exit("Can't get access to circular buffer from syslogd"); | ||
94 | |||
95 | if ( (semid = semget(KEY_ID, 0, 0)) == -1) | ||
96 | error_exit("Can't get access to semaphone(s) for circular buffer from syslogd"); | ||
97 | |||
98 | sem_down(semid); | ||
99 | // Read Memory | ||
100 | i=buf->head; | ||
101 | |||
102 | //printf("head: %i tail: %i size: %i\n",buf->head,buf->tail,buf->size); | ||
103 | if (buf->head == buf->tail) { | ||
104 | printf("<empty syslog>\n"); | ||
105 | } | ||
106 | |||
107 | while ( i != buf->tail) { | ||
108 | printf("%s", buf->data+i); | ||
109 | i+= strlen(buf->data+i) + 1; | ||
110 | if (i >= buf->size ) | ||
111 | i=0; | ||
112 | } | ||
113 | sem_up(semid); | ||
114 | |||
115 | output_end: | ||
116 | if (shmid != -1) | ||
117 | shmdt(buf); | ||
118 | |||
119 | return EXIT_SUCCESS; | ||
120 | } | ||
121 | |||
122 | static void interrupted(int sig){ | ||
123 | signal(SIGINT, SIG_IGN); | ||
124 | longjmp(jmp_env, 1); | ||
125 | } | ||
126 | |||
127 | static void error_exit(const char *str){ | ||
128 | perror(str); | ||
129 | //release all acquired resources | ||
130 | if (shmid != -1) | ||
131 | shmdt(buf); | ||
132 | |||
133 | exit(1); | ||
134 | } | ||
135 | |||
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c new file mode 100644 index 000000000..f44383637 --- /dev/null +++ b/sysklogd/klogd.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Mini klogd implementation for busybox | ||
4 | * | ||
5 | * Copyright (C) 2001 by Gennady Feldman <gfeldman@cachier.com>. | ||
6 | * Changes: Made this a standalone busybox module which uses standalone | ||
7 | * syslog() client interface. | ||
8 | * | ||
9 | * Copyright (C) 1999,2000,2001 by Lineo, inc. | ||
10 | * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> | ||
11 | * | ||
12 | * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org> | ||
13 | * | ||
14 | * "circular buffer" Copyright (C) 2000 by Gennady Feldman <gfeldman@mail.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or | ||
19 | * (at your option) any later version. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
24 | * General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, write to the Free Software | ||
28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <stdlib.h> | ||
34 | #include <signal.h> /* for our signal() handlers */ | ||
35 | #include <string.h> /* strncpy() */ | ||
36 | #include <errno.h> /* errno and friends */ | ||
37 | #include <unistd.h> | ||
38 | #include <ctype.h> | ||
39 | #include <sys/syslog.h> | ||
40 | |||
41 | #if ! defined __GLIBC__ && ! defined __UCLIBC__ | ||
42 | #include <sys/syscall.h> | ||
43 | #include <linux/unistd.h> | ||
44 | typedef unsigned int socklen_t; | ||
45 | |||
46 | #ifndef __alpha__ | ||
47 | # define __NR_klogctl __NR_syslog | ||
48 | static inline _syscall3(int, klogctl, int, type, char *, b, int, len); | ||
49 | #else /* __alpha__ */ | ||
50 | #define klogctl syslog | ||
51 | #endif | ||
52 | |||
53 | #else | ||
54 | # include <sys/klog.h> | ||
55 | #endif | ||
56 | #include "busybox.h" | ||
57 | |||
58 | static void klogd_signal(int sig) | ||
59 | { | ||
60 | klogctl(7, NULL, 0); | ||
61 | klogctl(0, 0, 0); | ||
62 | //logMessage(0, "Kernel log daemon exiting."); | ||
63 | syslog_msg(LOG_DAEMON, 0, "Kernel log daemon exiting."); | ||
64 | exit(TRUE); | ||
65 | } | ||
66 | |||
67 | static void doKlogd (void) __attribute__ ((noreturn)); | ||
68 | static void doKlogd (void) | ||
69 | { | ||
70 | int priority = LOG_INFO; | ||
71 | char log_buffer[4096]; | ||
72 | int i, n, lastc; | ||
73 | char *start; | ||
74 | |||
75 | /* Set up sig handlers */ | ||
76 | signal(SIGINT, klogd_signal); | ||
77 | signal(SIGKILL, klogd_signal); | ||
78 | signal(SIGTERM, klogd_signal); | ||
79 | signal(SIGHUP, SIG_IGN); | ||
80 | |||
81 | /* "Open the log. Currently a NOP." */ | ||
82 | klogctl(1, NULL, 0); | ||
83 | |||
84 | syslog_msg(LOG_DAEMON, 0, "klogd started: BusyBox v" BB_VER " (" BB_BT ")"); | ||
85 | |||
86 | while (1) { | ||
87 | /* Use kernel syscalls */ | ||
88 | memset(log_buffer, '\0', sizeof(log_buffer)); | ||
89 | n = klogctl(2, log_buffer, sizeof(log_buffer)); | ||
90 | if (n < 0) { | ||
91 | char message[80]; | ||
92 | |||
93 | if (errno == EINTR) | ||
94 | continue; | ||
95 | snprintf(message, 79, "klogd: Error return from sys_sycall: %d - %s.\n", | ||
96 | errno, strerror(errno)); | ||
97 | syslog_msg(LOG_DAEMON, LOG_SYSLOG | LOG_ERR, message); | ||
98 | exit(1); | ||
99 | } | ||
100 | |||
101 | /* klogctl buffer parsing modelled after code in dmesg.c */ | ||
102 | start=&log_buffer[0]; | ||
103 | lastc='\0'; | ||
104 | for (i=0; i<n; i++) { | ||
105 | if (lastc == '\0' && log_buffer[i] == '<') { | ||
106 | priority = 0; | ||
107 | i++; | ||
108 | while (isdigit(log_buffer[i])) { | ||
109 | priority = priority*10+(log_buffer[i]-'0'); | ||
110 | i++; | ||
111 | } | ||
112 | if (log_buffer[i] == '>') i++; | ||
113 | start = &log_buffer[i]; | ||
114 | } | ||
115 | if (log_buffer[i] == '\n') { | ||
116 | log_buffer[i] = '\0'; /* zero terminate this message */ | ||
117 | syslog_msg(LOG_DAEMON, LOG_KERN | priority, start); | ||
118 | start = &log_buffer[i+1]; | ||
119 | priority = LOG_INFO; | ||
120 | } | ||
121 | lastc = log_buffer[i]; | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | |||
126 | static void daemon_init (char **argv, char *dz, void fn (void)) | ||
127 | { | ||
128 | setsid(); /* start a new session? */ | ||
129 | strncpy(argv[0], dz, strlen(argv[0])); | ||
130 | fn(); | ||
131 | exit(0); | ||
132 | } | ||
133 | |||
134 | extern int klogd_main(int argc, char **argv) | ||
135 | { | ||
136 | /* no options, no getopt */ | ||
137 | int opt, pid; | ||
138 | int doFork = TRUE; | ||
139 | |||
140 | /* do normal option parsing */ | ||
141 | while ((opt = getopt(argc, argv, "n")) > 0) { | ||
142 | switch (opt) { | ||
143 | case 'n': | ||
144 | doFork = FALSE; | ||
145 | break; | ||
146 | default: | ||
147 | show_usage(); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | if (doFork == TRUE) { | ||
152 | pid = fork(); | ||
153 | if (pid < 0) | ||
154 | exit(pid); | ||
155 | else if (pid == 0) { | ||
156 | daemon_init (argv, "klogd", doKlogd); | ||
157 | } | ||
158 | } else { | ||
159 | doKlogd(); | ||
160 | } | ||
161 | |||
162 | return EXIT_SUCCESS; | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | Local Variables | ||
167 | c-file-style: "linux" | ||
168 | c-basic-offset: 4 | ||
169 | tab-width: 4 | ||
170 | End: | ||
171 | */ | ||
diff --git a/sysklogd/logger.c b/sysklogd/logger.c index 1218d8d2e..b8aae3d28 100644 --- a/sysklogd/logger.c +++ b/sysklogd/logger.c | |||
@@ -148,9 +148,10 @@ extern int logger_main(int argc, char **argv) | |||
148 | message[strlen(message)-1] = '\0'; | 148 | message[strlen(message)-1] = '\0'; |
149 | } | 149 | } |
150 | 150 | ||
151 | openlog(name, option, (pri | LOG_FACMASK)); | 151 | /*openlog(name, option, (pri | LOG_FACMASK)); |
152 | syslog(pri, "%s", message); | 152 | syslog(pri, "%s", message); |
153 | closelog(); | 153 | closelog();*/ |
154 | syslog_msg_with_name(name,(pri | LOG_FACMASK),pri,message); | ||
154 | return EXIT_SUCCESS; | 155 | return EXIT_SUCCESS; |
155 | } | 156 | } |
156 | 157 | ||
diff --git a/sysklogd/logread.c b/sysklogd/logread.c new file mode 100644 index 000000000..3bf4c541e --- /dev/null +++ b/sysklogd/logread.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * circular buffer syslog implementation for busybox | ||
4 | * | ||
5 | * Copyright (C) 2000 by Gennady Feldman <gfeldman@cachier.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
20 | * 02111-1307 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <stdio.h> | ||
25 | #include <stdlib.h> | ||
26 | #include <string.h> | ||
27 | #include <sys/ipc.h> | ||
28 | #include <sys/types.h> | ||
29 | #include <sys/sem.h> | ||
30 | #include <sys/shm.h> | ||
31 | #include <signal.h> | ||
32 | #include <setjmp.h> | ||
33 | #include "busybox.h" | ||
34 | |||
35 | static const long KEY_ID = 0x414e4547; /*"GENA"*/ | ||
36 | |||
37 | static struct shbuf_ds { | ||
38 | int size; // size of data written | ||
39 | int head; // start of message list | ||
40 | int tail; // end of message list | ||
41 | char data[1]; // data/messages | ||
42 | } *buf = NULL; // shared memory pointer | ||
43 | |||
44 | |||
45 | // Semaphore operation structures | ||
46 | static struct sembuf SMrup[1] = {{0, -1, IPC_NOWAIT | SEM_UNDO}}; // set SMrup | ||
47 | static struct sembuf SMrdn[2] = {{1, 0}, {0, +1, SEM_UNDO}}; // set SMrdn | ||
48 | |||
49 | static int shmid = -1; // ipc shared memory id | ||
50 | static int semid = -1; // ipc semaphore id | ||
51 | static jmp_buf jmp_env; | ||
52 | |||
53 | static void error_exit(const char *str); | ||
54 | static void interrupted(int sig); | ||
55 | |||
56 | /* | ||
57 | * sem_up - up()'s a semaphore. | ||
58 | */ | ||
59 | static inline void sem_up(int semid) | ||
60 | { | ||
61 | if ( semop(semid, SMrup, 1) == -1 ) | ||
62 | error_exit("semop[SMrup]"); | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * sem_down - down()'s a semaphore | ||
67 | */ | ||
68 | static inline void sem_down(int semid) | ||
69 | { | ||
70 | if ( semop(semid, SMrdn, 2) == -1 ) | ||
71 | error_exit("semop[SMrdn]"); | ||
72 | } | ||
73 | |||
74 | extern int logread_main(int argc, char **argv) | ||
75 | { | ||
76 | int i; | ||
77 | |||
78 | /* no options, no getopt */ | ||
79 | if (argc > 1) | ||
80 | show_usage(); | ||
81 | |||
82 | // handle intrrupt signal | ||
83 | if (setjmp(jmp_env)) goto output_end; | ||
84 | |||
85 | // attempt to redefine ^C signal | ||
86 | signal(SIGINT, interrupted); | ||
87 | |||
88 | if ( (shmid = shmget(KEY_ID, 0, 0)) == -1) | ||
89 | error_exit("Can't find circular buffer"); | ||
90 | |||
91 | // Attach shared memory to our char* | ||
92 | if ( (buf = shmat(shmid, NULL, SHM_RDONLY)) == NULL) | ||
93 | error_exit("Can't get access to circular buffer from syslogd"); | ||
94 | |||
95 | if ( (semid = semget(KEY_ID, 0, 0)) == -1) | ||
96 | error_exit("Can't get access to semaphone(s) for circular buffer from syslogd"); | ||
97 | |||
98 | sem_down(semid); | ||
99 | // Read Memory | ||
100 | i=buf->head; | ||
101 | |||
102 | //printf("head: %i tail: %i size: %i\n",buf->head,buf->tail,buf->size); | ||
103 | if (buf->head == buf->tail) { | ||
104 | printf("<empty syslog>\n"); | ||
105 | } | ||
106 | |||
107 | while ( i != buf->tail) { | ||
108 | printf("%s", buf->data+i); | ||
109 | i+= strlen(buf->data+i) + 1; | ||
110 | if (i >= buf->size ) | ||
111 | i=0; | ||
112 | } | ||
113 | sem_up(semid); | ||
114 | |||
115 | output_end: | ||
116 | if (shmid != -1) | ||
117 | shmdt(buf); | ||
118 | |||
119 | return EXIT_SUCCESS; | ||
120 | } | ||
121 | |||
122 | static void interrupted(int sig){ | ||
123 | signal(SIGINT, SIG_IGN); | ||
124 | longjmp(jmp_env, 1); | ||
125 | } | ||
126 | |||
127 | static void error_exit(const char *str){ | ||
128 | perror(str); | ||
129 | //release all acquired resources | ||
130 | if (shmid != -1) | ||
131 | shmdt(buf); | ||
132 | |||
133 | exit(1); | ||
134 | } | ||
135 | |||
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 1276201c3..a7f982a35 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org> | 8 | * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org> |
9 | * | 9 | * |
10 | * "circular buffer" Copyright (C) 2001 by Gennady Feldman <gfeldman@cachier.com> | ||
11 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or | 14 | * the Free Software Foundation; either version 2 of the License, or |
@@ -40,25 +42,8 @@ | |||
40 | #include <sys/un.h> | 42 | #include <sys/un.h> |
41 | #include <sys/param.h> | 43 | #include <sys/param.h> |
42 | 44 | ||
43 | #if ! defined __GLIBC__ && ! defined __UCLIBC__ | ||
44 | #include <sys/syscall.h> | ||
45 | #include <linux/unistd.h> | ||
46 | typedef unsigned int socklen_t; | ||
47 | |||
48 | #ifndef __alpha__ | ||
49 | # define __NR_klogctl __NR_syslog | ||
50 | static inline _syscall3(int, klogctl, int, type, char *, b, int, len); | ||
51 | #else /* __alpha__ */ | ||
52 | #define klogctl syslog | ||
53 | #endif | ||
54 | |||
55 | #else | ||
56 | # include <sys/klog.h> | ||
57 | #endif | ||
58 | #include "busybox.h" | 45 | #include "busybox.h" |
59 | 46 | ||
60 | |||
61 | |||
62 | /* SYSLOG_NAMES defined to pull some extra junk from syslog.h */ | 47 | /* SYSLOG_NAMES defined to pull some extra junk from syslog.h */ |
63 | #define SYSLOG_NAMES | 48 | #define SYSLOG_NAMES |
64 | #include <sys/syslog.h> | 49 | #include <sys/syslog.h> |
@@ -91,6 +76,184 @@ static int doRemoteLog = FALSE; | |||
91 | static int local_logging = FALSE; | 76 | static int local_logging = FALSE; |
92 | #endif | 77 | #endif |
93 | 78 | ||
79 | /* circular buffer variables/structures */ | ||
80 | #ifdef BB_FEATURE_IPC_SYSLOG | ||
81 | |||
82 | #include <sys/ipc.h> | ||
83 | #include <sys/sem.h> | ||
84 | #include <sys/shm.h> | ||
85 | |||
86 | /* our shared key */ | ||
87 | static const long KEY_ID = 0x414e4547; /*"GENA"*/ | ||
88 | |||
89 | // Semaphore operation structures | ||
90 | static struct shbuf_ds { | ||
91 | int size; // size of data written | ||
92 | int head; // start of message list | ||
93 | int tail; // end of message list | ||
94 | char data[1]; // data/messages | ||
95 | } *buf = NULL; // shared memory pointer | ||
96 | |||
97 | static struct sembuf SMwup[1] = {{1, -1, IPC_NOWAIT}}; // set SMwup | ||
98 | static struct sembuf SMwdn[3] = {{0, 0}, {1, 0}, {1, +1}}; // set SMwdn | ||
99 | |||
100 | static int shmid = -1; // ipc shared memory id | ||
101 | static int s_semid = -1; // ipc semaphore id | ||
102 | int data_size = 16000; // data size | ||
103 | int shm_size = 16000 + sizeof(*buf); // our buffer size | ||
104 | static int circular_logging = FALSE; | ||
105 | |||
106 | /* | ||
107 | * sem_up - up()'s a semaphore. | ||
108 | */ | ||
109 | static inline void sem_up(int semid) | ||
110 | { | ||
111 | if ( semop(semid, SMwup, 1) == -1 ) | ||
112 | perror_msg_and_die("semop[SMwup]"); | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * sem_down - down()'s a semaphore | ||
117 | */ | ||
118 | static inline void sem_down(int semid) | ||
119 | { | ||
120 | if ( semop(semid, SMwdn, 2) == -1 ) | ||
121 | perror_msg_and_die("semop[SMwdn]"); | ||
122 | } | ||
123 | |||
124 | |||
125 | void ipcsyslog_cleanup(void){ | ||
126 | printf("Exiting Syslogd!\n"); | ||
127 | if (shmid != -1) | ||
128 | shmdt(buf); | ||
129 | |||
130 | if (shmid != -1) | ||
131 | shmctl(shmid, IPC_RMID, NULL); | ||
132 | if (s_semid != -1) | ||
133 | semctl(s_semid, 0, IPC_RMID, 0); | ||
134 | } | ||
135 | |||
136 | void ipcsyslog_init(void){ | ||
137 | if (buf == NULL){ | ||
138 | if ((shmid = shmget(KEY_ID, shm_size, IPC_CREAT | 1023)) == -1) | ||
139 | perror_msg_and_die("shmget"); | ||
140 | |||
141 | |||
142 | if ((buf = shmat(shmid, NULL, 0)) == NULL) | ||
143 | perror_msg_and_die("shmat"); | ||
144 | |||
145 | |||
146 | buf->size=data_size; | ||
147 | buf->head=buf->tail=0; | ||
148 | |||
149 | // we'll trust the OS to set initial semval to 0 (let's hope) | ||
150 | if ((s_semid = semget(KEY_ID, 2, IPC_CREAT | IPC_EXCL | 1023)) == -1){ | ||
151 | if (errno == EEXIST){ | ||
152 | if ((s_semid = semget(KEY_ID, 2, 0)) == -1) | ||
153 | perror_msg_and_die("semget"); | ||
154 | }else | ||
155 | perror_msg_and_die("semget"); | ||
156 | } | ||
157 | }else{ | ||
158 | printf("Buffer already allocated just grab the semaphore?"); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | /* write message to buffer */ | ||
163 | void circ_message(const char *msg){ | ||
164 | int l=strlen(msg)+1; /* count the whole message w/ '\0' included */ | ||
165 | |||
166 | sem_down(s_semid); | ||
167 | |||
168 | /* | ||
169 | * Circular Buffer Algorithm: | ||
170 | * -------------------------- | ||
171 | * | ||
172 | * Start-off w/ empty buffer of specific size SHM_SIZ | ||
173 | * Start filling it up w/ messages. I use '\0' as separator to break up messages. | ||
174 | * This is also very handy since we can do printf on message. | ||
175 | * | ||
176 | * Once the buffer is full we need to get rid of the first message in buffer and | ||
177 | * insert the new message. (Note: if the message being added is >1 message then | ||
178 | * we will need to "remove" >1 old message from the buffer). The way this is done | ||
179 | * is the following: | ||
180 | * When we reach the end of the buffer we set a mark and start from the beginning. | ||
181 | * Now what about the beginning and end of the buffer? Well we have the "head" | ||
182 | * index/pointer which is the starting point for the messages and we have "tail" | ||
183 | * index/pointer which is the ending point for the messages. When we "display" the | ||
184 | * messages we start from the beginning and continue until we reach "tail". If we | ||
185 | * reach end of buffer, then we just start from the beginning (offset 0). "head" and | ||
186 | * "tail" are actually offsets from the beginning of the buffer. | ||
187 | * | ||
188 | * Note: This algorithm uses Linux IPC mechanism w/ shared memory and semaphores to provide | ||
189 | * a threasafe way of handling shared memory operations. | ||
190 | */ | ||
191 | if ( (buf->tail + l) < buf->size ){ | ||
192 | /* before we append the message we need to check the HEAD so that we won't | ||
193 | overwrite any of the message that we still need and adjust HEAD to point | ||
194 | to the next message! */ | ||
195 | if ( buf->tail < buf->head){ | ||
196 | if ( (buf->tail + l) >= buf->head ){ | ||
197 | /* we need to move the HEAD to point to the next message | ||
198 | * Theoretically we have enough room to add the whole message to the | ||
199 | * buffer, because of the first outer IF statement, so we don't have | ||
200 | * to worry about overflows here! | ||
201 | */ | ||
202 | int k= buf->tail + l - buf->head; /* we need to know how many bytes | ||
203 | we are overwriting to make | ||
204 | enough room */ | ||
205 | char *c=memchr(buf->data+buf->head + k,'\0',buf->size - (buf->head + k)); | ||
206 | if (c != NULL) {/* do a sanity check just in case! */ | ||
207 | buf->head = c - buf->data + 1; /* we need to convert pointer to | ||
208 | offset + skip the '\0' since | ||
209 | we need to point to the beginning | ||
210 | of the next message */ | ||
211 | /* Note: HEAD is only used to "retrieve" messages, it's not used | ||
212 | when writing messages into our buffer */ | ||
213 | }else{ /* show an error message to know we messed up? */ | ||
214 | printf("Weird! Can't find the terminator token??? \n"); | ||
215 | buf->head=0; | ||
216 | } | ||
217 | } | ||
218 | } /* in other cases no overflows have been done yet, so we don't care! */ | ||
219 | |||
220 | /* we should be ok to append the message now */ | ||
221 | strncpy(buf->data + buf->tail,msg,l); /* append our message */ | ||
222 | buf->tail+=l; /* count full message w/ '\0' terminating char */ | ||
223 | }else{ | ||
224 | /* we need to break up the message and "circle" it around */ | ||
225 | char *c; | ||
226 | int k=buf->tail + l - buf->size; /* count # of bytes we don't fit */ | ||
227 | |||
228 | /* We need to move HEAD! This is always the case since we are going | ||
229 | * to "circle" the message. | ||
230 | */ | ||
231 | c=memchr(buf->data + k ,'\0', buf->size - k); | ||
232 | |||
233 | if (c != NULL) /* if we don't have '\0'??? weird!!! */{ | ||
234 | /* move head pointer*/ | ||
235 | buf->head=c-buf->data+1; | ||
236 | |||
237 | /* now write the first part of the message */ | ||
238 | strncpy(buf->data + buf->tail, msg, l - k - 1); | ||
239 | |||
240 | /* ALWAYS terminate end of buffer w/ '\0' */ | ||
241 | buf->data[buf->size-1]='\0'; | ||
242 | |||
243 | /* now write out the rest of the string to the beginning of the buffer */ | ||
244 | strcpy(buf->data, &msg[l-k-1]); | ||
245 | |||
246 | /* we need to place the TAIL at the end of the message */ | ||
247 | buf->tail = k + 1; | ||
248 | }else{ | ||
249 | printf("Weird! Can't find the terminator token from the beginning??? \n"); | ||
250 | buf->head = buf->tail = 0; /* reset buffer, since it's probably corrupted */ | ||
251 | } | ||
252 | |||
253 | } | ||
254 | sem_up(s_semid); | ||
255 | } | ||
256 | #endif | ||
94 | /* Note: There is also a function called "message()" in init.c */ | 257 | /* Note: There is also a function called "message()" in init.c */ |
95 | /* Print a message to the log file. */ | 258 | /* Print a message to the log file. */ |
96 | static void message (char *fmt, ...) __attribute__ ((format (printf, 1, 2))); | 259 | static void message (char *fmt, ...) __attribute__ ((format (printf, 1, 2))); |
@@ -104,6 +267,16 @@ static void message (char *fmt, ...) | |||
104 | fl.l_start = 0; | 267 | fl.l_start = 0; |
105 | fl.l_len = 1; | 268 | fl.l_len = 1; |
106 | 269 | ||
270 | #ifdef BB_FEATURE_IPC_SYSLOG | ||
271 | if ((circular_logging == TRUE) && (buf != NULL)){ | ||
272 | char b[1024]; | ||
273 | va_start (arguments, fmt); | ||
274 | vsprintf (b, fmt, arguments); | ||
275 | va_end (arguments); | ||
276 | circ_message(b); | ||
277 | |||
278 | }else | ||
279 | #endif | ||
107 | if ((fd = device_open (logFilePath, | 280 | if ((fd = device_open (logFilePath, |
108 | O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND | | 281 | O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND | |
109 | O_NONBLOCK)) >= 0) { | 282 | O_NONBLOCK)) >= 0) { |
@@ -197,6 +370,10 @@ static void quit_signal(int sig) | |||
197 | { | 370 | { |
198 | logMessage(0, "System log daemon exiting."); | 371 | logMessage(0, "System log daemon exiting."); |
199 | unlink(lfile); | 372 | unlink(lfile); |
373 | #ifdef BB_FEATURE_IPC_SYSLOG | ||
374 | ipcsyslog_cleanup(); | ||
375 | #endif | ||
376 | |||
200 | exit(TRUE); | 377 | exit(TRUE); |
201 | } | 378 | } |
202 | 379 | ||
@@ -382,85 +559,6 @@ static void doSyslogd (void) | |||
382 | } /* for main loop */ | 559 | } /* for main loop */ |
383 | } | 560 | } |
384 | 561 | ||
385 | #ifdef BB_FEATURE_KLOGD | ||
386 | |||
387 | static void klogd_signal(int sig) | ||
388 | { | ||
389 | klogctl(7, NULL, 0); | ||
390 | klogctl(0, 0, 0); | ||
391 | logMessage(0, "Kernel log daemon exiting."); | ||
392 | exit(TRUE); | ||
393 | } | ||
394 | |||
395 | static void doKlogd (void) __attribute__ ((noreturn)); | ||
396 | static void doKlogd (void) | ||
397 | { | ||
398 | int priority = LOG_INFO; | ||
399 | char log_buffer[4096]; | ||
400 | int i, n, lastc; | ||
401 | char *start; | ||
402 | |||
403 | /* Set up sig handlers */ | ||
404 | signal(SIGINT, klogd_signal); | ||
405 | signal(SIGKILL, klogd_signal); | ||
406 | signal(SIGTERM, klogd_signal); | ||
407 | signal(SIGHUP, SIG_IGN); | ||
408 | |||
409 | #ifdef BB_FEATURE_REMOTE_LOG | ||
410 | if (doRemoteLog == TRUE){ | ||
411 | init_RemoteLog(); | ||
412 | } | ||
413 | #endif | ||
414 | |||
415 | logMessage(0, "klogd started: " | ||
416 | "BusyBox v" BB_VER " (" BB_BT ")"); | ||
417 | |||
418 | /* "Open the log. Currently a NOP." */ | ||
419 | klogctl(1, NULL, 0); | ||
420 | |||
421 | while (1) { | ||
422 | /* Use kernel syscalls */ | ||
423 | memset(log_buffer, '\0', sizeof(log_buffer)); | ||
424 | n = klogctl(2, log_buffer, sizeof(log_buffer)); | ||
425 | if (n < 0) { | ||
426 | char message[80]; | ||
427 | |||
428 | if (errno == EINTR) | ||
429 | continue; | ||
430 | snprintf(message, 79, "klogd: Error return from sys_sycall: " \ | ||
431 | "%d - %s.\n", errno, strerror(errno)); | ||
432 | logMessage(LOG_SYSLOG | LOG_ERR, message); | ||
433 | exit(1); | ||
434 | } | ||
435 | |||
436 | /* klogctl buffer parsing modelled after code in dmesg.c */ | ||
437 | start=&log_buffer[0]; | ||
438 | lastc='\0'; | ||
439 | for (i=0; i<n; i++) { | ||
440 | if (lastc == '\0' && log_buffer[i] == '<') { | ||
441 | priority = 0; | ||
442 | i++; | ||
443 | while (isdigit(log_buffer[i])) { | ||
444 | priority = priority*10+(log_buffer[i]-'0'); | ||
445 | i++; | ||
446 | } | ||
447 | if (log_buffer[i] == '>') i++; | ||
448 | start = &log_buffer[i]; | ||
449 | } | ||
450 | if (log_buffer[i] == '\n') { | ||
451 | log_buffer[i] = '\0'; /* zero terminate this message */ | ||
452 | logMessage(LOG_KERN | priority, start); | ||
453 | start = &log_buffer[i+1]; | ||
454 | priority = LOG_INFO; | ||
455 | } | ||
456 | lastc = log_buffer[i]; | ||
457 | } | ||
458 | } | ||
459 | |||
460 | } | ||
461 | |||
462 | #endif | ||
463 | |||
464 | static void daemon_init (char **argv, char *dz, void fn (void)) | 562 | static void daemon_init (char **argv, char *dz, void fn (void)) |
465 | { | 563 | { |
466 | setsid(); | 564 | setsid(); |
@@ -472,16 +570,13 @@ static void daemon_init (char **argv, char *dz, void fn (void)) | |||
472 | 570 | ||
473 | extern int syslogd_main(int argc, char **argv) | 571 | extern int syslogd_main(int argc, char **argv) |
474 | { | 572 | { |
475 | int opt, pid, klogd_pid; | 573 | int opt, pid; |
476 | int doFork = TRUE; | 574 | int doFork = TRUE; |
477 | 575 | ||
478 | #ifdef BB_FEATURE_KLOGD | ||
479 | int startKlogd = TRUE; | ||
480 | #endif | ||
481 | char *p; | 576 | char *p; |
482 | 577 | ||
483 | /* do normal option parsing */ | 578 | /* do normal option parsing */ |
484 | while ((opt = getopt(argc, argv, "m:nKO:R:L")) > 0) { | 579 | while ((opt = getopt(argc, argv, "m:nO:R:LC")) > 0) { |
485 | switch (opt) { | 580 | switch (opt) { |
486 | case 'm': | 581 | case 'm': |
487 | MarkInterval = atoi(optarg) * 60; | 582 | MarkInterval = atoi(optarg) * 60; |
@@ -489,11 +584,6 @@ extern int syslogd_main(int argc, char **argv) | |||
489 | case 'n': | 584 | case 'n': |
490 | doFork = FALSE; | 585 | doFork = FALSE; |
491 | break; | 586 | break; |
492 | #ifdef BB_FEATURE_KLOGD | ||
493 | case 'K': | ||
494 | startKlogd = FALSE; | ||
495 | break; | ||
496 | #endif | ||
497 | case 'O': | 587 | case 'O': |
498 | logFilePath = strdup(optarg); | 588 | logFilePath = strdup(optarg); |
499 | break; | 589 | break; |
@@ -510,6 +600,11 @@ extern int syslogd_main(int argc, char **argv) | |||
510 | local_logging = TRUE; | 600 | local_logging = TRUE; |
511 | break; | 601 | break; |
512 | #endif | 602 | #endif |
603 | #ifdef BB_FEATURE_IPC_SYSLOG | ||
604 | case 'C': | ||
605 | circular_logging = TRUE; | ||
606 | break; | ||
607 | #endif | ||
513 | default: | 608 | default: |
514 | show_usage(); | 609 | show_usage(); |
515 | } | 610 | } |
@@ -521,6 +616,7 @@ extern int syslogd_main(int argc, char **argv) | |||
521 | local_logging = TRUE; | 616 | local_logging = TRUE; |
522 | #endif | 617 | #endif |
523 | 618 | ||
619 | |||
524 | /* Store away localhost's name before the fork */ | 620 | /* Store away localhost's name before the fork */ |
525 | gethostname(LocalHostName, sizeof(LocalHostName)); | 621 | gethostname(LocalHostName, sizeof(LocalHostName)); |
526 | if ((p = strchr(LocalHostName, '.'))) { | 622 | if ((p = strchr(LocalHostName, '.'))) { |
@@ -529,13 +625,9 @@ extern int syslogd_main(int argc, char **argv) | |||
529 | 625 | ||
530 | umask(0); | 626 | umask(0); |
531 | 627 | ||
532 | #ifdef BB_FEATURE_KLOGD | 628 | #ifdef BB_FEATURE_IPC_SYSLOG |
533 | /* Start up the klogd process */ | 629 | if (circular_logging == TRUE ){ |
534 | if (startKlogd == TRUE) { | 630 | ipcsyslog_init(); |
535 | klogd_pid = fork(); | ||
536 | if (klogd_pid == 0) { | ||
537 | daemon_init (argv, "klogd", doKlogd); | ||
538 | } | ||
539 | } | 631 | } |
540 | #endif | 632 | #endif |
541 | 633 | ||
@@ -7,6 +7,8 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org> | 8 | * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org> |
9 | * | 9 | * |
10 | * "circular buffer" Copyright (C) 2001 by Gennady Feldman <gfeldman@cachier.com> | ||
11 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or | 14 | * the Free Software Foundation; either version 2 of the License, or |
@@ -40,25 +42,8 @@ | |||
40 | #include <sys/un.h> | 42 | #include <sys/un.h> |
41 | #include <sys/param.h> | 43 | #include <sys/param.h> |
42 | 44 | ||
43 | #if ! defined __GLIBC__ && ! defined __UCLIBC__ | ||
44 | #include <sys/syscall.h> | ||
45 | #include <linux/unistd.h> | ||
46 | typedef unsigned int socklen_t; | ||
47 | |||
48 | #ifndef __alpha__ | ||
49 | # define __NR_klogctl __NR_syslog | ||
50 | static inline _syscall3(int, klogctl, int, type, char *, b, int, len); | ||
51 | #else /* __alpha__ */ | ||
52 | #define klogctl syslog | ||
53 | #endif | ||
54 | |||
55 | #else | ||
56 | # include <sys/klog.h> | ||
57 | #endif | ||
58 | #include "busybox.h" | 45 | #include "busybox.h" |
59 | 46 | ||
60 | |||
61 | |||
62 | /* SYSLOG_NAMES defined to pull some extra junk from syslog.h */ | 47 | /* SYSLOG_NAMES defined to pull some extra junk from syslog.h */ |
63 | #define SYSLOG_NAMES | 48 | #define SYSLOG_NAMES |
64 | #include <sys/syslog.h> | 49 | #include <sys/syslog.h> |
@@ -91,6 +76,184 @@ static int doRemoteLog = FALSE; | |||
91 | static int local_logging = FALSE; | 76 | static int local_logging = FALSE; |
92 | #endif | 77 | #endif |
93 | 78 | ||
79 | /* circular buffer variables/structures */ | ||
80 | #ifdef BB_FEATURE_IPC_SYSLOG | ||
81 | |||
82 | #include <sys/ipc.h> | ||
83 | #include <sys/sem.h> | ||
84 | #include <sys/shm.h> | ||
85 | |||
86 | /* our shared key */ | ||
87 | static const long KEY_ID = 0x414e4547; /*"GENA"*/ | ||
88 | |||
89 | // Semaphore operation structures | ||
90 | static struct shbuf_ds { | ||
91 | int size; // size of data written | ||
92 | int head; // start of message list | ||
93 | int tail; // end of message list | ||
94 | char data[1]; // data/messages | ||
95 | } *buf = NULL; // shared memory pointer | ||
96 | |||
97 | static struct sembuf SMwup[1] = {{1, -1, IPC_NOWAIT}}; // set SMwup | ||
98 | static struct sembuf SMwdn[3] = {{0, 0}, {1, 0}, {1, +1}}; // set SMwdn | ||
99 | |||
100 | static int shmid = -1; // ipc shared memory id | ||
101 | static int s_semid = -1; // ipc semaphore id | ||
102 | int data_size = 16000; // data size | ||
103 | int shm_size = 16000 + sizeof(*buf); // our buffer size | ||
104 | static int circular_logging = FALSE; | ||
105 | |||
106 | /* | ||
107 | * sem_up - up()'s a semaphore. | ||
108 | */ | ||
109 | static inline void sem_up(int semid) | ||
110 | { | ||
111 | if ( semop(semid, SMwup, 1) == -1 ) | ||
112 | perror_msg_and_die("semop[SMwup]"); | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * sem_down - down()'s a semaphore | ||
117 | */ | ||
118 | static inline void sem_down(int semid) | ||
119 | { | ||
120 | if ( semop(semid, SMwdn, 2) == -1 ) | ||
121 | perror_msg_and_die("semop[SMwdn]"); | ||
122 | } | ||
123 | |||
124 | |||
125 | void ipcsyslog_cleanup(void){ | ||
126 | printf("Exiting Syslogd!\n"); | ||
127 | if (shmid != -1) | ||
128 | shmdt(buf); | ||
129 | |||
130 | if (shmid != -1) | ||
131 | shmctl(shmid, IPC_RMID, NULL); | ||
132 | if (s_semid != -1) | ||
133 | semctl(s_semid, 0, IPC_RMID, 0); | ||
134 | } | ||
135 | |||
136 | void ipcsyslog_init(void){ | ||
137 | if (buf == NULL){ | ||
138 | if ((shmid = shmget(KEY_ID, shm_size, IPC_CREAT | 1023)) == -1) | ||
139 | perror_msg_and_die("shmget"); | ||
140 | |||
141 | |||
142 | if ((buf = shmat(shmid, NULL, 0)) == NULL) | ||
143 | perror_msg_and_die("shmat"); | ||
144 | |||
145 | |||
146 | buf->size=data_size; | ||
147 | buf->head=buf->tail=0; | ||
148 | |||
149 | // we'll trust the OS to set initial semval to 0 (let's hope) | ||
150 | if ((s_semid = semget(KEY_ID, 2, IPC_CREAT | IPC_EXCL | 1023)) == -1){ | ||
151 | if (errno == EEXIST){ | ||
152 | if ((s_semid = semget(KEY_ID, 2, 0)) == -1) | ||
153 | perror_msg_and_die("semget"); | ||
154 | }else | ||
155 | perror_msg_and_die("semget"); | ||
156 | } | ||
157 | }else{ | ||
158 | printf("Buffer already allocated just grab the semaphore?"); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | /* write message to buffer */ | ||
163 | void circ_message(const char *msg){ | ||
164 | int l=strlen(msg)+1; /* count the whole message w/ '\0' included */ | ||
165 | |||
166 | sem_down(s_semid); | ||
167 | |||
168 | /* | ||
169 | * Circular Buffer Algorithm: | ||
170 | * -------------------------- | ||
171 | * | ||
172 | * Start-off w/ empty buffer of specific size SHM_SIZ | ||
173 | * Start filling it up w/ messages. I use '\0' as separator to break up messages. | ||
174 | * This is also very handy since we can do printf on message. | ||
175 | * | ||
176 | * Once the buffer is full we need to get rid of the first message in buffer and | ||
177 | * insert the new message. (Note: if the message being added is >1 message then | ||
178 | * we will need to "remove" >1 old message from the buffer). The way this is done | ||
179 | * is the following: | ||
180 | * When we reach the end of the buffer we set a mark and start from the beginning. | ||
181 | * Now what about the beginning and end of the buffer? Well we have the "head" | ||
182 | * index/pointer which is the starting point for the messages and we have "tail" | ||
183 | * index/pointer which is the ending point for the messages. When we "display" the | ||
184 | * messages we start from the beginning and continue until we reach "tail". If we | ||
185 | * reach end of buffer, then we just start from the beginning (offset 0). "head" and | ||
186 | * "tail" are actually offsets from the beginning of the buffer. | ||
187 | * | ||
188 | * Note: This algorithm uses Linux IPC mechanism w/ shared memory and semaphores to provide | ||
189 | * a threasafe way of handling shared memory operations. | ||
190 | */ | ||
191 | if ( (buf->tail + l) < buf->size ){ | ||
192 | /* before we append the message we need to check the HEAD so that we won't | ||
193 | overwrite any of the message that we still need and adjust HEAD to point | ||
194 | to the next message! */ | ||
195 | if ( buf->tail < buf->head){ | ||
196 | if ( (buf->tail + l) >= buf->head ){ | ||
197 | /* we need to move the HEAD to point to the next message | ||
198 | * Theoretically we have enough room to add the whole message to the | ||
199 | * buffer, because of the first outer IF statement, so we don't have | ||
200 | * to worry about overflows here! | ||
201 | */ | ||
202 | int k= buf->tail + l - buf->head; /* we need to know how many bytes | ||
203 | we are overwriting to make | ||
204 | enough room */ | ||
205 | char *c=memchr(buf->data+buf->head + k,'\0',buf->size - (buf->head + k)); | ||
206 | if (c != NULL) {/* do a sanity check just in case! */ | ||
207 | buf->head = c - buf->data + 1; /* we need to convert pointer to | ||
208 | offset + skip the '\0' since | ||
209 | we need to point to the beginning | ||
210 | of the next message */ | ||
211 | /* Note: HEAD is only used to "retrieve" messages, it's not used | ||
212 | when writing messages into our buffer */ | ||
213 | }else{ /* show an error message to know we messed up? */ | ||
214 | printf("Weird! Can't find the terminator token??? \n"); | ||
215 | buf->head=0; | ||
216 | } | ||
217 | } | ||
218 | } /* in other cases no overflows have been done yet, so we don't care! */ | ||
219 | |||
220 | /* we should be ok to append the message now */ | ||
221 | strncpy(buf->data + buf->tail,msg,l); /* append our message */ | ||
222 | buf->tail+=l; /* count full message w/ '\0' terminating char */ | ||
223 | }else{ | ||
224 | /* we need to break up the message and "circle" it around */ | ||
225 | char *c; | ||
226 | int k=buf->tail + l - buf->size; /* count # of bytes we don't fit */ | ||
227 | |||
228 | /* We need to move HEAD! This is always the case since we are going | ||
229 | * to "circle" the message. | ||
230 | */ | ||
231 | c=memchr(buf->data + k ,'\0', buf->size - k); | ||
232 | |||
233 | if (c != NULL) /* if we don't have '\0'??? weird!!! */{ | ||
234 | /* move head pointer*/ | ||
235 | buf->head=c-buf->data+1; | ||
236 | |||
237 | /* now write the first part of the message */ | ||
238 | strncpy(buf->data + buf->tail, msg, l - k - 1); | ||
239 | |||
240 | /* ALWAYS terminate end of buffer w/ '\0' */ | ||
241 | buf->data[buf->size-1]='\0'; | ||
242 | |||
243 | /* now write out the rest of the string to the beginning of the buffer */ | ||
244 | strcpy(buf->data, &msg[l-k-1]); | ||
245 | |||
246 | /* we need to place the TAIL at the end of the message */ | ||
247 | buf->tail = k + 1; | ||
248 | }else{ | ||
249 | printf("Weird! Can't find the terminator token from the beginning??? \n"); | ||
250 | buf->head = buf->tail = 0; /* reset buffer, since it's probably corrupted */ | ||
251 | } | ||
252 | |||
253 | } | ||
254 | sem_up(s_semid); | ||
255 | } | ||
256 | #endif | ||
94 | /* Note: There is also a function called "message()" in init.c */ | 257 | /* Note: There is also a function called "message()" in init.c */ |
95 | /* Print a message to the log file. */ | 258 | /* Print a message to the log file. */ |
96 | static void message (char *fmt, ...) __attribute__ ((format (printf, 1, 2))); | 259 | static void message (char *fmt, ...) __attribute__ ((format (printf, 1, 2))); |
@@ -104,6 +267,16 @@ static void message (char *fmt, ...) | |||
104 | fl.l_start = 0; | 267 | fl.l_start = 0; |
105 | fl.l_len = 1; | 268 | fl.l_len = 1; |
106 | 269 | ||
270 | #ifdef BB_FEATURE_IPC_SYSLOG | ||
271 | if ((circular_logging == TRUE) && (buf != NULL)){ | ||
272 | char b[1024]; | ||
273 | va_start (arguments, fmt); | ||
274 | vsprintf (b, fmt, arguments); | ||
275 | va_end (arguments); | ||
276 | circ_message(b); | ||
277 | |||
278 | }else | ||
279 | #endif | ||
107 | if ((fd = device_open (logFilePath, | 280 | if ((fd = device_open (logFilePath, |
108 | O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND | | 281 | O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND | |
109 | O_NONBLOCK)) >= 0) { | 282 | O_NONBLOCK)) >= 0) { |
@@ -197,6 +370,10 @@ static void quit_signal(int sig) | |||
197 | { | 370 | { |
198 | logMessage(0, "System log daemon exiting."); | 371 | logMessage(0, "System log daemon exiting."); |
199 | unlink(lfile); | 372 | unlink(lfile); |
373 | #ifdef BB_FEATURE_IPC_SYSLOG | ||
374 | ipcsyslog_cleanup(); | ||
375 | #endif | ||
376 | |||
200 | exit(TRUE); | 377 | exit(TRUE); |
201 | } | 378 | } |
202 | 379 | ||
@@ -382,85 +559,6 @@ static void doSyslogd (void) | |||
382 | } /* for main loop */ | 559 | } /* for main loop */ |
383 | } | 560 | } |
384 | 561 | ||
385 | #ifdef BB_FEATURE_KLOGD | ||
386 | |||
387 | static void klogd_signal(int sig) | ||
388 | { | ||
389 | klogctl(7, NULL, 0); | ||
390 | klogctl(0, 0, 0); | ||
391 | logMessage(0, "Kernel log daemon exiting."); | ||
392 | exit(TRUE); | ||
393 | } | ||
394 | |||
395 | static void doKlogd (void) __attribute__ ((noreturn)); | ||
396 | static void doKlogd (void) | ||
397 | { | ||
398 | int priority = LOG_INFO; | ||
399 | char log_buffer[4096]; | ||
400 | int i, n, lastc; | ||
401 | char *start; | ||
402 | |||
403 | /* Set up sig handlers */ | ||
404 | signal(SIGINT, klogd_signal); | ||
405 | signal(SIGKILL, klogd_signal); | ||
406 | signal(SIGTERM, klogd_signal); | ||
407 | signal(SIGHUP, SIG_IGN); | ||
408 | |||
409 | #ifdef BB_FEATURE_REMOTE_LOG | ||
410 | if (doRemoteLog == TRUE){ | ||
411 | init_RemoteLog(); | ||
412 | } | ||
413 | #endif | ||
414 | |||
415 | logMessage(0, "klogd started: " | ||
416 | "BusyBox v" BB_VER " (" BB_BT ")"); | ||
417 | |||
418 | /* "Open the log. Currently a NOP." */ | ||
419 | klogctl(1, NULL, 0); | ||
420 | |||
421 | while (1) { | ||
422 | /* Use kernel syscalls */ | ||
423 | memset(log_buffer, '\0', sizeof(log_buffer)); | ||
424 | n = klogctl(2, log_buffer, sizeof(log_buffer)); | ||
425 | if (n < 0) { | ||
426 | char message[80]; | ||
427 | |||
428 | if (errno == EINTR) | ||
429 | continue; | ||
430 | snprintf(message, 79, "klogd: Error return from sys_sycall: " \ | ||
431 | "%d - %s.\n", errno, strerror(errno)); | ||
432 | logMessage(LOG_SYSLOG | LOG_ERR, message); | ||
433 | exit(1); | ||
434 | } | ||
435 | |||
436 | /* klogctl buffer parsing modelled after code in dmesg.c */ | ||
437 | start=&log_buffer[0]; | ||
438 | lastc='\0'; | ||
439 | for (i=0; i<n; i++) { | ||
440 | if (lastc == '\0' && log_buffer[i] == '<') { | ||
441 | priority = 0; | ||
442 | i++; | ||
443 | while (isdigit(log_buffer[i])) { | ||
444 | priority = priority*10+(log_buffer[i]-'0'); | ||
445 | i++; | ||
446 | } | ||
447 | if (log_buffer[i] == '>') i++; | ||
448 | start = &log_buffer[i]; | ||
449 | } | ||
450 | if (log_buffer[i] == '\n') { | ||
451 | log_buffer[i] = '\0'; /* zero terminate this message */ | ||
452 | logMessage(LOG_KERN | priority, start); | ||
453 | start = &log_buffer[i+1]; | ||
454 | priority = LOG_INFO; | ||
455 | } | ||
456 | lastc = log_buffer[i]; | ||
457 | } | ||
458 | } | ||
459 | |||
460 | } | ||
461 | |||
462 | #endif | ||
463 | |||
464 | static void daemon_init (char **argv, char *dz, void fn (void)) | 562 | static void daemon_init (char **argv, char *dz, void fn (void)) |
465 | { | 563 | { |
466 | setsid(); | 564 | setsid(); |
@@ -472,16 +570,13 @@ static void daemon_init (char **argv, char *dz, void fn (void)) | |||
472 | 570 | ||
473 | extern int syslogd_main(int argc, char **argv) | 571 | extern int syslogd_main(int argc, char **argv) |
474 | { | 572 | { |
475 | int opt, pid, klogd_pid; | 573 | int opt, pid; |
476 | int doFork = TRUE; | 574 | int doFork = TRUE; |
477 | 575 | ||
478 | #ifdef BB_FEATURE_KLOGD | ||
479 | int startKlogd = TRUE; | ||
480 | #endif | ||
481 | char *p; | 576 | char *p; |
482 | 577 | ||
483 | /* do normal option parsing */ | 578 | /* do normal option parsing */ |
484 | while ((opt = getopt(argc, argv, "m:nKO:R:L")) > 0) { | 579 | while ((opt = getopt(argc, argv, "m:nO:R:LC")) > 0) { |
485 | switch (opt) { | 580 | switch (opt) { |
486 | case 'm': | 581 | case 'm': |
487 | MarkInterval = atoi(optarg) * 60; | 582 | MarkInterval = atoi(optarg) * 60; |
@@ -489,11 +584,6 @@ extern int syslogd_main(int argc, char **argv) | |||
489 | case 'n': | 584 | case 'n': |
490 | doFork = FALSE; | 585 | doFork = FALSE; |
491 | break; | 586 | break; |
492 | #ifdef BB_FEATURE_KLOGD | ||
493 | case 'K': | ||
494 | startKlogd = FALSE; | ||
495 | break; | ||
496 | #endif | ||
497 | case 'O': | 587 | case 'O': |
498 | logFilePath = strdup(optarg); | 588 | logFilePath = strdup(optarg); |
499 | break; | 589 | break; |
@@ -510,6 +600,11 @@ extern int syslogd_main(int argc, char **argv) | |||
510 | local_logging = TRUE; | 600 | local_logging = TRUE; |
511 | break; | 601 | break; |
512 | #endif | 602 | #endif |
603 | #ifdef BB_FEATURE_IPC_SYSLOG | ||
604 | case 'C': | ||
605 | circular_logging = TRUE; | ||
606 | break; | ||
607 | #endif | ||
513 | default: | 608 | default: |
514 | show_usage(); | 609 | show_usage(); |
515 | } | 610 | } |
@@ -521,6 +616,7 @@ extern int syslogd_main(int argc, char **argv) | |||
521 | local_logging = TRUE; | 616 | local_logging = TRUE; |
522 | #endif | 617 | #endif |
523 | 618 | ||
619 | |||
524 | /* Store away localhost's name before the fork */ | 620 | /* Store away localhost's name before the fork */ |
525 | gethostname(LocalHostName, sizeof(LocalHostName)); | 621 | gethostname(LocalHostName, sizeof(LocalHostName)); |
526 | if ((p = strchr(LocalHostName, '.'))) { | 622 | if ((p = strchr(LocalHostName, '.'))) { |
@@ -529,13 +625,9 @@ extern int syslogd_main(int argc, char **argv) | |||
529 | 625 | ||
530 | umask(0); | 626 | umask(0); |
531 | 627 | ||
532 | #ifdef BB_FEATURE_KLOGD | 628 | #ifdef BB_FEATURE_IPC_SYSLOG |
533 | /* Start up the klogd process */ | 629 | if (circular_logging == TRUE ){ |
534 | if (startKlogd == TRUE) { | 630 | ipcsyslog_init(); |
535 | klogd_pid = fork(); | ||
536 | if (klogd_pid == 0) { | ||
537 | daemon_init (argv, "klogd", doKlogd); | ||
538 | } | ||
539 | } | 631 | } |
540 | #endif | 632 | #endif |
541 | 633 | ||
@@ -468,6 +468,13 @@ | |||
468 | "Options:\n" \ | 468 | "Options:\n" \ |
469 | "\t-l\tList all signal names and numbers." | 469 | "\t-l\tList all signal names and numbers." |
470 | 470 | ||
471 | #define klogd_trivial_usage \ | ||
472 | "-n" | ||
473 | #define klogd_full_usage \ | ||
474 | "Kernel logger.\n"\ | ||
475 | "Options:\n"\ | ||
476 | "\t-n\tRun as a foreground process." | ||
477 | |||
471 | #define length_trivial_usage \ | 478 | #define length_trivial_usage \ |
472 | "STRING" | 479 | "STRING" |
473 | #define length_full_usage \ | 480 | #define length_full_usage \ |
@@ -513,6 +520,12 @@ | |||
513 | #define logname_full_usage \ | 520 | #define logname_full_usage \ |
514 | "Print the name of the current user." | 521 | "Print the name of the current user." |
515 | 522 | ||
523 | #define logread_trivial_usage \ | ||
524 | "" | ||
525 | |||
526 | #define logread_full_usage \ | ||
527 | "Shows the messages from syslogd (using circular buffer)." | ||
528 | |||
516 | #ifdef BB_FEATURE_LS_TIMESTAMPS | 529 | #ifdef BB_FEATURE_LS_TIMESTAMPS |
517 | #define USAGE_LS_TIMESTAMPS(a) a | 530 | #define USAGE_LS_TIMESTAMPS(a) a |
518 | #else | 531 | #else |
@@ -913,11 +926,6 @@ | |||
913 | "Write all buffered filesystem blocks to disk." | 926 | "Write all buffered filesystem blocks to disk." |
914 | 927 | ||
915 | 928 | ||
916 | #ifdef BB_FEATURE_KLOGD | ||
917 | #define USAGE_KLOGD(a) a | ||
918 | #else | ||
919 | #define USAGE_KLOGD(a) | ||
920 | #endif | ||
921 | #ifdef BB_FEATURE_REMOTE_LOG | 929 | #ifdef BB_FEATURE_REMOTE_LOG |
922 | #define USAGE_REMOTE_LOG(a) a | 930 | #define USAGE_REMOTE_LOG(a) a |
923 | #else | 931 | #else |
@@ -926,12 +934,11 @@ | |||
926 | #define syslogd_trivial_usage \ | 934 | #define syslogd_trivial_usage \ |
927 | "[OPTION]..." | 935 | "[OPTION]..." |
928 | #define syslogd_full_usage \ | 936 | #define syslogd_full_usage \ |
929 | "Linux system and kernel (provides klogd) logging utility.\n" \ | 937 | "Linux system and kernel logging utility.\n" \ |
930 | "Note that this version of syslogd/klogd ignores /etc/syslog.conf.\n\n" \ | 938 | "Note that this version of syslogd ignores /etc/syslog.conf.\n\n" \ |
931 | "Options:\n" \ | 939 | "Options:\n" \ |
932 | "\t-m NUM\t\tInterval between MARK lines (default=20min, 0=off)\n" \ | 940 | "\t-m NUM\t\tInterval between MARK lines (default=20min, 0=off)\n" \ |
933 | "\t-n\t\tRun as a foreground process\n" \ | 941 | "\t-n\t\tRun as a foreground process\n" \ |
934 | USAGE_KLOGD("\t-K\t\tDo not start up the klogd process\n") \ | ||
935 | "\t-O FILE\t\tUse an alternate log file (default=/var/log/messages)" \ | 942 | "\t-O FILE\t\tUse an alternate log file (default=/var/log/messages)" \ |
936 | USAGE_REMOTE_LOG( \ | 943 | USAGE_REMOTE_LOG( \ |
937 | "\n\t-R HOST[:PORT]\tLog to IP or hostname on PORT (default PORT=514/UDP)\n" \ | 944 | "\n\t-R HOST[:PORT]\tLog to IP or hostname on PORT (default PORT=514/UDP)\n" \ |
@@ -77,6 +77,10 @@ const char mtab_file[] = "/proc/mounts"; | |||
77 | # endif | 77 | # endif |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | #if defined(BB_KLOGD) || defined(BB_LOGGER) | ||
81 | #include <syslog.h> | ||
82 | #endif | ||
83 | |||
80 | static struct BB_applet *applet_using; | 84 | static struct BB_applet *applet_using; |
81 | 85 | ||
82 | extern void show_usage(void) | 86 | extern void show_usage(void) |
@@ -1828,6 +1832,20 @@ void chomp(char *s) | |||
1828 | } | 1832 | } |
1829 | #endif | 1833 | #endif |
1830 | 1834 | ||
1835 | #if defined(BB_KLOGD) || defined(BB_LOGGER) | ||
1836 | void syslog_msg_with_name(const char *name, int facility, int pri, const char *msg) | ||
1837 | { | ||
1838 | openlog(name, 0, facility); | ||
1839 | syslog(pri, "%s", msg); | ||
1840 | closelog(); | ||
1841 | } | ||
1842 | |||
1843 | void syslog_msg(int facility, int pri, const char *msg) | ||
1844 | { | ||
1845 | syslog_msg_with_name(applet_using->name, facility, pri, msg); | ||
1846 | } | ||
1847 | #endif | ||
1848 | |||
1831 | #if defined(BB_SH) | 1849 | #if defined(BB_SH) |
1832 | void trim(char *s) | 1850 | void trim(char *s) |
1833 | { | 1851 | { |