dmesg: add --noescape
We have no way how to print the kernel message buffer in really raw way. The new option --noescape disables all \x<hex> translations. Addresses: https://github.com/karelzak/util-linux/issues/858 Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
a6cc5c16f4
commit
646bba41fd
|
@ -45,6 +45,7 @@ _dmesg_module()
|
|||
--color
|
||||
--level
|
||||
--console-level
|
||||
--noespace
|
||||
--nopager
|
||||
--raw
|
||||
--syslog
|
||||
|
|
|
@ -113,12 +113,19 @@ option is used,
|
|||
will
|
||||
.I not
|
||||
print or clear the kernel ring buffer.
|
||||
.IP "\fB\-\-noescape\fR"
|
||||
The unprintable and potentially unsafe characters (e.g. broken multi-byte
|
||||
sequences, terminal controlling chars, etc.) are escaped in format \\x<hex> for
|
||||
security reason by default. This option disables this feature at all. It's
|
||||
usable for example for debugging purpose together with \fB\-\-raw\fR. Be
|
||||
careful and don't use it by default.
|
||||
.IP "\fB\-P\fR, \fB\-\-nopager\fR"
|
||||
Do not pipe output into a pager. A pager is enabled by default for \fB\-\-human\fR output.
|
||||
.IP "\fB\-p\fR, \fB\-\-force\-prefix\fR"
|
||||
Add facility, level or timestamp information to each line of a multi-line message.
|
||||
.IP "\fB\-r\fR, \fB\-\-raw\fR"
|
||||
Print the raw message buffer, i.e. do not strip the log-level prefixes.
|
||||
Print the raw message buffer, i.e. do not strip the log-level prefixes, but
|
||||
all unprintable characters are still escaped (see also \fB\-\-noescape\fR).
|
||||
|
||||
Note that the real raw format depends on the method how
|
||||
.BR dmesg (1)
|
||||
|
|
|
@ -191,6 +191,7 @@ struct dmesg_control {
|
|||
|
||||
unsigned int follow:1, /* wait for new messages */
|
||||
raw:1, /* raw mode */
|
||||
noesc:1, /* no escape */
|
||||
fltr_lev:1, /* filter out by levels[] */
|
||||
fltr_fac:1, /* filter out by facilities[] */
|
||||
decode:1, /* use "facility: level: " prefix */
|
||||
|
@ -286,6 +287,7 @@ static void __attribute__((__noreturn__)) usage(void)
|
|||
fputs(_(" -P, --nopager do not pipe output into a pager\n"), out);
|
||||
fputs(_(" -p, --force-prefix force timestamp output on each line of multi-line messages\n"), out);
|
||||
fputs(_(" -r, --raw print the raw message buffer\n"), out);
|
||||
fputs(_(" --noescape don't escape unprintable character\n"), out);
|
||||
fputs(_(" -S, --syslog force to use syslog(2) rather than /dev/kmsg\n"), out);
|
||||
fputs(_(" -s, --buffer-size <size> buffer size to query the kernel ring buffer\n"), out);
|
||||
fputs(_(" -u, --userspace display userspace messages\n"), out);
|
||||
|
@ -616,7 +618,7 @@ static int fwrite_hex(const char *buf, size_t size, FILE *out)
|
|||
/*
|
||||
* Prints to 'out' and non-printable chars are replaced with \x<hex> sequences.
|
||||
*/
|
||||
static void safe_fwrite(const char *buf, size_t size, int indent, FILE *out)
|
||||
static void safe_fwrite(struct dmesg_control *ctl, const char *buf, size_t size, int indent, FILE *out)
|
||||
{
|
||||
size_t i;
|
||||
#ifdef HAVE_WIDECHAR
|
||||
|
@ -626,30 +628,32 @@ static void safe_fwrite(const char *buf, size_t size, int indent, FILE *out)
|
|||
for (i = 0; i < size; i++) {
|
||||
const char *p = buf + i;
|
||||
int rc, hex = 0;
|
||||
size_t len;
|
||||
size_t len = 1;
|
||||
|
||||
if (!ctl->noesc) {
|
||||
#ifdef HAVE_WIDECHAR
|
||||
wchar_t wc;
|
||||
len = mbrtowc(&wc, p, size - i, &s);
|
||||
wchar_t wc;
|
||||
len = mbrtowc(&wc, p, size - i, &s);
|
||||
|
||||
if (len == 0) /* L'\0' */
|
||||
return;
|
||||
if (len == 0) /* L'\0' */
|
||||
return;
|
||||
|
||||
if (len == (size_t)-1 || len == (size_t)-2) { /* invalid sequence */
|
||||
memset(&s, 0, sizeof (s));
|
||||
len = hex = 1;
|
||||
i += len - 1;
|
||||
} else if (len > 1) {
|
||||
if (!iswprint(wc) && !iswspace(wc)) /* non-printable multibyte */
|
||||
hex = 1;
|
||||
i += len - 1;
|
||||
} else
|
||||
if (len == (size_t)-1 || len == (size_t)-2) { /* invalid sequence */
|
||||
memset(&s, 0, sizeof (s));
|
||||
len = hex = 1;
|
||||
i += len - 1;
|
||||
} else if (len > 1) {
|
||||
if (!iswprint(wc) && !iswspace(wc)) /* non-printable multibyte */
|
||||
hex = 1;
|
||||
i += len - 1;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
len = 1;
|
||||
if (!isprint((unsigned char) *p) &&
|
||||
!isspace((unsigned char) *p)) /* non-printable */
|
||||
hex = 1;
|
||||
{
|
||||
len = 1;
|
||||
if (!isprint((unsigned char) *p) &&
|
||||
!isspace((unsigned char) *p)) /* non-printable */
|
||||
hex = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (hex)
|
||||
|
@ -787,7 +791,7 @@ static void raw_print(struct dmesg_control *ctl, const char *buf, size_t size)
|
|||
/*
|
||||
* Print whole ring buffer
|
||||
*/
|
||||
safe_fwrite(buf, size, 0, stdout);
|
||||
safe_fwrite(ctl, buf, size, 0, stdout);
|
||||
lastc = buf[size - 1];
|
||||
} else {
|
||||
/*
|
||||
|
@ -797,7 +801,7 @@ static void raw_print(struct dmesg_control *ctl, const char *buf, size_t size)
|
|||
size_t sz = size > ctl->pagesize ? ctl->pagesize : size;
|
||||
char *x = ctl->mmap_buff;
|
||||
|
||||
safe_fwrite(x, sz, 0, stdout);
|
||||
safe_fwrite(ctl, x, sz, 0, stdout);
|
||||
lastc = x[sz - 1];
|
||||
size -= sz;
|
||||
ctl->mmap_buff += sz;
|
||||
|
@ -1039,7 +1043,7 @@ full_output:
|
|||
|
||||
if (subsys) {
|
||||
dmesg_enable_color(DMESG_COLOR_SUBSYS);
|
||||
safe_fwrite(line, subsys - line, ctl->indent, stdout);
|
||||
safe_fwrite(ctl, line, subsys - line, ctl->indent, stdout);
|
||||
color_disable();
|
||||
|
||||
mesg_size -= subsys - line;
|
||||
|
@ -1047,11 +1051,11 @@ full_output:
|
|||
}
|
||||
/* Error, alert .. etc. colors */
|
||||
has_color = set_level_color(rec->level, line, mesg_size) == 0;
|
||||
safe_fwrite(line, mesg_size, ctl->indent, stdout);
|
||||
safe_fwrite(ctl, line, mesg_size, ctl->indent, stdout);
|
||||
if (has_color)
|
||||
color_disable();
|
||||
} else
|
||||
safe_fwrite(line, mesg_size, ctl->indent, stdout);
|
||||
safe_fwrite(ctl, line, mesg_size, ctl->indent, stdout);
|
||||
|
||||
/* Get the next line */
|
||||
if (ctl->force_prefix) {
|
||||
|
@ -1313,6 +1317,7 @@ int main(int argc, char *argv[])
|
|||
int colormode = UL_COLORMODE_UNDEF;
|
||||
enum {
|
||||
OPT_TIME_FORMAT = CHAR_MAX + 1,
|
||||
OPT_NOESC
|
||||
};
|
||||
|
||||
static const struct option longopts[] = {
|
||||
|
@ -1336,6 +1341,7 @@ int main(int argc, char *argv[])
|
|||
{ "reltime", no_argument, NULL, 'e' },
|
||||
{ "show-delta", no_argument, NULL, 'd' },
|
||||
{ "ctime", no_argument, NULL, 'T' },
|
||||
{ "noescape", no_argument, NULL, OPT_NOESC },
|
||||
{ "notime", no_argument, NULL, 't' },
|
||||
{ "nopager", no_argument, NULL, 'P' },
|
||||
{ "userspace", no_argument, NULL, 'u' },
|
||||
|
@ -1461,6 +1467,9 @@ int main(int argc, char *argv[])
|
|||
case OPT_TIME_FORMAT:
|
||||
ctl.time_fmt = which_time_format(optarg);
|
||||
break;
|
||||
case OPT_NOESC:
|
||||
ctl.noesc = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage();
|
||||
|
|
Loading…
Reference in New Issue