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