blob: 9bedc84f29a7cd71145865f86027b23d9025bc2a [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 *
Erik Andersen61677fe2000-04-13 01:18:56 +00005 * Copyright (C) 1999,2000 by Lineo, inc.
Eric Andersen3843e961999-11-25 07:30:46 +00006 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 *
Erik Andersenf13df372000-04-18 23:51:51 +00008 * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org>
9 *
Eric Andersen3843e961999-11-25 07:30:46 +000010 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
Eric Andersenb99df0f1999-11-24 09:04:33 +000025
Eric Andersen3570a342000-09-25 21:45:58 +000026#include "busybox.h"
Eric Andersen67e32302000-06-19 17:48:02 +000027#include <stdio.h>
28#include <stdlib.h>
Eric Andersen3843e961999-11-25 07:30:46 +000029#include <ctype.h>
Eric Andersenb186d981999-12-03 09:19:54 +000030#include <errno.h>
Erik Andersen983b51b2000-04-04 18:14:25 +000031#include <fcntl.h>
32#include <netdb.h>
Eric Andersenb186d981999-12-03 09:19:54 +000033#include <paths.h>
Erik Andersen983b51b2000-04-04 18:14:25 +000034#include <signal.h>
35#include <stdarg.h>
Eric Andersen67e32302000-06-19 17:48:02 +000036#include <time.h>
37#include <unistd.h>
Erik Andersen983b51b2000-04-04 18:14:25 +000038#include <sys/socket.h>
Erik Andersen983b51b2000-04-04 18:14:25 +000039#include <sys/types.h>
40#include <sys/un.h>
Erik Andersen7d6ba572000-04-19 20:02:50 +000041#include <sys/param.h>
Eric Andersenb186d981999-12-03 09:19:54 +000042
Eric Andersen999bf722000-07-09 06:59:58 +000043#if ! defined __GLIBC__ && ! defined __UCLIBC__
Eric Andersen67e32302000-06-19 17:48:02 +000044
Eric Andersena15cd0b2000-06-19 18:14:20 +000045typedef unsigned int socklen_t;
46
Eric Andersen67e32302000-06-19 17:48:02 +000047#ifndef __alpha__
48# define __NR_klogctl __NR_syslog
49static inline _syscall3(int, klogctl, int, type, char *, b, int, len);
50#else /* __alpha__ */
51#define klogctl syslog
52#endif
53
54#else
55# include <sys/klog.h>
56#endif
57
Eric Andersenb99df0f1999-11-24 09:04:33 +000058
59
Eric Andersen3843e961999-11-25 07:30:46 +000060/* SYSLOG_NAMES defined to pull some extra junk from syslog.h */
61#define SYSLOG_NAMES
62#include <sys/syslog.h>
Eric Andersenced2cef2000-07-20 23:41:24 +000063#include <sys/uio.h>
Eric Andersen3843e961999-11-25 07:30:46 +000064
65/* Path for the file where all log messages are written */
Erik Andersen983b51b2000-04-04 18:14:25 +000066#define __LOG_FILE "/var/log/messages"
Eric Andersen3843e961999-11-25 07:30:46 +000067
Erik Andersen983b51b2000-04-04 18:14:25 +000068/* Path to the unix socket */
Erik Andersen4f3f7572000-04-28 00:18:56 +000069char lfile[BUFSIZ] = "";
Eric Andersen3843e961999-11-25 07:30:46 +000070
Erik Andersene49d5ec2000-02-08 19:58:47 +000071static char *logFilePath = __LOG_FILE;
72
Eric Andersen3843e961999-11-25 07:30:46 +000073/* interval between marks in seconds */
Erik Andersene49d5ec2000-02-08 19:58:47 +000074static int MarkInterval = 20 * 60;
75
Eric Andersen3843e961999-11-25 07:30:46 +000076/* localhost's name */
77static char LocalHostName[32];
78
Eric Andersenced2cef2000-07-20 23:41:24 +000079#ifdef BB_FEATURE_REMOTE_LOG
80#include <netinet/in.h>
81/* udp socket for logging to remote host */
82static int remotefd = -1;
83/* where do we log? */
84static char *RemoteHost;
85/* what port to log to? */
86static int RemotePort = 514;
87/* To remote log or not to remote log, that is the question. */
88static int doRemoteLog = FALSE;
89#endif
90
Erik Andersenc053e412000-03-21 01:31:24 +000091/* Note: There is also a function called "message()" in init.c */
Erik Andersen983b51b2000-04-04 18:14:25 +000092/* Print a message to the log file. */
Erik Andersenf13df372000-04-18 23:51:51 +000093static void message (char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
94static void message (char *fmt, ...)
Eric Andersen3843e961999-11-25 07:30:46 +000095{
Erik Andersene49d5ec2000-02-08 19:58:47 +000096 int fd;
Erik Andersene3ed1562000-04-19 18:52:56 +000097 struct flock fl;
Erik Andersene49d5ec2000-02-08 19:58:47 +000098 va_list arguments;
Eric Andersen3843e961999-11-25 07:30:46 +000099
Erik Andersene3ed1562000-04-19 18:52:56 +0000100 fl.l_whence = SEEK_SET;
101 fl.l_start = 0;
102 fl.l_len = 1;
103
Erik Andersenf13df372000-04-18 23:51:51 +0000104 if ((fd = device_open (logFilePath,
105 O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
106 O_NONBLOCK)) >= 0) {
Erik Andersene3ed1562000-04-19 18:52:56 +0000107 fl.l_type = F_WRLCK;
108 fcntl (fd, F_SETLKW, &fl);
Erik Andersenf13df372000-04-18 23:51:51 +0000109 va_start (arguments, fmt);
110 vdprintf (fd, fmt, arguments);
111 va_end (arguments);
Erik Andersene3ed1562000-04-19 18:52:56 +0000112 fl.l_type = F_UNLCK;
113 fcntl (fd, F_SETLKW, &fl);
Erik Andersenf13df372000-04-18 23:51:51 +0000114 close (fd);
Eric Andersen3843e961999-11-25 07:30:46 +0000115 } else {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000116 /* Always send console messages to /dev/console so people will see them. */
Erik Andersenf13df372000-04-18 23:51:51 +0000117 if ((fd = device_open (_PATH_CONSOLE,
118 O_WRONLY | O_NOCTTY | O_NONBLOCK)) >= 0) {
119 va_start (arguments, fmt);
120 vdprintf (fd, fmt, arguments);
121 va_end (arguments);
122 close (fd);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000123 } else {
Erik Andersenf13df372000-04-18 23:51:51 +0000124 fprintf (stderr, "Bummer, can't print: ");
125 va_start (arguments, fmt);
126 vfprintf (stderr, fmt, arguments);
127 fflush (stderr);
128 va_end (arguments);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000129 }
Eric Andersen3843e961999-11-25 07:30:46 +0000130 }
Eric Andersenb99df0f1999-11-24 09:04:33 +0000131}
132
Erik Andersenf13df372000-04-18 23:51:51 +0000133static void logMessage (int pri, char *msg)
Eric Andersen3843e961999-11-25 07:30:46 +0000134{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000135 time_t now;
136 char *timestamp;
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000137 static char res[20] = "";
Erik Andersene49d5ec2000-02-08 19:58:47 +0000138 CODE *c_pri, *c_fac;
Eric Andersenb99df0f1999-11-24 09:04:33 +0000139
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000140 if (pri != 0) {
141 for (c_fac = facilitynames;
142 c_fac->c_name && !(c_fac->c_val == LOG_FAC(pri) << 3); c_fac++);
143 for (c_pri = prioritynames;
144 c_pri->c_name && !(c_pri->c_val == LOG_PRI(pri)); c_pri++);
145 if (*c_fac->c_name == '\0' || *c_pri->c_name == '\0')
146 snprintf(res, sizeof(res), "<%d>", pri);
147 else
148 snprintf(res, sizeof(res), "%s.%s", c_fac->c_name, c_pri->c_name);
149 }
Eric Andersen3843e961999-11-25 07:30:46 +0000150
Erik Andersene49d5ec2000-02-08 19:58:47 +0000151 if (strlen(msg) < 16 || msg[3] != ' ' || msg[6] != ' ' ||
152 msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') {
153 time(&now);
154 timestamp = ctime(&now) + 4;
155 timestamp[15] = '\0';
156 } else {
157 timestamp = msg;
158 timestamp[15] = '\0';
159 msg += 16;
160 }
Eric Andersen3843e961999-11-25 07:30:46 +0000161
Erik Andersene49d5ec2000-02-08 19:58:47 +0000162 /* todo: supress duplicates */
Eric Andersen3843e961999-11-25 07:30:46 +0000163
Erik Andersene49d5ec2000-02-08 19:58:47 +0000164 /* now spew out the message to wherever it is supposed to go */
165 message("%s %s %s %s\n", timestamp, LocalHostName, res, msg);
Eric Andersenced2cef2000-07-20 23:41:24 +0000166
167#ifdef BB_FEATURE_REMOTE_LOG
168 /* send message to remote logger */
169 if ( -1 != remotefd){
170#define IOV_COUNT 2
171 struct iovec iov[IOV_COUNT];
172 struct iovec *v = iov;
173
174 bzero(&res, sizeof(res));
175 snprintf(res, sizeof(res), "<%d>", pri);
176 v->iov_base = res ;
177 v->iov_len = strlen(res);
178 v++;
179
180 v->iov_base = msg;
181 v->iov_len = strlen(msg);
182
183 if ( -1 == writev(remotefd,iov, IOV_COUNT)){
184 fatalError("syslogd: cannot write to remote file handle on"
185 "%s:%d\n",RemoteHost,RemotePort);
186 }
187 }
188#endif
189
Eric Andersen3843e961999-11-25 07:30:46 +0000190}
191
192static void quit_signal(int sig)
193{
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000194 logMessage(0, "System log daemon exiting.");
Erik Andersen983b51b2000-04-04 18:14:25 +0000195 unlink(lfile);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000196 exit(TRUE);
Eric Andersen3843e961999-11-25 07:30:46 +0000197}
198
Eric Andersen3843e961999-11-25 07:30:46 +0000199static void domark(int sig)
200{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000201 if (MarkInterval > 0) {
202 logMessage(LOG_SYSLOG | LOG_INFO, "-- MARK --");
203 alarm(MarkInterval);
204 }
Eric Andersen3843e961999-11-25 07:30:46 +0000205}
206
Pavel Roskinda10ec02000-06-07 21:08:25 +0000207#define BUFSIZE 1023
Eric Andersen67e32302000-06-19 17:48:02 +0000208static int serveConnection (int conn)
Pavel Roskinda10ec02000-06-07 21:08:25 +0000209{
210 char buf[ BUFSIZE + 1 ];
211 int n_read;
212
213 while ((n_read = read (conn, buf, BUFSIZE )) > 0) {
214
215 int pri = (LOG_USER | LOG_NOTICE);
216 char line[ BUFSIZE + 1 ];
217 unsigned char c;
218
219 char *p = buf, *q = line;
220
221 buf[ n_read - 1 ] = '\0';
222
223 while (p && (c = *p) && q < &line[ sizeof (line) - 1 ]) {
224 if (c == '<') {
225 /* Parse the magic priority number. */
226 pri = 0;
227 while (isdigit (*(++p))) {
228 pri = 10 * pri + (*p - '0');
229 }
Eric Andersenced2cef2000-07-20 23:41:24 +0000230 if (pri & ~(LOG_FACMASK | LOG_PRIMASK)){
Pavel Roskinda10ec02000-06-07 21:08:25 +0000231 pri = (LOG_USER | LOG_NOTICE);
Eric Andersenced2cef2000-07-20 23:41:24 +0000232 }
Pavel Roskinda10ec02000-06-07 21:08:25 +0000233 } else if (c == '\n') {
234 *q++ = ' ';
235 } else if (iscntrl (c) && (c < 0177)) {
236 *q++ = '^';
237 *q++ = c ^ 0100;
238 } else {
239 *q++ = c;
240 }
241 p++;
242 }
243 *q = '\0';
244 /* Now log it */
245 logMessage (pri, line);
246 }
Eric Andersen67e32302000-06-19 17:48:02 +0000247 return (0);
Pavel Roskinda10ec02000-06-07 21:08:25 +0000248}
249
Eric Andersenced2cef2000-07-20 23:41:24 +0000250
251#ifdef BB_FEATURE_REMOTE_LOG
252static void init_RemoteLog (void){
253
254 struct sockaddr_in remoteaddr;
255 struct hostent *hostinfo;
256 int len = sizeof(remoteaddr);
257
258 bzero(&remoteaddr, len);
259
260 remotefd = socket(AF_INET, SOCK_DGRAM, 0);
261
262 if (remotefd < 0) {
263 fatalError("syslogd: cannot create socket\n");
264 }
265
266 hostinfo = (struct hostent *) gethostbyname(RemoteHost);
267
268 if (!hostinfo) {
269 fatalError("syslogd: cannot resolve remote host name [%s]\n", RemoteHost);
270 }
271
272 remoteaddr.sin_family = AF_INET;
273 remoteaddr.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
274 remoteaddr.sin_port = htons(RemotePort);
275
276 /*
277 Since we are using UDP sockets, connect just sets the default host and port
278 for future operations
279 */
280 if ( 0 != (connect(remotefd, (struct sockaddr *) &remoteaddr, len))){
281 fatalError("syslogd: cannot connect to remote host %s:%d\n", RemoteHost, RemotePort);
282 }
283
284}
285#endif
286
Erik Andersen983b51b2000-04-04 18:14:25 +0000287static void doSyslogd (void) __attribute__ ((noreturn));
288static void doSyslogd (void)
Eric Andersen3843e961999-11-25 07:30:46 +0000289{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000290 struct sockaddr_un sunx;
Erik Andersen1d1d9502000-04-21 01:26:49 +0000291 socklen_t addrLength;
292
Erik Andersenf13df372000-04-18 23:51:51 +0000293
Erik Andersen983b51b2000-04-04 18:14:25 +0000294 int sock_fd;
Erik Andersenf13df372000-04-18 23:51:51 +0000295 fd_set fds;
296
Erik Andersen4f3f7572000-04-28 00:18:56 +0000297 char lfile[BUFSIZ];
Eric Andersenb99df0f1999-11-24 09:04:33 +0000298
Erik Andersenf13df372000-04-18 23:51:51 +0000299 /* Set up signal handlers. */
Erik Andersen983b51b2000-04-04 18:14:25 +0000300 signal (SIGINT, quit_signal);
301 signal (SIGTERM, quit_signal);
302 signal (SIGQUIT, quit_signal);
303 signal (SIGHUP, SIG_IGN);
Pavel Roskind39d1202000-09-13 14:14:29 +0000304 signal (SIGCHLD, SIG_IGN);
305#ifdef SIGCLD
Erik Andersene3ed1562000-04-19 18:52:56 +0000306 signal (SIGCLD, SIG_IGN);
Pavel Roskind39d1202000-09-13 14:14:29 +0000307#endif
Erik Andersen983b51b2000-04-04 18:14:25 +0000308 signal (SIGALRM, domark);
309 alarm (MarkInterval);
Eric Andersenb99df0f1999-11-24 09:04:33 +0000310
Erik Andersenf13df372000-04-18 23:51:51 +0000311 /* Create the syslog file so realpath() can work. */
312 close (open (_PATH_LOG, O_RDWR | O_CREAT, 0644));
313 if (realpath (_PATH_LOG, lfile) == NULL)
Pavel Roskin23ad7f72000-09-12 22:05:17 +0000314 fatalError ("Could not resolve path to " _PATH_LOG ": %s\n", strerror (errno));
Eric Andersen14ec6cf1999-12-05 22:17:02 +0000315
Erik Andersen983b51b2000-04-04 18:14:25 +0000316 unlink (lfile);
317
Erik Andersenf13df372000-04-18 23:51:51 +0000318 memset (&sunx, 0, sizeof (sunx));
Erik Andersen983b51b2000-04-04 18:14:25 +0000319 sunx.sun_family = AF_UNIX;
Erik Andersenf13df372000-04-18 23:51:51 +0000320 strncpy (sunx.sun_path, lfile, sizeof (sunx.sun_path));
321 if ((sock_fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
Eric Andersen86ab8a32000-06-02 03:21:42 +0000322 fatalError ("Couldn't obtain descriptor for socket " _PATH_LOG ": %s\n", strerror (errno));
Eric Andersenb99df0f1999-11-24 09:04:33 +0000323
Erik Andersen983b51b2000-04-04 18:14:25 +0000324 addrLength = sizeof (sunx.sun_family) + strlen (sunx.sun_path);
Erik Andersenf13df372000-04-18 23:51:51 +0000325 if ((bind (sock_fd, (struct sockaddr *) &sunx, addrLength)) || (listen (sock_fd, 5)))
Eric Andersen86ab8a32000-06-02 03:21:42 +0000326 fatalError ("Could not connect to socket " _PATH_LOG ": %s\n", strerror (errno));
Erik Andersene49d5ec2000-02-08 19:58:47 +0000327
Erik Andersenf13df372000-04-18 23:51:51 +0000328 if (chmod (lfile, 0666) < 0)
Eric Andersen86ab8a32000-06-02 03:21:42 +0000329 fatalError ("Could not set permission on " _PATH_LOG ": %s\n", strerror (errno));
Erik Andersene49d5ec2000-02-08 19:58:47 +0000330
Erik Andersenf13df372000-04-18 23:51:51 +0000331 FD_ZERO (&fds);
332 FD_SET (sock_fd, &fds);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000333
Eric Andersenced2cef2000-07-20 23:41:24 +0000334 #ifdef BB_FEATURE_REMOTE_LOG
335 if (doRemoteLog == TRUE){
336 init_RemoteLog();
337 }
338 #endif
339
Erik Andersen983b51b2000-04-04 18:14:25 +0000340 logMessage (0, "syslogd started: BusyBox v" BB_VER " (" BB_BT ")");
Erik Andersene49d5ec2000-02-08 19:58:47 +0000341
Erik Andersen983b51b2000-04-04 18:14:25 +0000342 for (;;) {
Erik Andersenf13df372000-04-18 23:51:51 +0000343
344 fd_set readfds;
345 int n_ready;
346 int fd;
347
348 memcpy (&readfds, &fds, sizeof (fds));
Erik Andersene49d5ec2000-02-08 19:58:47 +0000349
Erik Andersen983b51b2000-04-04 18:14:25 +0000350 if ((n_ready = select (FD_SETSIZE, &readfds, NULL, NULL, NULL)) < 0) {
351 if (errno == EINTR) continue; /* alarm may have happened. */
Erik Andersenf13df372000-04-18 23:51:51 +0000352 fatalError ("select error: %s\n", strerror (errno));
Erik Andersene49d5ec2000-02-08 19:58:47 +0000353 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000354
Erik Andersenf13df372000-04-18 23:51:51 +0000355 for (fd = 0; (n_ready > 0) && (fd < FD_SETSIZE); fd++) {
Erik Andersen983b51b2000-04-04 18:14:25 +0000356 if (FD_ISSET (fd, &readfds)) {
Erik Andersene3ed1562000-04-19 18:52:56 +0000357
Erik Andersenf13df372000-04-18 23:51:51 +0000358 --n_ready;
Erik Andersene3ed1562000-04-19 18:52:56 +0000359
Erik Andersen983b51b2000-04-04 18:14:25 +0000360 if (fd == sock_fd) {
Erik Andersene3ed1562000-04-19 18:52:56 +0000361
362 int conn;
363 pid_t pid;
364
Erik Andersenf13df372000-04-18 23:51:51 +0000365 if ((conn = accept (sock_fd, (struct sockaddr *) &sunx, &addrLength)) < 0) {
366 fatalError ("accept error: %s\n", strerror (errno));
Erik Andersen983b51b2000-04-04 18:14:25 +0000367 }
Erik Andersena6c75222000-04-18 00:00:52 +0000368
Erik Andersene3ed1562000-04-19 18:52:56 +0000369 pid = fork();
Erik Andersen983b51b2000-04-04 18:14:25 +0000370
Erik Andersene3ed1562000-04-19 18:52:56 +0000371 if (pid < 0) {
372 perror ("syslogd: fork");
373 close (conn);
374 continue;
Erik Andersen983b51b2000-04-04 18:14:25 +0000375 }
Erik Andersene3ed1562000-04-19 18:52:56 +0000376
Eric Andersenb2fc5a02000-08-20 06:11:32 +0000377 if (pid == 0) {
Pavel Roskinda10ec02000-06-07 21:08:25 +0000378 serveConnection (conn);
Eric Andersenb2fc5a02000-08-20 06:11:32 +0000379 close (conn);
380 exit( TRUE);
381 }
Erik Andersene3ed1562000-04-19 18:52:56 +0000382 close (conn);
Erik Andersen983b51b2000-04-04 18:14:25 +0000383 }
384 }
385 }
386 }
Eric Andersenb99df0f1999-11-24 09:04:33 +0000387}
388
Eric Andersen03f4c272000-07-06 23:10:29 +0000389#ifdef BB_FEATURE_KLOGD
Eric Andersen2cb55071999-12-10 08:25:07 +0000390
Eric Andersenb186d981999-12-03 09:19:54 +0000391static void klogd_signal(int sig)
392{
Eric Andersen67e32302000-06-19 17:48:02 +0000393 klogctl(7, NULL, 0);
394 klogctl(0, 0, 0);
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000395 logMessage(0, "Kernel log daemon exiting.");
Erik Andersene49d5ec2000-02-08 19:58:47 +0000396 exit(TRUE);
Eric Andersenb186d981999-12-03 09:19:54 +0000397}
398
Erik Andersen983b51b2000-04-04 18:14:25 +0000399static void doKlogd (void) __attribute__ ((noreturn));
400static void doKlogd (void)
Eric Andersenb186d981999-12-03 09:19:54 +0000401{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000402 int priority = LOG_INFO;
403 char log_buffer[4096];
404 char *logp;
Eric Andersenb186d981999-12-03 09:19:54 +0000405
Erik Andersene49d5ec2000-02-08 19:58:47 +0000406 /* Set up sig handlers */
407 signal(SIGINT, klogd_signal);
408 signal(SIGKILL, klogd_signal);
409 signal(SIGTERM, klogd_signal);
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000410 signal(SIGHUP, SIG_IGN);
Eric Andersenced2cef2000-07-20 23:41:24 +0000411
412#ifdef BB_FEATURE_REMOTE_LOG
413 if (doRemoteLog == TRUE){
414 init_RemoteLog();
415 }
416#endif
417
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000418 logMessage(0, "klogd started: "
Erik Andersene49d5ec2000-02-08 19:58:47 +0000419 "BusyBox v" BB_VER " (" BB_BT ")");
Eric Andersenb186d981999-12-03 09:19:54 +0000420
Eric Andersen67e32302000-06-19 17:48:02 +0000421 klogctl(1, NULL, 0);
Eric Andersen0ecb54a1999-12-05 23:24:55 +0000422
Erik Andersene49d5ec2000-02-08 19:58:47 +0000423 while (1) {
424 /* Use kernel syscalls */
425 memset(log_buffer, '\0', sizeof(log_buffer));
Eric Andersen67e32302000-06-19 17:48:02 +0000426 if (klogctl(2, log_buffer, sizeof(log_buffer)) < 0) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000427 char message[80];
428
429 if (errno == EINTR)
430 continue;
431 snprintf(message, 79, "klogd: Error return from sys_sycall: " \
432 "%d - %s.\n", errno, strerror(errno));
433 logMessage(LOG_SYSLOG | LOG_ERR, message);
434 exit(1);
435 }
436 logp = log_buffer;
437 if (*log_buffer == '<') {
438 switch (*(log_buffer + 1)) {
439 case '0':
440 priority = LOG_EMERG;
441 break;
442 case '1':
443 priority = LOG_ALERT;
444 break;
445 case '2':
446 priority = LOG_CRIT;
447 break;
448 case '3':
449 priority = LOG_ERR;
450 break;
451 case '4':
452 priority = LOG_WARNING;
453 break;
454 case '5':
455 priority = LOG_NOTICE;
456 break;
457 case '6':
458 priority = LOG_INFO;
459 break;
460 case '7':
461 default:
462 priority = LOG_DEBUG;
463 }
464 logp += 3;
465 }
466 logMessage(LOG_KERN | priority, logp);
Eric Andersenb186d981999-12-03 09:19:54 +0000467 }
Eric Andersenb186d981999-12-03 09:19:54 +0000468
469}
470
Eric Andersen2cb55071999-12-10 08:25:07 +0000471#endif
Eric Andersenb99df0f1999-11-24 09:04:33 +0000472
Erik Andersen983b51b2000-04-04 18:14:25 +0000473static void daemon_init (char **argv, char *dz, void fn (void))
474{
475 setsid();
476 chdir ("/");
477 strncpy(argv[0], dz, strlen(argv[0]));
478 fn();
479 exit(0);
480}
481
Eric Andersen3843e961999-11-25 07:30:46 +0000482extern int syslogd_main(int argc, char **argv)
483{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000484 int pid, klogd_pid;
485 int doFork = TRUE;
486
Eric Andersen03f4c272000-07-06 23:10:29 +0000487#ifdef BB_FEATURE_KLOGD
Erik Andersene49d5ec2000-02-08 19:58:47 +0000488 int startKlogd = TRUE;
Eric Andersen2cb55071999-12-10 08:25:07 +0000489#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000490 int stopDoingThat = FALSE;
491 char *p;
492 char **argv1 = argv;
493
494 while (--argc > 0 && **(++argv1) == '-') {
495 stopDoingThat = FALSE;
496 while (stopDoingThat == FALSE && *(++(*argv1))) {
497 switch (**argv1) {
498 case 'm':
499 if (--argc == 0) {
500 usage(syslogd_usage);
501 }
502 MarkInterval = atoi(*(++argv1)) * 60;
503 break;
504 case 'n':
505 doFork = FALSE;
506 break;
Eric Andersen03f4c272000-07-06 23:10:29 +0000507#ifdef BB_FEATURE_KLOGD
Erik Andersene49d5ec2000-02-08 19:58:47 +0000508 case 'K':
509 startKlogd = FALSE;
510 break;
511#endif
512 case 'O':
513 if (--argc == 0) {
514 usage(syslogd_usage);
515 }
516 logFilePath = *(++argv1);
517 stopDoingThat = TRUE;
518 break;
Eric Andersenced2cef2000-07-20 23:41:24 +0000519#ifdef BB_FEATURE_REMOTE_LOG
520 case 'R':
521 if (--argc == 0) {
522 usage(syslogd_usage);
523 }
524 RemoteHost = *(++argv1);
525 if ( (p = strchr(RemoteHost, ':'))){
526 RemotePort = atoi(p+1);
527 *p = '\0';
528 }
529 doRemoteLog = TRUE;
530 stopDoingThat = TRUE;
531 break;
532#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000533 default:
534 usage(syslogd_usage);
535 }
Eric Andersen3843e961999-11-25 07:30:46 +0000536 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000537 }
538
Pavel Roskinda10ec02000-06-07 21:08:25 +0000539 if (argc > 0)
540 usage(syslogd_usage);
541
Erik Andersene49d5ec2000-02-08 19:58:47 +0000542 /* Store away localhost's name before the fork */
543 gethostname(LocalHostName, sizeof(LocalHostName));
544 if ((p = strchr(LocalHostName, '.'))) {
545 *p++ = '\0';
546 }
547
Erik Andersen983b51b2000-04-04 18:14:25 +0000548 umask(0);
549
Eric Andersen03f4c272000-07-06 23:10:29 +0000550#ifdef BB_FEATURE_KLOGD
Erik Andersene2729152000-02-18 21:34:17 +0000551 /* Start up the klogd process */
552 if (startKlogd == TRUE) {
553 klogd_pid = fork();
554 if (klogd_pid == 0) {
Erik Andersen983b51b2000-04-04 18:14:25 +0000555 daemon_init (argv, "klogd", doKlogd);
Erik Andersene2729152000-02-18 21:34:17 +0000556 }
557 }
558#endif
559
Erik Andersene49d5ec2000-02-08 19:58:47 +0000560 if (doFork == TRUE) {
561 pid = fork();
562 if (pid < 0)
563 exit(pid);
564 else if (pid == 0) {
Erik Andersen983b51b2000-04-04 18:14:25 +0000565 daemon_init (argv, "syslogd", doSyslogd);
Eric Andersen3843e961999-11-25 07:30:46 +0000566 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000567 } else {
568 doSyslogd();
Eric Andersen3843e961999-11-25 07:30:46 +0000569 }
Eric Andersenb186d981999-12-03 09:19:54 +0000570
Eric Andersen67e32302000-06-19 17:48:02 +0000571 return(TRUE);
Eric Andersen3843e961999-11-25 07:30:46 +0000572}
Erik Andersen983b51b2000-04-04 18:14:25 +0000573
574/*
Erik Andersene3ed1562000-04-19 18:52:56 +0000575Local Variables
576c-file-style: "linux"
577c-basic-offset: 4
578tab-width: 4
579End:
580*/