File: log.c

package info (click to toggle)
kmod 34.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,864 kB
  • sloc: ansic: 16,990; makefile: 498; sh: 382; xml: 61; perl: 12
file content (134 lines) | stat: -rw-r--r-- 2,529 bytes parent folder | download
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);
}