2006-12-07 00:25:32 +01:00
|
|
|
|
/* dmesg.c -- Print out the contents of the kernel ring buffer
|
|
|
|
|
* Created: Sat Oct 9 16:19:47 1993
|
|
|
|
|
* Revised: Thu Oct 28 21:52:17 1993 by faith@cs.unc.edu
|
|
|
|
|
* Copyright 1993 Theodore Ts'o (tytso@athena.mit.edu)
|
|
|
|
|
* This program comes with ABSOLUTELY NO WARRANTY.
|
|
|
|
|
* Modifications by Rick Sladkey (jrs@world.std.com)
|
2006-12-07 00:25:35 +01:00
|
|
|
|
* Larger buffersize 3 June 1998 by Nicolai Langfeldt, based on a patch
|
|
|
|
|
* by Peeter Joot. This was also suggested by John Hudson.
|
2006-12-07 00:25:46 +01:00
|
|
|
|
* 1999-02-22 Arkadiusz Mi<EFBFBD>kiewicz <misiek@pld.ORG.PL>
|
2006-12-07 00:25:39 +01:00
|
|
|
|
* - added Native Language Support
|
|
|
|
|
*
|
2006-12-07 00:25:32 +01:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <linux/unistd.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <getopt.h>
|
2006-12-07 00:25:34 +01:00
|
|
|
|
#include <stdlib.h>
|
2011-02-03 17:41:56 -03:00
|
|
|
|
#include <sys/klog.h>
|
2011-02-28 10:10:32 +01:00
|
|
|
|
#include <ctype.h>
|
2008-07-24 13:44:44 +02:00
|
|
|
|
|
2011-02-28 10:10:32 +01:00
|
|
|
|
#include "c.h"
|
2008-07-24 13:44:44 +02:00
|
|
|
|
#include "nls.h"
|
2011-02-03 17:41:56 -03:00
|
|
|
|
#include "strutils.h"
|
2011-02-28 10:10:32 +01:00
|
|
|
|
#include "xalloc.h"
|
2006-12-07 00:25:32 +01:00
|
|
|
|
|
2011-07-01 13:41:56 +02:00
|
|
|
|
/* Close the log. Currently a NOP. */
|
|
|
|
|
#define SYSLOG_ACTION_CLOSE 0
|
|
|
|
|
/* Open the log. Currently a NOP. */
|
|
|
|
|
#define SYSLOG_ACTION_OPEN 1
|
|
|
|
|
/* Read from the log. */
|
|
|
|
|
#define SYSLOG_ACTION_READ 2
|
|
|
|
|
/* Read all messages remaining in the ring buffer. (allowed for non-root) */
|
|
|
|
|
#define SYSLOG_ACTION_READ_ALL 3
|
|
|
|
|
/* Read and clear all messages remaining in the ring buffer */
|
|
|
|
|
#define SYSLOG_ACTION_READ_CLEAR 4
|
|
|
|
|
/* Clear ring buffer. */
|
|
|
|
|
#define SYSLOG_ACTION_CLEAR 5
|
|
|
|
|
/* Disable printk's to console */
|
|
|
|
|
#define SYSLOG_ACTION_CONSOLE_OFF 6
|
|
|
|
|
/* Enable printk's to console */
|
|
|
|
|
#define SYSLOG_ACTION_CONSOLE_ON 7
|
|
|
|
|
/* Set level of messages printed to console */
|
|
|
|
|
#define SYSLOG_ACTION_CONSOLE_LEVEL 8
|
|
|
|
|
/* Return number of unread characters in the log buffer */
|
|
|
|
|
#define SYSLOG_ACTION_SIZE_UNREAD 9
|
|
|
|
|
/* Return size of the log buffer */
|
|
|
|
|
#define SYSLOG_ACTION_SIZE_BUFFER 10
|
|
|
|
|
|
2011-07-01 13:24:04 +02:00
|
|
|
|
static void __attribute__((__noreturn__)) usage(FILE *out)
|
2011-02-28 10:10:32 +01:00
|
|
|
|
{
|
2011-07-01 13:24:04 +02:00
|
|
|
|
fprintf(out, _(
|
|
|
|
|
"\nUsage:\n"
|
|
|
|
|
" %s [options]\n"), program_invocation_short_name);
|
|
|
|
|
|
|
|
|
|
fprintf(out, _(
|
|
|
|
|
"\nOptions:\n"
|
|
|
|
|
" -c, --read-clear read and clear all messages\n"
|
|
|
|
|
" -r, --raw print the raw message buffer\n"
|
|
|
|
|
" -s, --buffer-size=SIZE buffer size to query the kernel ring buffer\n"
|
|
|
|
|
" -n, --console-level=LEVEL set level of messages printed to console\n"
|
|
|
|
|
" -V, --version output version information and exit\n"
|
|
|
|
|
" -h, --help display this help and exit\n\n"));
|
|
|
|
|
|
|
|
|
|
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
|
2006-12-07 00:25:32 +01:00
|
|
|
|
}
|
|
|
|
|
|
2011-07-01 13:49:25 +02:00
|
|
|
|
static int get_buffer_size()
|
|
|
|
|
{
|
|
|
|
|
int n = klogctl(SYSLOG_ACTION_SIZE_BUFFER, NULL, 0);
|
|
|
|
|
|
|
|
|
|
return n > 0 ? n : 0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-28 10:10:32 +01:00
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
char *buf = NULL;
|
2006-12-07 00:26:16 +01:00
|
|
|
|
int sz;
|
|
|
|
|
int bufsize = 0;
|
2006-12-07 00:26:12 +01:00
|
|
|
|
int i;
|
|
|
|
|
int n;
|
|
|
|
|
int c;
|
|
|
|
|
int level = 0;
|
|
|
|
|
int lastc;
|
2011-07-01 13:41:56 +02:00
|
|
|
|
int cmd = SYSLOG_ACTION_READ_ALL;
|
2009-01-08 11:44:27 -05:00
|
|
|
|
int raw = 0;
|
2006-12-07 00:25:32 +01:00
|
|
|
|
|
2011-07-01 13:24:04 +02:00
|
|
|
|
static const struct option longopts[] = {
|
|
|
|
|
{ "read-clear", no_argument, NULL, 'c' },
|
|
|
|
|
{ "raw", no_argument, NULL, 'r' },
|
|
|
|
|
{ "buffer-size", required_argument, NULL, 's' },
|
|
|
|
|
{ "console-level", required_argument, NULL, 'n' },
|
|
|
|
|
{ "version", no_argument, NULL, 'V' },
|
|
|
|
|
{ "help", no_argument, NULL, 'h' },
|
|
|
|
|
{ NULL, 0, NULL, 0 }
|
|
|
|
|
};
|
|
|
|
|
|
2006-12-07 00:26:12 +01:00
|
|
|
|
setlocale(LC_ALL, "");
|
|
|
|
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
|
|
|
|
textdomain(PACKAGE);
|
2006-12-07 00:25:39 +01:00
|
|
|
|
|
2011-07-01 13:24:04 +02:00
|
|
|
|
while ((c = getopt_long(argc, argv, "chrn:s:V", longopts, NULL)) != -1) {
|
2006-12-07 00:26:12 +01:00
|
|
|
|
switch (c) {
|
|
|
|
|
case 'c':
|
2011-07-01 13:41:56 +02:00
|
|
|
|
cmd = SYSLOG_ACTION_READ_CLEAR;
|
2006-12-07 00:26:12 +01:00
|
|
|
|
break;
|
|
|
|
|
case 'n':
|
2011-07-01 13:41:56 +02:00
|
|
|
|
cmd = SYSLOG_ACTION_CONSOLE_LEVEL;
|
2011-02-03 17:41:56 -03:00
|
|
|
|
level = strtol_or_err(optarg, _("failed to parse level"));
|
2006-12-07 00:26:12 +01:00
|
|
|
|
break;
|
2009-01-08 11:44:27 -05:00
|
|
|
|
case 'r':
|
|
|
|
|
raw = 1;
|
|
|
|
|
break;
|
2006-12-07 00:26:12 +01:00
|
|
|
|
case 's':
|
2011-02-03 17:41:56 -03:00
|
|
|
|
bufsize = strtol_or_err(optarg, _("failed to parse buffer size"));
|
2006-12-07 00:26:16 +01:00
|
|
|
|
if (bufsize < 4096)
|
|
|
|
|
bufsize = 4096;
|
2006-12-07 00:26:12 +01:00
|
|
|
|
break;
|
2011-07-01 13:24:04 +02:00
|
|
|
|
case 'V':
|
|
|
|
|
printf(_("%s from %s\n"), program_invocation_short_name,
|
|
|
|
|
PACKAGE_STRING);
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
|
case 'h':
|
|
|
|
|
usage(stdout);
|
|
|
|
|
break;
|
2006-12-07 00:26:12 +01:00
|
|
|
|
case '?':
|
|
|
|
|
default:
|
2011-07-01 13:24:04 +02:00
|
|
|
|
usage(stderr);
|
2006-12-07 00:26:12 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
argc -= optind;
|
|
|
|
|
argv += optind;
|
2009-08-17 11:37:27 +02:00
|
|
|
|
|
2011-02-28 10:10:32 +01:00
|
|
|
|
if (argc > 1)
|
2011-07-01 13:24:04 +02:00
|
|
|
|
usage(stderr);
|
2006-12-07 00:25:32 +01:00
|
|
|
|
|
2011-07-01 13:41:56 +02:00
|
|
|
|
if (cmd == SYSLOG_ACTION_CONSOLE_LEVEL) {
|
2006-12-07 00:26:12 +01:00
|
|
|
|
n = klogctl(cmd, NULL, level);
|
2011-02-28 10:10:32 +01:00
|
|
|
|
if (n < 0)
|
|
|
|
|
err(EXIT_FAILURE, _("klogctl failed"));
|
|
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
2006-12-07 00:26:12 +01:00
|
|
|
|
}
|
2006-12-07 00:25:32 +01:00
|
|
|
|
|
2011-07-01 13:49:25 +02:00
|
|
|
|
if (!bufsize)
|
|
|
|
|
bufsize = get_buffer_size();
|
2006-12-07 00:26:16 +01:00
|
|
|
|
|
|
|
|
|
if (bufsize) {
|
|
|
|
|
sz = bufsize + 8;
|
2011-02-28 10:10:32 +01:00
|
|
|
|
buf = xmalloc(sz * sizeof(char));
|
2006-12-07 00:26:16 +01:00
|
|
|
|
n = klogctl(cmd, buf, sz);
|
|
|
|
|
} else {
|
|
|
|
|
sz = 16392;
|
|
|
|
|
while (1) {
|
2011-02-28 10:10:32 +01:00
|
|
|
|
buf = xmalloc(sz * sizeof(char));
|
2011-07-01 13:41:56 +02:00
|
|
|
|
n = klogctl(SYSLOG_ACTION_READ_ALL, buf, sz); /* read only */
|
2011-02-28 10:10:32 +01:00
|
|
|
|
if (n != sz || sz > (1 << 28))
|
2006-12-07 00:26:16 +01:00
|
|
|
|
break;
|
|
|
|
|
free(buf);
|
|
|
|
|
sz *= 4;
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-01 13:41:56 +02:00
|
|
|
|
if (n > 0 && cmd == SYSLOG_ACTION_READ_CLEAR)
|
2006-12-07 00:26:16 +01:00
|
|
|
|
n = klogctl(cmd, buf, sz); /* read and clear */
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-28 10:10:32 +01:00
|
|
|
|
if (n < 0)
|
|
|
|
|
err(EXIT_FAILURE, _("klogctl failed"));
|
2006-12-07 00:25:32 +01:00
|
|
|
|
|
2006-12-07 00:26:12 +01:00
|
|
|
|
lastc = '\n';
|
|
|
|
|
for (i = 0; i < n; i++) {
|
2009-01-08 11:44:27 -05:00
|
|
|
|
if (!raw && (i == 0 || buf[i - 1] == '\n') && buf[i] == '<') {
|
2006-12-07 00:26:12 +01:00
|
|
|
|
i++;
|
2011-02-28 10:10:32 +01:00
|
|
|
|
while (isdigit(buf[i]))
|
2006-12-07 00:26:12 +01:00
|
|
|
|
i++;
|
|
|
|
|
if (buf[i] == '>')
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
lastc = buf[i];
|
|
|
|
|
putchar(lastc);
|
|
|
|
|
}
|
|
|
|
|
if (lastc != '\n')
|
|
|
|
|
putchar('\n');
|
2010-07-30 11:43:36 -04:00
|
|
|
|
free(buf);
|
2011-02-28 10:10:32 +01:00
|
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
2006-12-07 00:25:32 +01:00
|
|
|
|
}
|