1 2/* This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 */ 16 17#include <stdlib.h> 18#include <stdio.h> 19#include <stdarg.h> 20#include <string.h> 21#include <time.h> 22 23#include "log.h" 24 25static FILE *log_fp = NULL; 26static int default_log_level = E_WARN; 27int log_level[L_MAX]; 28 29char *facility_name[] = { 30 "general", 31 "artwork", 32 "database", 33 "inotify", 34 "scanner", 35 "metadata", 36 "http", 37 "ssdp", 38 "tivo", 39 0 40}; 41 42char *level_name[] = { 43 "off", // E_OFF 44 "fatal", // E_FATAL 45 "error", // E_ERROR 46 "warn", // E_WARN 47 "info", // E_INFO 48 "debug", // E_DEBUG 49 0 50}; 51 52int 53log_init(const char *fname, const char *debug) 54{ 55 int i; 56 FILE *fp; 57 short int log_level_set[L_MAX]; 58 59 if (debug) 60 { 61 char *rhs, *lhs, *p; 62 int n; 63 int level, facility; 64 memset(&log_level_set, 0, sizeof(log_level_set)); 65 rhs = lhs = (char*) debug; 66 while (rhs && (rhs = strchr(rhs, '='))) { 67 rhs++; 68 p = strchr(rhs, ','); 69 n = p ? p - rhs : strlen(rhs); 70 for (level=0; level_name[level]; level++) { 71 if (!(strncasecmp(level_name[level], rhs, n))) 72 break; 73 } 74 rhs = p; 75 if (!(level_name[level])) { 76 // unknown level 77 continue; 78 } 79 do { 80 if (*lhs==',') lhs++; 81 p = strpbrk(lhs, ",="); 82 n = p ? p - lhs : strlen(lhs); 83 for (facility=0; facility_name[facility]; facility++) { 84 if (!(strncasecmp(facility_name[facility], lhs, n))) 85 break; 86 } 87 if ((facility_name[facility])) { 88 log_level[facility] = level; 89 log_level_set[facility] = 1; 90 } 91 lhs = p; 92 } while (*lhs && *lhs==','); 93 } 94 for (i=0; i<L_MAX; i++) 95 { 96 if( !log_level_set[i] ) 97 { 98 log_level[i] = default_log_level; 99 } 100 } 101 } 102 else { 103 for (i=0; i<L_MAX; i++) 104 log_level[i] = default_log_level; 105 } 106 107 if (!fname) // use default i.e. stdout 108 return 0; 109 110 if (!(fp = fopen(fname, "a"))) 111 return 1; 112 log_fp = fp; 113 return 0; 114} 115 116void 117log_err(int level, enum _log_facility facility, char *fname, int lineno, char *fmt, ...) 118{ 119 //char errbuf[1024]; 120 char * errbuf; 121 va_list ap; 122 time_t t; 123 struct tm *tm; 124 125 if (level && level>log_level[facility] && level>E_FATAL) 126 return; 127 128 if (!log_fp) 129 log_fp = stdout; 130 131 // user log 132 va_start(ap, fmt); 133 //vsnprintf(errbuf, sizeof(errbuf), fmt, ap); 134 vasprintf(&errbuf, fmt, ap); 135 va_end(ap); 136 137 // timestamp 138 t = time(NULL); 139 tm = localtime(&t); 140 fprintf(log_fp, "[%04d/%02d/%02d %02d:%02d:%02d] ", 141 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, 142 tm->tm_hour, tm->tm_min, tm->tm_sec); 143 144 if (level) 145 fprintf(log_fp, "%s:%d: %s: %s", fname, lineno, level_name[level], errbuf); 146 else 147 fprintf(log_fp, "%s:%d: %s", fname, lineno, errbuf); 148 fflush(log_fp); 149 free(errbuf); 150 151 if (level==E_FATAL) 152 exit(-1); 153 154 return; 155} 156