blob: e719001cfaec1fe42cef40cad1e88f04c103266d [file] [log] [blame]
Mark Whitley6317c4b2001-03-12 22:51:50 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Mini klogd implementation for busybox
4 *
Glenn L McGrath6ed77592002-12-12 10:54:48 +00005 * Copyright (C) 2001 by Gennady Feldman <gfeldman@gena01.com>.
Mark Whitley6317c4b2001-03-12 22:51:50 +00006 * Changes: Made this a standalone busybox module which uses standalone
Bernhard Reutner-Fischer86f5c992006-01-22 22:55:11 +00007 * syslog() client interface.
Mark Whitley6317c4b2001-03-12 22:51:50 +00008 *
Eric Andersenc7bda1c2004-03-15 08:29:22 +00009 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
Mark Whitley6317c4b2001-03-12 22:51:50 +000010 *
11 * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org>
12 *
Glenn L McGrath6ed77592002-12-12 10:54:48 +000013 * "circular buffer" Copyright (C) 2000 by Gennady Feldman <gfeldman@gena01.com>
Mark Whitley6317c4b2001-03-12 22:51:50 +000014 *
Glenn L McGrath6ed77592002-12-12 10:54:48 +000015 * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001
Mark Whitley6bff9cc2001-03-12 23:41:34 +000016 *
Bernhard Reutner-Fischer86f5c992006-01-22 22:55:11 +000017 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
Mark Whitley6317c4b2001-03-12 22:51:50 +000018 */
19
Denis Vlasenkob6adbf12007-05-26 19:00:18 +000020#include "libbb.h"
Bernhard Reutner-Fischerf4701962008-01-27 12:50:12 +000021#include <syslog.h>
Eric Andersen85e5e722003-07-22 08:56:55 +000022#include <sys/klog.h>
Eric Andersene76c3b02001-04-05 03:14:39 +000023
Denis Vlasenko7bdf0c82008-06-06 16:08:04 +000024static void klogd_signal(int sig)
Mark Whitley6317c4b2001-03-12 22:51:50 +000025{
Denis Vlasenko7bdf0c82008-06-06 16:08:04 +000026 /* FYI: cmd 7 is equivalent to setting console_loglevel to 7
27 * via klogctl(8, NULL, 7). */
28 klogctl(7, NULL, 0); /* "7 -- Enable printk's to console" */
29 klogctl(0, NULL, 0); /* "0 -- Close the log. Currently a NOP" */
Denis Vlasenko7e3a5f52007-11-16 20:18:54 +000030 syslog(LOG_NOTICE, "klogd: exiting");
Denis Vlasenko400d8bb2008-02-24 13:36:01 +000031 kill_myself_with_sig(sig);
Mark Whitley6317c4b2001-03-12 22:51:50 +000032}
33
Denis Vlasenkoc84520d2007-02-17 14:12:10 +000034#define log_buffer bb_common_bufsiz1
Denis Vlasenko7e3a5f52007-11-16 20:18:54 +000035enum {
36 KLOGD_LOGBUF_SIZE = sizeof(log_buffer),
37 OPT_LEVEL = (1 << 0),
38 OPT_FOREGROUND = (1 << 1),
39};
Bernhard Reutner-Fischer595159f2006-05-31 12:22:13 +000040
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +000041int klogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denis Vlasenko68404f12008-03-17 09:00:54 +000042int klogd_main(int argc ATTRIBUTE_UNUSED, char **argv)
Mark Whitley6317c4b2001-03-12 22:51:50 +000043{
Denis Vlasenko7bdf0c82008-06-06 16:08:04 +000044 int i = 0;
Mark Whitley6317c4b2001-03-12 22:51:50 +000045 char *start;
Denis Vlasenko7bdf0c82008-06-06 16:08:04 +000046 int opt;
Mark Whitley6317c4b2001-03-12 22:51:50 +000047
Denis Vlasenko7bdf0c82008-06-06 16:08:04 +000048 opt = getopt32(argv, "c:n", &start);
49 if (opt & OPT_LEVEL) {
Denis Vlasenkoe428e9d2007-01-04 03:07:57 +000050 /* Valid levels are between 1 and 8 */
Denis Vlasenko7bdf0c82008-06-06 16:08:04 +000051 i = xatou_range(start, 1, 8);
Denis Vlasenkoe428e9d2007-01-04 03:07:57 +000052 }
Denis Vlasenko7bdf0c82008-06-06 16:08:04 +000053 if (!(opt & OPT_FOREGROUND)) {
Denis Vlasenko5a142022007-03-26 13:20:54 +000054 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
Bernhard Reutner-Fischer595159f2006-05-31 12:22:13 +000055 }
56
Eric Andersen36adca82004-06-22 10:07:17 +000057 openlog("kernel", 0, LOG_KERN);
58
Denis Vlasenko25591c32008-02-16 22:58:56 +000059 bb_signals(0
60 + (1 << SIGINT)
61 + (1 << SIGTERM)
62 , klogd_signal);
Mark Whitley6317c4b2001-03-12 22:51:50 +000063 signal(SIGHUP, SIG_IGN);
64
Denis Vlasenko7bdf0c82008-06-06 16:08:04 +000065 /* "Open the log. Currently a NOP" */
Mark Whitley6317c4b2001-03-12 22:51:50 +000066 klogctl(1, NULL, 0);
67
Denis Vlasenko7bdf0c82008-06-06 16:08:04 +000068 /* "printk() prints a message on the console only if it has a loglevel
69 * less than console_loglevel". Here we set console_loglevel = i. */
70 if (i)
Bernhard Reutner-Fischer8fc40112007-01-09 15:46:36 +000071 klogctl(8, NULL, i);
Glenn L McGrathe1ad6722002-12-01 11:31:58 +000072
Denis Vlasenkoca525b42007-06-13 12:27:17 +000073 syslog(LOG_NOTICE, "klogd started: %s", bb_banner);
Mark Whitley6317c4b2001-03-12 22:51:50 +000074
Denis Vlasenkoc84520d2007-02-17 14:12:10 +000075 /* Note: this code does not detect incomplete messages
76 * (messages not ending with '\n' or just when kernel
77 * generates too many messages for us to keep up)
78 * and will split them in two separate lines */
Mark Whitley6317c4b2001-03-12 22:51:50 +000079 while (1) {
Bernhard Reutner-Fischer8fc40112007-01-09 15:46:36 +000080 int n;
81 int priority;
Bernhard Reutner-Fischer8fc40112007-01-09 15:46:36 +000082
Denis Vlasenko7bdf0c82008-06-06 16:08:04 +000083 /* "2 -- Read from the log." */
Denis Vlasenkoe428e9d2007-01-04 03:07:57 +000084 n = klogctl(2, log_buffer, KLOGD_LOGBUF_SIZE - 1);
Mark Whitley6317c4b2001-03-12 22:51:50 +000085 if (n < 0) {
Mark Whitley6317c4b2001-03-12 22:51:50 +000086 if (errno == EINTR)
87 continue;
Denis Vlasenko7bdf0c82008-06-06 16:08:04 +000088 syslog(LOG_ERR, "klogd: error %d in klogctl(2): %m",
Denis Vlasenkoc84520d2007-02-17 14:12:10 +000089 errno);
Denis Vlasenkoe428e9d2007-01-04 03:07:57 +000090 break;
Mark Whitley6317c4b2001-03-12 22:51:50 +000091 }
Denis Vlasenkoc84520d2007-02-17 14:12:10 +000092 log_buffer[n] = '\n';
93 i = 0;
94 while (i < n) {
95 priority = LOG_INFO;
96 start = &log_buffer[i];
97 if (log_buffer[i] == '<') {
Mark Whitley6317c4b2001-03-12 22:51:50 +000098 i++;
Denis Vlasenkoe428e9d2007-01-04 03:07:57 +000099 // kernel never ganerates multi-digit prios
100 //priority = 0;
101 //while (log_buffer[i] >= '0' && log_buffer[i] <= '9') {
102 // priority = priority * 10 + (log_buffer[i] - '0');
103 // i++;
104 //}
105 if (isdigit(log_buffer[i])) {
106 priority = (log_buffer[i] - '0');
Mark Whitley6317c4b2001-03-12 22:51:50 +0000107 i++;
108 }
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000109 if (log_buffer[i] == '>')
110 i++;
Mark Whitley6317c4b2001-03-12 22:51:50 +0000111 start = &log_buffer[i];
112 }
Denis Vlasenkoc84520d2007-02-17 14:12:10 +0000113 while (log_buffer[i] != '\n')
114 i++;
115 log_buffer[i] = '\0';
116 syslog(priority, "%s", start);
117 i++;
Mark Whitley6317c4b2001-03-12 22:51:50 +0000118 }
119 }
Glenn L McGrath9fef17d2002-08-22 18:41:20 +0000120
Denis Vlasenkoe428e9d2007-01-04 03:07:57 +0000121 return EXIT_FAILURE;
Mark Whitley6317c4b2001-03-12 22:51:50 +0000122}