• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * kmod - log infrastructure
3  *
4  * Copyright (C) 2012-2013  ProFUSION embedded systems
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <errno.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <syslog.h>
24 
25 #include <libkmod/libkmod.h>
26 
27 #include "kmod.h"
28 
29 #define PRIO_MAX_SIZE 32
30 
31 static bool log_use_syslog;
32 static int log_priority = LOG_WARNING;
33 
prio_to_str(char buf[static PRIO_MAX_SIZE],int prio)34 static const char *prio_to_str(char buf[static PRIO_MAX_SIZE], int prio)
35 {
36 	const char *prioname;
37 
38 	switch (prio) {
39 	case LOG_CRIT:
40 		prioname = "FATAL";
41 		break;
42 	case LOG_ERR:
43 		prioname = "ERROR";
44 		break;
45 	case LOG_WARNING:
46 		prioname = "WARNING";
47 		break;
48 	case LOG_NOTICE:
49 		prioname = "NOTICE";
50 		break;
51 	case LOG_INFO:
52 		prioname = "INFO";
53 		break;
54 	case LOG_DEBUG:
55 		prioname = "DEBUG";
56 		break;
57 	default:
58 		snprintf(buf, PRIO_MAX_SIZE, "LOG-%03d", prio);
59 		prioname = buf;
60 	}
61 
62 	return prioname;
63 }
64 
65 _printf_format_(6, 0)
log_kmod(void * data,int priority,const char * file,int line,const char * fn,const char * format,va_list args)66 static void log_kmod(void *data, int priority, const char *file, int line,
67 		     const char *fn, const char *format, va_list args)
68 {
69 	char buf[PRIO_MAX_SIZE];
70 	const char *prioname;
71 	char *str;
72 
73 	prioname = prio_to_str(buf, priority);
74 
75 	if (vasprintf(&str, format, args) < 0)
76 		return;
77 
78 	if (log_use_syslog) {
79 #ifdef ENABLE_DEBUG
80 		syslog(priority, "%s: %s:%d %s() %s", prioname, file, line,
81 		       fn, str);
82 #else
83 		syslog(priority, "%s: %s", prioname, str);
84 #endif
85 	} else {
86 #ifdef ENABLE_DEBUG
87 		fprintf(stderr, "%s: %s: %s:%d %s() %s",
88 			program_invocation_short_name, prioname, file, line,
89 			fn, str);
90 #else
91 		fprintf(stderr, "%s: %s: %s", program_invocation_short_name,
92 			prioname, str);
93 #endif
94 	}
95 
96 	free(str);
97 	(void)data;
98 }
log_open(bool use_syslog)99 void log_open(bool use_syslog)
100 {
101 	log_use_syslog = use_syslog;
102 
103 	if (log_use_syslog)
104 		openlog(program_invocation_short_name, LOG_CONS, LOG_DAEMON);
105 }
106 
log_close(void)107 void log_close(void)
108 {
109 	if (log_use_syslog)
110 		closelog();
111 }
112 
log_printf(int prio,const char * fmt,...)113 void log_printf(int prio, const char *fmt, ...)
114 {
115 	char buf[PRIO_MAX_SIZE];
116 	const char *prioname;
117 	char *msg;
118 	va_list args;
119 
120 	if (prio > log_priority)
121 		return;
122 
123 	va_start(args, fmt);
124 	if (vasprintf(&msg, fmt, args) < 0)
125 		msg = NULL;
126 	va_end(args);
127 	if (msg == NULL)
128 		return;
129 
130 	prioname = prio_to_str(buf, prio);
131 
132 	if (log_use_syslog)
133 		syslog(prio, "%s: %s", prioname, msg);
134 	else
135 		fprintf(stderr, "%s: %s: %s", program_invocation_short_name,
136 			prioname, msg);
137 	free(msg);
138 
139 	if (prio <= LOG_CRIT)
140 		exit(EXIT_FAILURE);
141 }
142 
log_setup_kmod_log(struct kmod_ctx * ctx,int priority)143 void log_setup_kmod_log(struct kmod_ctx *ctx, int priority)
144 {
145 	log_priority = priority;
146 
147 	kmod_set_log_priority(ctx, log_priority);
148 	kmod_set_log_fn(ctx, log_kmod, NULL);
149 }
150