6e0d6947f7c72cfb0e144969e6a1d8f2b2a477ac
[oweals/busybox.git] / util-linux / dmesg.c
1 /* vi: set sw=4 ts=4: */
2 /* dmesg.c -- Print out the contents of the kernel ring buffer
3  * Created: Sat Oct  9 16:19:47 1993
4  * Revised: Thu Oct 28 21:52:17 1993 by faith@cs.unc.edu
5  * Copyright 1993 Theodore Ts'o (tytso@athena.mit.edu)
6  * This program comes with ABSOLUTELY NO WARRANTY.
7  * Modifications by Rick Sladkey (jrs@world.std.com)
8  * Larger buffersize 3 June 1998 by Nicolai Langfeldt, based on a patch
9  * by Peeter Joot.  This was also suggested by John Hudson.
10  * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
11  * - added Native Language Support
12  *
13  * from util-linux -- adapted for busybox by 
14  * Erik Andersen <andersen@codepoet.org>. I ripped out Native Language 
15  * Support, replaced getopt, added some gotos for redundant stuff.
16  *
17  * Audited and cleaned up on 7 March 2003 to reduce size of
18  * check error handling by Erik Andersen <andersen@codepoet.org>
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <getopt.h>
24 #include <errno.h>
25
26 #if __GNU_LIBRARY__ < 5
27 # ifdef __alpha__
28 #   define klogctl syslog
29 # endif
30 #else
31 # include <sys/klog.h>
32 #endif
33
34 #include "busybox.h"
35
36 int dmesg_main(int argc, char **argv)
37 {
38         char *buf;
39         int bufsize = 8196;
40         int i, n;
41         int level = 0;
42         int lastc;
43         int cmd = 3;
44
45         while ((i = getopt(argc, argv, "cn:s:")) > 0) {
46                 switch (i) {
47                         case 'c':
48                                 cmd = 4;
49                                 break;
50                         case 'n':
51                                 cmd = 8;
52                                 level = bb_xgetlarg(optarg, 10, 0, 10);
53                                 break;
54                         case 's':
55                                 /* I think a 512k max kernel ring buffer is big enough for
56                                  * anybody, as the default is 16k...  Could be wrong though.
57                                  * If so I'm sure I'll hear about it by the enraged masses*/
58                                 bufsize = bb_xgetlarg(optarg, 10, 4096, 512*1024);
59                                 break;
60                         default:
61                                 bb_show_usage();
62                 }
63         }
64
65         if (optind < argc) {
66                 bb_show_usage();
67         }
68
69         if (cmd == 8) {
70                 if (klogctl(cmd, NULL, level) < 0)
71                         goto die_the_death;
72                 goto all_done;
73         }
74
75         buf = xmalloc(bufsize);
76         if ((n = klogctl(cmd, buf, bufsize)) < 0)
77                 goto die_the_death;
78
79         lastc = '\n';
80         for (i = 0; i < n; i++) {
81                 if (lastc == '\n' && buf[i] == '<') {
82                         i++;
83                         while (buf[i] >= '0' && buf[i] <= '9')
84                                 i++;
85                         if (buf[i] == '>')
86                                 i++;
87                 }
88                 lastc = buf[i];
89                 putchar(lastc);
90         }
91         if (lastc != '\n')
92                 putchar('\n');
93 all_done:
94 #ifdef CONFIG_FEATURE_CLEAN_UP
95         if (buf) {
96                 free(buf);
97         }
98 #endif
99         return EXIT_SUCCESS;
100 die_the_death:
101         bb_perror_nomsg_and_die();
102 }