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