blob: 8648da271b53b312380cf1ccc7a942da5d47d38f [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 Andersen3843e961999-11-25 07:30:46 +000026#include "internal.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);
Erik Andersene3ed1562000-04-19 18:52:56 +0000304 signal (SIGCLD, SIG_IGN);
Erik Andersen983b51b2000-04-04 18:14:25 +0000305 signal (SIGALRM, domark);
306 alarm (MarkInterval);
Eric Andersenb99df0f1999-11-24 09:04:33 +0000307
Erik Andersenf13df372000-04-18 23:51:51 +0000308 /* Create the syslog file so realpath() can work. */
309 close (open (_PATH_LOG, O_RDWR | O_CREAT, 0644));
310 if (realpath (_PATH_LOG, lfile) == NULL)
Pavel Roskin23ad7f72000-09-12 22:05:17 +0000311 fatalError ("Could not resolve path to " _PATH_LOG ": %s\n", strerror (errno));
Eric Andersen14ec6cf1999-12-05 22:17:02 +0000312
Erik Andersen983b51b2000-04-04 18:14:25 +0000313 unlink (lfile);
314
Erik Andersenf13df372000-04-18 23:51:51 +0000315 memset (&sunx, 0, sizeof (sunx));
Erik Andersen983b51b2000-04-04 18:14:25 +0000316 sunx.sun_family = AF_UNIX;
Erik Andersenf13df372000-04-18 23:51:51 +0000317 strncpy (sunx.sun_path, lfile, sizeof (sunx.sun_path));
318 if ((sock_fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
Eric Andersen86ab8a32000-06-02 03:21:42 +0000319 fatalError ("Couldn't obtain descriptor for socket " _PATH_LOG ": %s\n", strerror (errno));
Eric Andersenb99df0f1999-11-24 09:04:33 +0000320
Erik Andersen983b51b2000-04-04 18:14:25 +0000321 addrLength = sizeof (sunx.sun_family) + strlen (sunx.sun_path);
Erik Andersenf13df372000-04-18 23:51:51 +0000322 if ((bind (sock_fd, (struct sockaddr *) &sunx, addrLength)) || (listen (sock_fd, 5)))
Eric Andersen86ab8a32000-06-02 03:21:42 +0000323 fatalError ("Could not connect to socket " _PATH_LOG ": %s\n", strerror (errno));
Erik Andersene49d5ec2000-02-08 19:58:47 +0000324
Erik Andersenf13df372000-04-18 23:51:51 +0000325 if (chmod (lfile, 0666) < 0)
Eric Andersen86ab8a32000-06-02 03:21:42 +0000326 fatalError ("Could not set permission on " _PATH_LOG ": %s\n", strerror (errno));
Erik Andersene49d5ec2000-02-08 19:58:47 +0000327
Erik Andersenf13df372000-04-18 23:51:51 +0000328 FD_ZERO (&fds);
329 FD_SET (sock_fd, &fds);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000330
Eric Andersenced2cef2000-07-20 23:41:24 +0000331 #ifdef BB_FEATURE_REMOTE_LOG
332 if (doRemoteLog == TRUE){
333 init_RemoteLog();
334 }
335 #endif
336
Erik Andersen983b51b2000-04-04 18:14:25 +0000337 logMessage (0, "syslogd started: BusyBox v" BB_VER " (" BB_BT ")");
Erik Andersene49d5ec2000-02-08 19:58:47 +0000338
Erik Andersen983b51b2000-04-04 18:14:25 +0000339 for (;;) {
Erik Andersenf13df372000-04-18 23:51:51 +0000340
341 fd_set readfds;
342 int n_ready;
343 int fd;
344
345 memcpy (&readfds, &fds, sizeof (fds));
Erik Andersene49d5ec2000-02-08 19:58:47 +0000346
Erik Andersen983b51b2000-04-04 18:14:25 +0000347 if ((n_ready = select (FD_SETSIZE, &readfds, NULL, NULL, NULL)) < 0) {
348 if (errno == EINTR) continue; /* alarm may have happened. */
Erik Andersenf13df372000-04-18 23:51:51 +0000349 fatalError ("select error: %s\n", strerror (errno));
Erik Andersene49d5ec2000-02-08 19:58:47 +0000350 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000351
Erik Andersenf13df372000-04-18 23:51:51 +0000352 for (fd = 0; (n_ready > 0) && (fd < FD_SETSIZE); fd++) {
Erik Andersen983b51b2000-04-04 18:14:25 +0000353 if (FD_ISSET (fd, &readfds)) {
Erik Andersene3ed1562000-04-19 18:52:56 +0000354
Erik Andersenf13df372000-04-18 23:51:51 +0000355 --n_ready;
Erik Andersene3ed1562000-04-19 18:52:56 +0000356
Erik Andersen983b51b2000-04-04 18:14:25 +0000357 if (fd == sock_fd) {
Erik Andersene3ed1562000-04-19 18:52:56 +0000358
359 int conn;
360 pid_t pid;
361
Erik Andersenf13df372000-04-18 23:51:51 +0000362 if ((conn = accept (sock_fd, (struct sockaddr *) &sunx, &addrLength)) < 0) {
363 fatalError ("accept error: %s\n", strerror (errno));
Erik Andersen983b51b2000-04-04 18:14:25 +0000364 }
Erik Andersena6c75222000-04-18 00:00:52 +0000365
Erik Andersene3ed1562000-04-19 18:52:56 +0000366 pid = fork();
Erik Andersen983b51b2000-04-04 18:14:25 +0000367
Erik Andersene3ed1562000-04-19 18:52:56 +0000368 if (pid < 0) {
369 perror ("syslogd: fork");
370 close (conn);
371 continue;
Erik Andersen983b51b2000-04-04 18:14:25 +0000372 }
Erik Andersene3ed1562000-04-19 18:52:56 +0000373
Eric Andersenb2fc5a02000-08-20 06:11:32 +0000374 if (pid == 0) {
Pavel Roskinda10ec02000-06-07 21:08:25 +0000375 serveConnection (conn);
Eric Andersenb2fc5a02000-08-20 06:11:32 +0000376 close (conn);
377 exit( TRUE);
378 }
Erik Andersene3ed1562000-04-19 18:52:56 +0000379 close (conn);
Erik Andersen983b51b2000-04-04 18:14:25 +0000380 }
381 }
382 }
383 }
Eric Andersenb99df0f1999-11-24 09:04:33 +0000384}
385
Eric Andersen03f4c272000-07-06 23:10:29 +0000386#ifdef BB_FEATURE_KLOGD
Eric Andersen2cb55071999-12-10 08:25:07 +0000387
Eric Andersenb186d981999-12-03 09:19:54 +0000388static void klogd_signal(int sig)
389{
Eric Andersen67e32302000-06-19 17:48:02 +0000390 klogctl(7, NULL, 0);
391 klogctl(0, 0, 0);
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000392 logMessage(0, "Kernel log daemon exiting.");
Erik Andersene49d5ec2000-02-08 19:58:47 +0000393 exit(TRUE);
Eric Andersenb186d981999-12-03 09:19:54 +0000394}
395
Erik Andersen983b51b2000-04-04 18:14:25 +0000396static void doKlogd (void) __attribute__ ((noreturn));
397static void doKlogd (void)
Eric Andersenb186d981999-12-03 09:19:54 +0000398{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000399 int priority = LOG_INFO;
400 char log_buffer[4096];
401 char *logp;
Eric Andersenb186d981999-12-03 09:19:54 +0000402
Erik Andersene49d5ec2000-02-08 19:58:47 +0000403 /* Set up sig handlers */
404 signal(SIGINT, klogd_signal);
405 signal(SIGKILL, klogd_signal);
406 signal(SIGTERM, klogd_signal);
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000407 signal(SIGHUP, SIG_IGN);
Eric Andersenced2cef2000-07-20 23:41:24 +0000408
409#ifdef BB_FEATURE_REMOTE_LOG
410 if (doRemoteLog == TRUE){
411 init_RemoteLog();
412 }
413#endif
414
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000415 logMessage(0, "klogd started: "
Erik Andersene49d5ec2000-02-08 19:58:47 +0000416 "BusyBox v" BB_VER " (" BB_BT ")");
Eric Andersenb186d981999-12-03 09:19:54 +0000417
Eric Andersen67e32302000-06-19 17:48:02 +0000418 klogctl(1, NULL, 0);
Eric Andersen0ecb54a1999-12-05 23:24:55 +0000419
Erik Andersene49d5ec2000-02-08 19:58:47 +0000420 while (1) {
421 /* Use kernel syscalls */
422 memset(log_buffer, '\0', sizeof(log_buffer));
Eric Andersen67e32302000-06-19 17:48:02 +0000423 if (klogctl(2, log_buffer, sizeof(log_buffer)) < 0) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000424 char message[80];
425
426 if (errno == EINTR)
427 continue;
428 snprintf(message, 79, "klogd: Error return from sys_sycall: " \
429 "%d - %s.\n", errno, strerror(errno));
430 logMessage(LOG_SYSLOG | LOG_ERR, message);
431 exit(1);
432 }
433 logp = log_buffer;
434 if (*log_buffer == '<') {
435 switch (*(log_buffer + 1)) {
436 case '0':
437 priority = LOG_EMERG;
438 break;
439 case '1':
440 priority = LOG_ALERT;
441 break;
442 case '2':
443 priority = LOG_CRIT;
444 break;
445 case '3':
446 priority = LOG_ERR;
447 break;
448 case '4':
449 priority = LOG_WARNING;
450 break;
451 case '5':
452 priority = LOG_NOTICE;
453 break;
454 case '6':
455 priority = LOG_INFO;
456 break;
457 case '7':
458 default:
459 priority = LOG_DEBUG;
460 }
461 logp += 3;
462 }
463 logMessage(LOG_KERN | priority, logp);
Eric Andersenb186d981999-12-03 09:19:54 +0000464 }
Eric Andersenb186d981999-12-03 09:19:54 +0000465
466}
467
Eric Andersen2cb55071999-12-10 08:25:07 +0000468#endif
Eric Andersenb99df0f1999-11-24 09:04:33 +0000469
Erik Andersen983b51b2000-04-04 18:14:25 +0000470static void daemon_init (char **argv, char *dz, void fn (void))
471{
472 setsid();
473 chdir ("/");
474 strncpy(argv[0], dz, strlen(argv[0]));
475 fn();
476 exit(0);
477}
478
Eric Andersen3843e961999-11-25 07:30:46 +0000479extern int syslogd_main(int argc, char **argv)
480{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000481 int pid, klogd_pid;
482 int doFork = TRUE;
483
Eric Andersen03f4c272000-07-06 23:10:29 +0000484#ifdef BB_FEATURE_KLOGD
Erik Andersene49d5ec2000-02-08 19:58:47 +0000485 int startKlogd = TRUE;
Eric Andersen2cb55071999-12-10 08:25:07 +0000486#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000487 int stopDoingThat = FALSE;
488 char *p;
489 char **argv1 = argv;
490
491 while (--argc > 0 && **(++argv1) == '-') {
492 stopDoingThat = FALSE;
493 while (stopDoingThat == FALSE && *(++(*argv1))) {
494 switch (**argv1) {
495 case 'm':
496 if (--argc == 0) {
497 usage(syslogd_usage);
498 }
499 MarkInterval = atoi(*(++argv1)) * 60;
500 break;
501 case 'n':
502 doFork = FALSE;
503 break;
Eric Andersen03f4c272000-07-06 23:10:29 +0000504#ifdef BB_FEATURE_KLOGD
Erik Andersene49d5ec2000-02-08 19:58:47 +0000505 case 'K':
506 startKlogd = FALSE;
507 break;
508#endif
509 case 'O':
510 if (--argc == 0) {
511 usage(syslogd_usage);
512 }
513 logFilePath = *(++argv1);
514 stopDoingThat = TRUE;
515 break;
Eric Andersenced2cef2000-07-20 23:41:24 +0000516#ifdef BB_FEATURE_REMOTE_LOG
517 case 'R':
518 if (--argc == 0) {
519 usage(syslogd_usage);
520 }
521 RemoteHost = *(++argv1);
522 if ( (p = strchr(RemoteHost, ':'))){
523 RemotePort = atoi(p+1);
524 *p = '\0';
525 }
526 doRemoteLog = TRUE;
527 stopDoingThat = TRUE;
528 break;
529#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000530 default:
531 usage(syslogd_usage);
532 }
Eric Andersen3843e961999-11-25 07:30:46 +0000533 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000534 }
535
Pavel Roskinda10ec02000-06-07 21:08:25 +0000536 if (argc > 0)
537 usage(syslogd_usage);
538
Erik Andersene49d5ec2000-02-08 19:58:47 +0000539 /* Store away localhost's name before the fork */
540 gethostname(LocalHostName, sizeof(LocalHostName));
541 if ((p = strchr(LocalHostName, '.'))) {
542 *p++ = '\0';
543 }
544
Erik Andersen983b51b2000-04-04 18:14:25 +0000545 umask(0);
546
Eric Andersen03f4c272000-07-06 23:10:29 +0000547#ifdef BB_FEATURE_KLOGD
Erik Andersene2729152000-02-18 21:34:17 +0000548 /* Start up the klogd process */
549 if (startKlogd == TRUE) {
550 klogd_pid = fork();
551 if (klogd_pid == 0) {
Erik Andersen983b51b2000-04-04 18:14:25 +0000552 daemon_init (argv, "klogd", doKlogd);
Erik Andersene2729152000-02-18 21:34:17 +0000553 }
554 }
555#endif
556
Erik Andersene49d5ec2000-02-08 19:58:47 +0000557 if (doFork == TRUE) {
558 pid = fork();
559 if (pid < 0)
560 exit(pid);
561 else if (pid == 0) {
Erik Andersen983b51b2000-04-04 18:14:25 +0000562 daemon_init (argv, "syslogd", doSyslogd);
Eric Andersen3843e961999-11-25 07:30:46 +0000563 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000564 } else {
565 doSyslogd();
Eric Andersen3843e961999-11-25 07:30:46 +0000566 }
Eric Andersenb186d981999-12-03 09:19:54 +0000567
Eric Andersen67e32302000-06-19 17:48:02 +0000568 return(TRUE);
Eric Andersen3843e961999-11-25 07:30:46 +0000569}
Erik Andersen983b51b2000-04-04 18:14:25 +0000570
571/*
Erik Andersene3ed1562000-04-19 18:52:56 +0000572Local Variables
573c-file-style: "linux"
574c-basic-offset: 4
575tab-width: 4
576End:
577*/