]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
dmesg: add --noescape
authorKarel Zak <kzak@redhat.com>
Mon, 9 Sep 2019 10:53:08 +0000 (12:53 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 9 Sep 2019 10:56:53 +0000 (12:56 +0200)
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>
bash-completion/dmesg
sys-utils/dmesg.1
sys-utils/dmesg.c

index 5073e5b3e48c778ead3865bf9b252bf0f48e8673..604307d66846c61cebb4a3f686eab63825fa878c 100644 (file)
@@ -45,6 +45,7 @@ _dmesg_module()
                --color
                --level
                --console-level
+               --noespace
                --nopager
                --raw
                --syslog
index a93821aeae2507035ef1a9ef7c0a98cc39dbd1a1..05ef911f7578080e8b952e9026178366f39b7a68 100644 (file)
@@ -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)
index d12ca8025a9d6cc5d966fa1bb50d7c2f6bd2ac92..55cf127f32e4341a77d7cf3cd65629230c8a5cc4 100644 (file)
@@ -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);
-
-               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
+                       wchar_t wc;
+                       len = mbrtowc(&wc, p, size - i, &s);
+
+                       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
 #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();