4b436106781f1a4868df414df02ccc1770ed3b01
[fms.git] / libs / shttpd / log.c
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
17 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 || c->ctx->inetd_mode == 0) {
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(&current_time));
34
35         len = my_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 defined(_WIN32) && !defined(NO_GUI)
52         {
53                 extern HWND     hLog;
54
55                 if (hLog != NULL)
56                         SendMessage(hLog, WM_APP, 0, (LPARAM) buf);
57         }
58 #endif /* _WIN32 */
59
60         if (flags & E_FATAL)
61                 exit(EXIT_FAILURE);
62 }
63
64 void
65 log_access(FILE *fp, const struct conn *c)
66 {
67         static const struct vec dash = {"-", 1};
68
69         const struct vec        *user = &c->ch.user.v_vec;
70         const struct vec        *referer = &c->ch.referer.v_vec;
71         const struct vec        *user_agent = &c->ch.useragent.v_vec;
72         char                    date[64], buf[URI_MAX], *q1 = "\"", *q2 = "\"";
73
74         if (user->len == 0)
75                 user = &dash;
76
77         if (referer->len == 0) {
78                 referer = &dash;
79                 q1 = "";
80         }
81
82         if (user_agent->len == 0) {
83                 user_agent = &dash;
84                 q2 = "";
85         }
86
87         (void) strftime(date, sizeof(date), "%d/%b/%Y:%H:%M:%S",
88                         localtime(&current_time));
89
90         (void) my_snprintf(buf, sizeof(buf),
91             "%s - %.*s [%s %+05d] \"%s\" %d %lu %s%.*s%s %s%.*s%s",
92             inet_ntoa(c->sa.u.sin.sin_addr), user->len, user->ptr,
93             date, tz_offset, c->request ? c->request : "-",
94             c->status, (unsigned long) c->loc.io.total,
95             q1, referer->len, referer->ptr, q1,
96             q2, user_agent->len, user_agent->ptr, q2);
97
98         if (fp != NULL) {
99                 (void) fprintf(fp, "%s\n", buf);
100                 (void) fflush(fp);
101         }
102
103 #if defined(_WIN32) && !defined(NO_GUI)
104         {
105                 extern HWND     hLog;
106
107                 if (hLog != NULL)
108                         SendMessage(hLog, WM_APP, 0, (LPARAM) buf);
109         }
110 #endif /* _WIN32 */
111 }