]> git.ipfire.org Git - people/ms/network.git/blobdiff - src/libnetwork/libnetwork.c
libnetwork: Add logging infrastructure
[people/ms/network.git] / src / libnetwork / libnetwork.c
index 6793fd5251aa646ad25a45035ed1c996cfe0c7b3..09651a066537c9c81630d57043a97d91b2626a49 100644 (file)
 #                                                                             #
 #############################################################################*/
 
+#include <ctype.h>
 #include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
 
 #include <network/libnetwork.h>
+#include <network/logging.h>
 #include "libnetwork-private.h"
 
 struct network_ctx {
        int refcount;
+
+       // Logging
+       void (*log_fn)(struct network_ctx* ctx,
+               int priority, const char *file, int line, const char *fn,
+               const char *format, va_list args);
+       int log_priority;
 };
 
+void network_log(struct network_ctx* ctx,
+               int priority, const char* file, int line, const char* fn,
+               const char* format, ...) {
+       va_list args;
+
+       va_start(args, format);
+       ctx->log_fn(ctx, priority, file, line, fn, format, args);
+       va_end(args);
+}
+
+static void log_stderr(struct network_ctx* ctx,
+               int priority, const char* file, int line, const char* fn,
+               const char* format, va_list args) {
+       fprintf(stderr, "libnetwork: %s: ", fn);
+       vfprintf(stderr, format, args);
+}
+
+static int log_priority(const char* priority) {
+       char *endptr;
+
+       int prio = strtol(priority, &endptr, 10);
+
+       if (endptr[0] == '\0' || isspace(endptr[0]))
+               return prio;
+
+       if (strncmp(priority, "err", 3) == 0)
+               return LOG_ERR;
+
+       if (strncmp(priority, "info", 4) == 0)
+               return LOG_INFO;
+
+       if (strncmp(priority, "debug", 5) == 0)
+               return LOG_DEBUG;
+
+       return 0;
+}
+
 NETWORK_EXPORT int network_new(struct network_ctx** ctx) {
        struct network_ctx* c = calloc(1, sizeof(*c));
        if (!c)
@@ -36,6 +85,17 @@ NETWORK_EXPORT int network_new(struct network_ctx** ctx) {
        // Initialise basic variables
        c->refcount = 1;
 
+       // Initialise logging
+       c->log_fn = log_stderr;
+       c->log_priority = LOG_ERR;
+
+       const char* env = secure_getenv("NETWORK_LOG");
+       if (env)
+               network_set_log_priority(c, log_priority(env));
+
+       INFO(c, "network ctx %p created\n", c);
+       DEBUG(c, "log_priority=%d\n", c->log_priority);
+
        *ctx = c;
        return 0;
 }
@@ -49,7 +109,7 @@ NETWORK_EXPORT struct network_ctx* network_ref(struct network_ctx* ctx) {
 }
 
 static void network_free(struct network_ctx* ctx) {
-       // Nothing to do, yet
+       DEBUG(ctx, "network ctx %p released\n", ctx);
 }
 
 NETWORK_EXPORT struct network_ctx* network_unref(struct network_ctx* ctx) {
@@ -63,6 +123,21 @@ NETWORK_EXPORT struct network_ctx* network_unref(struct network_ctx* ctx) {
        return NULL;
 }
 
+NETWORK_EXPORT void network_set_log_fn(struct network_ctx* ctx,
+               void (*log_fn)(struct network_ctx* ctx, int priority, const char* file,
+               int line, const char* fn, const char* format, va_list args)) {
+       ctx->log_fn = log_fn;
+       INFO(ctx, "custom logging function %p registered\n", log_fn);
+}
+
+NETWORK_EXPORT int network_get_log_priority(struct network_ctx* ctx) {
+       return ctx->log_priority;
+}
+
+NETWORK_EXPORT void network_set_log_priority(struct network_ctx* ctx, int priority) {
+       ctx->log_priority = priority;
+}
+
 NETWORK_EXPORT const char* network_version() {
        return "network " VERSION;
 }