Fix whitespace.
[tinc] / src / logger.c
1 /*
2     logger.c -- logging code
3     Copyright (C) 2004-2006 Guus Sliepen <guus@tinc-vpn.org>
4                   2004-2005 Ivo Timmermans
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License along
17     with this program; if not, write to the Free Software Foundation, Inc.,
18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "system.h"
22
23 #include "conf.h"
24 #include "meta.h"
25 #include "logger.h"
26 #include "connection.h"
27 #include "control_common.h"
28
29 debug_t debug_level = DEBUG_NOTHING;
30 static logmode_t logmode = LOGMODE_STDERR;
31 static pid_t logpid;
32 extern char *logfilename;
33 static FILE *logfile = NULL;
34 #ifdef HAVE_MINGW
35 static HANDLE loghandle = NULL;
36 #endif
37 static const char *logident = NULL;
38 bool logcontrol = false;
39
40 void openlogger(const char *ident, logmode_t mode) {
41         logident = ident;
42         logmode = mode;
43
44         switch(mode) {
45                 case LOGMODE_STDERR:
46                         logpid = getpid();
47                         break;
48                 case LOGMODE_FILE:
49                         logpid = getpid();
50                         logfile = fopen(logfilename, "a");
51                         if(!logfile) {
52                                 fprintf(stderr, "Could not open log file %s: %s\n", logfilename, strerror(errno));
53                                 logmode = LOGMODE_NULL;
54                         }
55                         break;
56                 case LOGMODE_SYSLOG:
57 #ifdef HAVE_MINGW
58                         loghandle = RegisterEventSource(NULL, logident);
59                         if(!loghandle) {
60                                 fprintf(stderr, "Could not open log handle!");
61                                 logmode = LOGMODE_NULL;
62                         }
63                         break;
64 #else
65 #ifdef HAVE_SYSLOG_H
66                         openlog(logident, LOG_CONS | LOG_PID, LOG_DAEMON);
67                         break;
68 #endif
69 #endif
70                 case LOGMODE_NULL:
71                         break;
72         }
73 }
74
75 void reopenlogger() {
76         if(logmode != LOGMODE_FILE)
77                 return;
78
79         fflush(logfile);
80         FILE *newfile = fopen(logfilename, "a");
81         if(!newfile) {
82                 logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reopen log file %s: %s", logfilename, strerror(errno));
83                 return;
84         }
85         fclose(logfile);
86         logfile = newfile;
87 }
88
89 void logger(int level, int priority, const char *format, ...) {
90         va_list ap;
91         int len;
92         char timestr[32] = "";
93         char message[1024] = "";
94         time_t now;
95         static bool suppress = false;
96
97         // Bail out early if there is nothing to do.
98         if(suppress)
99                 return;
100
101         if(!logcontrol && (level > debug_level || logmode == LOGMODE_NULL))
102                 return;
103
104         va_start(ap, format);
105         len = vsnprintf(message, sizeof message, format, ap);
106         va_end(ap);
107
108         if(len > 0 && len < sizeof message && message[len - 1] == '\n')
109                 message[len - 1] = 0;
110
111         if(level <= debug_level) {
112                 switch(logmode) {
113                         case LOGMODE_STDERR:
114                                 fprintf(stderr, "%s\n", message);
115                                 fflush(stderr);
116                                 break;
117                         case LOGMODE_FILE:
118                                 now = time(NULL);
119                                 strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now));
120                                 fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message);
121                                 fflush(logfile);
122                                 break;
123                         case LOGMODE_SYSLOG:
124 #ifdef HAVE_MINGW
125                                 {
126                                         const char *messages[] = {message};
127                                         ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL);
128                                 }
129 #else
130 #ifdef HAVE_SYSLOG_H
131                                 syslog(priority, "%s", message);
132 #endif
133 #endif
134                                 break;
135                         case LOGMODE_NULL:
136                                 break;
137                 }
138         }
139
140         if(logcontrol) {
141                 suppress = true;
142                 logcontrol = false;
143                 for list_each(connection_t, c, connection_list) {
144                         if(!c->status.log)
145                                 continue;
146                         logcontrol = true;
147                         if(level > (c->outcompression >= 0 ? c->outcompression : debug_level))
148                                 continue;
149                         int len = strlen(message);
150                         if(send_request(c, "%d %d %d", CONTROL, REQ_LOG, len))
151                                 send_meta(c, message, len);
152                 }
153                 suppress = false;
154         }
155 }
156
157 void closelogger(void) {
158         switch(logmode) {
159                 case LOGMODE_FILE:
160                         fclose(logfile);
161                         break;
162                 case LOGMODE_SYSLOG:
163 #ifdef HAVE_MINGW
164                         DeregisterEventSource(loghandle);
165                         break;
166 #else
167 #ifdef HAVE_SYSLOG_H
168                         closelog();
169                         break;
170 #endif
171 #endif
172                 case LOGMODE_NULL:
173                 case LOGMODE_STDERR:
174                         break;
175                         break;
176         }
177 }