1 /*
2  * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
3  * All rights reserved
4  *
5  * "THE BEER-WARE LICENSE" (Revision 42):
6  * Sergey Lyubka wrote this file.  As long as you retain this notice you
7  * can do whatever you want with this stuff. If we meet some day, and you think
8  * this stuff is worth it, you can buy me a beer in return.
9  */
10 
11 #include "defs.h"
12 
13 /*
14  * Log function
15  */
16 void
_shttpd_elog(int flags,struct conn * c,const char * fmt,...)17 _shttpd_elog(int flags, struct conn *c, const char *fmt, ...)
18 {
19 	char	date[64], buf[URI_MAX];
20 	int	len;
21 	FILE	*fp = c == NULL ? NULL : c->ctx->error_log;
22 	va_list	ap;
23 
24 	/* Print to stderr */
25 	if (c == NULL || !IS_TRUE(c->ctx, OPT_INETD)) {
26 		va_start(ap, fmt);
27 		(void) vfprintf(stderr, fmt, ap);
28 		(void) fputc('\n', stderr);
29 		va_end(ap);
30 	}
31 
32 	strftime(date, sizeof(date), "%a %b %d %H:%M:%S %Y",
33 	    localtime(&_shttpd_current_time));
34 
35 	len = _shttpd_snprintf(buf, sizeof(buf),
36 	    "[%s] [error] [client %s] \"%s\" ",
37 	    date, c ? inet_ntoa(c->sa.u.sin.sin_addr) : "-",
38 	    c && c->request ? c->request : "-");
39 
40 	va_start(ap, fmt);
41 	(void) vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
42 	va_end(ap);
43 
44 	buf[sizeof(buf) - 1] = '\0';
45 
46 	if (fp != NULL && (flags & (E_FATAL | E_LOG))) {
47 		(void) fprintf(fp, "%s\n", buf);
48 		(void) fflush(fp);
49 	}
50 
51 	if (flags & E_FATAL)
52 		exit(EXIT_FAILURE);
53 }
54 
55 void
_shttpd_log_access(FILE * fp,const struct conn * c)56 _shttpd_log_access(FILE *fp, const struct conn *c)
57 {
58 	static const struct vec	dash = {"-", 1};
59 
60 	const struct vec	*user = &c->ch.user.v_vec;
61 	const struct vec	*referer = &c->ch.referer.v_vec;
62 	const struct vec	*user_agent = &c->ch.useragent.v_vec;
63 	char			date[64], buf[URI_MAX], *q1 = "\"", *q2 = "\"";
64 
65 	if (user->len == 0)
66 		user = &dash;
67 
68 	if (referer->len == 0) {
69 		referer = &dash;
70 		q1 = "";
71 	}
72 
73 	if (user_agent->len == 0) {
74 		user_agent = &dash;
75 		q2 = "";
76 	}
77 
78 	(void) strftime(date, sizeof(date), "%d/%b/%Y:%H:%M:%S",
79 			localtime(&c->birth_time));
80 
81 	(void) _shttpd_snprintf(buf, sizeof(buf),
82 	    "%s - %.*s [%s %+05d] \"%s\" %d %lu %s%.*s%s %s%.*s%s",
83 	    inet_ntoa(c->sa.u.sin.sin_addr), user->len, user->ptr,
84 	    date, _shttpd_tz_offset, c->request ? c->request : "-",
85 	    c->status, (unsigned long) c->loc.io.total,
86 	    q1, referer->len, referer->ptr, q1,
87 	    q2, user_agent->len, user_agent->ptr, q2);
88 
89 	if (fp != NULL) {
90 		(void) fprintf(fp, "%s\n", buf);
91 		(void) fflush(fp);
92 	}
93 }
94