1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2012-2013 ProFUSION embedded systems
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <libkmod/libkmod.h>
#include "kmod.h"
#define PRIO_MAX_SIZE 32
static bool log_use_syslog;
static int log_priority = LOG_WARNING;
static const char *prio_to_str(char buf[static PRIO_MAX_SIZE], int prio)
{
const char *prioname;
switch (prio) {
case LOG_CRIT:
prioname = "FATAL";
break;
case LOG_ERR:
prioname = "ERROR";
break;
case LOG_WARNING:
prioname = "WARNING";
break;
case LOG_NOTICE:
prioname = "NOTICE";
break;
case LOG_INFO:
prioname = "INFO";
break;
case LOG_DEBUG:
prioname = "DEBUG";
break;
default:
snprintf(buf, PRIO_MAX_SIZE, "LOG-%03d", prio);
prioname = buf;
}
return prioname;
}
_printf_format_(6, 0) static void log_kmod(void *data, int priority, const char *file,
int line, const char *fn, const char *format,
va_list args)
{
char buf[PRIO_MAX_SIZE];
const char *prioname;
char *str;
prioname = prio_to_str(buf, priority);
if (vasprintf(&str, format, args) < 0)
return;
if (log_use_syslog) {
if (ENABLE_DEBUG == 1)
syslog(priority, "%s: %s:%d %s() %s", prioname, file, line, fn,
str);
else
syslog(priority, "%s: %s", prioname, str);
} else {
if (ENABLE_DEBUG == 1)
fprintf(stderr, "%s: %s: %s:%d %s() %s",
program_invocation_short_name, prioname, file, line, fn,
str);
else
fprintf(stderr, "%s: %s: %s", program_invocation_short_name,
prioname, str);
}
free(str);
(void)data;
}
void log_open(bool use_syslog)
{
log_use_syslog = use_syslog;
if (log_use_syslog)
openlog(program_invocation_short_name, LOG_CONS, LOG_DAEMON);
}
void log_close(void)
{
if (log_use_syslog)
closelog();
}
void log_printf(int prio, const char *fmt, ...)
{
char buf[PRIO_MAX_SIZE];
const char *prioname;
char *msg;
va_list args;
if (prio > log_priority)
return;
va_start(args, fmt);
if (vasprintf(&msg, fmt, args) < 0)
msg = NULL;
va_end(args);
if (msg == NULL)
return;
prioname = prio_to_str(buf, prio);
if (log_use_syslog)
syslog(prio, "%s: %s", prioname, msg);
else
fprintf(stderr, "%s: %s: %s", program_invocation_short_name, prioname,
msg);
free(msg);
if (prio <= LOG_CRIT)
exit(EXIT_FAILURE);
}
void log_setup_kmod_log(struct kmod_ctx *ctx, int priority)
{
log_priority = priority;
kmod_set_log_priority(ctx, log_priority);
kmod_set_log_fn(ctx, log_kmod, NULL);
}
|