2006-12-06 17:25:32 -06: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-06 17:25:35 -06: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-06 17:25:46 -06:00
|
|
|
|
* 1999-02-22 Arkadiusz Mi<EFBFBD>kiewicz <misiek@pld.ORG.PL>
|
2006-12-06 17:25:39 -06:00
|
|
|
|
* - added Native Language Support
|
|
|
|
|
*
|
2006-12-06 17:25:32 -06:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <linux/unistd.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <getopt.h>
|
2006-12-06 17:25:34 -06:00
|
|
|
|
#include <stdlib.h>
|
2011-02-03 14:41:56 -06:00
|
|
|
|
#include <sys/klog.h>
|
2011-07-01 09:33:34 -05:00
|
|
|
|
#include <sys/syslog.h>
|
2011-02-28 03:10:32 -06:00
|
|
|
|
#include <ctype.h>
|
2008-07-24 06:44:44 -05:00
|
|
|
|
|
2011-02-28 03:10:32 -06:00
|
|
|
|
#include "c.h"
|
2008-07-24 06:44:44 -05:00
|
|
|
|
#include "nls.h"
|
2011-02-03 14:41:56 -06:00
|
|
|
|
#include "strutils.h"
|
2011-02-28 03:10:32 -06:00
|
|
|
|
#include "xalloc.h"
|
2011-07-13 08:00:49 -05:00
|
|
|
|
#include "widechar.h"
|
|
|
|
|
#include "writeall.h"
|
2011-07-13 08:50:47 -05:00
|
|
|
|
#include "bitops.h"
|
2006-12-06 17:25:32 -06:00
|
|
|
|
|
2011-07-01 06:41:56 -05: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-13 08:50:47 -05:00
|
|
|
|
#ifndef LOG_PRIMASK
|
|
|
|
|
#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */
|
|
|
|
|
/* extract priority */
|
|
|
|
|
#define LOG_PRI(p) ((p) & LOG_PRIMASK)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef LOG_FACMASK
|
|
|
|
|
#define LOG_FACMASK 0x03f8 /* mask to extract facility part */
|
|
|
|
|
/* facility of pri */
|
|
|
|
|
#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-07-01 09:33:34 -05:00
|
|
|
|
/*
|
|
|
|
|
* Priority names, based on sys/syslog.h
|
|
|
|
|
*/
|
|
|
|
|
struct dmesg_name {
|
|
|
|
|
const char *name;
|
|
|
|
|
const char *help;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const struct dmesg_name level_names[] =
|
|
|
|
|
{
|
|
|
|
|
[LOG_EMERG] = { "emerg", N_("system is unusable") },
|
|
|
|
|
[LOG_ALERT] = { "alert", N_("action must be taken immediately") },
|
|
|
|
|
[LOG_CRIT] = { "crit", N_("critical conditions") },
|
|
|
|
|
[LOG_ERR] = { "err", N_("error conditions") },
|
|
|
|
|
[LOG_WARNING] = { "warn", N_("warning conditions") },
|
|
|
|
|
[LOG_NOTICE] = { "notice",N_("normal but significant condition") },
|
|
|
|
|
[LOG_INFO] = { "info", N_("informational") },
|
|
|
|
|
[LOG_DEBUG] = { "debug", N_("debug-level messages") }
|
|
|
|
|
};
|
|
|
|
|
|
2011-07-01 06:57:36 -05:00
|
|
|
|
/* dmesg flags */
|
2011-07-13 08:00:49 -05:00
|
|
|
|
#define DMESG_FL_RAW (1 << 1)
|
|
|
|
|
#define DMESG_FL_LEVEL (1 << 2)
|
|
|
|
|
#define DMESG_FL_FACILITY (1 << 3)
|
2011-07-01 06:57:36 -05:00
|
|
|
|
|
2011-07-01 06:24:04 -05:00
|
|
|
|
static void __attribute__((__noreturn__)) usage(FILE *out)
|
2011-02-28 03:10:32 -06:00
|
|
|
|
{
|
2011-07-01 09:33:34 -05:00
|
|
|
|
int i;
|
|
|
|
|
|
2011-07-01 06:24:04 -05:00
|
|
|
|
fprintf(out, _(
|
|
|
|
|
"\nUsage:\n"
|
|
|
|
|
" %s [options]\n"), program_invocation_short_name);
|
|
|
|
|
|
|
|
|
|
fprintf(out, _(
|
|
|
|
|
"\nOptions:\n"
|
2011-07-01 07:33:27 -05:00
|
|
|
|
" -C, --clear clear the kernel ring buffer\n"
|
2011-07-01 06:24:04 -05:00
|
|
|
|
" -c, --read-clear read and clear all messages\n"
|
2011-07-01 08:30:16 -05:00
|
|
|
|
" -d, --console-off disable printing messages to console\n"
|
|
|
|
|
" -e, --console-on enable printing messages to console\n"
|
|
|
|
|
" -h, --help display this help and exit\n"
|
2011-07-13 08:50:47 -05:00
|
|
|
|
" -l, --level=LIST restrict output to defined levels\n"
|
2011-07-01 08:30:16 -05:00
|
|
|
|
" -n, --console-level=LEVEL set level of messages printed to console\n"
|
2011-07-01 06:24:04 -05:00
|
|
|
|
" -r, --raw print the raw message buffer\n"
|
|
|
|
|
" -s, --buffer-size=SIZE buffer size to query the kernel ring buffer\n"
|
2011-07-01 08:30:16 -05:00
|
|
|
|
" -V, --version output version information and exit\n\n"));
|
2011-07-01 06:24:04 -05:00
|
|
|
|
|
2011-07-01 09:33:34 -05:00
|
|
|
|
fprintf(out, _("Supported log levels (priorities):\n"));
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(level_names); i++) {
|
|
|
|
|
fprintf(stderr, " <%d> %7s - %s\n", i,
|
|
|
|
|
level_names[i].name,
|
|
|
|
|
_(level_names[i].help));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fputc('\n', out);
|
|
|
|
|
|
2011-07-01 06:24:04 -05:00
|
|
|
|
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
|
2006-12-06 17:25:32 -06:00
|
|
|
|
}
|
|
|
|
|
|
2011-07-13 08:06:53 -05:00
|
|
|
|
static int parse_level(const char *str, size_t len)
|
2011-07-01 09:33:34 -05:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
2011-07-13 08:06:53 -05:00
|
|
|
|
if (!str)
|
2011-07-01 09:33:34 -05:00
|
|
|
|
return -1;
|
2011-07-13 08:06:53 -05:00
|
|
|
|
if (!len)
|
|
|
|
|
len = strlen(str);
|
|
|
|
|
errno = 0;
|
2011-07-01 09:33:34 -05:00
|
|
|
|
|
2011-07-13 08:06:53 -05:00
|
|
|
|
if (isdigit(*str)) {
|
|
|
|
|
char *end = NULL;
|
|
|
|
|
|
|
|
|
|
i = strtol(str, &end, 10);
|
|
|
|
|
if (!errno && end && end > str && end - str == len &&
|
|
|
|
|
i >= 0 && i < ARRAY_SIZE(level_names))
|
2011-07-01 09:33:34 -05:00
|
|
|
|
return i;
|
2011-07-13 08:06:53 -05:00
|
|
|
|
} else {
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(level_names); i++) {
|
|
|
|
|
const char *n = level_names[i].name;
|
|
|
|
|
|
|
|
|
|
if (strncasecmp(str, n, len) == 0 && *(n + len) == '\0')
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (errno)
|
|
|
|
|
err(EXIT_FAILURE, _("failed to parse level '%s'"), str);
|
|
|
|
|
|
|
|
|
|
errx(EXIT_FAILURE, _("unknown level '%s'"), str);
|
2011-07-01 09:33:34 -05:00
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-13 08:50:47 -05:00
|
|
|
|
static const char *parse_faclev(const char *str, int *fac, int *lev)
|
|
|
|
|
{
|
|
|
|
|
long num;
|
|
|
|
|
char *end = NULL;
|
|
|
|
|
|
|
|
|
|
if (!str)
|
|
|
|
|
return str;
|
|
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
num = strtol(str, &end, 10);
|
|
|
|
|
|
|
|
|
|
if (!errno && end && end > str) {
|
|
|
|
|
*fac = LOG_FAC(num);
|
|
|
|
|
*lev = LOG_PRI(num);
|
|
|
|
|
return end + 1; /* skip '<' */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int list_to_bitarray(const char *list,
|
|
|
|
|
int (*name2id)(const char *name, size_t namesz),
|
|
|
|
|
char *ary)
|
|
|
|
|
{
|
|
|
|
|
const char *begin = NULL, *p;
|
|
|
|
|
|
|
|
|
|
for (p = list; p && *p; p++) {
|
|
|
|
|
const char *end = NULL;
|
|
|
|
|
int id;
|
|
|
|
|
|
|
|
|
|
if (!begin)
|
|
|
|
|
begin = p; /* begin of the level name */
|
|
|
|
|
if (*p == ',')
|
|
|
|
|
end = p; /* terminate the name */
|
|
|
|
|
if (*(p + 1) == '\0')
|
|
|
|
|
end = p + 1; /* end of string */
|
|
|
|
|
if (!begin || !end)
|
|
|
|
|
continue;
|
|
|
|
|
if (end <= begin)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
id = name2id(begin, end - begin);
|
|
|
|
|
if (id < 0)
|
|
|
|
|
return id;
|
|
|
|
|
setbit(ary, id);
|
|
|
|
|
begin = NULL;
|
|
|
|
|
if (end && !*end)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-01 06:49:25 -05:00
|
|
|
|
static int get_buffer_size()
|
|
|
|
|
{
|
|
|
|
|
int n = klogctl(SYSLOG_ACTION_SIZE_BUFFER, NULL, 0);
|
|
|
|
|
|
|
|
|
|
return n > 0 ? n : 0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-01 07:15:07 -05:00
|
|
|
|
static int read_buffer(char **buf, size_t bufsize, int clear)
|
|
|
|
|
{
|
|
|
|
|
size_t sz;
|
|
|
|
|
int rc = -1;
|
|
|
|
|
int cmd = clear ? SYSLOG_ACTION_READ_CLEAR :
|
|
|
|
|
SYSLOG_ACTION_READ_ALL;
|
|
|
|
|
|
|
|
|
|
if (bufsize) {
|
|
|
|
|
sz = bufsize + 8;
|
|
|
|
|
*buf = xmalloc(sz * sizeof(char));
|
|
|
|
|
rc = klogctl(cmd, *buf, sz);
|
|
|
|
|
} else {
|
|
|
|
|
sz = 16392;
|
|
|
|
|
while (1) {
|
|
|
|
|
*buf = xmalloc(sz * sizeof(char));
|
|
|
|
|
rc = klogctl(SYSLOG_ACTION_READ_ALL, *buf, sz);
|
|
|
|
|
if (rc != sz || sz > (1 << 28))
|
|
|
|
|
break;
|
|
|
|
|
free(*buf);
|
|
|
|
|
*buf = NULL;
|
|
|
|
|
sz *= 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rc > 0 && clear)
|
|
|
|
|
rc = klogctl(SYSLOG_ACTION_READ_CLEAR, *buf, sz);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-13 08:00:49 -05:00
|
|
|
|
static int fwrite_hex(const char *buf, size_t size, FILE *out)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
|
int rc = fprintf(out, "\\x%02x", buf[i]);
|
|
|
|
|
if (rc < 0)
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void safe_fwrite(const char *buf, size_t size, FILE *out)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
#ifdef HAVE_WIDECHAR
|
|
|
|
|
mbstate_t s;
|
|
|
|
|
memset(&s, 0, sizeof (s));
|
|
|
|
|
#endif
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
|
const char *p = buf + i;
|
|
|
|
|
int rc, hex = 0;
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_WIDECHAR
|
|
|
|
|
wchar_t wc;
|
|
|
|
|
size_t len = mbrtowc(&wc, p, size - i, &s);
|
|
|
|
|
|
|
|
|
|
if (len == 0) /* L'\0' */
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (len < 0) { /* invalid sequence */
|
|
|
|
|
memset(&s, 0, sizeof (s));
|
|
|
|
|
len = hex = 1;
|
|
|
|
|
|
|
|
|
|
} else if (len > 1 && !iswprint(wc)) { /* non-printable multibyte */
|
|
|
|
|
hex = 1;
|
|
|
|
|
} else
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
if (!isprint((unsigned int) *p) &&
|
|
|
|
|
!isspace((unsigned int) *p)) /* non-printable */
|
|
|
|
|
hex = 1;
|
|
|
|
|
}
|
|
|
|
|
if (hex)
|
|
|
|
|
rc = fwrite_hex(p, len, out);
|
|
|
|
|
else
|
|
|
|
|
rc = write_all(fileno(out), p, len);
|
|
|
|
|
if (rc != 0)
|
|
|
|
|
err(EXIT_FAILURE, _("write failed"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-13 08:50:47 -05:00
|
|
|
|
static void print_buffer(const char *buf, size_t size, int flags, char *levels)
|
2011-07-01 06:57:36 -05:00
|
|
|
|
{
|
|
|
|
|
int i;
|
2011-07-13 08:00:49 -05:00
|
|
|
|
const char *begin = NULL;
|
|
|
|
|
|
|
|
|
|
if (flags & DMESG_FL_RAW) {
|
|
|
|
|
/* print whole buffer */
|
|
|
|
|
safe_fwrite(buf, size, stdout);
|
|
|
|
|
if (buf[size - 1] != '\n')
|
|
|
|
|
putchar('\n');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2011-07-01 06:57:36 -05:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
2011-07-13 08:00:49 -05:00
|
|
|
|
const char *p = buf + i, *end = NULL;
|
2011-07-13 08:50:47 -05:00
|
|
|
|
int fac = 0, lev = 0;
|
2011-07-13 08:00:49 -05:00
|
|
|
|
|
|
|
|
|
if (!begin)
|
|
|
|
|
begin = p;
|
|
|
|
|
if (*p == '\n')
|
|
|
|
|
end = p;
|
|
|
|
|
if (i + 1 == size) {
|
|
|
|
|
end = p + 1;
|
2011-07-01 06:57:36 -05:00
|
|
|
|
i++;
|
|
|
|
|
}
|
2011-07-13 08:00:49 -05:00
|
|
|
|
if (!begin || !end)
|
|
|
|
|
continue;
|
|
|
|
|
if (end <= begin)
|
|
|
|
|
continue; /* error or empty line? */
|
|
|
|
|
|
2011-07-13 08:50:47 -05:00
|
|
|
|
if (*begin == '<') {
|
|
|
|
|
if ((flags & DMESG_FL_LEVEL) || (flags & DMESG_FL_FACILITY)) {
|
|
|
|
|
/* parse facility and level */
|
|
|
|
|
begin = parse_faclev(begin + 1, &fac, &lev);
|
|
|
|
|
} else {
|
|
|
|
|
/* ignore facility and level */
|
|
|
|
|
while (begin < end) {
|
|
|
|
|
begin++;
|
|
|
|
|
if (*(begin - 1) == '>')
|
|
|
|
|
break;
|
|
|
|
|
}
|
2011-07-13 08:00:49 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-13 08:50:47 -05:00
|
|
|
|
if (begin < end &&
|
|
|
|
|
(!lev || !levels || isset(levels, lev))) {
|
2011-07-13 08:00:49 -05:00
|
|
|
|
size_t sz = end - begin;
|
|
|
|
|
|
|
|
|
|
safe_fwrite(begin, sz, stdout);
|
|
|
|
|
if (*(begin + sz - 1) != '\n')
|
|
|
|
|
putchar('\n');
|
|
|
|
|
}
|
|
|
|
|
begin = NULL;
|
2011-07-01 06:57:36 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-28 03:10:32 -06:00
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
char *buf = NULL;
|
2006-12-06 17:26:16 -06:00
|
|
|
|
int bufsize = 0;
|
2006-12-06 17:26:12 -06:00
|
|
|
|
int n;
|
|
|
|
|
int c;
|
2011-07-01 07:26:19 -05:00
|
|
|
|
int console_level = 0;
|
2011-07-01 07:56:22 -05:00
|
|
|
|
int cmd = -1;
|
2011-07-01 06:57:36 -05:00
|
|
|
|
int flags = 0;
|
2011-07-13 08:50:47 -05:00
|
|
|
|
char levels[ARRAY_SIZE(level_names) / NBBY + 1] = { 0 };
|
2006-12-06 17:25:32 -06:00
|
|
|
|
|
2011-07-01 06:24:04 -05:00
|
|
|
|
static const struct option longopts[] = {
|
2011-07-01 07:33:27 -05:00
|
|
|
|
{ "clear", no_argument, NULL, 'C' },
|
2011-07-01 06:24:04 -05:00
|
|
|
|
{ "read-clear", no_argument, NULL, 'c' },
|
|
|
|
|
{ "raw", no_argument, NULL, 'r' },
|
|
|
|
|
{ "buffer-size", required_argument, NULL, 's' },
|
|
|
|
|
{ "console-level", required_argument, NULL, 'n' },
|
2011-07-13 08:50:47 -05:00
|
|
|
|
{ "level", required_argument, NULL, 'l' },
|
2011-07-01 08:30:16 -05:00
|
|
|
|
{ "console-off", no_argument, NULL, 'd' },
|
|
|
|
|
{ "console-on", no_argument, NULL, 'e' },
|
2011-07-01 06:24:04 -05:00
|
|
|
|
{ "version", no_argument, NULL, 'V' },
|
|
|
|
|
{ "help", no_argument, NULL, 'h' },
|
|
|
|
|
{ NULL, 0, NULL, 0 }
|
|
|
|
|
};
|
|
|
|
|
|
2006-12-06 17:26:12 -06:00
|
|
|
|
setlocale(LC_ALL, "");
|
|
|
|
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
|
|
|
|
textdomain(PACKAGE);
|
2006-12-06 17:25:39 -06:00
|
|
|
|
|
2011-07-13 08:50:47 -05:00
|
|
|
|
while ((c = getopt_long(argc, argv, "Ccdehl:rn:s:V", longopts, NULL)) != -1) {
|
2011-07-01 07:56:22 -05:00
|
|
|
|
|
2011-07-01 08:30:16 -05:00
|
|
|
|
if (cmd != -1 && strchr("Ccnde", c))
|
2011-07-01 07:56:22 -05:00
|
|
|
|
errx(EXIT_FAILURE, "%s %s",
|
2011-07-01 08:30:16 -05:00
|
|
|
|
"--{clear,read-clear,console-level,console-on,console-off}",
|
2011-07-01 07:56:22 -05:00
|
|
|
|
_("options are mutually exclusive"));
|
|
|
|
|
|
2006-12-06 17:26:12 -06:00
|
|
|
|
switch (c) {
|
2011-07-01 07:33:27 -05:00
|
|
|
|
case 'C':
|
|
|
|
|
cmd = SYSLOG_ACTION_CLEAR;
|
|
|
|
|
break;
|
2006-12-06 17:26:12 -06:00
|
|
|
|
case 'c':
|
2011-07-01 06:41:56 -05:00
|
|
|
|
cmd = SYSLOG_ACTION_READ_CLEAR;
|
2006-12-06 17:26:12 -06:00
|
|
|
|
break;
|
2011-07-01 08:30:16 -05:00
|
|
|
|
case 'd':
|
|
|
|
|
cmd = SYSLOG_ACTION_CONSOLE_OFF;
|
|
|
|
|
break;
|
|
|
|
|
case 'e':
|
|
|
|
|
cmd = SYSLOG_ACTION_CONSOLE_ON;
|
|
|
|
|
break;
|
2006-12-06 17:26:12 -06:00
|
|
|
|
case 'n':
|
2011-07-01 06:41:56 -05:00
|
|
|
|
cmd = SYSLOG_ACTION_CONSOLE_LEVEL;
|
2011-07-13 08:06:53 -05:00
|
|
|
|
console_level = parse_level(optarg, 0);
|
2006-12-06 17:26:12 -06:00
|
|
|
|
break;
|
2011-07-13 08:50:47 -05:00
|
|
|
|
case 'l':
|
|
|
|
|
flags |= DMESG_FL_LEVEL;
|
|
|
|
|
list_to_bitarray(optarg, parse_level, levels);
|
|
|
|
|
break;
|
2009-01-08 10:44:27 -06:00
|
|
|
|
case 'r':
|
2011-07-01 06:57:36 -05:00
|
|
|
|
flags |= DMESG_FL_RAW;
|
2009-01-08 10:44:27 -06:00
|
|
|
|
break;
|
2006-12-06 17:26:12 -06:00
|
|
|
|
case 's':
|
2011-07-01 07:56:22 -05:00
|
|
|
|
bufsize = strtol_or_err(optarg,
|
|
|
|
|
_("failed to parse buffer size"));
|
2006-12-06 17:26:16 -06:00
|
|
|
|
if (bufsize < 4096)
|
|
|
|
|
bufsize = 4096;
|
2006-12-06 17:26:12 -06:00
|
|
|
|
break;
|
2011-07-01 06:24:04 -05:00
|
|
|
|
case 'V':
|
|
|
|
|
printf(_("%s from %s\n"), program_invocation_short_name,
|
|
|
|
|
PACKAGE_STRING);
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
|
case 'h':
|
|
|
|
|
usage(stdout);
|
|
|
|
|
break;
|
2006-12-06 17:26:12 -06:00
|
|
|
|
case '?':
|
|
|
|
|
default:
|
2011-07-01 06:24:04 -05:00
|
|
|
|
usage(stderr);
|
2006-12-06 17:26:12 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
argc -= optind;
|
|
|
|
|
argv += optind;
|
2009-08-17 04:37:27 -05:00
|
|
|
|
|
2011-02-28 03:10:32 -06:00
|
|
|
|
if (argc > 1)
|
2011-07-01 06:24:04 -05:00
|
|
|
|
usage(stderr);
|
2006-12-06 17:25:32 -06:00
|
|
|
|
|
2011-07-01 07:56:22 -05:00
|
|
|
|
if (cmd == -1)
|
|
|
|
|
cmd = SYSLOG_ACTION_READ_ALL; /* default */
|
|
|
|
|
|
2011-07-01 07:26:19 -05:00
|
|
|
|
switch (cmd) {
|
|
|
|
|
case SYSLOG_ACTION_READ_ALL:
|
|
|
|
|
case SYSLOG_ACTION_READ_CLEAR:
|
|
|
|
|
if (!bufsize)
|
|
|
|
|
bufsize = get_buffer_size();
|
|
|
|
|
n = read_buffer(&buf, bufsize, cmd == SYSLOG_ACTION_READ_CLEAR);
|
|
|
|
|
if (n > 0)
|
2011-07-13 08:50:47 -05:00
|
|
|
|
print_buffer(buf, n, flags, levels);
|
2011-07-01 07:26:19 -05:00
|
|
|
|
free(buf);
|
|
|
|
|
break;
|
2011-07-01 07:33:27 -05:00
|
|
|
|
case SYSLOG_ACTION_CLEAR:
|
2011-07-01 08:30:16 -05:00
|
|
|
|
case SYSLOG_ACTION_CONSOLE_OFF:
|
|
|
|
|
case SYSLOG_ACTION_CONSOLE_ON:
|
2011-07-01 07:33:27 -05:00
|
|
|
|
n = klogctl(cmd, NULL, 0);
|
|
|
|
|
break;
|
2011-07-01 07:26:19 -05:00
|
|
|
|
case SYSLOG_ACTION_CONSOLE_LEVEL:
|
|
|
|
|
n = klogctl(cmd, NULL, console_level);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
errx(EXIT_FAILURE, _("unsupported command"));
|
|
|
|
|
break;
|
2006-12-06 17:26:12 -06:00
|
|
|
|
}
|
2006-12-06 17:25:32 -06:00
|
|
|
|
|
2011-02-28 03:10:32 -06:00
|
|
|
|
if (n < 0)
|
|
|
|
|
err(EXIT_FAILURE, _("klogctl failed"));
|
2006-12-06 17:25:32 -06:00
|
|
|
|
|
2011-02-28 03:10:32 -06:00
|
|
|
|
return EXIT_SUCCESS;
|
2006-12-06 17:25:32 -06:00
|
|
|
|
}
|