76eaf1b36b42884fb6cd3e71346161fd0b0369dd
[yaz-moved-to-github.git] / util / log.c
1 /*
2  * Copyright (c) 1995, Index Data
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: log.c,v $
7  * Revision 1.8  1995-09-27 15:03:02  quinn
8  * Modified function heads & prototypes.
9  *
10  * Revision 1.7  1995/06/19  12:40:18  quinn
11  * Added log_file()
12  *
13  * Revision 1.6  1995/06/15  15:45:03  quinn
14  * Added date info.
15  *
16  * Revision 1.5  1995/05/16  08:51:11  quinn
17  * License, documentation, and memory fixes
18  *
19  * Revision 1.4  1995/05/15  11:56:55  quinn
20  * Debuggng & adjustments.
21  *
22  * Revision 1.3  1995/04/10  10:23:51  quinn
23  * Fixes.
24  *
25  * Revision 1.2  1995/03/31  10:16:55  quinn
26  * Fixed logging.
27  *
28  * Revision 1.1  1995/03/30  10:26:53  quinn
29  * Logging system
30  *
31  * Revision 1.9  1994/12/12  12:09:02  quinn
32  * Changes
33  *
34  * Revision 1.8  1994/11/22  13:15:38  quinn
35  * Simple
36  *
37  * Revision 1.7  1994/10/05  10:16:11  quinn
38  * Added xrealloc. Fixed bug in log.
39  *
40  * Revision 1.6  1994/10/04  14:02:19  quinn
41  * Fixed log_init
42  *
43  * Revision 1.5  1994/09/28  13:07:41  adam
44  * Implemented log_mask_str.
45  *
46  * Revision 1.4  1994/09/27  20:04:13  quinn
47  * Added fflush.
48  *
49  * Revision 1.3  1994/08/18  08:18:48  quinn
50  * Added prefix to log_init.
51  *
52  * Revision 1.2  1994/08/17  14:27:53  quinn
53  * added LOG_ERRNO
54  *
55  * Revision 1.1  1994/08/17  13:23:15  quinn
56  * First version
57  * Added log.c
58  *
59  */
60
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <ctype.h>
64 #include <stdarg.h>
65 #include <errno.h>
66 #include <time.h>
67 #include <log.h>
68
69 static int l_level = LOG_DEFAULT_LEVEL;
70 static FILE *l_file = stderr;
71 static char l_prefix[30] = "log";
72
73 static struct {
74     int mask;
75     char *name;
76 } mask_names[] =
77 {
78     { LOG_FATAL, "fatal"},
79     { LOG_DEBUG, "debug"},
80     { LOG_WARN,  "warn" },
81     { LOG_LOG,   "log"  },
82     { LOG_ERRNO, ""},
83     { LOG_ALL,   "all"  },
84     { 0,         "none" },
85     { 0, NULL }
86 };  
87
88 #ifndef strerror
89
90 char *strerror(int n)
91 {
92         extern char *sys_errlist[];
93         return sys_errlist[n];
94 }
95
96 #endif
97
98 FILE MDF *log_file(void)
99 {
100     return l_file;
101 }
102
103 void MDF log_init(int level, const char *prefix, const char *name)
104 {
105     l_level = level;
106     if (prefix && *prefix)
107         strcpy(l_prefix, prefix);
108     if (!name || !*name || l_file != stderr)
109         return;
110     if (!(l_file = fopen(name, "a")))
111         return;
112     setvbuf(l_file, 0, _IONBF, 0);
113 }
114
115 void MDF logf(int level, const char *fmt, ...)
116 {
117     va_list ap;
118     char buf[4096], flags[1024];
119     int i, p_error = 0;
120     time_t ti;
121     struct tm *tim;
122     char tbuf[50];
123
124     if (!(level & l_level))
125         return;
126     if (level & LOG_ERRNO)
127         p_error = 1;
128     *flags = '\0';
129     for (i = 0; level && mask_names[i].name; i++)
130         if (mask_names[i].mask & level)
131         {
132             if (*mask_names[i].name)
133                 sprintf(flags + strlen(flags), "[%s]", mask_names[i].name);
134             level -= mask_names[i].mask;
135         }
136     va_start(ap, fmt);
137     vsprintf(buf, fmt, ap);
138     if (p_error)
139         sprintf(buf + strlen(buf), " [%s]", strerror(errno));
140     ti = time(0);
141     tim = localtime(&ti);
142     strftime(tbuf, 50, "%H:%M:%S-%d/%m", tim);
143     fprintf(l_file, "%s: %s: %s %s\n", tbuf, l_prefix, flags, buf);
144     fflush(l_file);
145 }
146
147 int MDF log_mask_str (const char *str)
148 {
149     const char *p;
150     int i, level = LOG_DEFAULT_LEVEL;
151
152     while (*str)
153     {
154         for (p = str; *p && *p != ','; p++)
155             ;
156         if (*str == '-' || isdigit(*str))
157             level = atoi (str);
158         else
159             for (i = 0; mask_names[i].name; i++)
160                 if (strlen (mask_names[i].name) == p-str &&
161                     memcmp (mask_names[i].name, str, p-str) == 0)
162                 {
163                     if (mask_names[i].mask)
164                         level |= mask_names[i].mask;
165                     else
166                         level = 0;
167                 }
168         if (*p == ',')
169             p++;
170         str = p;
171     }
172     return level;
173 }