Getopt'ed by Marc Nijdam <marc_nijdam@hp.com>
[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 <andersee@debian.org>. I ripped out Native Language 
15  * Support, replaced getopt, added some gotos for redundant stuff.
16  */
17
18 #include "internal.h"
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #if __GNU_LIBRARY__ < 5
23
24 #ifndef __alpha__
25 # define __NR_klogctl __NR_syslog
26 static inline _syscall3(int, klogctl, int, type, char *, b, int, len);
27 #else                                                   /* __alpha__ */
28 #define klogctl syslog
29 #endif
30
31 #else
32 # include <sys/klog.h>
33 #endif
34
35 static const char dmesg_usage[] = "dmesg [-c] [-n LEVEL] [-s SIZE]\n"
36 #ifndef BB_FEATURE_TRIVIAL_HELP
37         "\nPrints or controls the kernel ring buffer\n\n"
38         "Options:\n"
39         "\t-c\t\tClears the ring buffer's contents after printing\n"
40         "\t-n LEVEL\tSets console logging level\n"
41         "\t-s SIZE\t\tUse a buffer of size SIZE\n"
42 #endif
43         ;
44
45 int dmesg_main(int argc, char **argv)
46 {
47         char *buf, c;
48         int bufsize = 8196;
49         int i;
50         int n;
51         int level = 0;
52         int lastc;
53         int cmd = 3;
54
55         while ((c = getopt(argc, argv, "cn:s:")) != EOF) {
56                 switch (c) {
57                 case 'c':
58                         cmd = 4;
59                         break;
60                 case 'n':
61                         cmd = 8;
62                         if (optarg == NULL)
63                                 usage(dmesg_usage);
64                         level = atoi(optarg);
65                         break;
66                 case 's':
67                         if (optarg == NULL)
68                                 usage(dmesg_usage);
69                         bufsize = atoi(optarg);
70                         break;
71                 default:
72                         usage(dmesg_usage);
73                 }
74         }                       
75
76         if (optind < argc) {
77                 goto end;
78         }
79
80         if (cmd == 8) {
81                 n = klogctl(cmd, NULL, level);
82                 if (n < 0) {
83                         goto klogctl_error;
84                 }
85                 exit(TRUE);
86         }
87
88         if (bufsize < 4096)
89                 bufsize = 4096;
90         buf = (char *) xmalloc(bufsize);
91         n = klogctl(cmd, buf, bufsize);
92         if (n < 0) {
93                 goto klogctl_error;
94         }
95
96         lastc = '\n';
97         for (i = 0; i < n; i++) {
98                 if ((i == 0 || buf[i - 1] == '\n') && buf[i] == '<') {
99                         i++;
100                         while (buf[i] >= '0' && buf[i] <= '9')
101                                 i++;
102                         if (buf[i] == '>')
103                                 i++;
104                 }
105                 lastc = buf[i];
106                 putchar(lastc);
107         }
108         if (lastc != '\n')
109                 putchar('\n');
110         exit(TRUE);
111   end:
112         usage(dmesg_usage);
113         exit(FALSE);
114   klogctl_error:
115         perror("klogctl");
116         return(FALSE);
117 }