source: MondoRescue/branches/stable/mindi-busybox/sysklogd/syslogd.c@ 1770

Last change on this file since 1770 was 1770, checked in by Bruno Cornec, 16 years ago
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

File size: 15.9 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * Mini syslogd implementation for busybox
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 *
7 * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org>
8 *
9 * "circular buffer" Copyright (C) 2001 by Gennady Feldman <gfeldman@gena01.com>
10 *
11 * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001
12 *
13 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
14 */
15
16#include "libbb.h"
17#include <paths.h>
18#include <sys/un.h>
19
20/* SYSLOG_NAMES defined to pull prioritynames[] and facilitynames[]
21 * from syslog.h. Grrrr - glibc puts those in _rwdata_! :( */
22#define SYSLOG_NAMES
23#define SYSLOG_NAMES_CONST /* uclibc is saner :) */
24#include <sys/syslog.h>
25#include <sys/uio.h>
26
27#if ENABLE_FEATURE_REMOTE_LOG
28#include <netinet/in.h>
29#endif
30
31#if ENABLE_FEATURE_IPC_SYSLOG
32#include <sys/ipc.h>
33#include <sys/sem.h>
34#include <sys/shm.h>
35#endif
36
37
38#define DEBUG 0
39
40/* MARK code is not very useful, is bloat, and broken:
41 * can deadlock if alarmed to make MARK while writing to IPC buffer
42 * (semaphores are down but do_mark routine tries to down them again) */
43#undef SYSLOGD_MARK
44
45enum { MAX_READ = 256 };
46
47/* Semaphore operation structures */
48struct shbuf_ds {
49 int32_t size; /* size of data - 1 */
50 int32_t tail; /* end of message list */
51 char data[1]; /* data/messages */
52};
53
54/* Allows us to have smaller initializer. Ugly. */
55#define GLOBALS \
56 const char *logFilePath; \
57 int logFD; \
58 /* interval between marks in seconds */ \
59 /*int markInterval;*/ \
60 /* level of messages to be logged */ \
61 int logLevel; \
62USE_FEATURE_ROTATE_LOGFILE( \
63 /* max size of file before rotation */ \
64 unsigned logFileSize; \
65 /* number of rotated message files */ \
66 unsigned logFileRotate; \
67 unsigned curFileSize; \
68 smallint isRegular; \
69) \
70USE_FEATURE_REMOTE_LOG( \
71 /* udp socket for remote logging */ \
72 int remoteFD; \
73 len_and_sockaddr* remoteAddr; \
74) \
75USE_FEATURE_IPC_SYSLOG( \
76 int shmid; /* ipc shared memory id */ \
77 int s_semid; /* ipc semaphore id */ \
78 int shm_size; \
79 struct sembuf SMwup[1]; \
80 struct sembuf SMwdn[3]; \
81)
82
83struct init_globals {
84 GLOBALS
85};
86
87struct globals {
88 GLOBALS
89#if ENABLE_FEATURE_IPC_SYSLOG
90 struct shbuf_ds *shbuf;
91#endif
92 time_t last_log_time;
93 /* localhost's name */
94 char localHostName[64];
95
96 /* We recv into recvbuf... */
97 char recvbuf[MAX_READ];
98 /* ...then copy to parsebuf, escaping control chars */
99 /* (can grow x2 max) */
100 char parsebuf[MAX_READ*2];
101 /* ...then sprintf into printbuf, adding timestamp (15 chars),
102 * host (64), fac.prio (20) to the message */
103 /* (growth by: 15 + 64 + 20 + delims = ~110) */
104 char printbuf[MAX_READ*2 + 128];
105};
106
107static const struct init_globals init_data = {
108 .logFilePath = "/var/log/messages",
109 .logFD = -1,
110#ifdef SYSLOGD_MARK
111 .markInterval = 20 * 60,
112#endif
113 .logLevel = 8,
114#if ENABLE_FEATURE_ROTATE_LOGFILE
115 .logFileSize = 200 * 1024,
116 .logFileRotate = 1,
117#endif
118#if ENABLE_FEATURE_REMOTE_LOG
119 .remoteFD = -1,
120#endif
121#if ENABLE_FEATURE_IPC_SYSLOG
122 .shmid = -1,
123 .s_semid = -1,
124 .shm_size = ((CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE)*1024), // default shm size
125 .SMwup = { {1, -1, IPC_NOWAIT} },
126 .SMwdn = { {0, 0}, {1, 0}, {1, +1} },
127#endif
128};
129
130#define G (*ptr_to_globals)
131
132
133/* Options */
134enum {
135 OPTBIT_mark = 0, // -m
136 OPTBIT_nofork, // -n
137 OPTBIT_outfile, // -O
138 OPTBIT_loglevel, // -l
139 OPTBIT_small, // -S
140 USE_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize ,) // -s
141 USE_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt ,) // -b
142 USE_FEATURE_REMOTE_LOG( OPTBIT_remote ,) // -R
143 USE_FEATURE_REMOTE_LOG( OPTBIT_localtoo ,) // -L
144 USE_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C
145
146 OPT_mark = 1 << OPTBIT_mark ,
147 OPT_nofork = 1 << OPTBIT_nofork ,
148 OPT_outfile = 1 << OPTBIT_outfile ,
149 OPT_loglevel = 1 << OPTBIT_loglevel,
150 OPT_small = 1 << OPTBIT_small ,
151 OPT_filesize = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize )) + 0,
152 OPT_rotatecnt = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt )) + 0,
153 OPT_remotelog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_remote )) + 0,
154 OPT_locallog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_localtoo )) + 0,
155 OPT_circularlog = USE_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0,
156};
157#define OPTION_STR "m:nO:l:S" \
158 USE_FEATURE_ROTATE_LOGFILE("s:" ) \
159 USE_FEATURE_ROTATE_LOGFILE("b:" ) \
160 USE_FEATURE_REMOTE_LOG( "R:" ) \
161 USE_FEATURE_REMOTE_LOG( "L" ) \
162 USE_FEATURE_IPC_SYSLOG( "C::")
163#define OPTION_DECL *opt_m, *opt_l \
164 USE_FEATURE_ROTATE_LOGFILE(,*opt_s) \
165 USE_FEATURE_ROTATE_LOGFILE(,*opt_b) \
166 USE_FEATURE_REMOTE_LOG( ,*opt_R) \
167 USE_FEATURE_IPC_SYSLOG( ,*opt_C = NULL)
168#define OPTION_PARAM &opt_m, &G.logFilePath, &opt_l \
169 USE_FEATURE_ROTATE_LOGFILE(,&opt_s) \
170 USE_FEATURE_ROTATE_LOGFILE(,&opt_b) \
171 USE_FEATURE_REMOTE_LOG( ,&opt_R) \
172 USE_FEATURE_IPC_SYSLOG( ,&opt_C)
173
174
175/* circular buffer variables/structures */
176#if ENABLE_FEATURE_IPC_SYSLOG
177
178#if CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE < 4
179#error Sorry, you must set the syslogd buffer size to at least 4KB.
180#error Please check CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE
181#endif
182
183/* our shared key */
184#define KEY_ID ((long)0x414e4547) /* "GENA" */
185
186static void ipcsyslog_cleanup(void)
187{
188 if (G.shmid != -1) {
189 shmdt(G.shbuf);
190 }
191 if (G.shmid != -1) {
192 shmctl(G.shmid, IPC_RMID, NULL);
193 }
194 if (G.s_semid != -1) {
195 semctl(G.s_semid, 0, IPC_RMID, 0);
196 }
197}
198
199static void ipcsyslog_init(void)
200{
201 if (DEBUG)
202 printf("shmget(%lx, %d,...)\n", KEY_ID, G.shm_size);
203
204 G.shmid = shmget(KEY_ID, G.shm_size, IPC_CREAT | 0644);
205 if (G.shmid == -1) {
206 bb_perror_msg_and_die("shmget");
207 }
208
209 G.shbuf = shmat(G.shmid, NULL, 0);
210 if (!G.shbuf) {
211 bb_perror_msg_and_die("shmat");
212 }
213
214 memset(G.shbuf, 0, G.shm_size);
215 G.shbuf->size = G.shm_size - offsetof(struct shbuf_ds, data) - 1;
216 /*G.shbuf->tail = 0;*/
217
218 // we'll trust the OS to set initial semval to 0 (let's hope)
219 G.s_semid = semget(KEY_ID, 2, IPC_CREAT | IPC_EXCL | 1023);
220 if (G.s_semid == -1) {
221 if (errno == EEXIST) {
222 G.s_semid = semget(KEY_ID, 2, 0);
223 if (G.s_semid != -1)
224 return;
225 }
226 bb_perror_msg_and_die("semget");
227 }
228}
229
230/* Write message to shared mem buffer */
231static void log_to_shmem(const char *msg, int len)
232{
233 int old_tail, new_tail;
234
235 if (semop(G.s_semid, G.SMwdn, 3) == -1) {
236 bb_perror_msg_and_die("SMwdn");
237 }
238
239 /* Circular Buffer Algorithm:
240 * --------------------------
241 * tail == position where to store next syslog message.
242 * tail's max value is (shbuf->size - 1)
243 * Last byte of buffer is never used and remains NUL.
244 */
245 len++; /* length with NUL included */
246 again:
247 old_tail = G.shbuf->tail;
248 new_tail = old_tail + len;
249 if (new_tail < G.shbuf->size) {
250 /* store message, set new tail */
251 memcpy(G.shbuf->data + old_tail, msg, len);
252 G.shbuf->tail = new_tail;
253 } else {
254 /* k == available buffer space ahead of old tail */
255 int k = G.shbuf->size - old_tail;
256 /* copy what fits to the end of buffer, and repeat */
257 memcpy(G.shbuf->data + old_tail, msg, k);
258 msg += k;
259 len -= k;
260 G.shbuf->tail = 0;
261 goto again;
262 }
263 if (semop(G.s_semid, G.SMwup, 1) == -1) {
264 bb_perror_msg_and_die("SMwup");
265 }
266 if (DEBUG)
267 printf("tail:%d\n", G.shbuf->tail);
268}
269#else
270void ipcsyslog_cleanup(void);
271void ipcsyslog_init(void);
272void log_to_shmem(const char *msg);
273#endif /* FEATURE_IPC_SYSLOG */
274
275
276/* Print a message to the log file. */
277static void log_locally(char *msg)
278{
279 struct flock fl;
280 int len = strlen(msg);
281
282#if ENABLE_FEATURE_IPC_SYSLOG
283 if ((option_mask32 & OPT_circularlog) && G.shbuf) {
284 log_to_shmem(msg, len);
285 return;
286 }
287#endif
288 if (G.logFD >= 0) {
289 time_t cur;
290 time(&cur);
291 if (G.last_log_time != cur) {
292 G.last_log_time = cur; /* reopen log file every second */
293 close(G.logFD);
294 goto reopen;
295 }
296 } else {
297 reopen:
298 G.logFD = device_open(G.logFilePath, O_WRONLY | O_CREAT
299 | O_NOCTTY | O_APPEND | O_NONBLOCK);
300 if (G.logFD < 0) {
301 /* cannot open logfile? - print to /dev/console then */
302 int fd = device_open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK);
303 if (fd < 0)
304 fd = 2; /* then stderr, dammit */
305 full_write(fd, msg, len);
306 if (fd != 2)
307 close(fd);
308 return;
309 }
310#if ENABLE_FEATURE_ROTATE_LOGFILE
311 {
312 struct stat statf;
313 G.isRegular = (fstat(G.logFD, &statf) == 0 && S_ISREG(statf.st_mode));
314 /* bug (mostly harmless): can wrap around if file > 4gb */
315 G.curFileSize = statf.st_size;
316 }
317#endif
318 }
319
320 fl.l_whence = SEEK_SET;
321 fl.l_start = 0;
322 fl.l_len = 1;
323 fl.l_type = F_WRLCK;
324 fcntl(G.logFD, F_SETLKW, &fl);
325
326#if ENABLE_FEATURE_ROTATE_LOGFILE
327 if (G.logFileSize && G.isRegular && G.curFileSize > G.logFileSize) {
328 if (G.logFileRotate) { /* always 0..99 */
329 int i = strlen(G.logFilePath) + 3 + 1;
330 char oldFile[i];
331 char newFile[i];
332 i = G.logFileRotate - 1;
333 /* rename: f.8 -> f.9; f.7 -> f.8; ... */
334 while (1) {
335 sprintf(newFile, "%s.%d", G.logFilePath, i);
336 if (i == 0) break;
337 sprintf(oldFile, "%s.%d", G.logFilePath, --i);
338 rename(oldFile, newFile);
339 }
340 /* newFile == "f.0" now */
341 rename(G.logFilePath, newFile);
342 fl.l_type = F_UNLCK;
343 fcntl(G.logFD, F_SETLKW, &fl);
344 close(G.logFD);
345 goto reopen;
346 }
347 ftruncate(G.logFD, 0);
348 }
349 G.curFileSize +=
350#endif
351 full_write(G.logFD, msg, len);
352 fl.l_type = F_UNLCK;
353 fcntl(G.logFD, F_SETLKW, &fl);
354}
355
356static void parse_fac_prio_20(int pri, char *res20)
357{
358 const CODE *c_pri, *c_fac;
359
360 if (pri != 0) {
361 c_fac = facilitynames;
362 while (c_fac->c_name) {
363 if (c_fac->c_val != (LOG_FAC(pri) << 3)) {
364 c_fac++; continue;
365 }
366 /* facility is found, look for prio */
367 c_pri = prioritynames;
368 while (c_pri->c_name) {
369 if (c_pri->c_val != LOG_PRI(pri)) {
370 c_pri++; continue;
371 }
372 snprintf(res20, 20, "%s.%s",
373 c_fac->c_name, c_pri->c_name);
374 return;
375 }
376 /* prio not found, bail out */
377 break;
378 }
379 snprintf(res20, 20, "<%d>", pri);
380 }
381}
382
383/* len parameter is used only for "is there a timestamp?" check.
384 * NB: some callers cheat and supply 0 when they know
385 * that there is no timestamp, short-cutting the test. */
386static void timestamp_and_log(int pri, char *msg, int len)
387{
388 char *timestamp;
389
390 if (len < 16 || msg[3] != ' ' || msg[6] != ' '
391 || msg[9] != ':' || msg[12] != ':' || msg[15] != ' '
392 ) {
393 time_t now;
394 time(&now);
395 timestamp = ctime(&now) + 4;
396 } else {
397 timestamp = msg;
398 msg += 16;
399 }
400 timestamp[15] = '\0';
401
402 /* Log message locally (to file or shared mem) */
403 if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
404 if (LOG_PRI(pri) < G.logLevel) {
405 if (option_mask32 & OPT_small)
406 sprintf(G.printbuf, "%s %s\n", timestamp, msg);
407 else {
408 char res[20];
409 parse_fac_prio_20(pri, res);
410 sprintf(G.printbuf, "%s %s %s %s\n", timestamp, G.localHostName, res, msg);
411 }
412 log_locally(G.printbuf);
413 }
414 }
415}
416
417static void split_escape_and_log(char *tmpbuf, int len)
418{
419 char *p = tmpbuf;
420
421 tmpbuf += len;
422 while (p < tmpbuf) {
423 char c;
424 char *q = G.parsebuf;
425 int pri = (LOG_USER | LOG_NOTICE);
426
427 if (*p == '<') {
428 /* Parse the magic priority number */
429 pri = bb_strtou(p + 1, &p, 10);
430 if (*p == '>') p++;
431 if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) {
432 pri = (LOG_USER | LOG_NOTICE);
433 }
434 }
435
436 while ((c = *p++)) {
437 if (c == '\n')
438 c = ' ';
439 if (!(c & ~0x1f) && c != '\t') {
440 *q++ = '^';
441 c += '@'; /* ^@, ^A, ^B... */
442 }
443 *q++ = c;
444 }
445 *q = '\0';
446 /* Now log it */
447 timestamp_and_log(pri, G.parsebuf, q - G.parsebuf);
448 }
449}
450
451static void quit_signal(int sig)
452{
453 timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)"syslogd exiting", 0);
454 puts("syslogd exiting");
455 if (ENABLE_FEATURE_IPC_SYSLOG)
456 ipcsyslog_cleanup();
457 exit(1);
458}
459
460#ifdef SYSLOGD_MARK
461static void do_mark(int sig)
462{
463 if (G.markInterval) {
464 timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)"-- MARK --", 0);
465 alarm(G.markInterval);
466 }
467}
468#endif
469
470static void do_syslogd(void) ATTRIBUTE_NORETURN;
471static void do_syslogd(void)
472{
473 struct sockaddr_un sunx;
474 int sock_fd;
475 fd_set fds;
476 char *dev_log_name;
477
478 /* Set up signal handlers */
479 signal(SIGINT, quit_signal);
480 signal(SIGTERM, quit_signal);
481 signal(SIGQUIT, quit_signal);
482 signal(SIGHUP, SIG_IGN);
483 signal(SIGCHLD, SIG_IGN);
484#ifdef SIGCLD
485 signal(SIGCLD, SIG_IGN);
486#endif
487#ifdef SYSLOGD_MARK
488 signal(SIGALRM, do_mark);
489 alarm(G.markInterval);
490#endif
491 remove_pidfile("/var/run/syslogd.pid");
492
493 memset(&sunx, 0, sizeof(sunx));
494 sunx.sun_family = AF_UNIX;
495 strcpy(sunx.sun_path, "/dev/log");
496
497 /* Unlink old /dev/log or object it points to. */
498 /* (if it exists, bind will fail) */
499 logmode = LOGMODE_NONE;
500 dev_log_name = xmalloc_readlink_or_warn("/dev/log");
501 logmode = LOGMODE_STDIO;
502 if (dev_log_name) {
503 int fd = xopen(".", O_NONBLOCK);
504 xchdir("/dev");
505 /* we do not check whether this is a link also */
506 unlink(dev_log_name);
507 fchdir(fd);
508 close(fd);
509 safe_strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path));
510 free(dev_log_name);
511 } else {
512 unlink("/dev/log");
513 }
514
515 sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0);
516 xbind(sock_fd, (struct sockaddr *) &sunx, sizeof(sunx));
517
518 if (chmod("/dev/log", 0666) < 0) {
519 bb_perror_msg_and_die("cannot set permission on /dev/log");
520 }
521 if (ENABLE_FEATURE_IPC_SYSLOG && (option_mask32 & OPT_circularlog)) {
522 ipcsyslog_init();
523 }
524
525 timestamp_and_log(LOG_SYSLOG | LOG_INFO,
526 (char*)"syslogd started: BusyBox v" BB_VER, 0);
527
528 for (;;) {
529 FD_ZERO(&fds);
530 FD_SET(sock_fd, &fds);
531
532 if (select(sock_fd + 1, &fds, NULL, NULL, NULL) < 0) {
533 if (errno == EINTR) {
534 /* alarm may have happened */
535 continue;
536 }
537 bb_perror_msg_and_die("select");
538 }
539
540 if (FD_ISSET(sock_fd, &fds)) {
541 int i;
542 i = recv(sock_fd, G.recvbuf, MAX_READ - 1, 0);
543 if (i <= 0)
544 bb_perror_msg_and_die("UNIX socket error");
545 /* TODO: maybe suppress duplicates? */
546#if ENABLE_FEATURE_REMOTE_LOG
547 /* We are not modifying log messages in any way before send */
548 /* Remote site cannot trust _us_ anyway and need to do validation again */
549 if (G.remoteAddr) {
550 if (-1 == G.remoteFD) {
551 G.remoteFD = socket(G.remoteAddr->sa.sa_family, SOCK_DGRAM, 0);
552 }
553 if (-1 != G.remoteFD) {
554 /* send message to remote logger, ignore possible error */
555 sendto(G.remoteFD, G.recvbuf, i, MSG_DONTWAIT,
556 &G.remoteAddr->sa, G.remoteAddr->len);
557 }
558 }
559#endif
560 G.recvbuf[i] = '\0';
561 split_escape_and_log(G.recvbuf, i);
562 } /* FD_ISSET() */
563 } /* for */
564}
565
566int syslogd_main(int argc, char **argv);
567int syslogd_main(int argc, char **argv)
568{
569 char OPTION_DECL;
570 char *p;
571
572 PTR_TO_GLOBALS = memcpy(xzalloc(sizeof(G)), &init_data, sizeof(init_data));
573
574 /* do normal option parsing */
575 opt_complementary = "=0"; /* no non-option params */
576 getopt32(argv, OPTION_STR, OPTION_PARAM);
577#ifdef SYSLOGD_MARK
578 if (option_mask32 & OPT_mark) // -m
579 G.markInterval = xatou_range(opt_m, 0, INT_MAX/60) * 60;
580#endif
581 //if (option_mask32 & OPT_nofork) // -n
582 //if (option_mask32 & OPT_outfile) // -O
583 if (option_mask32 & OPT_loglevel) // -l
584 G.logLevel = xatou_range(opt_l, 1, 8);
585 //if (option_mask32 & OPT_small) // -S
586#if ENABLE_FEATURE_ROTATE_LOGFILE
587 if (option_mask32 & OPT_filesize) // -s
588 G.logFileSize = xatou_range(opt_s, 0, INT_MAX/1024) * 1024;
589 if (option_mask32 & OPT_rotatecnt) // -b
590 G.logFileRotate = xatou_range(opt_b, 0, 99);
591#endif
592#if ENABLE_FEATURE_REMOTE_LOG
593 if (option_mask32 & OPT_remotelog) { // -R
594 G.remoteAddr = xhost2sockaddr(opt_R, 514);
595 }
596 //if (option_mask32 & OPT_locallog) // -L
597#endif
598#if ENABLE_FEATURE_IPC_SYSLOG
599 if (opt_C) // -Cn
600 G.shm_size = xatoul_range(opt_C, 4, INT_MAX/1024) * 1024;
601#endif
602
603 /* If they have not specified remote logging, then log locally */
604 if (ENABLE_FEATURE_REMOTE_LOG && !(option_mask32 & OPT_remotelog))
605 option_mask32 |= OPT_locallog;
606
607 /* Store away localhost's name before the fork */
608 gethostname(G.localHostName, sizeof(G.localHostName));
609 p = strchr(G.localHostName, '.');
610 if (p) {
611 *p = '\0';
612 }
613
614 if (!(option_mask32 & OPT_nofork)) {
615 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
616 }
617 umask(0);
618 write_pidfile("/var/run/syslogd.pid");
619 do_syslogd();
620 /* return EXIT_SUCCESS; */
621}
Note: See TracBrowser for help on using the repository browser.