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 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) 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 } 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 107 void log_close(void) 108 { 109 if (log_use_syslog) 110 closelog(); 111 } 112 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 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