Line data Source code
1 : #include "burp.h"
2 : #include "alloc.h"
3 : #include "asfd.h"
4 : #include "async.h"
5 : #include "cmd.h"
6 : #include "cntr.h"
7 : #include "iobuf.h"
8 : #include "log.h"
9 : #include "strlist.h"
10 :
11 : const char *prog="unknown";
12 : const char *prog_long="unknown";
13 :
14 : static struct fzp *logfzp=NULL;
15 : // Start with all logging on, so that something is said when initial startup
16 : // goes wrong - for example, reading the conf file.
17 : static int do_syslog=1;
18 : static int do_stdout=1;
19 : static int do_progress_counter=1;
20 : static int force_quiet=0;
21 : static int syslog_opened=0;
22 : static int json=0;
23 :
24 0 : void log_init(char *progname)
25 : {
26 0 : prog_long=progname;
27 0 : if((prog=strrchr(progname, '/'))) prog++;
28 0 : else prog=progname;
29 0 : }
30 :
31 : #ifndef UTEST
32 : static char *gettm(void)
33 : {
34 : time_t t=0;
35 : const struct tm *ctm=NULL;
36 : static char tmbuf[32]="";
37 :
38 : time(&t);
39 : ctm=localtime(&t);
40 : // Windows does not like the %T strftime format option - you get
41 : // complaints under gdb.
42 : strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%d %H:%M:%S", ctm);
43 : return tmbuf;
44 : }
45 : #endif
46 :
47 1151 : void logp(const char *fmt, ...)
48 : {
49 : #ifndef UTEST
50 : int pid;
51 : char buf[512]="";
52 : va_list ap;
53 : va_start(ap, fmt);
54 : vsnprintf(buf, sizeof(buf), fmt, ap);
55 : pid=(int)getpid();
56 : if(logfzp)
57 : fzp_printf(logfzp, "%s: %s[%d] %s", gettm(), prog, pid, buf);
58 : else
59 : {
60 : if(do_syslog)
61 : syslog(LOG_INFO, "%s", buf);
62 : if(do_stdout)
63 : {
64 : if(json)
65 : {
66 : char *cp;
67 : // To help programs parsing the monitor output,
68 : // log things with simple JSON.
69 : // So do simple character substitution to have
70 : // a better chance of valid JSON.
71 : for(cp=buf; *cp; cp++)
72 : {
73 : if(*cp=='"')
74 : *cp='\'';
75 : else if(!isprint(*cp))
76 : *cp='.';
77 : }
78 : fprintf(stdout, "{ \"logline\": \"%s\" }\n", buf);
79 : }
80 : else
81 : fprintf(stdout, "%s: %s[%d] %s",
82 : gettm(), prog, pid, buf);
83 : }
84 : }
85 : va_end(ap);
86 : #endif
87 1151 : }
88 :
89 0 : void logp_ssl_err(const char *fmt, ...)
90 : {
91 0 : char buf[512]="";
92 : va_list ap;
93 0 : va_start(ap, fmt);
94 : vsnprintf(buf, sizeof(buf), fmt, ap);
95 0 : va_end(ap);
96 : logp("%s", buf);
97 0 : if(logfzp) fzp_ERR_print_errors_fp(logfzp);
98 : else
99 : {
100 0 : if(do_syslog)
101 : {
102 : // FIX THIS: How to send to syslog?
103 : static BIO *bio_err=NULL;
104 0 : if(!bio_err) bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
105 0 : ERR_print_errors(bio_err);
106 : }
107 0 : if(do_stdout)
108 : {
109 0 : if(!json)
110 : {
111 : static BIO *bio_err=NULL;
112 0 : if(!bio_err) bio_err=BIO_new_fp(stdout,
113 : BIO_NOCLOSE);
114 0 : ERR_print_errors(bio_err);
115 : }
116 : }
117 : }
118 0 : }
119 :
120 : // For the counters.
121 0 : void logc(const char *fmt, ...)
122 : {
123 0 : char buf[512]="";
124 : va_list ap;
125 0 : va_start(ap, fmt);
126 : vsnprintf(buf, sizeof(buf), fmt, ap);
127 0 : if(logfzp)
128 0 : fzp_printf(logfzp, "%s", buf); // for the server side
129 : else
130 : {
131 0 : if(do_progress_counter
132 0 : && do_stdout)
133 0 : fprintf(stdout, "%s", buf);
134 : }
135 0 : va_end(ap);
136 0 : }
137 :
138 96 : void logfmt(const char *fmt, ...)
139 : {
140 : #ifndef UTEST
141 : if(do_stdout)
142 : {
143 : char buf[512]="";
144 : va_list ap;
145 : va_start(ap, fmt);
146 : vsnprintf(buf, sizeof(buf), fmt, ap);
147 : fprintf(stdout, "%s", buf);
148 : }
149 : #endif
150 96 : }
151 :
152 101 : const char *progname(void)
153 : {
154 101 : return prog;
155 : }
156 :
157 18 : int log_fzp_set(const char *path, struct conf **confs)
158 : {
159 18 : fzp_close(&logfzp);
160 18 : if(path)
161 : {
162 : logp("Logging to %s\n", path);
163 9 : if(!(logfzp=fzp_open(path, "ab"))) return -1;
164 : }
165 18 : if(logfzp) fzp_setlinebuf(logfzp);
166 18 : do_syslog=get_int(confs[OPT_SYSLOG]);
167 18 : if(force_quiet)
168 : {
169 0 : do_stdout=0;
170 0 : do_progress_counter=0;
171 : }
172 : else
173 : {
174 18 : do_stdout=get_int(confs[OPT_STDOUT]);
175 18 : do_progress_counter=get_int(confs[OPT_PROGRESS_COUNTER]);
176 : }
177 :
178 18 : if(syslog_opened)
179 : {
180 0 : closelog();
181 0 : syslog_opened=0;
182 : }
183 18 : if(do_syslog)
184 : {
185 0 : openlog(prog, LOG_PID, LOG_USER);
186 0 : syslog_opened++;
187 : }
188 : return 0;
189 : }
190 :
191 0 : void log_force_quiet(void)
192 : {
193 0 : force_quiet=1;
194 0 : }
195 :
196 0 : void log_fzp_set_direct(struct fzp *fzp)
197 : {
198 0 : fzp_close(&logfzp);
199 0 : logfzp=fzp;
200 0 : }
201 :
202 1 : void log_out_of_memory(const char *function)
203 : {
204 : if(function) logp("out of memory in %s()\n", function);
205 : else logp("out of memory in unknown function\n");
206 1 : }
207 :
208 8 : void log_restore_settings(struct conf **cconfs, int srestore)
209 : {
210 : struct strlist *l;
211 : logp("Restore settings:\n");
212 8 : if(get_string(cconfs[OPT_ORIG_CLIENT]))
213 1 : logp("orig_client = '%s'\n",
214 : get_string(cconfs[OPT_ORIG_CLIENT]));
215 8 : if(get_string(cconfs[OPT_BACKUP]))
216 8 : logp("backup = '%s'\n",
217 : get_string(cconfs[OPT_BACKUP]));
218 8 : if(srestore)
219 : {
220 : // This are unknown unless doing a server initiated restore.
221 2 : logp("overwrite = %d\n", get_int(cconfs[OPT_OVERWRITE]));
222 2 : logp("strip = %d\n", get_int(cconfs[OPT_STRIP]));
223 : }
224 8 : if(get_string(cconfs[OPT_RESTOREPREFIX]))
225 0 : logp("restoreprefix = '%s'\n",
226 : get_string(cconfs[OPT_RESTOREPREFIX]));
227 8 : if(get_string(cconfs[OPT_STRIP_FROM_PATH]))
228 0 : logp("stripfrompath = '%s'\n",
229 : get_string(cconfs[OPT_STRIP_FROM_PATH]));
230 8 : if(get_string(cconfs[OPT_REGEX]))
231 0 : logp("regex = '%s'\n", get_string(cconfs[OPT_REGEX]));
232 11 : for(l=get_strlist(cconfs[OPT_INCLUDE]); l; l=l->next)
233 3 : logp("include = '%s'\n", l->path);
234 8 : }
235 :
236 0 : int logm(struct asfd *asfd, struct conf **confs, const char *fmt, ...)
237 : {
238 0 : int r=0;
239 0 : char buf[512]="";
240 : va_list ap;
241 0 : va_start(ap, fmt);
242 : vsnprintf(buf, sizeof(buf), fmt, ap);
243 0 : if(asfd && asfd->as->doing_estimate) printf("\nMESSAGE: %s", buf);
244 : else
245 : {
246 0 : if(asfd
247 0 : && get_int(confs[OPT_MESSAGE])) // Backwards compatibility
248 0 : r=asfd->write_str(asfd, CMD_MESSAGE, buf);
249 : logp("MESSAGE: %s", buf);
250 : }
251 0 : va_end(ap);
252 0 : if(confs) cntr_add(get_cntr(confs), CMD_MESSAGE, 1);
253 0 : return r;
254 : }
255 :
256 13 : int logw(struct asfd *asfd, struct cntr *cntr, const char *fmt, ...)
257 : {
258 13 : int r=0;
259 13 : char buf[512]="";
260 : va_list ap;
261 13 : va_start(ap, fmt);
262 : vsnprintf(buf, sizeof(buf), fmt, ap);
263 13 : if(asfd
264 10 : && asfd->as
265 3 : && asfd->as->doing_estimate) printf("\nWARNING: %s", buf);
266 : else
267 : {
268 13 : if(asfd) r=asfd->write_str(asfd, CMD_WARNING, buf);
269 : logp("WARNING: %s", buf);
270 : }
271 13 : va_end(ap);
272 13 : cntr_add(cntr, CMD_WARNING, 1);
273 13 : return r;
274 : }
275 :
276 10 : void log_and_send(struct asfd *asfd, const char *msg)
277 : {
278 : logp("%s\n", msg);
279 10 : if(asfd)
280 10 : asfd->write_str(asfd, CMD_ERROR, msg);
281 10 : }
282 :
283 0 : void log_and_send_oom(struct asfd *asfd)
284 : {
285 0 : char m[256]="";
286 : snprintf(m, sizeof(m), "out of memory in %s()\n", __func__);
287 : logp("%s", m);
288 0 : if(asfd)
289 0 : asfd->write_str(asfd, CMD_ERROR, m);
290 0 : }
291 :
292 0 : void log_set_json(int value)
293 : {
294 0 : json=value;
295 0 : }
296 :
297 10 : void log_oom_w(const char *func, const char *orig_func)
298 : {
299 : logp("out of memory in %s, called from %s\n", func, orig_func);
300 10 : }
301 :
302 0 : int log_incexcs_buf(const char *incexc)
303 : {
304 0 : char *tok=NULL;
305 0 : char *copy=NULL;
306 0 : if(!incexc || !*incexc) return 0;
307 0 : if(!(copy=strdup_w(incexc, __func__)))
308 : return -1;
309 0 : if(!(tok=strtok(copy, "\n")))
310 : {
311 : logp("unable to parse server incexc\n");
312 0 : free_w(©);
313 0 : return -1;
314 : }
315 : do
316 : {
317 : logp("%s\n", tok);
318 0 : } while((tok=strtok(NULL, "\n")));
319 0 : free_w(©);
320 0 : return 0;
321 : }
322 :
323 8 : void log_recvd(struct iobuf *iobuf, struct cntr *cntr, int print)
324 : {
325 8 : const char *prefix="unset";
326 8 : switch(iobuf->cmd)
327 : {
328 : case CMD_MESSAGE: prefix="MESSAGE"; break;
329 : case CMD_WARNING: prefix="WARNING"; break;
330 : default: break;
331 : }
332 8 : logp("%s: %s", prefix, iobuf->buf);
333 8 : cntr_add(cntr, iobuf->cmd, print);
334 8 : }
|