blob: 745f5b3d3f7cf317bd46aed57ad19256095e0c1b [file] [log] [blame]
Lucas De Marchi92aad742012-11-06 18:04:09 -02001/*
2 * kmod - log infrastructure
3 *
4 * Copyright (C) 2012 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 <stdio.h>
21#include <stdlib.h>
22#include <syslog.h>
23
Lucas De Marchi52a50fe2012-11-06 18:26:34 -020024#include "libkmod.h"
Lucas De Marchi92aad742012-11-06 18:04:09 -020025#include "kmod.h"
26
27static bool log_use_syslog;
Lucas De Marchi52a50fe2012-11-06 18:26:34 -020028static int log_priority = LOG_ERR;
Lucas De Marchi92aad742012-11-06 18:04:09 -020029
Lucas De Marchic8412732012-11-06 19:06:11 -020030static _always_inline_ const char *prio_to_str(int prio)
Lucas De Marchi92aad742012-11-06 18:04:09 -020031{
Lucas De Marchic8412732012-11-06 19:06:11 -020032 const char *prioname;
33 char buf[32];
Lucas De Marchi92aad742012-11-06 18:04:09 -020034
Lucas De Marchic8412732012-11-06 19:06:11 -020035 switch (prio) {
36 case LOG_CRIT:
37 prioname = "FATAL";
38 break;
39 case LOG_ERR:
40 prioname = "ERROR";
41 break;
42 case LOG_WARNING:
43 prioname = "WARNING";
44 break;
45 case LOG_NOTICE:
46 prioname = "NOTICE";
47 break;
48 case LOG_INFO:
49 prioname = "INFO";
50 break;
51 case LOG_DEBUG:
52 prioname = "DEBUG";
53 break;
54 default:
55 snprintf(buf, sizeof(buf), "LOG-%03d", prio);
56 prioname = buf;
57 }
58
59 return prioname;
Lucas De Marchi92aad742012-11-06 18:04:09 -020060}
61
Lucas De Marchic8412732012-11-06 19:06:11 -020062static void log_kmod(void *data, int priority, const char *file, int line,
63 const char *fn, const char *format, va_list args)
Lucas De Marchi92aad742012-11-06 18:04:09 -020064{
65 const char *prioname = prio_to_str(priority);
66 char *str;
67
68 if (vasprintf(&str, format, args) < 0)
69 return;
70
71 if (log_use_syslog) {
72#ifdef ENABLE_DEBUG
73 syslog(priority, "%s: %s:%d %s() %s", prioname, file, line,
74 fn, str);
75#else
76 syslog(priority, "%s: %s", prioname, str);
77#endif
78 } else {
79#ifdef ENABLE_DEBUG
80 fprintf(stderr, "%s: %s: %s:%d %s() %s", binname, prioname,
81 file, line, fn, str);
82#else
83 fprintf(stderr, "%s: %s: %s", binname, prioname, str);
84#endif
85 }
86
87 free(str);
88 (void)data;
89}
Lucas De Marchic8412732012-11-06 19:06:11 -020090void log_open(bool use_syslog)
91{
92 log_use_syslog = use_syslog;
93
94 if (log_use_syslog)
95 openlog(binname, LOG_CONS, LOG_DAEMON);
96}
97
98void log_close(void)
99{
100 if (log_use_syslog)
101 closelog();
102}
Lucas De Marchi52a50fe2012-11-06 18:26:34 -0200103
Lucas De Marchifcb0ce92012-11-06 19:01:59 -0200104void log_printf(int prio, const char *fmt, ...)
105{
106 const char *prioname;
107 char *msg;
108 va_list args;
109
110 if (prio > log_priority)
111 return;
112
113 va_start(args, fmt);
114 if (vasprintf(&msg, fmt, args) < 0)
115 msg = NULL;
116 va_end(args);
117 if (msg == NULL)
118 return;
119
120 prioname = prio_to_str(prio);
121
122 if (log_use_syslog)
123 syslog(prio, "%s: %s", prioname, msg);
124 else
125 fprintf(stderr, "%s: %s: %s", binname, prioname, msg);
126 free(msg);
127
128 if (prio <= LOG_CRIT)
129 exit(EXIT_FAILURE);
130}
131
Lucas De Marchi52a50fe2012-11-06 18:26:34 -0200132void log_setup_kmod_log(struct kmod_ctx *ctx, int priority)
133{
134 log_priority = priority;
135
136 kmod_set_log_priority(ctx, log_priority);
137 kmod_set_log_fn(ctx, log_kmod, NULL);
138}