Upload Tizen:Base source
[framework/base/util-linux-ng.git] / sys-utils / dmesg.c
1 /* dmesg.c -- Print out the contents of the kernel ring buffer
2  * Created: Sat Oct  9 16:19:47 1993
3  * Revised: Thu Oct 28 21:52:17 1993 by faith@cs.unc.edu
4  * Copyright 1993 Theodore Ts'o (tytso@athena.mit.edu)
5  * This program comes with ABSOLUTELY NO WARRANTY.
6  * Modifications by Rick Sladkey (jrs@world.std.com)
7  * Larger buffersize 3 June 1998 by Nicolai Langfeldt, based on a patch
8  * by Peeter Joot.  This was also suggested by John Hudson.
9  * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
10  * - added Native Language Support
11  *
12  */
13
14 /*
15  * Commands to sys_syslog:
16  *
17  *      0 -- Close the log.  Currently a NOP.
18  *      1 -- Open the log. Currently a NOP.
19  *      2 -- Read from the log.
20  *      3 -- Read all messages remaining in the ring buffer.
21  *      4 -- Read and clear all messages remaining in the ring buffer
22  *      5 -- Clear ring buffer.
23  *      6 -- Disable printk's to console
24  *      7 -- Enable printk's to console
25  *      8 -- Set level of messages printed to console
26  *      9 -- Return number of unread characters in the log buffer
27  *           [supported since 2.4.10]
28  *
29  * Only function 3 is allowed to non-root processes.
30  */
31
32 #include <linux/unistd.h>
33 #include <stdio.h>
34 #include <getopt.h>
35 #include <stdlib.h>
36 # include <sys/klog.h>
37
38 #include "nls.h"
39
40 static char *progname;
41
42 static void
43 usage(void) {
44         fprintf(stderr,
45                 _("Usage: %s [-c] [-n level] [-r] [-s bufsize]\n"), progname);
46 }
47
48 int
49 main(int argc, char *argv[]) {
50         char *buf;
51         int  sz;
52         int  bufsize = 0;
53         int  i;
54         int  n;
55         int  c;
56         int  level = 0;
57         int  lastc;
58         int  cmd = 3;           /* Read all messages in the ring buffer */
59         int  raw = 0;
60
61         setlocale(LC_ALL, "");
62         bindtextdomain(PACKAGE, LOCALEDIR);
63         textdomain(PACKAGE);
64
65         progname = argv[0];
66         while ((c = getopt(argc, argv, "crn:s:")) != -1) {
67                 switch (c) {
68                 case 'c':
69                         cmd = 4;        /* Read and clear all messages */
70                         break;
71                 case 'n':
72                         cmd = 8;        /* Set level of messages */
73                         level = atoi(optarg);
74                         break;
75                 case 'r':
76                         raw = 1;
77                         break;
78                 case 's':
79                         bufsize = atoi(optarg);
80                         if (bufsize < 4096)
81                                 bufsize = 4096;
82                         break;
83                 case '?':
84                 default:
85                         usage();
86                         exit(1);
87                 }
88         }
89         argc -= optind;
90         argv += optind;
91
92         if (argc > 1) {
93                 usage();
94                 exit(1);
95         }
96
97         if (cmd == 8) {
98                 n = klogctl(cmd, NULL, level);
99                 if (n < 0) {
100                         perror("klogctl");
101                         exit(1);
102                 }
103                 exit(0);
104         }
105
106         if (!bufsize) {
107                 n = klogctl(10, NULL, 0);       /* read ringbuffer size */
108                 if (n > 0)
109                         bufsize = n;
110         }
111
112         if (bufsize) {
113                 sz = bufsize + 8;
114                 buf = (char *) malloc(sz);
115                 n = klogctl(cmd, buf, sz);
116         } else {
117                 sz = 16392;
118                 while (1) {
119                         buf = (char *) malloc(sz);
120                         n = klogctl(3, buf, sz);        /* read only */
121                         if (n != sz || sz > (1<<28))
122                                 break;
123                         free(buf);
124                         sz *= 4;
125                 }
126
127                 if (n > 0 && cmd == 4)
128                         n = klogctl(cmd, buf, sz);      /* read and clear */
129         }
130
131         if (n < 0) {
132                 perror("klogctl");
133                 exit(1);
134         }
135
136         lastc = '\n';
137         for (i = 0; i < n; i++) {
138                 if (!raw && (i == 0 || buf[i - 1] == '\n') && buf[i] == '<') {
139                         i++;
140                         while (buf[i] >= '0' && buf[i] <= '9')
141                                 i++;
142                         if (buf[i] == '>')
143                                 i++;
144                 }
145                 lastc = buf[i];
146                 putchar(lastc);
147         }
148         if (lastc != '\n')
149                 putchar('\n');
150         return 0;
151 }