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