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