Home | History | Annotate | Download | only in tools
      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