1 /* Copyright (C) 2000-2015 Lavtech.com corp. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18 #include "udm_config.h"
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <sys/types.h>
25
26 #include "udm_common.h"
27 #include "udm_utils.h"
28 #include "udm_vars.h"
29 #include "udm_log.h"
30
31
32 UDM_API(void)
UdmSetRefProc(UDM_ENV * Conf,void (* _RefProc)(int code,const char * url,const char * ref))33 UdmSetRefProc(UDM_ENV * Conf,
34 void (*_RefProc)(int code,const char *url, const char *ref))
35 {
36 Conf->RefInfo= _RefProc;
37 }
38
39 UDM_API(void)
UdmSetThreadProc(UDM_ENV * Conf,void (* _ThreadInfo)(UDM_AGENT * A,const char * state,const char * str))40 UdmSetThreadProc(UDM_ENV * Conf,
41 void (*_ThreadInfo)(UDM_AGENT *A,const char *state, const char* str))
42 {
43 Conf->ThreadInfo=_ThreadInfo;
44 }
45
46
47 UDM_API(void)
UdmShowThreadInfo(UDM_AGENT * A,const char * state,const char * str)48 UdmShowThreadInfo(UDM_AGENT *A, const char *state, const char *str)
49 {
50 if (A->Conf->ThreadInfo)
51 A->Conf->ThreadInfo(A, state, str);
52 }
53
54
55 typedef struct _code
56 {
57 const char *c_name;
58 int c_val;
59 } CODE;
60
61
62 #if defined HAVE_SYSLOG_H && defined USE_SYSLOG
63 static const CODE facilitynames[]={
64 #ifdef LOG_AUTH
65 {"auth", LOG_AUTH},
66 #endif
67 #ifdef LOG_AUTHPRIV
68 {"authpriv", LOG_AUTHPRIV},
69 #endif
70 #ifdef LOG_CRON
71 {"cron", LOG_CRON},
72 #endif
73 #ifdef LOG_DAEMON
74 {"daemon", LOG_DAEMON},
75 #endif
76 #ifdef LOG_FTP
77 {"ftp", LOG_FTP},
78 #endif
79 #ifdef LOG_KERN
80 {"kern", LOG_KERN},
81 #endif
82 #ifdef LOG_LPR
83 {"lpr", LOG_LPR},
84 #endif
85 #ifdef LOG_MAIL
86 {"mail", LOG_MAIL},
87 #endif
88 #ifdef LOG_NEWS
89 {"news", LOG_NEWS},
90 #endif
91 #ifdef LOG_SYSLOG
92 {"syslog", LOG_SYSLOG},
93 #endif
94 #ifdef LOG_USER
95 {"user", LOG_USER},
96 #endif
97 #ifdef LOG_UUCP
98 {"uucp", LOG_UUCP},
99 #endif
100 #ifdef LOG_LOCAL0
101 {"local0", LOG_LOCAL0},
102 #endif
103 #ifdef LOG_LOCAL1
104 {"local1", LOG_LOCAL1},
105 #endif
106 #ifdef LOG_LOCAL2
107 {"local2", LOG_LOCAL2},
108 #endif
109 #ifdef LOG_LOCAL3
110 {"local3", LOG_LOCAL3},
111 #endif
112 #ifdef LOG_LOCAL4
113 {"local4", LOG_LOCAL4},
114 #endif
115 #ifdef LOG_LOCAL5
116 {"local5", LOG_LOCAL5},
117 #endif
118 #ifdef LOG_LOCAL6
119 {"local6", LOG_LOCAL6},
120 #endif
121 #ifdef LOG_LOCAL7
122 {"local7", LOG_LOCAL7},
123 #endif
124 {"none", UDM_LOG_FACILITY_NONE},
125 {NULL, 0},
126 };
127
128
129 #define UDM_LOG_FACILITY_DEFAULT UDM_LOG_FACILITY_NONE
130
131 static int
syslog_facility(const char * f)132 syslog_facility(const char *f)
133 {
134 const CODE *fn= facilitynames;
135 if (!f || !f[0])
136 return UDM_LOG_FACILITY_DEFAULT;
137 while (fn->c_name != NULL)
138 {
139 if (strcasecmp(f, fn->c_name) == 0)
140 return fn->c_val;
141 fn++;
142 }
143 fprintf(stderr, "Config file error: unknown facility given: '%s'\n\r", f);
144 fprintf(stderr, "Will continue with default facility\n\r");
145 return UDM_LOG_FACILITY_DEFAULT;
146 }
147
148 #endif /* HAVE_SYSLOG_H */
149
150
151 UDM_API(void)
UdmEnvSetLogLevel(UDM_ENV * Env,int level)152 UdmEnvSetLogLevel(UDM_ENV *Env, int level)
153 {
154 Env->Log.level= level;
155 }
156
157
158 UDM_API(void)
UdmEnvIncLogLevel(UDM_ENV * Env)159 UdmEnvIncLogLevel(UDM_ENV *Env)
160 {
161 if (Env->Log.level < UDM_LOG_DEBUG)
162 Env->Log.level++;
163 }
164
165
166 UDM_API(void)
UdmEnvDecLogLevel(UDM_ENV * Env)167 UdmEnvDecLogLevel(UDM_ENV *Env)
168 {
169 if (Env->Log.level > 0)
170 Env->Log.level--;
171 }
172
173
174 int
UdmOpenLog(const char * appname,UDM_ENV * Env,int log2stderr)175 UdmOpenLog(const char * appname,UDM_ENV *Env, int log2stderr)
176 {
177 #if defined HAVE_SYSLOG_H && defined USE_SYSLOG
178 int openlog_flag= LOG_PID;
179
180 Env->Log.flags= UdmVarListFindInt(&Env->Vars, "LogFlags", 0);
181 Env->Log.facility= syslog_facility(UdmVarListFindStr(&Env->Vars,"SyslogFacility",""));
182
183 #ifdef LOG_PERROR
184 /* LOG_PERROR supported by 4.3BSD Reno releases and later */
185 if (log2stderr)
186 {
187 if (Env->Log.facility != UDM_LOG_FACILITY_NONE)
188 {
189 openlog_flag|= LOG_PERROR;
190 log2stderr= 0;
191 }
192 }
193 #endif
194
195 if (Env->Log.facility != UDM_LOG_FACILITY_NONE)
196 openlog(appname ? appname : "<NULL>", openlog_flag, Env->Log.facility);
197
198
199 #endif /* HAVE_SYSLOG_H */
200
201 if (log2stderr)
202 Env->Log.logFD= stderr;
203
204 Env->Log.is_log_open= 1;
205 return 0;
206 }
207
208
209 UDM_API(int)
UdmNeedLog(const UDM_ENV * Env,int level)210 UdmNeedLog(const UDM_ENV *Env, int level)
211 {
212 if (Env->Log.level < level)
213 return 0;
214 return 1;
215 }
216
217
218 static int
udm_logger(UDM_ENV * Env,int handle,int level,const char * fmt,va_list ap)219 udm_logger(UDM_ENV *Env, int handle, int level, const char *fmt, va_list ap)
220 {
221 char buf[UDM_LOG_BUF_LEN + 1];
222 size_t maxlen= sizeof(buf) - 4; /* for "...\0" */
223 int i= 0;
224
225 if (!Env->Log.is_log_open)
226 UdmOpenLog("search.cgi", Env, Env->Log.logFD != NULL);
227
228 strcpy(buf + maxlen, "...");
229 if (!(Env->Log.flags & UDM_LOG_FLAG_SKIP_PID))
230 {
231 if (handle)
232 i= snprintf(buf, maxlen, "[%d]{%02d} ", (int) getpid(), handle);
233 else
234 i= snprintf(buf, maxlen,"[%d]{--} ", (int) getpid());
235 }
236 if (i < 0) /* Extra safety */
237 i= 0;
238 maxlen-= (size_t) i;
239
240 #ifdef WIN32
241 _vsnprintf(buf + i, maxlen, fmt, ap);
242 if(Env->ThreadInfo)
243 Env->ThreadInfo(0,"",buf);
244 else
245 printf("%s\n",buf);
246 #else
247 vsnprintf(buf + i, maxlen, fmt, ap);
248 #endif
249
250 #if defined HAVE_SYSLOG_H && defined USE_SYSLOG
251 if (Env->Log.facility != UDM_LOG_FACILITY_NONE)
252 syslog((level != UDM_LOG_ERROR) ? LOG_INFO : LOG_ERR, "%s", buf);
253 #endif
254 if (Env->Log.logFD)
255 fprintf(Env->Log.logFD,"%s\n",buf);
256 return 1;
257 }
258
259
260 void
UdmLog(UDM_AGENT * Agent,int level,const char * fmt,...)261 UdmLog(UDM_AGENT *Agent, int level, const char *fmt, ...)
262 {
263 UDM_GETLOCK(Agent, UDM_LOCK_LOG);
264 if (UdmNeedLog(Agent->Conf, level))
265 {
266 va_list ap;
267 va_start(ap,fmt);
268 udm_logger(Agent->Conf, Agent->handle,level,fmt,ap);
269 va_end(ap);
270 }
271 UDM_RELEASELOCK(Agent, UDM_LOCK_LOG);
272 return;
273 }
274
275
276 void
UdmEnvLog(UDM_ENV * Env,int level,const char * fmt,...)277 UdmEnvLog(UDM_ENV * Env, int level, const char *fmt, ...)
278 {
279 va_list ap;
280 if (UdmNeedLog(Env, level))
281 {
282 va_start(ap,fmt);
283 udm_logger(Env, 0, level, fmt, ap);
284 va_end(ap);
285 }
286 return;
287 }
288