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