Merge branch 'js/pthread-exit-emu-windows'
[git] / compat / win32 / syslog.c
1 #include "../../git-compat-util.h"
2
3 static HANDLE ms_eventlog;
4
5 void openlog(const char *ident, int logopt, int facility)
6 {
7         if (ms_eventlog)
8                 return;
9
10         ms_eventlog = RegisterEventSourceA(NULL, ident);
11
12         if (!ms_eventlog)
13                 warning("RegisterEventSource() failed: %lu", GetLastError());
14 }
15
16 void syslog(int priority, const char *fmt, ...)
17 {
18         WORD logtype;
19         char *str, *pos;
20         int str_len;
21         va_list ap;
22
23         if (!ms_eventlog)
24                 return;
25
26         va_start(ap, fmt);
27         str_len = vsnprintf(NULL, 0, fmt, ap);
28         va_end(ap);
29
30         if (str_len < 0) {
31                 warning("vsnprintf failed: '%s'", strerror(errno));
32                 return;
33         }
34
35         str = malloc(st_add(str_len, 1));
36         if (!str) {
37                 warning("malloc failed: '%s'", strerror(errno));
38                 return;
39         }
40
41         va_start(ap, fmt);
42         vsnprintf(str, str_len + 1, fmt, ap);
43         va_end(ap);
44
45         while ((pos = strstr(str, "%1")) != NULL) {
46                 str = realloc(str, st_add(++str_len, 1));
47                 if (!str) {
48                         warning("realloc failed: '%s'", strerror(errno));
49                         return;
50                 }
51                 memmove(pos + 2, pos + 1, strlen(pos));
52                 pos[1] = ' ';
53         }
54
55         switch (priority) {
56         case LOG_EMERG:
57         case LOG_ALERT:
58         case LOG_CRIT:
59         case LOG_ERR:
60                 logtype = EVENTLOG_ERROR_TYPE;
61                 break;
62
63         case LOG_WARNING:
64                 logtype = EVENTLOG_WARNING_TYPE;
65                 break;
66
67         case LOG_NOTICE:
68         case LOG_INFO:
69         case LOG_DEBUG:
70         default:
71                 logtype = EVENTLOG_INFORMATION_TYPE;
72                 break;
73         }
74
75         ReportEventA(ms_eventlog, logtype, 0, 0, NULL, 1, 0,
76             (const char **)&str, NULL);
77         free(str);
78 }