1/* vi: set sw=4 ts=4: */ 2/* 3 * Mini klogd implementation for busybox 4 * 5 * Copyright (C) 2001 by Gennady Feldman <gfeldman@cachier.com>. 6 * Changes: Made this a standalone busybox module which uses standalone 7 * syslog() client interface. 8 * 9 * Copyright (C) 1999,2000,2001 by Lineo, inc. 10 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> 11 * 12 * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org> 13 * 14 * "circular buffer" Copyright (C) 2000 by Gennady Feldman <gfeldman@mail.com> 15 * 16 * Maintainer: Gennady Feldman <gena01@cachier.com> as of Mar 12, 2001 17 * 18 * This program is free software; you can redistribute it and/or modify 19 * it under the terms of the GNU General Public License as published by 20 * the Free Software Foundation; either version 2 of the License, or 21 * (at your option) any later version. 22 * 23 * This program is distributed in the hope that it will be useful, 24 * but WITHOUT ANY WARRANTY; without even the implied warranty of 25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 26 * General Public License for more details. 27 * 28 * You should have received a copy of the GNU General Public License 29 * along with this program; if not, write to the Free Software 30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 31 * 32 */ 33 34#include <stdio.h> 35#include <stdlib.h> 36#include <signal.h> /* for our signal() handlers */ 37#include <string.h> /* strncpy() */ 38#include <errno.h> /* errno and friends */ 39#include <unistd.h> 40#include <ctype.h> 41#include <sys/syslog.h> 42 43#if __GNU_LIBRARY__ < 5 44# ifdef __alpha__ 45# define klogctl syslog 46# endif 47#else 48# include <sys/klog.h> 49#endif 50 51#include "busybox.h" 52 53static void klogd_signal(int sig) 54{ 55 klogctl(7, NULL, 0); 56 klogctl(0, 0, 0); 57 //logMessage(0, "Kernel log daemon exiting."); 58 syslog_msg(LOG_DAEMON, 0, "Kernel log daemon exiting."); 59 exit(TRUE); 60} 61 62static void doKlogd (void) __attribute__ ((noreturn)); 63static void doKlogd (void) 64{ 65 int priority = LOG_INFO; 66 char log_buffer[4096]; 67 int i, n, lastc; 68 char *start; 69 70 /* Set up sig handlers */ 71 signal(SIGINT, klogd_signal); 72 signal(SIGKILL, klogd_signal); 73 signal(SIGTERM, klogd_signal); 74 signal(SIGHUP, SIG_IGN); 75 76 /* "Open the log. Currently a NOP." */ 77 klogctl(1, NULL, 0); 78 79 syslog_msg(LOG_DAEMON, 0, "klogd started: " BB_BANNER); 80 81 while (1) { 82 /* Use kernel syscalls */ 83 memset(log_buffer, '\0', sizeof(log_buffer)); 84 n = klogctl(2, log_buffer, sizeof(log_buffer)); 85 if (n < 0) { 86 char message[80]; 87 88 if (errno == EINTR) 89 continue; 90 snprintf(message, 79, "klogd: Error return from sys_sycall: %d - %s.\n", 91 errno, strerror(errno)); 92 syslog_msg(LOG_DAEMON, LOG_SYSLOG | LOG_ERR, message); 93 exit(1); 94 } 95 96 /* klogctl buffer parsing modelled after code in dmesg.c */ 97 start=&log_buffer[0]; 98 lastc='\0'; 99 for (i=0; i<n; i++) { 100 if (lastc == '\0' && log_buffer[i] == '<') { 101 priority = 0; 102 i++; 103 while (isdigit(log_buffer[i])) { 104 priority = priority*10+(log_buffer[i]-'0'); 105 i++; 106 } 107 if (log_buffer[i] == '>') i++; 108 start = &log_buffer[i]; 109 } 110 if (log_buffer[i] == '\n') { 111 log_buffer[i] = '\0'; /* zero terminate this message */ 112 syslog_msg(LOG_DAEMON, LOG_KERN | priority, start); 113 start = &log_buffer[i+1]; 114 priority = LOG_INFO; 115 } 116 lastc = log_buffer[i]; 117 } 118 } 119} 120 121extern int klogd_main(int argc, char **argv) 122{ 123 /* no options, no getopt */ 124 int opt; 125 int doFork = TRUE; 126 127 /* do normal option parsing */ 128 while ((opt = getopt(argc, argv, "n")) > 0) { 129 switch (opt) { 130 case 'n': 131 doFork = FALSE; 132 break; 133 default: 134 show_usage(); 135 } 136 } 137 138 if (doFork == TRUE) { 139 if (daemon(0, 1) < 0) 140 perror_msg_and_die("daemon"); 141 } 142 doKlogd(); 143 144 return EXIT_SUCCESS; 145} 146 147/* 148Local Variables 149c-file-style: "linux" 150c-basic-offset: 4 151tab-width: 4 152End: 153*/ 154