# #
#############################################################################*/
+#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)
// 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;
}
}
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) {
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;
}