blob: 42426ed805ead6e3c7b4385c823014e60c2fd608 [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 Andersencb81e642003-07-14 21:21:08 +00005 * Copyright (C) 1999-2003 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 *
Eric Andersen3843e961999-11-25 07:30:46 +000013 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
Eric Andersenb99df0f1999-11-24 09:04:33 +000028
Eric Andersen67e32302000-06-19 17:48:02 +000029#include <stdio.h>
30#include <stdlib.h>
Eric Andersen3843e961999-11-25 07:30:46 +000031#include <ctype.h>
Eric Andersenb186d981999-12-03 09:19:54 +000032#include <errno.h>
Erik Andersen983b51b2000-04-04 18:14:25 +000033#include <fcntl.h>
34#include <netdb.h>
Eric Andersenb186d981999-12-03 09:19:54 +000035#include <paths.h>
Erik Andersen983b51b2000-04-04 18:14:25 +000036#include <signal.h>
37#include <stdarg.h>
Eric Andersen67e32302000-06-19 17:48:02 +000038#include <time.h>
Eric Andersened3ef502001-01-27 08:24:39 +000039#include <string.h>
Eric Andersen67e32302000-06-19 17:48:02 +000040#include <unistd.h>
Erik Andersen983b51b2000-04-04 18:14:25 +000041#include <sys/socket.h>
Erik Andersen983b51b2000-04-04 18:14:25 +000042#include <sys/types.h>
43#include <sys/un.h>
Erik Andersen7d6ba572000-04-19 20:02:50 +000044#include <sys/param.h>
Eric Andersenb186d981999-12-03 09:19:54 +000045
Eric Andersencbe31da2001-02-20 06:14:08 +000046#include "busybox.h"
Eric Andersen67e32302000-06-19 17:48:02 +000047
Eric Andersen3843e961999-11-25 07:30:46 +000048/* SYSLOG_NAMES defined to pull some extra junk from syslog.h */
49#define SYSLOG_NAMES
50#include <sys/syslog.h>
Eric Andersenced2cef2000-07-20 23:41:24 +000051#include <sys/uio.h>
Eric Andersen3843e961999-11-25 07:30:46 +000052
53/* Path for the file where all log messages are written */
Erik Andersen983b51b2000-04-04 18:14:25 +000054#define __LOG_FILE "/var/log/messages"
Eric Andersen3843e961999-11-25 07:30:46 +000055
Erik Andersen983b51b2000-04-04 18:14:25 +000056/* Path to the unix socket */
Eric Andersen871d93c2002-09-17 20:06:29 +000057static char lfile[MAXPATHLEN];
Eric Andersen3843e961999-11-25 07:30:46 +000058
Glenn L McGrathfe538ba2003-09-10 23:35:45 +000059static const char *logFilePath = __LOG_FILE;
Erik Andersene49d5ec2000-02-08 19:58:47 +000060
Eric Andersen29c77f72003-10-09 09:43:18 +000061#ifdef CONFIG_FEATURE_ROTATE_LOGFILE
62/* max size of message file bevor being rotated */
63static int logFileSize = 200 * 1024;
64
65/* number of rotated message files */
66static int logFileRotate = 1;
67#endif
68
Eric Andersen3843e961999-11-25 07:30:46 +000069/* interval between marks in seconds */
Erik Andersene49d5ec2000-02-08 19:58:47 +000070static int MarkInterval = 20 * 60;
71
Eric Andersen3843e961999-11-25 07:30:46 +000072/* localhost's name */
Eric Andersen871d93c2002-09-17 20:06:29 +000073static char LocalHostName[64];
Eric Andersen3843e961999-11-25 07:30:46 +000074
Eric Andersenbdfd0d72001-10-24 05:00:29 +000075#ifdef CONFIG_FEATURE_REMOTE_LOG
Eric Andersenced2cef2000-07-20 23:41:24 +000076#include <netinet/in.h>
77/* udp socket for logging to remote host */
Eric Andersenbf2b8ae2000-12-08 19:52:01 +000078static int remotefd = -1;
Glenn L McGrath912d8f42002-11-10 22:46:45 +000079
Eric Andersenced2cef2000-07-20 23:41:24 +000080/* where do we log? */
81static char *RemoteHost;
Glenn L McGrath912d8f42002-11-10 22:46:45 +000082
Eric Andersenced2cef2000-07-20 23:41:24 +000083/* what port to log to? */
Eric Andersenbf2b8ae2000-12-08 19:52:01 +000084static int RemotePort = 514;
Glenn L McGrath912d8f42002-11-10 22:46:45 +000085
Eric Andersenced2cef2000-07-20 23:41:24 +000086/* To remote log or not to remote log, that is the question. */
Eric Andersenbf2b8ae2000-12-08 19:52:01 +000087static int doRemoteLog = FALSE;
Eric Andersen70d09ed2000-12-11 16:24:16 +000088static int local_logging = FALSE;
Eric Andersenced2cef2000-07-20 23:41:24 +000089#endif
90
Eric Andersen871d93c2002-09-17 20:06:29 +000091
Glenn L McGrath912d8f42002-11-10 22:46:45 +000092#define MAXLINE 1024 /* maximum line length */
Eric Andersen871d93c2002-09-17 20:06:29 +000093
94
Mark Whitley6317c4b2001-03-12 22:51:50 +000095/* circular buffer variables/structures */
Eric Andersenbdfd0d72001-10-24 05:00:29 +000096#ifdef CONFIG_FEATURE_IPC_SYSLOG
Eric Andersend4a5e252003-12-19 11:32:14 +000097
98#if CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE < 4
99#error Sorry, you must set the syslogd buffer size to at least 4KB.
100#error Please check CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE
101#endif
102
Mark Whitley6317c4b2001-03-12 22:51:50 +0000103#include <sys/ipc.h>
104#include <sys/sem.h>
105#include <sys/shm.h>
106
107/* our shared key */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000108static const long KEY_ID = 0x414e4547; /*"GENA" */
Mark Whitley6317c4b2001-03-12 22:51:50 +0000109
110// Semaphore operation structures
111static struct shbuf_ds {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000112 int size; // size of data written
113 int head; // start of message list
114 int tail; // end of message list
115 char data[1]; // data/messages
116} *buf = NULL; // shared memory pointer
Mark Whitley6317c4b2001-03-12 22:51:50 +0000117
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000118static struct sembuf SMwup[1] = { {1, -1, IPC_NOWAIT} }; // set SMwup
119static struct sembuf SMwdn[3] = { {0, 0}, {1, 0}, {1, +1} }; // set SMwdn
Mark Whitley6317c4b2001-03-12 22:51:50 +0000120
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000121static int shmid = -1; // ipc shared memory id
122static int s_semid = -1; // ipc semaphore id
Eric Andersend4a5e252003-12-19 11:32:14 +0000123static int shm_size = ((CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE)*1024); // default shm size
Mark Whitley6317c4b2001-03-12 22:51:50 +0000124static int circular_logging = FALSE;
125
126/*
127 * sem_up - up()'s a semaphore.
128 */
129static inline void sem_up(int semid)
130{
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000131 if (semop(semid, SMwup, 1) == -1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000132 bb_perror_msg_and_die("semop[SMwup]");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000133 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000134}
135
136/*
137 * sem_down - down()'s a semaphore
138 */
139static inline void sem_down(int semid)
140{
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000141 if (semop(semid, SMwdn, 3) == -1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000142 bb_perror_msg_and_die("semop[SMwdn]");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000143 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000144}
145
Eric Andersen871d93c2002-09-17 20:06:29 +0000146
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000147void ipcsyslog_cleanup(void)
148{
Mark Whitley6317c4b2001-03-12 22:51:50 +0000149 printf("Exiting Syslogd!\n");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000150 if (shmid != -1) {
Mark Whitley6317c4b2001-03-12 22:51:50 +0000151 shmdt(buf);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000152 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000153
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000154 if (shmid != -1) {
Mark Whitley6317c4b2001-03-12 22:51:50 +0000155 shmctl(shmid, IPC_RMID, NULL);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000156 }
157 if (s_semid != -1) {
Mark Whitley6317c4b2001-03-12 22:51:50 +0000158 semctl(s_semid, 0, IPC_RMID, 0);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000159 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000160}
161
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000162void ipcsyslog_init(void)
163{
164 if (buf == NULL) {
Eric Andersend4a5e252003-12-19 11:32:14 +0000165 if ((shmid = shmget(KEY_ID, shm_size, IPC_CREAT | 1023)) == -1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000166 bb_perror_msg_and_die("shmget");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000167 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000168
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000169 if ((buf = shmat(shmid, NULL, 0)) == NULL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000170 bb_perror_msg_and_die("shmat");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000171 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000172
Eric Andersend4a5e252003-12-19 11:32:14 +0000173 buf->size = shm_size - sizeof(*buf);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000174 buf->head = buf->tail = 0;
Mark Whitley6317c4b2001-03-12 22:51:50 +0000175
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000176 // we'll trust the OS to set initial semval to 0 (let's hope)
177 if ((s_semid = semget(KEY_ID, 2, IPC_CREAT | IPC_EXCL | 1023)) == -1) {
178 if (errno == EEXIST) {
179 if ((s_semid = semget(KEY_ID, 2, 0)) == -1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000180 bb_perror_msg_and_die("semget");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000181 }
182 } else {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000183 bb_perror_msg_and_die("semget");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000184 }
185 }
186 } else {
Mark Whitley6317c4b2001-03-12 22:51:50 +0000187 printf("Buffer already allocated just grab the semaphore?");
188 }
189}
190
191/* write message to buffer */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000192void circ_message(const char *msg)
193{
194 int l = strlen(msg) + 1; /* count the whole message w/ '\0' included */
Mark Whitley6317c4b2001-03-12 22:51:50 +0000195
196 sem_down(s_semid);
197
198 /*
199 * Circular Buffer Algorithm:
200 * --------------------------
201 *
202 * Start-off w/ empty buffer of specific size SHM_SIZ
203 * Start filling it up w/ messages. I use '\0' as separator to break up messages.
204 * This is also very handy since we can do printf on message.
205 *
206 * Once the buffer is full we need to get rid of the first message in buffer and
207 * insert the new message. (Note: if the message being added is >1 message then
208 * we will need to "remove" >1 old message from the buffer). The way this is done
209 * is the following:
Eric Andersen871d93c2002-09-17 20:06:29 +0000210 * When we reach the end of the buffer we set a mark and start from the beginning.
211 * Now what about the beginning and end of the buffer? Well we have the "head"
212 * index/pointer which is the starting point for the messages and we have "tail"
213 * index/pointer which is the ending point for the messages. When we "display" the
214 * messages we start from the beginning and continue until we reach "tail". If we
215 * reach end of buffer, then we just start from the beginning (offset 0). "head" and
216 * "tail" are actually offsets from the beginning of the buffer.
Mark Whitley6317c4b2001-03-12 22:51:50 +0000217 *
218 * Note: This algorithm uses Linux IPC mechanism w/ shared memory and semaphores to provide
Eric Andersen871d93c2002-09-17 20:06:29 +0000219 * a threasafe way of handling shared memory operations.
Mark Whitley6317c4b2001-03-12 22:51:50 +0000220 */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000221 if ((buf->tail + l) < buf->size) {
Mark Whitley6317c4b2001-03-12 22:51:50 +0000222 /* before we append the message we need to check the HEAD so that we won't
223 overwrite any of the message that we still need and adjust HEAD to point
224 to the next message! */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000225 if (buf->tail < buf->head) {
226 if ((buf->tail + l) >= buf->head) {
227 /* we need to move the HEAD to point to the next message
228 * Theoretically we have enough room to add the whole message to the
229 * buffer, because of the first outer IF statement, so we don't have
230 * to worry about overflows here!
231 */
232 int k = buf->tail + l - buf->head; /* we need to know how many bytes
233 we are overwriting to make
234 enough room */
235 char *c =
236 memchr(buf->data + buf->head + k, '\0',
237 buf->size - (buf->head + k));
238 if (c != NULL) { /* do a sanity check just in case! */
239 buf->head = c - buf->data + 1; /* we need to convert pointer to
240 offset + skip the '\0' since
241 we need to point to the beginning
242 of the next message */
243 /* Note: HEAD is only used to "retrieve" messages, it's not used
244 when writing messages into our buffer */
245 } else { /* show an error message to know we messed up? */
246 printf("Weird! Can't find the terminator token??? \n");
247 buf->head = 0;
248 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000249 }
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000250 }
Mark Whitley6317c4b2001-03-12 22:51:50 +0000251
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000252 /* in other cases no overflows have been done yet, so we don't care! */
Mark Whitley6317c4b2001-03-12 22:51:50 +0000253 /* we should be ok to append the message now */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000254 strncpy(buf->data + buf->tail, msg, l); /* append our message */
255 buf->tail += l; /* count full message w/ '\0' terminating char */
256 } else {
Mark Whitley6317c4b2001-03-12 22:51:50 +0000257 /* we need to break up the message and "circle" it around */
258 char *c;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000259 int k = buf->tail + l - buf->size; /* count # of bytes we don't fit */
Eric Andersen871d93c2002-09-17 20:06:29 +0000260
Mark Whitley6317c4b2001-03-12 22:51:50 +0000261 /* We need to move HEAD! This is always the case since we are going
262 * to "circle" the message.
263 */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000264 c = memchr(buf->data + k, '\0', buf->size - k);
Eric Andersen871d93c2002-09-17 20:06:29 +0000265
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000266 if (c != NULL) { /* if we don't have '\0'??? weird!!! */
267 /* move head pointer */
268 buf->head = c - buf->data + 1;
Eric Andersen871d93c2002-09-17 20:06:29 +0000269
270 /* now write the first part of the message */
Mark Whitley6317c4b2001-03-12 22:51:50 +0000271 strncpy(buf->data + buf->tail, msg, l - k - 1);
Eric Andersen871d93c2002-09-17 20:06:29 +0000272
Mark Whitley6317c4b2001-03-12 22:51:50 +0000273 /* ALWAYS terminate end of buffer w/ '\0' */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000274 buf->data[buf->size - 1] = '\0';
Eric Andersen871d93c2002-09-17 20:06:29 +0000275
Mark Whitley6317c4b2001-03-12 22:51:50 +0000276 /* now write out the rest of the string to the beginning of the buffer */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000277 strcpy(buf->data, &msg[l - k - 1]);
Mark Whitley6317c4b2001-03-12 22:51:50 +0000278
279 /* we need to place the TAIL at the end of the message */
280 buf->tail = k + 1;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000281 } else {
282 printf
283 ("Weird! Can't find the terminator token from the beginning??? \n");
284 buf->head = buf->tail = 0; /* reset buffer, since it's probably corrupted */
Mark Whitley6317c4b2001-03-12 22:51:50 +0000285 }
Eric Andersen871d93c2002-09-17 20:06:29 +0000286
Mark Whitley6317c4b2001-03-12 22:51:50 +0000287 }
288 sem_up(s_semid);
289}
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000290#endif /* CONFIG_FEATURE_IPC_SYSLOG */
Eric Andersen871d93c2002-09-17 20:06:29 +0000291
Erik Andersenc053e412000-03-21 01:31:24 +0000292/* Note: There is also a function called "message()" in init.c */
Erik Andersen983b51b2000-04-04 18:14:25 +0000293/* Print a message to the log file. */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000294static void message(char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
295static void message(char *fmt, ...)
Eric Andersen3843e961999-11-25 07:30:46 +0000296{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000297 int fd;
Erik Andersene3ed1562000-04-19 18:52:56 +0000298 struct flock fl;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000299 va_list arguments;
Eric Andersen3843e961999-11-25 07:30:46 +0000300
Erik Andersene3ed1562000-04-19 18:52:56 +0000301 fl.l_whence = SEEK_SET;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000302 fl.l_start = 0;
303 fl.l_len = 1;
Erik Andersene3ed1562000-04-19 18:52:56 +0000304
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000305#ifdef CONFIG_FEATURE_IPC_SYSLOG
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000306 if ((circular_logging == TRUE) && (buf != NULL)) {
307 char b[1024];
Mark Whitley6317c4b2001-03-12 22:51:50 +0000308
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000309 va_start(arguments, fmt);
310 vsnprintf(b, sizeof(b) - 1, fmt, arguments);
311 va_end(arguments);
312 circ_message(b);
313
314 } else
Mark Whitley6317c4b2001-03-12 22:51:50 +0000315#endif
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000316 if ((fd =
317 device_open(logFilePath,
318 O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
319 O_NONBLOCK)) >= 0) {
Erik Andersene3ed1562000-04-19 18:52:56 +0000320 fl.l_type = F_WRLCK;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000321 fcntl(fd, F_SETLKW, &fl);
Eric Andersen29c77f72003-10-09 09:43:18 +0000322#ifdef CONFIG_FEATURE_ROTATE_LOGFILE
323 if ( logFileSize > 0 ) {
324 struct stat statf;
325 int r = fstat(fd, &statf);
326 if( !r && (statf.st_mode & S_IFREG)
327 && (lseek(fd,0,SEEK_END) > logFileSize) ) {
328 if(logFileRotate > 0) {
329 int i;
330 char oldFile[(strlen(logFilePath)+3)], newFile[(strlen(logFilePath)+3)];
331 for(i=logFileRotate-1;i>0;i--) {
332 sprintf(oldFile, "%s.%d", logFilePath, i-1);
333 sprintf(newFile, "%s.%d", logFilePath, i);
334 rename(oldFile, newFile);
335 }
336 sprintf(newFile, "%s.%d", logFilePath, 0);
337 fl.l_type = F_UNLCK;
338 fcntl (fd, F_SETLKW, &fl);
339 close(fd);
340 rename(logFilePath, newFile);
341 fd = device_open (logFilePath,
342 O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
343 O_NONBLOCK);
344 fl.l_type = F_WRLCK;
345 fcntl (fd, F_SETLKW, &fl);
346 } else {
347 ftruncate( fd, 0 );
348 }
349 }
350 }
351#endif
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000352 va_start(arguments, fmt);
353 vdprintf(fd, fmt, arguments);
354 va_end(arguments);
Erik Andersene3ed1562000-04-19 18:52:56 +0000355 fl.l_type = F_UNLCK;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000356 fcntl(fd, F_SETLKW, &fl);
357 close(fd);
Eric Andersen3843e961999-11-25 07:30:46 +0000358 } else {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000359 /* Always send console messages to /dev/console so people will see them. */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000360 if ((fd =
361 device_open(_PATH_CONSOLE,
362 O_WRONLY | O_NOCTTY | O_NONBLOCK)) >= 0) {
363 va_start(arguments, fmt);
364 vdprintf(fd, fmt, arguments);
365 va_end(arguments);
366 close(fd);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000367 } else {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000368 fprintf(stderr, "Bummer, can't print: ");
369 va_start(arguments, fmt);
370 vfprintf(stderr, fmt, arguments);
371 fflush(stderr);
372 va_end(arguments);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000373 }
Eric Andersen3843e961999-11-25 07:30:46 +0000374 }
Eric Andersenb99df0f1999-11-24 09:04:33 +0000375}
376
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000377static void logMessage(int pri, char *msg)
Eric Andersen3843e961999-11-25 07:30:46 +0000378{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000379 time_t now;
380 char *timestamp;
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000381 static char res[20] = "";
Erik Andersene49d5ec2000-02-08 19:58:47 +0000382 CODE *c_pri, *c_fac;
Eric Andersenb99df0f1999-11-24 09:04:33 +0000383
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000384 if (pri != 0) {
385 for (c_fac = facilitynames;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000386 c_fac->c_name && !(c_fac->c_val == LOG_FAC(pri) << 3); c_fac++);
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000387 for (c_pri = prioritynames;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000388 c_pri->c_name && !(c_pri->c_val == LOG_PRI(pri)); c_pri++);
389 if (c_fac->c_name == NULL || c_pri->c_name == NULL) {
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000390 snprintf(res, sizeof(res), "<%d>", pri);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000391 } else {
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000392 snprintf(res, sizeof(res), "%s.%s", c_fac->c_name, c_pri->c_name);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000393 }
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000394 }
Eric Andersen3843e961999-11-25 07:30:46 +0000395
Erik Andersene49d5ec2000-02-08 19:58:47 +0000396 if (strlen(msg) < 16 || msg[3] != ' ' || msg[6] != ' ' ||
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000397 msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000398 time(&now);
399 timestamp = ctime(&now) + 4;
400 timestamp[15] = '\0';
401 } else {
402 timestamp = msg;
403 timestamp[15] = '\0';
404 msg += 16;
405 }
Eric Andersen3843e961999-11-25 07:30:46 +0000406
Erik Andersene49d5ec2000-02-08 19:58:47 +0000407 /* todo: supress duplicates */
Eric Andersen3843e961999-11-25 07:30:46 +0000408
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000409#ifdef CONFIG_FEATURE_REMOTE_LOG
Eric Andersenced2cef2000-07-20 23:41:24 +0000410 /* send message to remote logger */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000411 if (-1 != remotefd) {
412 static const int IOV_COUNT = 2;
Eric Andersenbf2b8ae2000-12-08 19:52:01 +0000413 struct iovec iov[IOV_COUNT];
414 struct iovec *v = iov;
Eric Andersenced2cef2000-07-20 23:41:24 +0000415
Eric Andersen044228d2001-07-17 01:12:36 +0000416 memset(&res, 0, sizeof(res));
Eric Andersenbf2b8ae2000-12-08 19:52:01 +0000417 snprintf(res, sizeof(res), "<%d>", pri);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000418 v->iov_base = res;
Eric Andersen871d93c2002-09-17 20:06:29 +0000419 v->iov_len = strlen(res);
Eric Andersenbf2b8ae2000-12-08 19:52:01 +0000420 v++;
Eric Andersenced2cef2000-07-20 23:41:24 +0000421
Eric Andersenbf2b8ae2000-12-08 19:52:01 +0000422 v->iov_base = msg;
Eric Andersen871d93c2002-09-17 20:06:29 +0000423 v->iov_len = strlen(msg);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000424 writev_retry:
Glenn L McGrath877d4182003-02-09 05:07:42 +0000425 if ((-1 == writev(remotefd, iov, IOV_COUNT)) && (errno == EINTR)) {
426 goto writev_retry;
Eric Andersenbf2b8ae2000-12-08 19:52:01 +0000427 }
428 }
Eric Andersen871d93c2002-09-17 20:06:29 +0000429 if (local_logging == TRUE)
Eric Andersenced2cef2000-07-20 23:41:24 +0000430#endif
Eric Andersenbf2b8ae2000-12-08 19:52:01 +0000431 /* now spew out the message to wherever it is supposed to go */
432 message("%s %s %s %s\n", timestamp, LocalHostName, res, msg);
Eric Andersen3843e961999-11-25 07:30:46 +0000433}
434
435static void quit_signal(int sig)
436{
Eric Andersen238bc402001-05-07 17:55:05 +0000437 logMessage(LOG_SYSLOG | LOG_INFO, "System log daemon exiting.");
Erik Andersen983b51b2000-04-04 18:14:25 +0000438 unlink(lfile);
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000439#ifdef CONFIG_FEATURE_IPC_SYSLOG
Mark Whitley6317c4b2001-03-12 22:51:50 +0000440 ipcsyslog_cleanup();
441#endif
442
Erik Andersene49d5ec2000-02-08 19:58:47 +0000443 exit(TRUE);
Eric Andersen3843e961999-11-25 07:30:46 +0000444}
445
Eric Andersen3843e961999-11-25 07:30:46 +0000446static void domark(int sig)
447{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000448 if (MarkInterval > 0) {
449 logMessage(LOG_SYSLOG | LOG_INFO, "-- MARK --");
450 alarm(MarkInterval);
451 }
Eric Andersen3843e961999-11-25 07:30:46 +0000452}
453
Eric Andersene5272072003-07-22 22:15:21 +0000454/* This must be a #define, since when CONFIG_DEBUG and BUFFERS_GO_IN_BSS are
Eric Andersen22ecf042001-07-02 17:32:40 +0000455 * enabled, we otherwise get a "storage size isn't constant error. */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000456static int serveConnection(char *tmpbuf, int n_read)
Pavel Roskinda10ec02000-06-07 21:08:25 +0000457{
Matt Kraaib6ec7812001-08-14 17:32:23 +0000458 char *p = tmpbuf;
Pavel Roskinda10ec02000-06-07 21:08:25 +0000459
Matt Kraaib6ec7812001-08-14 17:32:23 +0000460 while (p < tmpbuf + n_read) {
Pavel Roskinda10ec02000-06-07 21:08:25 +0000461
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000462 int pri = (LOG_USER | LOG_NOTICE);
Eric Andersend4f90ed2003-05-23 09:28:01 +0000463 int num_lt = 0;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000464 char line[MAXLINE + 1];
Pavel Roskinda10ec02000-06-07 21:08:25 +0000465 unsigned char c;
Matt Kraaib6ec7812001-08-14 17:32:23 +0000466 char *q = line;
Pavel Roskinda10ec02000-06-07 21:08:25 +0000467
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000468 while ((c = *p) && q < &line[sizeof(line) - 1]) {
Eric Andersend4f90ed2003-05-23 09:28:01 +0000469 if (c == '<' && num_lt == 0) {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000470 /* Parse the magic priority number. */
Eric Andersend4f90ed2003-05-23 09:28:01 +0000471 num_lt++;
Pavel Roskinda10ec02000-06-07 21:08:25 +0000472 pri = 0;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000473 while (isdigit(*(++p))) {
Pavel Roskinda10ec02000-06-07 21:08:25 +0000474 pri = 10 * pri + (*p - '0');
475 }
Eric Andersen46ba5682003-05-23 09:29:57 +0000476 if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) {
Eric Andersend4f90ed2003-05-23 09:28:01 +0000477 pri = (LOG_USER | LOG_NOTICE);
Eric Andersen46ba5682003-05-23 09:29:57 +0000478 }
Pavel Roskinda10ec02000-06-07 21:08:25 +0000479 } else if (c == '\n') {
480 *q++ = ' ';
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000481 } else if (iscntrl(c) && (c < 0177)) {
Pavel Roskinda10ec02000-06-07 21:08:25 +0000482 *q++ = '^';
483 *q++ = c ^ 0100;
484 } else {
485 *q++ = c;
486 }
487 p++;
488 }
489 *q = '\0';
Matt Kraaib6ec7812001-08-14 17:32:23 +0000490 p++;
Pavel Roskinda10ec02000-06-07 21:08:25 +0000491 /* Now log it */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000492 logMessage(pri, line);
Pavel Roskinda10ec02000-06-07 21:08:25 +0000493 }
Mark Whitleybff6b182001-03-27 20:17:58 +0000494 return n_read;
Pavel Roskinda10ec02000-06-07 21:08:25 +0000495}
496
Eric Andersenced2cef2000-07-20 23:41:24 +0000497
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000498#ifdef CONFIG_FEATURE_REMOTE_LOG
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000499static void init_RemoteLog(void)
Eric Andersen871d93c2002-09-17 20:06:29 +0000500{
Eric Andersenced2cef2000-07-20 23:41:24 +0000501
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000502 struct sockaddr_in remoteaddr;
503 struct hostent *hostinfo;
504 int len = sizeof(remoteaddr);
Eric Andersenced2cef2000-07-20 23:41:24 +0000505
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000506 memset(&remoteaddr, 0, len);
Mark Whitleybff6b182001-03-27 20:17:58 +0000507
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000508 remotefd = socket(AF_INET, SOCK_DGRAM, 0);
Eric Andersenced2cef2000-07-20 23:41:24 +0000509
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000510 if (remotefd < 0) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000511 bb_error_msg_and_die("cannot create socket");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000512 }
Eric Andersenced2cef2000-07-20 23:41:24 +0000513
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000514 hostinfo = xgethostbyname(RemoteHost);
Eric Andersenced2cef2000-07-20 23:41:24 +0000515
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000516 remoteaddr.sin_family = AF_INET;
517 remoteaddr.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
518 remoteaddr.sin_port = htons(RemotePort);
Eric Andersenced2cef2000-07-20 23:41:24 +0000519
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000520 /* Since we are using UDP sockets, connect just sets the default host and port
521 * for future operations
522 */
523 if (0 != (connect(remotefd, (struct sockaddr *) &remoteaddr, len))) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000524 bb_error_msg_and_die("cannot connect to remote host %s:%d", RemoteHost,
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000525 RemotePort);
526 }
Eric Andersenced2cef2000-07-20 23:41:24 +0000527
528}
529#endif
530
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000531static void doSyslogd(void) __attribute__ ((noreturn));
532static void doSyslogd(void)
Eric Andersen3843e961999-11-25 07:30:46 +0000533{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000534 struct sockaddr_un sunx;
Erik Andersen1d1d9502000-04-21 01:26:49 +0000535 socklen_t addrLength;
536
Erik Andersen983b51b2000-04-04 18:14:25 +0000537 int sock_fd;
Erik Andersenf13df372000-04-18 23:51:51 +0000538 fd_set fds;
539
Erik Andersenf13df372000-04-18 23:51:51 +0000540 /* Set up signal handlers. */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000541 signal(SIGINT, quit_signal);
542 signal(SIGTERM, quit_signal);
543 signal(SIGQUIT, quit_signal);
544 signal(SIGHUP, SIG_IGN);
545 signal(SIGCHLD, SIG_IGN);
Pavel Roskind39d1202000-09-13 14:14:29 +0000546#ifdef SIGCLD
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000547 signal(SIGCLD, SIG_IGN);
Pavel Roskind39d1202000-09-13 14:14:29 +0000548#endif
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000549 signal(SIGALRM, domark);
550 alarm(MarkInterval);
Eric Andersenb99df0f1999-11-24 09:04:33 +0000551
Erik Andersenf13df372000-04-18 23:51:51 +0000552 /* Create the syslog file so realpath() can work. */
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000553 if (realpath(_PATH_LOG, lfile) != NULL) {
554 unlink(lfile);
555 }
Erik Andersen983b51b2000-04-04 18:14:25 +0000556
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000557 memset(&sunx, 0, sizeof(sunx));
Erik Andersen983b51b2000-04-04 18:14:25 +0000558 sunx.sun_family = AF_UNIX;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000559 strncpy(sunx.sun_path, lfile, sizeof(sunx.sun_path));
560 if ((sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000561 bb_perror_msg_and_die("Couldn't get file descriptor for socket "
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000562 _PATH_LOG);
563 }
Eric Andersenb99df0f1999-11-24 09:04:33 +0000564
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000565 addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
566 if (bind(sock_fd, (struct sockaddr *) &sunx, addrLength) < 0) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000567 bb_perror_msg_and_die("Could not connect to socket " _PATH_LOG);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000568 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000569
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000570 if (chmod(lfile, 0666) < 0) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000571 bb_perror_msg_and_die("Could not set permission on " _PATH_LOG);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000572 }
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000573#ifdef CONFIG_FEATURE_IPC_SYSLOG
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000574 if (circular_logging == TRUE) {
575 ipcsyslog_init();
Eric Andersenea906502001-04-05 20:55:17 +0000576 }
577#endif
578
Eric Andersen871d93c2002-09-17 20:06:29 +0000579#ifdef CONFIG_FEATURE_REMOTE_LOG
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000580 if (doRemoteLog == TRUE) {
581 init_RemoteLog();
Eric Andersen871d93c2002-09-17 20:06:29 +0000582 }
583#endif
Eric Andersenced2cef2000-07-20 23:41:24 +0000584
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000585 logMessage(LOG_SYSLOG | LOG_INFO, "syslogd started: " BB_BANNER);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000586
Erik Andersen983b51b2000-04-04 18:14:25 +0000587 for (;;) {
Erik Andersenf13df372000-04-18 23:51:51 +0000588
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000589 FD_ZERO(&fds);
590 FD_SET(sock_fd, &fds);
Erik Andersenf13df372000-04-18 23:51:51 +0000591
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000592 if (select(sock_fd + 1, &fds, NULL, NULL, NULL) < 0) {
Eric Andersen871d93c2002-09-17 20:06:29 +0000593 if (errno == EINTR) {
594 /* alarm may have happened. */
595 continue;
596 }
Manuel Novoa III cad53642003-03-19 09:13:01 +0000597 bb_perror_msg_and_die("select error");
Erik Andersene49d5ec2000-02-08 19:58:47 +0000598 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000599
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000600 if (FD_ISSET(sock_fd, &fds)) {
601 int i;
Erik Andersene3ed1562000-04-19 18:52:56 +0000602
Eric Andersen900c8f32003-05-16 08:35:02 +0000603 RESERVE_CONFIG_BUFFER(tmpbuf, MAXLINE + 1);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000604
Eric Andersen900c8f32003-05-16 08:35:02 +0000605 memset(tmpbuf, '\0', MAXLINE + 1);
606 if ((i = recv(sock_fd, tmpbuf, MAXLINE, 0)) > 0) {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000607 serveConnection(tmpbuf, i);
608 } else {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000609 bb_perror_msg_and_die("UNIX socket error");
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000610 }
611 RELEASE_CONFIG_BUFFER(tmpbuf);
612 } /* FD_ISSET() */
613 } /* for main loop */
Eric Andersenb99df0f1999-11-24 09:04:33 +0000614}
615
Eric Andersen3843e961999-11-25 07:30:46 +0000616extern int syslogd_main(int argc, char **argv)
617{
Eric Andersene5c24df2001-03-29 21:58:33 +0000618 int opt;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000619
Erik Andersene49d5ec2000-02-08 19:58:47 +0000620 int doFork = TRUE;
621
Erik Andersene49d5ec2000-02-08 19:58:47 +0000622 char *p;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000623
Eric Andersen394cf222000-12-11 16:48:50 +0000624 /* do normal option parsing */
Eric Andersen29c77f72003-10-09 09:43:18 +0000625 while ((opt = getopt(argc, argv, "m:nO:s:b:R:LC::")) > 0) {
Eric Andersen394cf222000-12-11 16:48:50 +0000626 switch (opt) {
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000627 case 'm':
628 MarkInterval = atoi(optarg) * 60;
629 break;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000630 case 'n':
631 doFork = FALSE;
632 break;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000633 case 'O':
Glenn L McGrathfe538ba2003-09-10 23:35:45 +0000634 logFilePath = optarg;
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000635 break;
Eric Andersen29c77f72003-10-09 09:43:18 +0000636#ifdef CONFIG_FEATURE_ROTATE_LOGFILE
637 case 's':
638 logFileSize = atoi(optarg) * 1024;
639 break;
640 case 'b':
641 logFileRotate = atoi(optarg);
642 if( logFileRotate > 99 ) logFileRotate = 99;
643 break;
644#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000645#ifdef CONFIG_FEATURE_REMOTE_LOG
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000646 case 'R':
Manuel Novoa III cad53642003-03-19 09:13:01 +0000647 RemoteHost = bb_xstrdup(optarg);
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000648 if ((p = strchr(RemoteHost, ':'))) {
649 RemotePort = atoi(p + 1);
650 *p = '\0';
651 }
652 doRemoteLog = TRUE;
653 break;
654 case 'L':
655 local_logging = TRUE;
656 break;
Eric Andersenced2cef2000-07-20 23:41:24 +0000657#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000658#ifdef CONFIG_FEATURE_IPC_SYSLOG
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000659 case 'C':
Glenn L McGratha79220d2003-09-26 00:49:05 +0000660 if (optarg) {
661 int buf_size = atoi(optarg);
662 if (buf_size >= 4) {
Eric Andersend4a5e252003-12-19 11:32:14 +0000663 shm_size = buf_size;
Glenn L McGratha79220d2003-09-26 00:49:05 +0000664 }
665 }
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000666 circular_logging = TRUE;
667 break;
Mark Whitley6317c4b2001-03-12 22:51:50 +0000668#endif
Glenn L McGrath912d8f42002-11-10 22:46:45 +0000669 default:
Manuel Novoa III cad53642003-03-19 09:13:01 +0000670 bb_show_usage();
Eric Andersen3843e961999-11-25 07:30:46 +0000671 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000672 }
673
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000674#ifdef CONFIG_FEATURE_REMOTE_LOG
Eric Andersen4ed17822000-12-11 19:28:29 +0000675 /* If they have not specified remote logging, then log locally */
Eric Andersen871d93c2002-09-17 20:06:29 +0000676 if (doRemoteLog == FALSE)
Eric Andersen4ed17822000-12-11 19:28:29 +0000677 local_logging = TRUE;
678#endif
679
Mark Whitley6317c4b2001-03-12 22:51:50 +0000680
Erik Andersene49d5ec2000-02-08 19:58:47 +0000681 /* Store away localhost's name before the fork */
682 gethostname(LocalHostName, sizeof(LocalHostName));
683 if ((p = strchr(LocalHostName, '.'))) {
Glenn L McGrathfe538ba2003-09-10 23:35:45 +0000684 *p = '\0';
Erik Andersene49d5ec2000-02-08 19:58:47 +0000685 }
686
Erik Andersen983b51b2000-04-04 18:14:25 +0000687 umask(0);
688
Glenn L McGrathfe538ba2003-09-10 23:35:45 +0000689 if (doFork == TRUE) {
Glenn L McGrathdc72f3a2003-08-29 07:35:08 +0000690#if defined(__uClinux__)
Russ Dilla1fece22003-12-15 21:57:44 +0000691 vfork_daemon_rexec(0, 1, argc, argv, "-n");
692#else /* __uClinux__ */
693 if(daemon(0, 1) < 0)
694 bb_perror_msg_and_die("daemon");
695#endif /* __uClinux__ */
Eric Andersen35e643b2003-07-28 07:40:39 +0000696 }
Eric Andersene5c24df2001-03-29 21:58:33 +0000697 doSyslogd();
Eric Andersenb186d981999-12-03 09:19:54 +0000698
Matt Kraai3e856ce2000-12-01 02:55:13 +0000699 return EXIT_SUCCESS;
Eric Andersen3843e961999-11-25 07:30:46 +0000700}
Erik Andersen983b51b2000-04-04 18:14:25 +0000701
702/*
Erik Andersene3ed1562000-04-19 18:52:56 +0000703Local Variables
704c-file-style: "linux"
705c-basic-offset: 4
706tab-width: 4
707End:
708*/