]> git.mdlowis.com Git - proto/albase.git/commitdiff
Added initial implementation of dmesg
authorMike Lowis <mike.lowis@gentex.com>
Thu, 28 Apr 2016 16:44:13 +0000 (12:44 -0400)
committerMike Lowis <mike.lowis@gentex.com>
Thu, 28 Apr 2016 16:44:13 +0000 (12:44 -0400)
Makefile
include/util.h
source/dmesg.c

index 642dbf7874ae5d0179ee22695df9b60fac76cb8d..b0894fc5f10aa37de90b8774078830dbb080b38f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ BUILD    = $(CC) $(CFLAGS) -o $@ $<
 #------------------------------------------------------------------------------
 # Build-Specific Macros
 #------------------------------------------------------------------------------
-BINS = init getty login
+BINS = init getty login dmesg
 
 # load user-specific settings
 -include config.mk
@@ -36,6 +36,9 @@ getty: source/getty.c
 login: source/login.c
        $(BUILD) -lcrypt
 
+dmesg: source/dmesg.c
+       $(BUILD)
+
 clean:
        $(RM) $(BINS)
 
index 95b4afa3e583445716bdf6bbc8bb8ddd4d074f42..824991efe37ef0dee37720ffebbab4eec433020f 100644 (file)
@@ -31,6 +31,28 @@ typedef signed char schar;
 typedef long long vlong;
 typedef unsigned long long uvlong;
 
+/* Error Handling Macros
+ *****************************************************************************/
+#ifdef NDEBUG
+    #define debug(msg, ...) \
+        ((void)0)
+#else
+    #define debug(msg, ...) \
+        fprintf(stderr, "DEBUG %s:%d: " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__)
+#endif
+
+#define errnostr() \
+    (errno == 0 ? "None" : strerror(errno))
+
+#define print_error(msg, ...) \
+    fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " msg "\n", __FILE__, __LINE__, errnostr(), ##__VA_ARGS__)
+
+#define check(expr, msg, ...) \
+    if(!(expr)) { print_error(msg, ##__VA_ARGS__); errno=0; goto error; }
+
+#define sentinel(msg, ...) \
+    { print_error(msg, ##__VA_ARGS__); errno=0; goto error; }
+
 /* Generic Death Function
  *****************************************************************************/
 static void die(const char* msgfmt, ...)
@@ -163,6 +185,22 @@ static char* estrdup(const char *s)
     return ns;
 }
 
+static long int estrtol(const char* str, int base) {
+    errno = 0;
+    long int result = strtol(str, NULL, base);
+    if (errno)
+        die("estrtol failed: %s", errnostr());
+    return result;
+}
+
+static unsigned long int estrtoul(const char* str, int base) {
+    errno = 0;
+    unsigned long int result = strtol(str, NULL, base);
+    if (errno)
+        die("estrtoul failed: %s", errnostr());
+    return result;
+}
+
 /* Option Parsing
  ******************************************************************************
  * This following macros implement a simple POSIX-style option parsing strategy.
@@ -262,28 +300,6 @@ static inline char* _getopt_(int* p_argc, char*** p_argv) {
 #define OPTLONG \
     case '-'
 
-/* Error Handling
- *****************************************************************************/
-#ifdef NDEBUG
-    #define debug(msg, ...) \
-        ((void)0)
-#else
-    #define debug(msg, ...) \
-        fprintf(stderr, "DEBUG %s:%d: " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__)
-#endif
-
-#define errnostr() \
-    (errno == 0 ? "None" : strerror(errno))
-
-#define print_error(msg, ...) \
-    fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " msg "\n", __FILE__, __LINE__, errnostr(), ##__VA_ARGS__)
-
-#define check(expr, msg, ...) \
-    if(!(expr)) { print_error(msg, ##__VA_ARGS__); errno=0; goto error; }
-
-#define sentinel(msg, ...) \
-    { print_error(msg, ##__VA_ARGS__); errno=0; goto error; }
-
 /* Miscellaneous
  *****************************************************************************/
 #ifndef nelem
index fff14615a05f4ad31ec21e3a3c57166e568548a7..20f23ec866bb0cd2b8f26c05c09cf1e3e6383847 100644 (file)
@@ -1,81 +1,61 @@
-/* See LICENSE file for copyright and license details. */
-#include <sys/klog.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
+/**
+  @brief
+  @author Michael D. Lowis
+  @license BSD 2-clause License
+*/
 #include "util.h"
+#include <sys/klog.h>
 
-enum {
-       SYSLOG_ACTION_READ_ALL = 3,
-       SYSLOG_ACTION_CLEAR = 5,
-       SYSLOG_ACTION_CONSOLE_LEVEL = 8,
-       SYSLOG_ACTION_SIZE_BUFFER = 10
-};
+#define SYSLOG_ACTION_READ_ALL       3
+#define SYSLOG_ACTION_CLEAR          5
+#define SYSLOG_ACTION_CONSOLE_LEVEL  8
+#define SYSLOG_ACTION_SIZE_BUFFER   10
 
-static void
-dmesg_show(const void *buf, size_t n)
-{
-       const char *p = buf;
-       ssize_t r;
+char* ARGV0;
 
-       r = write(1, p, n);
-       if (r < 0)
-               eprintf("write:");
-       if (r > 0 && p[r - 1] != '\n')
-               putchar('\n');
+static void usage(void) {
+    fprintf(stderr, "Usage: %s [-Cc] [-n level]\n", ARGV0);
+    exit(1);
 }
 
-static void
-usage(void)
-{
-       eprintf("usage: %s [-Ccr] [-n level]\n", argv0);
+int eklogctl(int type, char *bufp, int len) {
+    int nbytes = klogctl(type, bufp, len);
+    if (nbytes < 0)
+        die("klogctl failed: %s", errnostr());
+    return nbytes;
 }
 
-int
-main(int argc, char *argv[])
-{
-       int n;
-       char *buf;
-       int cflag = 0;
-       long level;
-
-       ARGBEGIN {
-       case 'C':
-               if (klogctl(SYSLOG_ACTION_CLEAR, NULL, 0) < 0)
-                       eprintf("klogctl:");
-               return 0;
-       case 'c':
-               cflag = 1;
-               break;
-       case 'r':
-               break;
-       case 'n':
-               level = estrtol(EARGF(usage()), 10);
-               if (klogctl(SYSLOG_ACTION_CONSOLE_LEVEL, NULL, level) < 0)
-                       eprintf("klogctl:");
-               return 0;
-       default:
-               usage();
-       } ARGEND;
-
-       n = klogctl(SYSLOG_ACTION_SIZE_BUFFER, NULL, 0);
-       if (n < 0)
-               eprintf("klogctl:");
-
-       buf = emalloc(n);
-
-       n = klogctl(SYSLOG_ACTION_READ_ALL, buf, n);
-       if (n < 0)
-               eprintf("klogctl:");
-
-       dmesg_show(buf, n);
-
-       if (cflag && klogctl(SYSLOG_ACTION_CLEAR, NULL, 0) < 0)
-               eprintf("klogctl:");
-
-       free(buf);
-       return 0;
-}
\ No newline at end of file
+int main(int argc, char** argv) {
+    long level = -1;
+    bool read  = true;
+    bool clear_before = false;
+    bool clear_after = false;
+    /* Parse command line options */
+    OPTBEGIN {
+        case 'C': clear_before = true; read = false;     break;
+        case 'c': clear_after = true;  read = true;      break;
+        case 'n': level = estrtol(EOPTARG(usage()), 10); break;
+        default:
+            usage();
+    } OPTEND;
+    /* clear the before before  doing anything else */
+    if (clear_before)
+        eklogctl(SYSLOG_ACTION_CLEAR, NULL, 0);
+    /* Set the log level */
+    if (level >= 0)
+        eklogctl(SYSLOG_ACTION_CONSOLE_LEVEL, NULL, level);
+    /* Read the raw log data and print it out */
+    if (read) {
+        int nbytes = eklogctl(SYSLOG_ACTION_SIZE_BUFFER, NULL, 0);
+        char* buf  = (char*)emalloc(nbytes);
+        eklogctl(SYSLOG_ACTION_READ_ALL, buf, nbytes);
+        nbytes = efwrite(buf, 1, nbytes, stdout);
+        if (buf[nbytes - 1] != '\n')
+            fputc('\n', stdout);
+        free(buf);
+    }
+    /* Clear the log after we've read it out */
+    if (clear_after)
+        eklogctl(SYSLOG_ACTION_CLEAR, NULL, 0);
+    return 0;
+}