--- /dev/null
+#define _GNU_SOURCE 1
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+#include "notify.h"
+
+/*
+ * Generic console notifier.
+ */
+
+static void
+notify_fn_default_(int level, const char * func_name, const char * fmt, ...)
+{
+ FILE *f = (level <= 1) ? stderr : stdout;
+ static const char * const levels[] = { "FATAL", "ERROR", "INFO", "DEBUG" };
+ const int levels_num = sizeof levels / sizeof *levels;
+ va_list ap;
+
+ flockfile(f);
+
+ fputs_unlocked((func_name && *func_name) ? func_name : "[null]", f);
+ fputs_unlocked(": --", f);
+ if (level >= 0
+ && level <= levels_num) {
+ fputs_unlocked(levels[level], f);
+ } else {
+ fprintf(f, "%d", level);
+ }
+ fputs_unlocked("-- ", f);
+
+ va_start(ap, fmt);
+ vfprintf(f, fmt, ap);
+ va_end(ap);
+
+ fputc_unlocked('\n', f);
+ fflush_unlocked(f);
+
+ funlockfile(f);
+
+}
+
+void (* notify_fn)(int level, const char *func_name, const char *msg, ...) __attribute__((format(printf, 3, 4))) = notify_fn_default_;
+
+void
+notify_fn_set(void (* fn)(int level, const char *func_name, const char *fmt, ...))
+{
+ notify_fn = fn;
+}