1 /* vi: set sw=4 ts=4: */
2 /*
3 *
4 * dmesg - display/control kernel ring buffer.
5 *
6 * Copyright 2006 Rob Landley <rob@landley.net>
7 * Copyright 2006 Bernhard Reutner-Fischer <rep.nop@aon.at>
8 *
9 * Licensed under GPLv2, see file LICENSE in this source tree.
10 */
11 //config:config DMESG
12 //config: bool "dmesg (3.7 kb)"
13 //config: default y
14 //config: help
15 //config: dmesg is used to examine or control the kernel ring buffer. When the
16 //config: Linux kernel prints messages to the system log, they are stored in
17 //config: the kernel ring buffer. You can use dmesg to print the kernel's ring
18 //config: buffer, clear the kernel ring buffer, change the size of the kernel
19 //config: ring buffer, and change the priority level at which kernel messages
20 //config: are also logged to the system console. Enable this option if you
21 //config: wish to enable the 'dmesg' utility.
22 //config:
23 //config:config FEATURE_DMESG_PRETTY
24 //config: bool "Pretty output"
25 //config: default y
26 //config: depends on DMESG
27 //config: help
28 //config: If you wish to scrub the syslog level from the output, say 'Y' here.
29 //config: The syslog level is a string prefixed to every line with the form
30 //config: "<#>".
31 //config:
32 //config: With this option you will see:
33 //config: # dmesg
34 //config: Linux version 2.6.17.4 .....
35 //config: BIOS-provided physical RAM map:
36 //config: BIOS-e820: 0000000000000000 - 000000000009f000 (usable)
37 //config:
38 //config: Without this option you will see:
39 //config: # dmesg
40 //config: <5>Linux version 2.6.17.4 .....
41 //config: <6>BIOS-provided physical RAM map:
42 //config: <6> BIOS-e820: 0000000000000000 - 000000000009f000 (usable)
43
44 //applet:IF_DMESG(APPLET(dmesg, BB_DIR_BIN, BB_SUID_DROP))
45
46 //kbuild:lib-$(CONFIG_DMESG) += dmesg.o
47
48 //usage:#define dmesg_trivial_usage
49 //usage: "[-cr] [-n LEVEL] [-s SIZE]"
50 //usage:#define dmesg_full_usage "\n\n"
51 //usage: "Print or control the kernel ring buffer\n"
52 //usage: "\n -c Clear ring buffer after printing"
53 //usage: "\n -n LEVEL Set console logging level"
54 //usage: "\n -s SIZE Buffer size"
55 //usage: "\n -r Print raw message buffer"
56
57 #include <sys/klog.h>
58 #include "libbb.h"
59
60 int dmesg_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
dmesg_main(int argc UNUSED_PARAM,char ** argv)61 int dmesg_main(int argc UNUSED_PARAM, char **argv)
62 {
63 int len, level;
64 char *buf;
65 unsigned opts;
66 enum {
67 OPT_c = 1 << 0,
68 OPT_s = 1 << 1,
69 OPT_n = 1 << 2,
70 OPT_r = 1 << 3
71 };
72
73 opts = getopt32(argv, "cs:+n:+r", &len, &level);
74 if (opts & OPT_n) {
75 if (klogctl(8, NULL, (long) level))
76 bb_simple_perror_msg_and_die("klogctl");
77 return EXIT_SUCCESS;
78 }
79
80 if (!(opts & OPT_s))
81 len = klogctl(10, NULL, 0); /* read ring buffer size */
82 if (len < 16*1024)
83 len = 16*1024;
84 if (len > 16*1024*1024)
85 len = 16*1024*1024;
86
87 buf = xmalloc(len);
88 len = klogctl(3 + (opts & OPT_c), buf, len); /* read ring buffer */
89 if (len < 0)
90 bb_simple_perror_msg_and_die("klogctl");
91 if (len == 0)
92 return EXIT_SUCCESS;
93
94
95 if (ENABLE_FEATURE_DMESG_PRETTY && !(opts & OPT_r)) {
96 int last = '\n';
97 int in = 0;
98
99 /* Skip <[0-9]+> at the start of lines */
100 while (1) {
101 if (last == '\n' && buf[in] == '<') {
102 while (buf[in++] != '>' && in < len)
103 ;
104 } else {
105 last = buf[in++];
106 putchar(last);
107 }
108 if (in >= len)
109 break;
110 }
111 /* Make sure we end with a newline */
112 if (last != '\n')
113 bb_putchar('\n');
114 } else {
115 full_write(STDOUT_FILENO, buf, len);
116 if (buf[len-1] != '\n')
117 bb_putchar('\n');
118 }
119
120 if (ENABLE_FEATURE_CLEAN_UP) free(buf);
121
122 return EXIT_SUCCESS;
123 }
124