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