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
26
27
28
29
30
31
32#define FOR_dmesg
33#include "toys.h"
34#include <sys/klog.h>
35
36GLOBALS(
37 long level;
38 long size;
39
40 int use_color;
41 time_t tea;
42)
43
44static void color(int c)
45{
46 if (TT.use_color) printf("\033[%dm", c);
47}
48
49static void format_message(char *msg, int new)
50{
51 unsigned long long time_s, time_us;
52 int facpri, subsystem, pos;
53 char *p, *text;
54
55
56 if (new) {
57 if (sscanf(msg, "%u,%*u,%llu,%*[^;]; %n", &facpri, &time_us, &pos) != 2)
58 return;
59
60 time_s = time_us/1000000;
61 time_us %= 1000000;
62 } else if (sscanf(msg, "<%u>[%llu.%llu] %n",
63 &facpri, &time_s, &time_us, &pos) != 3) return;
64
65
66 if ((p = strchr(text = msg+pos, '\n'))) *p = 0;
67
68
69 p = strstr(text, ": ");
70 subsystem = p ? (p-text) : 0;
71
72
73 if (toys.optflags&FLAG_r) {
74 color(0);
75 printf("<%d>", facpri);
76 }
77
78
79 if (!(toys.optflags&FLAG_t)) {
80 color(32);
81 if (toys.optflags&FLAG_T) {
82 time_t t = TT.tea+time_s;
83 char *ts = ctime(&t);
84
85 printf("[%.*s] ", (int)(strlen(ts)-1), ts);
86 } else printf("[%5lld.%06lld] ", time_s, time_us);
87 }
88
89
90 if (subsystem) {
91 color(33);
92 printf("%.*s", subsystem, text);
93 text += subsystem;
94 }
95 color(31*((facpri&7)<=3));
96 xputs(text);
97}
98
99static int xklogctl(int type, char *buf, int len)
100{
101 int rc = klogctl(type, buf, len);
102
103 if (rc<0) perror_exit("klogctl");
104
105 return rc;
106}
107
108static void dmesg_cleanup(void)
109{
110 color(0);
111}
112
113void dmesg_main(void)
114{
115 TT.use_color = isatty(1);
116
117 if (TT.use_color) sigatexit(dmesg_cleanup);
118
119 if (toys.optflags & (FLAG_C|FLAG_n)) goto no_output;
120
121 if (toys.optflags&FLAG_T) {
122 struct sysinfo info;
123
124 sysinfo(&info);
125 TT.tea = time(0)-info.uptime;
126 }
127
128 if (!(toys.optflags&FLAG_S)) {
129 char msg[8193];
130 ssize_t len;
131 int fd;
132
133
134
135 fd = open("/dev/kmsg", O_RDONLY|(O_NONBLOCK*!(toys.optflags&FLAG_w)));
136 if (fd == -1) goto klogctl_mode;
137
138
139
140 lseek(fd, 0, SEEK_DATA);
141
142 for (;;) {
143
144
145 if (-1==(len = read(fd, msg, sizeof(msg))) && errno==EPIPE) continue;
146
147 if (len==-1 && errno==EINVAL) goto klogctl_mode;
148 if (len<1) break;
149
150 msg[len] = 0;
151 format_message(msg, 1);
152 }
153 close(fd);
154 } else {
155 char *data, *to, *from, *end;
156 int size;
157
158klogctl_mode:
159
160 if (!(size = TT.size)) size = xklogctl(10, 0, 0);
161 data = from = xmalloc(size+1);
162 data[size = xklogctl(3+(toys.optflags&FLAG_c), data, size)] = 0;
163
164
165 to = data + size;
166 while (from < to) {
167 if (!(end = memchr(from, '\n', to-from))) break;
168 *end = 0;
169 format_message(from, 0);
170 from = end + 1;
171 }
172
173 if (CFG_TOYBOX_FREE) free(data);
174 }
175
176no_output:
177
178 if (toys.optflags & FLAG_n) xklogctl(8, 0, TT.level);
179
180
181 if (toys.optflags & (FLAG_C|FLAG_c)) xklogctl(5, 0, 0);
182}
183