blob: 254d7e73c83ca234823941d597a310aaf0e5e81e [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersen3843e961999-11-25 07:30:46 +00002/*
3 * Mini syslogd implementation for busybox
4 *
Eric Andersenc7bda1c2004-03-15 08:29:22 +00005 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
Eric Andersen3843e961999-11-25 07:30:46 +00006 *
Erik Andersenf13df372000-04-18 23:51:51 +00007 * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org>
8 *
Glenn L McGrath6ed77592002-12-12 10:54:48 +00009 * "circular buffer" Copyright (C) 2001 by Gennady Feldman <gfeldman@gena01.com>
Mark Whitley6317c4b2001-03-12 22:51:50 +000010 *
Glenn L McGrath6ed77592002-12-12 10:54:48 +000011 * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001
Mark Whitley6bff9cc2001-03-12 23:41:34 +000012 *
Bernhard Reutner-Fischer86f5c992006-01-22 22:55:11 +000013 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
Eric Andersen3843e961999-11-25 07:30:46 +000014 */
Eric Andersenb99df0f1999-11-24 09:04:33 +000015
Bernhard Reutner-Fischere15d7572006-06-02 20:56:16 +000016#include "busybox.h"
Eric Andersenb186d981999-12-03 09:19:54 +000017#include <paths.h>
Eric Andersen7f94a5c2004-06-22 10:12:59 +000018#include <stdbool.h>
Erik Andersen983b51b2000-04-04 18:14:25 +000019#include <sys/un.h>
Eric Andersenb186d981999-12-03 09:19:54 +000020
Eric Andersen3843e961999-11-25 07:30:46 +000021/* SYSLOG_NAMES defined to pull some extra junk from syslog.h */
22#define SYSLOG_NAMES
23#include <sys/syslog.h>
Eric Andersenced2cef2000-07-20 23:41:24 +000024#include <sys/uio.h>
Eric Andersen3843e961999-11-25 07:30:46 +000025
Erik Andersen983b51b2000-04-04 18:14:25 +000026/* Path to the unix socket */
Eric Andersen871d93c2002-09-17 20:06:29 +000027static char lfile[MAXPATHLEN];
Eric Andersen3843e961999-11-25 07:30:46 +000028
Denis Vlasenko14c19402006-09-30 19:20:00 +000029/* Path for the file where all log messages are written */
30static const char *logFilePath = "/var/log/messages";
Erik Andersene49d5ec2000-02-08 19:58:47 +000031
Eric Andersen29c77f72003-10-09 09:43:18 +000032#ifdef CONFIG_FEATURE_ROTATE_LOGFILE
Eric Andersenaff114c2004-04-14 17:51:38 +000033/* max size of message file before being rotated */
Eric Andersen29c77f72003-10-09 09:43:18 +000034static int logFileSize = 200 * 1024;
35
36/* number of rotated message files */
37static int logFileRotate = 1;
38#endif
39
Eric Andersen3843e961999-11-25 07:30:46 +000040/* interval between marks in seconds */
Erik Andersene49d5ec2000-02-08 19:58:47 +000041static int MarkInterval = 20 * 60;
42
Denis Vlasenko1decd0e2006-09-30 19:17:40 +000043/* level of messages to be locally logged */
44static int logLevel = 8;
45
Eric Andersen3843e961999-11-25 07:30:46 +000046/* localhost's name */
Eric Andersen871d93c2002-09-17 20:06:29 +000047static char LocalHostName[64];
Eric Andersen3843e961999-11-25 07:30:46 +000048
Eric Andersenbdfd0d72001-10-24 05:00:29 +000049#ifdef CONFIG_FEATURE_REMOTE_LOG
Eric Andersenced2cef2000-07-20 23:41:24 +000050#include <netinet/in.h>
51/* udp socket for logging to remote host */
Eric Andersenbf2b8ae2000-12-08 19:52:01 +000052static int remotefd = -1;
Eric Andersen75813ee2004-08-26 23:15:29 +000053static struct sockaddr_in remoteaddr;
Glenn L McGrath912d8f42002-11-10 22:46:45 +000054
Eric Andersenced2cef2000-07-20 23:41:24 +000055#endif
56
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +000057/* options */
Denis Vlasenko14c19402006-09-30 19:20:00 +000058/* Correct regardless of combination of CONFIG_xxx */
59enum {
60 OPTBIT_mark = 0, // -m
61 OPTBIT_nofork, // -n
62 OPTBIT_outfile, // -O
63 OPTBIT_loglevel, // -l
64 OPTBIT_small, // -S
65 USE_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize ,) // -s
66 USE_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt ,) // -b
67 USE_FEATURE_REMOTE_LOG( OPTBIT_remote ,) // -R
68 USE_FEATURE_REMOTE_LOG( OPTBIT_localtoo ,) // -L
69 USE_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C
70
71 OPT_mark = 1 << OPTBIT_mark ,
72 OPT_nofork = 1 << OPTBIT_nofork ,
73 OPT_outfile = 1 << OPTBIT_outfile ,
74 OPT_loglevel = 1 << OPTBIT_loglevel,
75 OPT_small = 1 << OPTBIT_small ,
76 OPT_filesize = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize )) + 0,
77 OPT_rotatecnt = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt )) + 0,
78 OPT_remotelog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_remote )) + 0,
79 OPT_locallog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_localtoo )) + 0,
80 OPT_circularlog = USE_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0,
81};
82#define OPTION_STR "m:nO:l:S" \
83 USE_FEATURE_ROTATE_LOGFILE("s:" ) \
84 USE_FEATURE_ROTATE_LOGFILE("b:" ) \
85 USE_FEATURE_REMOTE_LOG( "R:" ) \
86 USE_FEATURE_REMOTE_LOG( "L" ) \
87 USE_FEATURE_IPC_SYSLOG( "C::")
88#define OPTION_DECL *opt_m, *opt_l \
89 USE_FEATURE_ROTATE_LOGFILE(,*opt_s) \
90 USE_FEATURE_ROTATE_LOGFILE(,*opt_b) \
91 USE_FEATURE_REMOTE_LOG( ,*opt_R) \
92 USE_FEATURE_IPC_SYSLOG( ,*opt_C = NULL)
93#define OPTION_PARAM &opt_m, &logFilePath, &opt_l \
94 USE_FEATURE_ROTATE_LOGFILE(,&opt_s) \
95 USE_FEATURE_ROTATE_LOGFILE(,&opt_b) \
96 USE_FEATURE_REMOTE_LOG( ,&opt_R) \
97 USE_FEATURE_IPC_SYSLOG( ,&opt_C)
Eric Andersen871d93c2002-09-17 20:06:29 +000098
Glenn L McGrath912d8f42002-11-10 22:46:45 +000099#define MAXLINE 1024 /* maximum line length */
Eric Andersen871d93c2002-09-17 20:06:29 +0000100
Mark Whitley6317c4b2001-03-12 22:51:50 +0000101/* circular buffer variables/structures */
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000102#ifdef CONFIG_FEATURE_IPC_SYSLOG
Eric Andersend4a5e252003-12-19 11:32:14 +0000103
104#if CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE < 4
105#error Sorry, you must set the syslogd buffer size to at least 4KB.
106#error Please check CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE
107#endif
108
Mark Whitley6317c4b2001-03-12 22:51:50 +0000109#include <sys/ipc.h>
110#include <sys/sem.h>
111#include <sys/shm.h>
112
113/* our shared key */
Denis Vlasenko14c19402006-09-30 19:20:00 +0000114#define KEY_ID ((long)0x414e4547) /* "GENA" */
Mark Whitley6317c4b2001-03-12 22:51:50 +0000115
116// Semaphore operation structures
117static struct shbuf_ds {
Denis Vlasenko14c19402006-09-30 19:20:00 +0000118 int size; // size of data written
119 int head; // start of message list
120 int tail; // end of message list
121 char data[1]; // data/messages
122} *shbuf = NULL; // shared memory pointer
Mark Whitley6317c4b2001-03-12 22:51:50 +0000123
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000124static struct sembuf SMwup[1] = { {1, -1, IPC_NOWAIT} }; // set SMwup
125static struct sembuf SMwdn[3] = { {0, 0}, {1, 0}, {1, +1} }; // set SMwdn
Mark Whitley6317c4b2001-03-12 22:51:50 +0000126
Denis Vlasenko14c19402006-09-30 19:20:00 +0000127static int shmid = -1; // ipc shared memory id
128static int s_semid = -1; // ipc semaphore id
Eric Andersend4a5e252003-12-19 11:32:14 +0000129static int shm_size = ((CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE)*1024); // default shm size
Eric Andersen871d93c2002-09-17 20:06:29 +0000130
"Vladimir N. Oleynik"e4baaa22005-09-22 12:59:26 +0000131static void ipcsyslog_cleanup(void)
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000132{
Denis Vlasenko14c19402006-09-30 19:20:00 +0000133 puts("Exiting syslogd!");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000134 if (shmid != -1) {
Denis Vlasenko14c19402006-09-30 19:20:00 +0000135 shmdt(shbuf);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000136 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000137
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000138 if (shmid != -1) {
Mark Whitley6317c4b2001-03-12 22:51:50 +0000139 shmctl(shmid, IPC_RMID, NULL);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000140 }
141 if (s_semid != -1) {
Mark Whitley6317c4b2001-03-12 22:51:50 +0000142 semctl(s_semid, 0, IPC_RMID, 0);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000143 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000144}
145
"Vladimir N. Oleynik"e4baaa22005-09-22 12:59:26 +0000146static void ipcsyslog_init(void)
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000147{
Denis Vlasenko14c19402006-09-30 19:20:00 +0000148 if (shbuf == NULL) {
149 shmid = shmget(KEY_ID, shm_size, IPC_CREAT | 1023);
150 if (shmid == -1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000151 bb_perror_msg_and_die("shmget");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000152 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000153
Denis Vlasenko14c19402006-09-30 19:20:00 +0000154 shbuf = shmat(shmid, NULL, 0);
155 if (!shbuf) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000156 bb_perror_msg_and_die("shmat");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000157 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000158
Denis Vlasenko14c19402006-09-30 19:20:00 +0000159 shbuf->size = shm_size - sizeof(*shbuf);
160 shbuf->head = shbuf->tail = 0;
Mark Whitley6317c4b2001-03-12 22:51:50 +0000161
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000162 // we'll trust the OS to set initial semval to 0 (let's hope)
Denis Vlasenko14c19402006-09-30 19:20:00 +0000163 s_semid = semget(KEY_ID, 2, IPC_CREAT | IPC_EXCL | 1023);
164 if (s_semid == -1) {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000165 if (errno == EEXIST) {
Denis Vlasenko14c19402006-09-30 19:20:00 +0000166 s_semid = semget(KEY_ID, 2, 0);
167 if (s_semid == -1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000168 bb_perror_msg_and_die("semget");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000169 }
170 } else {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000171 bb_perror_msg_and_die("semget");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000172 }
173 }
174 } else {
Mark Whitley6317c4b2001-03-12 22:51:50 +0000175 printf("Buffer already allocated just grab the semaphore?");
176 }
177}
178
179/* write message to buffer */
"Vladimir N. Oleynik"e4baaa22005-09-22 12:59:26 +0000180static void circ_message(const char *msg)
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000181{
182 int l = strlen(msg) + 1; /* count the whole message w/ '\0' included */
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000183 const char * const fail_msg = "Can't find the terminator token%s?\n";
Mark Whitley6317c4b2001-03-12 22:51:50 +0000184
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000185 if (semop(s_semid, SMwdn, 3) == -1) {
186 bb_perror_msg_and_die("SMwdn");
187 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000188
189 /*
190 * Circular Buffer Algorithm:
191 * --------------------------
192 *
193 * Start-off w/ empty buffer of specific size SHM_SIZ
194 * Start filling it up w/ messages. I use '\0' as separator to break up messages.
195 * This is also very handy since we can do printf on message.
196 *
197 * Once the buffer is full we need to get rid of the first message in buffer and
198 * insert the new message. (Note: if the message being added is >1 message then
199 * we will need to "remove" >1 old message from the buffer). The way this is done
200 * is the following:
Eric Andersen871d93c2002-09-17 20:06:29 +0000201 * When we reach the end of the buffer we set a mark and start from the beginning.
202 * Now what about the beginning and end of the buffer? Well we have the "head"
203 * index/pointer which is the starting point for the messages and we have "tail"
204 * index/pointer which is the ending point for the messages. When we "display" the
205 * messages we start from the beginning and continue until we reach "tail". If we
206 * reach end of buffer, then we just start from the beginning (offset 0). "head" and
207 * "tail" are actually offsets from the beginning of the buffer.
Mark Whitley6317c4b2001-03-12 22:51:50 +0000208 *
209 * Note: This algorithm uses Linux IPC mechanism w/ shared memory and semaphores to provide
Bernhard Reutner-Fischer0c013f52006-04-18 12:46:56 +0000210 * a threadsafe way of handling shared memory operations.
Mark Whitley6317c4b2001-03-12 22:51:50 +0000211 */
Denis Vlasenko14c19402006-09-30 19:20:00 +0000212 if ((shbuf->tail + l) < shbuf->size) {
Mark Whitley6317c4b2001-03-12 22:51:50 +0000213 /* before we append the message we need to check the HEAD so that we won't
214 overwrite any of the message that we still need and adjust HEAD to point
215 to the next message! */
Denis Vlasenko14c19402006-09-30 19:20:00 +0000216 if (shbuf->tail < shbuf->head) {
217 if ((shbuf->tail + l) >= shbuf->head) {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000218 /* we need to move the HEAD to point to the next message
219 * Theoretically we have enough room to add the whole message to the
220 * buffer, because of the first outer IF statement, so we don't have
221 * to worry about overflows here!
222 */
Denis Vlasenko14c19402006-09-30 19:20:00 +0000223 /* we need to know how many bytes we are overwriting to make enough room */
224 int k = shbuf->tail + l - shbuf->head;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000225 char *c =
Denis Vlasenko14c19402006-09-30 19:20:00 +0000226 memchr(shbuf->data + shbuf->head + k, '\0',
227 shbuf->size - (shbuf->head + k));
228 if (c != NULL) { /* do a sanity check just in case! */
229 /* we need to convert pointer to offset + skip the '\0'
230 since we need to point to the beginning of the next message */
231 shbuf->head = c - shbuf->data + 1;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000232 /* Note: HEAD is only used to "retrieve" messages, it's not used
233 when writing messages into our buffer */
Denis Vlasenko14c19402006-09-30 19:20:00 +0000234 } else { /* show an error message to know we messed up? */
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000235 printf(fail_msg,"");
Denis Vlasenko14c19402006-09-30 19:20:00 +0000236 shbuf->head = 0;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000237 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000238 }
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000239 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000240
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000241 /* in other cases no overflows have been done yet, so we don't care! */
Mark Whitley6317c4b2001-03-12 22:51:50 +0000242 /* we should be ok to append the message now */
Denis Vlasenko14c19402006-09-30 19:20:00 +0000243 strncpy(shbuf->data + shbuf->tail, msg, l); /* append our message */
244 shbuf->tail += l; /* count full message w/ '\0' terminating char */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000245 } else {
Mark Whitley6317c4b2001-03-12 22:51:50 +0000246 /* we need to break up the message and "circle" it around */
247 char *c;
Denis Vlasenko14c19402006-09-30 19:20:00 +0000248 int k = shbuf->tail + l - shbuf->size; /* count # of bytes we don't fit */
Eric Andersen871d93c2002-09-17 20:06:29 +0000249
Mark Whitley6317c4b2001-03-12 22:51:50 +0000250 /* We need to move HEAD! This is always the case since we are going
Denis Vlasenko14c19402006-09-30 19:20:00 +0000251 * to "circle" the message. */
252 c = memchr(shbuf->data + k, '\0', shbuf->size - k);
Eric Andersen871d93c2002-09-17 20:06:29 +0000253
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000254 if (c != NULL) { /* if we don't have '\0'??? weird!!! */
255 /* move head pointer */
Denis Vlasenko14c19402006-09-30 19:20:00 +0000256 shbuf->head = c - shbuf->data + 1;
Eric Andersen871d93c2002-09-17 20:06:29 +0000257
258 /* now write the first part of the message */
Denis Vlasenko14c19402006-09-30 19:20:00 +0000259 strncpy(shbuf->data + shbuf->tail, msg, l - k - 1);
Eric Andersen871d93c2002-09-17 20:06:29 +0000260
Mark Whitley6317c4b2001-03-12 22:51:50 +0000261 /* ALWAYS terminate end of buffer w/ '\0' */
Denis Vlasenko14c19402006-09-30 19:20:00 +0000262 shbuf->data[shbuf->size - 1] = '\0';
Eric Andersen871d93c2002-09-17 20:06:29 +0000263
Mark Whitley6317c4b2001-03-12 22:51:50 +0000264 /* now write out the rest of the string to the beginning of the buffer */
Denis Vlasenko14c19402006-09-30 19:20:00 +0000265 strcpy(shbuf->data, &msg[l - k - 1]);
Mark Whitley6317c4b2001-03-12 22:51:50 +0000266
267 /* we need to place the TAIL at the end of the message */
Denis Vlasenko14c19402006-09-30 19:20:00 +0000268 shbuf->tail = k + 1;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000269 } else {
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000270 printf(fail_msg, " from the beginning");
Denis Vlasenko14c19402006-09-30 19:20:00 +0000271 shbuf->head = shbuf->tail = 0; /* reset buffer, since it's probably corrupted */
Mark Whitley6317c4b2001-03-12 22:51:50 +0000272 }
Eric Andersen871d93c2002-09-17 20:06:29 +0000273
Mark Whitley6317c4b2001-03-12 22:51:50 +0000274 }
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000275 if (semop(s_semid, SMwup, 1) == -1) {
276 bb_perror_msg_and_die("SMwup");
277 }
278
Mark Whitley6317c4b2001-03-12 22:51:50 +0000279}
Rob Landley028ba282006-08-28 20:16:42 +0000280#else
281void ipcsyslog_cleanup(void);
282void ipcsyslog_init(void);
283void circ_message(const char *msg);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000284#endif /* CONFIG_FEATURE_IPC_SYSLOG */
Eric Andersen871d93c2002-09-17 20:06:29 +0000285
Erik Andersenc053e412000-03-21 01:31:24 +0000286/* Note: There is also a function called "message()" in init.c */
Erik Andersen983b51b2000-04-04 18:14:25 +0000287/* Print a message to the log file. */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000288static void message(char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
289static void message(char *fmt, ...)
Eric Andersen3843e961999-11-25 07:30:46 +0000290{
Rob Landley49ea4662006-09-11 01:34:21 +0000291 int fd = -1;
Erik Andersene3ed1562000-04-19 18:52:56 +0000292 struct flock fl;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000293 va_list arguments;
Eric Andersen3843e961999-11-25 07:30:46 +0000294
Erik Andersene3ed1562000-04-19 18:52:56 +0000295 fl.l_whence = SEEK_SET;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000296 fl.l_start = 0;
297 fl.l_len = 1;
Erik Andersene3ed1562000-04-19 18:52:56 +0000298
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000299#ifdef CONFIG_FEATURE_IPC_SYSLOG
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000300 if ((option_mask32 & OPT_circularlog) && shbuf) {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000301 char b[1024];
Mark Whitley6317c4b2001-03-12 22:51:50 +0000302
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000303 va_start(arguments, fmt);
304 vsnprintf(b, sizeof(b) - 1, fmt, arguments);
305 va_end(arguments);
306 circ_message(b);
307
308 } else
Mark Whitley6317c4b2001-03-12 22:51:50 +0000309#endif
Denis Vlasenkobd8f43d2006-09-08 17:31:55 +0000310 fd = device_open(logFilePath, O_WRONLY | O_CREAT
311 | O_NOCTTY | O_APPEND | O_NONBLOCK);
312 if (fd >= 0) {
Erik Andersene3ed1562000-04-19 18:52:56 +0000313 fl.l_type = F_WRLCK;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000314 fcntl(fd, F_SETLKW, &fl);
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000315
Rob Landley028ba282006-08-28 20:16:42 +0000316#ifdef CONFIG_FEATURE_ROTATE_LOGFILE
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000317 if (ENABLE_FEATURE_ROTATE_LOGFILE && logFileSize > 0 ) {
Eric Andersen29c77f72003-10-09 09:43:18 +0000318 struct stat statf;
319 int r = fstat(fd, &statf);
Denis Vlasenko14c19402006-09-30 19:20:00 +0000320 if (!r && (statf.st_mode & S_IFREG)
321 && (lseek(fd,0,SEEK_END) > logFileSize)) {
322 if (logFileRotate > 0) {
323 int i = strlen(logFilePath) + 4;
324 char oldFile[i];
325 char newFile[i];
326 for (i=logFileRotate-1; i>0; i--) {
Eric Andersen29c77f72003-10-09 09:43:18 +0000327 sprintf(oldFile, "%s.%d", logFilePath, i-1);
328 sprintf(newFile, "%s.%d", logFilePath, i);
329 rename(oldFile, newFile);
330 }
331 sprintf(newFile, "%s.%d", logFilePath, 0);
332 fl.l_type = F_UNLCK;
Denis Vlasenko14c19402006-09-30 19:20:00 +0000333 fcntl(fd, F_SETLKW, &fl);
Eric Andersen29c77f72003-10-09 09:43:18 +0000334 close(fd);
335 rename(logFilePath, newFile);
Denis Vlasenko14c19402006-09-30 19:20:00 +0000336 fd = device_open(logFilePath,
Eric Andersen29c77f72003-10-09 09:43:18 +0000337 O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
338 O_NONBLOCK);
339 fl.l_type = F_WRLCK;
Denis Vlasenko14c19402006-09-30 19:20:00 +0000340 fcntl(fd, F_SETLKW, &fl);
Eric Andersen29c77f72003-10-09 09:43:18 +0000341 } else {
Denis Vlasenko14c19402006-09-30 19:20:00 +0000342 ftruncate(fd, 0);
Eric Andersen29c77f72003-10-09 09:43:18 +0000343 }
344 }
345 }
Rob Landley028ba282006-08-28 20:16:42 +0000346#endif
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000347 va_start(arguments, fmt);
348 vdprintf(fd, fmt, arguments);
349 va_end(arguments);
Erik Andersene3ed1562000-04-19 18:52:56 +0000350 fl.l_type = F_UNLCK;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000351 fcntl(fd, F_SETLKW, &fl);
352 close(fd);
Eric Andersen3843e961999-11-25 07:30:46 +0000353 } else {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000354 /* Always send console messages to /dev/console so people will see them. */
Denis Vlasenkobd8f43d2006-09-08 17:31:55 +0000355 fd = device_open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK);
356 if (fd >= 0) {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000357 va_start(arguments, fmt);
358 vdprintf(fd, fmt, arguments);
359 va_end(arguments);
360 close(fd);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000361 } else {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000362 fprintf(stderr, "Bummer, can't print: ");
363 va_start(arguments, fmt);
364 vfprintf(stderr, fmt, arguments);
365 fflush(stderr);
366 va_end(arguments);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000367 }
Eric Andersen3843e961999-11-25 07:30:46 +0000368 }
Eric Andersenb99df0f1999-11-24 09:04:33 +0000369}
370
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000371static void logMessage(int pri, char *msg)
Eric Andersen3843e961999-11-25 07:30:46 +0000372{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000373 time_t now;
374 char *timestamp;
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000375 char res[20];
Erik Andersene49d5ec2000-02-08 19:58:47 +0000376 CODE *c_pri, *c_fac;
Eric Andersenb99df0f1999-11-24 09:04:33 +0000377
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000378 if (pri != 0) {
Denis Vlasenko14c19402006-09-30 19:20:00 +0000379 c_fac = facilitynames;
380 while (c_fac->c_name && !(c_fac->c_val == LOG_FAC(pri) << 3))
381 c_fac++;
382 c_pri = prioritynames;
383 while (c_pri->c_name && !(c_pri->c_val == LOG_PRI(pri)))
384 c_pri++;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000385 if (c_fac->c_name == NULL || c_pri->c_name == NULL) {
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000386 snprintf(res, sizeof(res), "<%d>", pri);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000387 } else {
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000388 snprintf(res, sizeof(res), "%s.%s", c_fac->c_name, c_pri->c_name);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000389 }
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000390 }
Eric Andersen3843e961999-11-25 07:30:46 +0000391
Erik Andersene49d5ec2000-02-08 19:58:47 +0000392 if (strlen(msg) < 16 || msg[3] != ' ' || msg[6] != ' ' ||
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000393 msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000394 time(&now);
395 timestamp = ctime(&now) + 4;
396 timestamp[15] = '\0';
397 } else {
398 timestamp = msg;
399 timestamp[15] = '\0';
400 msg += 16;
401 }
Eric Andersen3843e961999-11-25 07:30:46 +0000402
Erik Andersene49d5ec2000-02-08 19:58:47 +0000403 /* todo: supress duplicates */
Eric Andersen3843e961999-11-25 07:30:46 +0000404
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000405#ifdef CONFIG_FEATURE_REMOTE_LOG
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000406 if (option_mask32 & OPT_remotelog) {
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000407 char line[MAXLINE + 1];
Glenn L McGrath73ebb882004-09-14 18:12:13 +0000408 /* trying connect the socket */
409 if (-1 == remotefd) {
Denis Vlasenko02be0f52006-09-30 19:21:24 +0000410 remotefd = socket(AF_INET, SOCK_DGRAM, 0);
Glenn L McGrath73ebb882004-09-14 18:12:13 +0000411 }
Glenn L McGrath73ebb882004-09-14 18:12:13 +0000412 /* if we have a valid socket, send the message */
413 if (-1 != remotefd) {
Paul Fox27cbffd2005-07-20 18:02:11 +0000414 snprintf(line, sizeof(line), "<%d>%s", pri, msg);
Denis Vlasenko02be0f52006-09-30 19:21:24 +0000415 /* send message to remote logger, ignore possible error */
416 sendto(remotefd, line, strlen(line), 0,
417 (struct sockaddr *) &remoteaddr, sizeof(remoteaddr));
Eric Andersenbf2b8ae2000-12-08 19:52:01 +0000418 }
419 }
Glenn L McGrath73ebb882004-09-14 18:12:13 +0000420
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000421 if (option_mask32 & OPT_locallog)
Eric Andersenced2cef2000-07-20 23:41:24 +0000422#endif
Eric Andersen7f94a5c2004-06-22 10:12:59 +0000423 {
Eric Andersenbf2b8ae2000-12-08 19:52:01 +0000424 /* now spew out the message to wherever it is supposed to go */
Denis Vlasenko1decd0e2006-09-30 19:17:40 +0000425 if (pri == 0 || LOG_PRI(pri) < logLevel) {
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000426 if (option_mask32 & OPT_small)
Denis Vlasenko1decd0e2006-09-30 19:17:40 +0000427 message("%s %s\n", timestamp, msg);
428 else
429 message("%s %s %s %s\n", timestamp, LocalHostName, res, msg);
430 }
Eric Andersen7f94a5c2004-06-22 10:12:59 +0000431 }
Eric Andersen3843e961999-11-25 07:30:46 +0000432}
433
434static void quit_signal(int sig)
435{
Eric Andersen238bc402001-05-07 17:55:05 +0000436 logMessage(LOG_SYSLOG | LOG_INFO, "System log daemon exiting.");
Erik Andersen983b51b2000-04-04 18:14:25 +0000437 unlink(lfile);
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000438 if (ENABLE_FEATURE_IPC_SYSLOG)
439 ipcsyslog_cleanup();
Mark Whitley6317c4b2001-03-12 22:51:50 +0000440
Denis Vlasenko02be0f52006-09-30 19:21:24 +0000441 exit(1);
Eric Andersen3843e961999-11-25 07:30:46 +0000442}
443
Eric Andersen3843e961999-11-25 07:30:46 +0000444static void domark(int sig)
445{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000446 if (MarkInterval > 0) {
447 logMessage(LOG_SYSLOG | LOG_INFO, "-- MARK --");
448 alarm(MarkInterval);
449 }
Eric Andersen3843e961999-11-25 07:30:46 +0000450}
451
Eric Andersene5272072003-07-22 22:15:21 +0000452/* This must be a #define, since when CONFIG_DEBUG and BUFFERS_GO_IN_BSS are
Eric Andersen22ecf042001-07-02 17:32:40 +0000453 * enabled, we otherwise get a "storage size isn't constant error. */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000454static int serveConnection(char *tmpbuf, int n_read)
Pavel Roskinda10ec02000-06-07 21:08:25 +0000455{
Matt Kraaib6ec7812001-08-14 17:32:23 +0000456 char *p = tmpbuf;
Pavel Roskinda10ec02000-06-07 21:08:25 +0000457
Matt Kraaib6ec7812001-08-14 17:32:23 +0000458 while (p < tmpbuf + n_read) {
Pavel Roskinda10ec02000-06-07 21:08:25 +0000459
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000460 int pri = (LOG_USER | LOG_NOTICE);
Eric Andersend4f90ed2003-05-23 09:28:01 +0000461 int num_lt = 0;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000462 char line[MAXLINE + 1];
Pavel Roskinda10ec02000-06-07 21:08:25 +0000463 unsigned char c;
Matt Kraaib6ec7812001-08-14 17:32:23 +0000464 char *q = line;
Pavel Roskinda10ec02000-06-07 21:08:25 +0000465
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000466 while ((c = *p) && q < &line[sizeof(line) - 1]) {
Eric Andersend4f90ed2003-05-23 09:28:01 +0000467 if (c == '<' && num_lt == 0) {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000468 /* Parse the magic priority number. */
Eric Andersend4f90ed2003-05-23 09:28:01 +0000469 num_lt++;
Pavel Roskinda10ec02000-06-07 21:08:25 +0000470 pri = 0;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000471 while (isdigit(*(++p))) {
Pavel Roskinda10ec02000-06-07 21:08:25 +0000472 pri = 10 * pri + (*p - '0');
473 }
Eric Andersen46ba5682003-05-23 09:29:57 +0000474 if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) {
Eric Andersend4f90ed2003-05-23 09:28:01 +0000475 pri = (LOG_USER | LOG_NOTICE);
Eric Andersen46ba5682003-05-23 09:29:57 +0000476 }
Pavel Roskinda10ec02000-06-07 21:08:25 +0000477 } else if (c == '\n') {
478 *q++ = ' ';
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000479 } else if (iscntrl(c) && (c < 0177)) {
Pavel Roskinda10ec02000-06-07 21:08:25 +0000480 *q++ = '^';
481 *q++ = c ^ 0100;
482 } else {
483 *q++ = c;
484 }
485 p++;
486 }
487 *q = '\0';
Matt Kraaib6ec7812001-08-14 17:32:23 +0000488 p++;
Pavel Roskinda10ec02000-06-07 21:08:25 +0000489 /* Now log it */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000490 logMessage(pri, line);
Pavel Roskinda10ec02000-06-07 21:08:25 +0000491 }
Mark Whitleybff6b182001-03-27 20:17:58 +0000492 return n_read;
Pavel Roskinda10ec02000-06-07 21:08:25 +0000493}
494
Bernhard Reutner-Fischer86f5c992006-01-22 22:55:11 +0000495static void doSyslogd(void) ATTRIBUTE_NORETURN;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000496static void doSyslogd(void)
Eric Andersen3843e961999-11-25 07:30:46 +0000497{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000498 struct sockaddr_un sunx;
Erik Andersen1d1d9502000-04-21 01:26:49 +0000499 socklen_t addrLength;
500
Erik Andersen983b51b2000-04-04 18:14:25 +0000501 int sock_fd;
Erik Andersenf13df372000-04-18 23:51:51 +0000502 fd_set fds;
503
Erik Andersenf13df372000-04-18 23:51:51 +0000504 /* Set up signal handlers. */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000505 signal(SIGINT, quit_signal);
506 signal(SIGTERM, quit_signal);
507 signal(SIGQUIT, quit_signal);
508 signal(SIGHUP, SIG_IGN);
509 signal(SIGCHLD, SIG_IGN);
Pavel Roskind39d1202000-09-13 14:14:29 +0000510#ifdef SIGCLD
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000511 signal(SIGCLD, SIG_IGN);
Pavel Roskind39d1202000-09-13 14:14:29 +0000512#endif
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000513 signal(SIGALRM, domark);
514 alarm(MarkInterval);
Eric Andersenb99df0f1999-11-24 09:04:33 +0000515
Erik Andersenf13df372000-04-18 23:51:51 +0000516 /* Create the syslog file so realpath() can work. */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000517 if (realpath(_PATH_LOG, lfile) != NULL) {
518 unlink(lfile);
519 }
Erik Andersen983b51b2000-04-04 18:14:25 +0000520
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000521 memset(&sunx, 0, sizeof(sunx));
Erik Andersen983b51b2000-04-04 18:14:25 +0000522 sunx.sun_family = AF_UNIX;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000523 strncpy(sunx.sun_path, lfile, sizeof(sunx.sun_path));
Rob Landleyd921b2e2006-08-03 15:41:12 +0000524 sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000525 addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
526 if (bind(sock_fd, (struct sockaddr *) &sunx, addrLength) < 0) {
Denis Vlasenko14c19402006-09-30 19:20:00 +0000527 bb_perror_msg_and_die("cannot connect to socket %s", lfile);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000528 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000529
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000530 if (chmod(lfile, 0666) < 0) {
Denis Vlasenko14c19402006-09-30 19:20:00 +0000531 bb_perror_msg_and_die("cannot set permission on %s", lfile);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000532 }
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000533 if (ENABLE_FEATURE_IPC_SYSLOG && (option_mask32 & OPT_circularlog)) {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000534 ipcsyslog_init();
Eric Andersenea906502001-04-05 20:55:17 +0000535 }
Eric Andersenea906502001-04-05 20:55:17 +0000536
"Vladimir N. Oleynik"dd1ccdd2006-02-16 15:40:24 +0000537 logMessage(LOG_SYSLOG | LOG_INFO, "syslogd started: " "BusyBox v" BB_VER );
Erik Andersene49d5ec2000-02-08 19:58:47 +0000538
Erik Andersen983b51b2000-04-04 18:14:25 +0000539 for (;;) {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000540 FD_ZERO(&fds);
541 FD_SET(sock_fd, &fds);
Erik Andersenf13df372000-04-18 23:51:51 +0000542
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000543 if (select(sock_fd + 1, &fds, NULL, NULL, NULL) < 0) {
Eric Andersen871d93c2002-09-17 20:06:29 +0000544 if (errno == EINTR) {
545 /* alarm may have happened. */
546 continue;
547 }
Denis Vlasenko14c19402006-09-30 19:20:00 +0000548 bb_perror_msg_and_die("select");
Erik Andersene49d5ec2000-02-08 19:58:47 +0000549 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000550
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000551 if (FD_ISSET(sock_fd, &fds)) {
552 int i;
"Vladimir N. Oleynik"b32b1db2005-10-15 13:49:21 +0000553#if MAXLINE > BUFSIZ
554# define TMP_BUF_SZ BUFSIZ
555#else
556# define TMP_BUF_SZ MAXLINE
557#endif
558#define tmpbuf bb_common_bufsiz1
Erik Andersene3ed1562000-04-19 18:52:56 +0000559
"Vladimir N. Oleynik"b32b1db2005-10-15 13:49:21 +0000560 if ((i = recv(sock_fd, tmpbuf, TMP_BUF_SZ, 0)) > 0) {
561 tmpbuf[i] = '\0';
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000562 serveConnection(tmpbuf, i);
563 } else {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000564 bb_perror_msg_and_die("UNIX socket error");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000565 }
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000566 } /* FD_ISSET() */
567 } /* for main loop */
Eric Andersenb99df0f1999-11-24 09:04:33 +0000568}
569
Denis Vlasenko14c19402006-09-30 19:20:00 +0000570
Rob Landleydfba7412006-03-06 20:47:33 +0000571int syslogd_main(int argc, char **argv)
Eric Andersen3843e961999-11-25 07:30:46 +0000572{
Denis Vlasenko14c19402006-09-30 19:20:00 +0000573 char OPTION_DECL;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000574 char *p;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000575
Eric Andersen394cf222000-12-11 16:48:50 +0000576 /* do normal option parsing */
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000577 getopt32(argc, argv, OPTION_STR, OPTION_PARAM);
578 if (option_mask32 & OPT_mark) MarkInterval = atoi(opt_m) * 60; // -m
579 //if (option_mask32 & OPT_nofork) // -n
580 //if (option_mask32 & OPT_outfile) // -O
581 if (option_mask32 & OPT_loglevel) { // -l
Denis Vlasenko14c19402006-09-30 19:20:00 +0000582 logLevel = atoi(opt_l);
583 /* Valid levels are between 1 and 8 */
584 if (logLevel < 1 || logLevel > 8)
Manuel Novoa III cad53642003-03-19 09:13:01 +0000585 bb_show_usage();
Denis Vlasenko14c19402006-09-30 19:20:00 +0000586 }
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000587 //if (option_mask32 & OPT_small) // -S
Denis Vlasenko14c19402006-09-30 19:20:00 +0000588#if ENABLE_FEATURE_ROTATE_LOGFILE
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000589 if (option_mask32 & OPT_filesize) logFileSize = atoi(opt_s) * 1024; // -s
590 if (option_mask32 & OPT_rotatecnt) { // -b
Denis Vlasenko14c19402006-09-30 19:20:00 +0000591 logFileRotate = atoi(opt_b);
592 if (logFileRotate > 99) logFileRotate = 99;
593 }
594#endif
595#if ENABLE_FEATURE_REMOTE_LOG
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000596 if (option_mask32 & OPT_remotelog) { // -R
Denis Vlasenko02be0f52006-09-30 19:21:24 +0000597 int port = 514;
598 char *host = xstrdup(opt_R);
599 p = strchr(host, ':');
Denis Vlasenko14c19402006-09-30 19:20:00 +0000600 if (p) {
Denis Vlasenko02be0f52006-09-30 19:21:24 +0000601 port = atoi(p + 1);
Denis Vlasenko14c19402006-09-30 19:20:00 +0000602 *p = '\0';
Eric Andersen3843e961999-11-25 07:30:46 +0000603 }
Denis Vlasenko02be0f52006-09-30 19:21:24 +0000604 remoteaddr.sin_family = AF_INET;
605 /* FIXME: looks ip4-specific. need to do better */
606 remoteaddr.sin_addr = *(struct in_addr *) *(xgethostbyname(host)->h_addr_list);
607 remoteaddr.sin_port = htons(port);
608 free(host);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000609 }
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000610 //if (option_mask32 & OPT_locallog) // -L
Denis Vlasenko14c19402006-09-30 19:20:00 +0000611#endif
612#if ENABLE_FEATURE_IPC_SYSLOG
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000613 if (option_mask32 & OPT_circularlog) { // -C
Denis Vlasenko14c19402006-09-30 19:20:00 +0000614 if (opt_C) {
615 int buf_size = atoi(opt_C);
616 if (buf_size >= 4)
617 shm_size = buf_size * 1024;
618 }
619 }
620#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000621
Eric Andersen4ed17822000-12-11 19:28:29 +0000622 /* If they have not specified remote logging, then log locally */
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000623 if (ENABLE_FEATURE_REMOTE_LOG && !(option_mask32 & OPT_remotelog))
624 option_mask32 |= OPT_locallog;
Mark Whitley6317c4b2001-03-12 22:51:50 +0000625
Erik Andersene49d5ec2000-02-08 19:58:47 +0000626 /* Store away localhost's name before the fork */
627 gethostname(LocalHostName, sizeof(LocalHostName));
Denis Vlasenko14c19402006-09-30 19:20:00 +0000628 p = strchr(LocalHostName, '.');
629 if (p) {
Glenn L McGrathfe538ba2003-09-10 23:35:45 +0000630 *p = '\0';
Erik Andersene49d5ec2000-02-08 19:58:47 +0000631 }
632
Erik Andersen983b51b2000-04-04 18:14:25 +0000633 umask(0);
634
Denis Vlasenkoc12f5302006-10-06 09:49:47 +0000635 if (!(option_mask32 & OPT_nofork)) {
Bernhard Reutner-Fischerc418d482006-05-31 10:19:51 +0000636#ifdef BB_NOMMU
Russ Dilla1fece22003-12-15 21:57:44 +0000637 vfork_daemon_rexec(0, 1, argc, argv, "-n");
Bernhard Reutner-Fischerc418d482006-05-31 10:19:51 +0000638#else
Rob Landleyd921b2e2006-08-03 15:41:12 +0000639 xdaemon(0, 1);
Bernhard Reutner-Fischerc418d482006-05-31 10:19:51 +0000640#endif
Eric Andersen35e643b2003-07-28 07:40:39 +0000641 }
Eric Andersene5c24df2001-03-29 21:58:33 +0000642 doSyslogd();
Eric Andersenb186d981999-12-03 09:19:54 +0000643
Matt Kraai3e856ce2000-12-01 02:55:13 +0000644 return EXIT_SUCCESS;
Eric Andersen3843e961999-11-25 07:30:46 +0000645}