]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
dmesg: add --facility option
authorKarel Zak <kzak@redhat.com>
Thu, 14 Jul 2011 10:48:07 +0000 (12:48 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 14 Jul 2011 10:48:07 +0000 (12:48 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/dmesg.1
sys-utils/dmesg.c

index cd8f9cfe0f5f7956ad45a4072d0838114aa16d56..0628232e2255aa17b735192ef53a7396616600d3 100644 (file)
@@ -36,6 +36,14 @@ Clear the ring buffer contents after printing.
 Disable printing messages to the console.
 .IP "\fB\-e, \-\-console-on\fP"
 Enable printing messages to the console.
+.IP "\fB\-f, \-\-facility \fIlist\fP"
+Restrict output to defined (comma separated) list of facilities. For exmaple
+.sp
+  dmesg --facility=daemon
+.sp
+will print messages from system daemons only.
+.IP "\fB\-x, \-\-decode\fP"
+Decode facility and level (priority) number to human readable prefixes.
 .IP "\fB\-h, \-\-help\fP"
 Print a help text and exit.
 .IP "\fB\-l, \-\-level \fIlist\fP"
index 1a71af30dabd2c21d9e0b4d1d91db53e9b4a1e05..244cf65cb4a219b015f11125dd363822cbf55fdc 100644 (file)
@@ -127,6 +127,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
                " -c, --read-clear          read and clear all messages\n"
                " -d, --console-off         disable printing messages to console\n"
                " -e, --console-on          enable printing messages to console\n"
+               " -f, --facility=LIST       restrict output to defined facilities\n"
                " -x, --decode              decode facility and level to readable string\n"
                " -h, --help                display this help and exit\n"
                " -l, --level=LIST          restrict output to defined levels\n"
@@ -187,6 +188,39 @@ static int parse_level(const char *str, size_t len)
        return -1;
 }
 
+static int parse_facility(const char *str, size_t len)
+{
+       int i;
+
+       if (!str)
+               return -1;
+       if (!len)
+               len = strlen(str);
+       errno = 0;
+
+       if (isdigit(*str)) {
+               char *end = NULL;
+
+               i = strtol(str, &end, 10);
+               if (!errno && end && end > str && end - str == len &&
+                   i >= 0 && i < ARRAY_SIZE(facility_names))
+                       return i;
+       } else {
+               for (i = 0; i < ARRAY_SIZE(facility_names); i++) {
+                       const char *n = facility_names[i].name;
+
+                       if (strncasecmp(str, n, len) == 0 && *(n + len) == '\0')
+                               return i;
+               }
+       }
+
+       if (errno)
+               err(EXIT_FAILURE, _("failed to parse facility '%s'"), str);
+
+       errx(EXIT_FAILURE, _("unknown facility '%s'"), str);
+       return -1;
+}
+
 static const char *parse_faclev(const char *str, int *fac, int *lev)
 {
        long num;
@@ -333,7 +367,8 @@ static void safe_fwrite(const char *buf, size_t size, FILE *out)
        }
 }
 
-static void print_buffer(const char *buf, size_t size, int flags, char *levels)
+static void print_buffer(const char *buf, size_t size, int flags,
+                        char *levels, char *facilities)
 {
        int i;
        const char *begin = NULL;
@@ -380,7 +415,10 @@ static void print_buffer(const char *buf, size_t size, int flags, char *levels)
                }
 
                if (begin < end &&
-                   (lev < 0 || !(flags & DMESG_FL_LEVEL) || isset(levels, lev))) {
+                   (lev < 0 || !(flags & DMESG_FL_LEVEL) ||
+                                          isset(levels, lev)) &&
+                   (fac < 0 || !(flags & DMESG_FL_FACILITY) ||
+                                         isset(facilities, fac))) {
                        size_t sz =  end - begin;
 
                        if ((flags & DMESG_FL_DECODE) && lev >= 0 && fac >= 0) {
@@ -404,7 +442,10 @@ int main(int argc, char *argv[])
        int  console_level = 0;
        int  cmd = -1;
        int  flags = 0;
+
+       /* bit arrays -- see include/bitops.h */
        char levels[ARRAY_SIZE(level_names) / NBBY + 1] = { 0 };
+       char facilities[ARRAY_SIZE(facility_names) / NBBY + 1] = { 0 };
 
        static const struct option longopts[] = {
                { "clear",         no_argument,       NULL, 'C' },
@@ -416,6 +457,7 @@ int main(int argc, char *argv[])
                { "level",         required_argument, NULL, 'l' },
                { "console-off",   no_argument,       NULL, 'd' },
                { "console-on",    no_argument,       NULL, 'e' },
+               { "facility",      required_argument, NULL, 'f' },
                { "version",       no_argument,       NULL, 'V' },
                { "help",          no_argument,       NULL, 'h' },
                { NULL,            0, NULL, 0 }
@@ -425,7 +467,7 @@ int main(int argc, char *argv[])
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
 
-       while ((c = getopt_long(argc, argv, "Ccdehl:rn:s:Vx", longopts, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, "Ccdehl:rn:s:Vxf:", longopts, NULL)) != -1) {
 
                if (cmd != -1 && strchr("Ccnde", c))
                        errx(EXIT_FAILURE, "%s %s",
@@ -445,6 +487,10 @@ int main(int argc, char *argv[])
                case 'e':
                        cmd = SYSLOG_ACTION_CONSOLE_ON;
                        break;
+               case 'f':
+                       flags |= DMESG_FL_FACILITY;
+                       list_to_bitarray(optarg, parse_facility, facilities);
+                       break;
                case 'n':
                        cmd = SYSLOG_ACTION_CONSOLE_LEVEL;
                        console_level = parse_level(optarg, 0);
@@ -496,7 +542,7 @@ int main(int argc, char *argv[])
                        bufsize = get_buffer_size();
                n = read_buffer(&buf, bufsize, cmd == SYSLOG_ACTION_READ_CLEAR);
                if (n > 0)
-                       print_buffer(buf, n, flags, levels);
+                       print_buffer(buf, n, flags, levels, facilities);
                free(buf);
                break;
        case SYSLOG_ACTION_CLEAR: