1 | /*
|
---|
2 | * Copyright (c) 1995-2000, Index Data
|
---|
3 | * See the file LICENSE for details.
|
---|
4 | * Sebastian Hammer, Adam Dickmeiss
|
---|
5 | *
|
---|
6 | * $Log$
|
---|
7 | * Revision 1.1 2000/08/03 03:12:06 johnmcp
|
---|
8 | * Added the YAZ toolkit source to the packages directory (for z39.50 stuff)
|
---|
9 | *
|
---|
10 | * Revision 1.22 2000/02/29 13:44:55 adam
|
---|
11 | * Check for config.h (currently not generated).
|
---|
12 | *
|
---|
13 | * Revision 1.21 2000/02/28 11:20:06 adam
|
---|
14 | * Using autoconf. New definitions: YAZ_BEGIN_CDECL/YAZ_END_CDECL.
|
---|
15 | *
|
---|
16 | * Revision 1.20 1999/11/30 13:47:12 adam
|
---|
17 | * Improved installation. Moved header files to include/yaz.
|
---|
18 | *
|
---|
19 | * Revision 1.19 1999/08/27 09:40:32 adam
|
---|
20 | * Renamed logf function to yaz_log. Removed VC++ project files.
|
---|
21 | *
|
---|
22 | * Revision 1.18 1998/10/28 10:27:00 adam
|
---|
23 | * New functions log_init_file, log_init_level, log_init_prefix.
|
---|
24 | *
|
---|
25 | * Revision 1.17 1997/12/09 16:11:02 adam
|
---|
26 | * Assume strerror is defined on Unixes as well. It's standard ANSI.
|
---|
27 | *
|
---|
28 | * Revision 1.16 1997/10/06 08:55:07 adam
|
---|
29 | * Changed log_init so that previous (if any) is closed.
|
---|
30 | *
|
---|
31 | * Revision 1.15 1997/09/29 07:13:13 adam
|
---|
32 | * Minor changes.
|
---|
33 | *
|
---|
34 | * Revision 1.14 1997/09/18 08:48:09 adam
|
---|
35 | * Fixed minor bug that caused log_init to ignore filename.
|
---|
36 | *
|
---|
37 | * Revision 1.13 1997/09/01 08:54:13 adam
|
---|
38 | * New windows NT/95 port using MSV5.0. Made prefix query handling
|
---|
39 | * thread safe. The function options ignores empty arguments when met.
|
---|
40 | *
|
---|
41 | * Revision 1.12 1997/05/01 15:08:14 adam
|
---|
42 | * Added log_mask_str_x routine.
|
---|
43 | *
|
---|
44 | * Revision 1.11 1996/02/05 12:24:32 adam
|
---|
45 | * Implemented log_event_{start,end}-functions.
|
---|
46 | *
|
---|
47 | * Revision 1.10 1995/12/06 09:51:27 quinn
|
---|
48 | * Fixed the log-prefix buffer - it was too small and the setup code lacked
|
---|
49 | * a bounds-check.
|
---|
50 | *
|
---|
51 | * Revision 1.9 1995/09/29 17:12:34 quinn
|
---|
52 | * Smallish
|
---|
53 | *
|
---|
54 | * Revision 1.8 1995/09/27 15:03:02 quinn
|
---|
55 | * Modified function heads & prototypes.
|
---|
56 | *
|
---|
57 | * Revision 1.7 1995/06/19 12:40:18 quinn
|
---|
58 | * Added log_file()
|
---|
59 | *
|
---|
60 | * Revision 1.6 1995/06/15 15:45:03 quinn
|
---|
61 | * Added date info.
|
---|
62 | *
|
---|
63 | * Revision 1.5 1995/05/16 08:51:11 quinn
|
---|
64 | * License, documentation, and memory fixes
|
---|
65 | *
|
---|
66 | * Revision 1.4 1995/05/15 11:56:55 quinn
|
---|
67 | * Debuggng & adjustments.
|
---|
68 | *
|
---|
69 | * Revision 1.3 1995/04/10 10:23:51 quinn
|
---|
70 | * Fixes.
|
---|
71 | *
|
---|
72 | * Revision 1.2 1995/03/31 10:16:55 quinn
|
---|
73 | * Fixed logging.
|
---|
74 | *
|
---|
75 | * Revision 1.1 1995/03/30 10:26:53 quinn
|
---|
76 | * Logging system
|
---|
77 | *
|
---|
78 | * Revision 1.9 1994/12/12 12:09:02 quinn
|
---|
79 | * Changes
|
---|
80 | *
|
---|
81 | * Revision 1.8 1994/11/22 13:15:38 quinn
|
---|
82 | * Simple
|
---|
83 | *
|
---|
84 | * Revision 1.7 1994/10/05 10:16:11 quinn
|
---|
85 | * Added xrealloc. Fixed bug in log.
|
---|
86 | *
|
---|
87 | * Revision 1.6 1994/10/04 14:02:19 quinn
|
---|
88 | * Fixed log_init
|
---|
89 | *
|
---|
90 | * Revision 1.5 1994/09/28 13:07:41 adam
|
---|
91 | * Implemented log_mask_str.
|
---|
92 | *
|
---|
93 | * Revision 1.4 1994/09/27 20:04:13 quinn
|
---|
94 | * Added fflush.
|
---|
95 | *
|
---|
96 | * Revision 1.3 1994/08/18 08:18:48 quinn
|
---|
97 | * Added prefix to log_init.
|
---|
98 | *
|
---|
99 | * Revision 1.2 1994/08/17 14:27:53 quinn
|
---|
100 | * added LOG_ERRNO
|
---|
101 | *
|
---|
102 | * Revision 1.1 1994/08/17 13:23:15 quinn
|
---|
103 | * First version
|
---|
104 | * Added log.c
|
---|
105 | *
|
---|
106 | */
|
---|
107 |
|
---|
108 | #if HAVE_CONFIG_H
|
---|
109 | #include <config.h>
|
---|
110 | #endif
|
---|
111 |
|
---|
112 | #include <stdio.h>
|
---|
113 | #include <stdlib.h>
|
---|
114 | #include <ctype.h>
|
---|
115 | #include <string.h>
|
---|
116 | #include <stdarg.h>
|
---|
117 | #include <errno.h>
|
---|
118 | #include <time.h>
|
---|
119 | #include <yaz/log.h>
|
---|
120 |
|
---|
121 | #define HAS_STRERROR 1
|
---|
122 |
|
---|
123 | #if HAS_STRERROR
|
---|
124 |
|
---|
125 | #else
|
---|
126 | char *strerror(int n)
|
---|
127 | {
|
---|
128 | extern char *sys_errlist[];
|
---|
129 | return sys_errlist[n];
|
---|
130 | }
|
---|
131 |
|
---|
132 | #endif
|
---|
133 |
|
---|
134 | static int l_level = LOG_DEFAULT_LEVEL;
|
---|
135 | static FILE *l_file = NULL;
|
---|
136 | static char l_prefix[512] = "log";
|
---|
137 |
|
---|
138 | static struct {
|
---|
139 | int mask;
|
---|
140 | char *name;
|
---|
141 | } mask_names[] =
|
---|
142 | {
|
---|
143 | { LOG_FATAL, "fatal"},
|
---|
144 | { LOG_DEBUG, "debug"},
|
---|
145 | { LOG_WARN, "warn" },
|
---|
146 | { LOG_LOG, "log" },
|
---|
147 | { LOG_ERRNO, ""},
|
---|
148 | { LOG_ALL, "all" },
|
---|
149 | { 0, "none" },
|
---|
150 | { 0, NULL }
|
---|
151 | };
|
---|
152 |
|
---|
153 | FILE *log_file(void)
|
---|
154 | {
|
---|
155 | if (!l_file)
|
---|
156 | l_file = stderr;
|
---|
157 | return l_file;
|
---|
158 | }
|
---|
159 |
|
---|
160 | void log_init_file (const char *fname)
|
---|
161 | {
|
---|
162 | FILE *new_file;
|
---|
163 | if (!l_file)
|
---|
164 | l_file = stderr;
|
---|
165 | if (!fname || !*fname)
|
---|
166 | return;
|
---|
167 | if (!(new_file = fopen(fname, "a")))
|
---|
168 | return;
|
---|
169 | if (l_file != stderr)
|
---|
170 | {
|
---|
171 | fclose (l_file);
|
---|
172 | }
|
---|
173 | setvbuf(new_file, 0, _IONBF, 0);
|
---|
174 | l_file = new_file;
|
---|
175 | }
|
---|
176 |
|
---|
177 | void log_init_level (int level)
|
---|
178 | {
|
---|
179 | l_level = level;
|
---|
180 | }
|
---|
181 |
|
---|
182 | void log_init_prefix (const char *prefix)
|
---|
183 | {
|
---|
184 | if (prefix && *prefix)
|
---|
185 | sprintf(l_prefix, "%.512s", prefix);
|
---|
186 | }
|
---|
187 |
|
---|
188 | void log_init(int level, const char *prefix, const char *fname)
|
---|
189 | {
|
---|
190 | log_init_level (level);
|
---|
191 | log_init_prefix (prefix);
|
---|
192 | log_init_file (fname);
|
---|
193 | }
|
---|
194 |
|
---|
195 | static void (*start_hook_func)(int, const char *, void *) = NULL;
|
---|
196 | static void *start_hook_info;
|
---|
197 | static void (*end_hook_func)(int, const char *, void *) = NULL;
|
---|
198 | static void *end_hook_info;
|
---|
199 |
|
---|
200 | void log_event_start (void (*func)(int, const char *, void *), void *info)
|
---|
201 | {
|
---|
202 | start_hook_func = func;
|
---|
203 | start_hook_info = info;
|
---|
204 | }
|
---|
205 |
|
---|
206 | void log_event_end (void (*func)(int, const char *, void *), void *info)
|
---|
207 | {
|
---|
208 | end_hook_func = func;
|
---|
209 | end_hook_info = info;
|
---|
210 | }
|
---|
211 |
|
---|
212 | void yaz_log(int level, const char *fmt, ...)
|
---|
213 | {
|
---|
214 | va_list ap;
|
---|
215 | char buf[4096], flags[1024];
|
---|
216 | int i;
|
---|
217 | time_t ti;
|
---|
218 | struct tm *tim;
|
---|
219 | char tbuf[50];
|
---|
220 | int o_level = level;
|
---|
221 |
|
---|
222 | if (!(level & l_level))
|
---|
223 | return;
|
---|
224 | if (!l_file)
|
---|
225 | l_file = stderr;
|
---|
226 | *flags = '\0';
|
---|
227 | for (i = 0; level && mask_names[i].name; i++)
|
---|
228 | if (mask_names[i].mask & level)
|
---|
229 | {
|
---|
230 | if (*mask_names[i].name)
|
---|
231 | sprintf(flags + strlen(flags), "[%s]", mask_names[i].name);
|
---|
232 | level -= mask_names[i].mask;
|
---|
233 | }
|
---|
234 | va_start(ap, fmt);
|
---|
235 | vsprintf(buf, fmt, ap);
|
---|
236 | if (o_level & LOG_ERRNO)
|
---|
237 | sprintf(buf + strlen(buf), " [%s]", strerror(errno));
|
---|
238 | if (start_hook_func)
|
---|
239 | (*start_hook_func)(o_level, buf, start_hook_info);
|
---|
240 | ti = time(0);
|
---|
241 | tim = localtime(&ti);
|
---|
242 | strftime(tbuf, 50, "%H:%M:%S-%d/%m", tim);
|
---|
243 | fprintf(l_file, "%s: %s: %s %s\n", tbuf, l_prefix, flags, buf);
|
---|
244 | fflush(l_file);
|
---|
245 | if (end_hook_func)
|
---|
246 | (*end_hook_func)(o_level, buf, end_hook_info);
|
---|
247 | }
|
---|
248 |
|
---|
249 | int log_mask_str (const char *str)
|
---|
250 | {
|
---|
251 | return log_mask_str_x (str, LOG_DEFAULT_LEVEL);
|
---|
252 | }
|
---|
253 |
|
---|
254 | int log_mask_str_x (const char *str, int level)
|
---|
255 | {
|
---|
256 | const char *p;
|
---|
257 | int i;
|
---|
258 |
|
---|
259 | while (*str)
|
---|
260 | {
|
---|
261 | for (p = str; *p && *p != ','; p++)
|
---|
262 | ;
|
---|
263 | if (*str == '-' || isdigit(*str))
|
---|
264 | level = atoi (str);
|
---|
265 | else
|
---|
266 | for (i = 0; mask_names[i].name; i++)
|
---|
267 | if (strlen (mask_names[i].name) == (size_t) (p-str) &&
|
---|
268 | memcmp (mask_names[i].name, str, p-str) == 0)
|
---|
269 | {
|
---|
270 | if (mask_names[i].mask)
|
---|
271 | level |= mask_names[i].mask;
|
---|
272 | else
|
---|
273 | level = 0;
|
---|
274 | }
|
---|
275 | if (*p == ',')
|
---|
276 | p++;
|
---|
277 | str = p;
|
---|
278 | }
|
---|
279 | return level;
|
---|
280 | }
|
---|