1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#define FOR_klogd
26#include "toys.h"
27#include <signal.h>
28#include <sys/klog.h>
29GLOBALS(
30 long level;
31
32 int fd;
33)
34
35static void set_log_level(int level)
36{
37 if (CFG_KLOGD_SOURCE_RING_BUFFER)
38 klogctl(8, NULL, level);
39 else {
40 FILE *fptr = xfopen("/proc/sys/kernel/printk", "w");
41 fprintf(fptr, "%u\n", level);
42 fclose(fptr);
43 fptr = NULL;
44 }
45}
46
47static void handle_signal(int sig)
48{
49 if (CFG_KLOGD_SOURCE_RING_BUFFER) {
50 klogctl(7, NULL, 0);
51 klogctl(0, NULL, 0);
52 } else {
53 set_log_level(7);
54 xclose(TT.fd);
55 }
56 syslog(LOG_NOTICE,"KLOGD: Daemon exiting......");
57 exit(1);
58}
59
60
61
62
63
64void klogd_main(void)
65{
66 int prio, size, used = 0;
67 char *start, *line_start, msg_buffer[16348];
68
69 sigatexit(handle_signal);
70 if (toys.optflags & FLAG_c) set_log_level(TT.level);
71 if (!(toys.optflags & FLAG_n)) daemon(0, 0);
72
73 if (CFG_KLOGD_SOURCE_RING_BUFFER) {
74 syslog(LOG_NOTICE, "KLOGD: started with Kernel ring buffer as log source\n");
75 klogctl(1, NULL, 0);
76 } else {
77 TT.fd = xopenro("/proc/kmsg");
78 syslog(LOG_NOTICE, "KLOGD: started with /proc/kmsg as log source\n");
79 }
80 openlog("Kernel", 0, LOG_KERN);
81
82 while(1) {
83 start = msg_buffer + used;
84 if (CFG_KLOGD_SOURCE_RING_BUFFER) {
85 size = klogctl(2, start, sizeof(msg_buffer) - used - 1);
86 } else {
87 size = xread(TT.fd, start, sizeof(msg_buffer) - used - 1);
88 }
89 if (size < 0) perror_exit("error reading file:");
90 start[size] = '\0';
91 if (used) start = msg_buffer;
92 while(start) {
93 if ((line_start = strsep(&start, "\n")) != NULL && start != NULL) used = 0;
94 else {
95 used = strlen(line_start);
96 strcpy(msg_buffer, line_start);
97 if (used < (sizeof(msg_buffer) - 1)) break;
98 used = 0;
99 }
100 prio = LOG_INFO;
101 if (*line_start == '<') {
102 line_start++;
103 if (line_start) prio = (int)strtoul(line_start, &line_start, 10);
104 if (*line_start == '>') line_start++;
105 }
106 if (*line_start) syslog(prio, "%s", line_start);
107 }
108 }
109}
110