Merge branch 'upstream'
[debian/uanytun.git] / src / log_targets.h
1 /*
2  *  uAnytun
3  *
4  *  uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full
5  *  featured implementation uAnytun has no support for multiple connections
6  *  or synchronisation. It is a small single threaded implementation intended
7  *  to act as a client on small platforms.
8  *  The secure anycast tunneling protocol (satp) defines a protocol used
9  *  for communication between any combination of unicast and anycast
10  *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
11  *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
12  *  ethernet, ip, arp ...). satp directly includes cryptography and
13  *  message authentication based on the methodes used by SRTP.  It is
14  *  intended to deliver a generic, scaleable and secure solution for
15  *  tunneling and relaying of packets of any protocol.
16  *  
17  *
18  *  Copyright (C) 2007-2010 Christian Pointner <equinox@anytun.org>
19  *
20  *  This file is part of uAnytun.
21  *
22  *  uAnytun is free software: you can redistribute it and/or modify
23  *  it under the terms of the GNU General Public License as published by
24  *  the Free Software Foundation, either version 3 of the License, or
25  *  any later version.
26  *
27  *  uAnytun is distributed in the hope that it will be useful,
28  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30  *  GNU General Public License for more details.
31  *
32  *  You should have received a copy of the GNU General Public License
33  *  along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
34  */
35
36 #ifndef UANYTUN_log_targets_h_INCLUDED
37 #define UANYTUN_log_targets_h_INCLUDED
38
39 #include <time.h>
40
41 static char* get_time_formatted()
42 {
43   char* time_string;
44   time_t t = time(NULL);
45   if(t < 0) 
46     time_string = "<time read error>";
47   else {
48     time_string = ctime(&t);
49     if(!time_string)
50       time_string = "<time format error>";
51     else {
52       char* newline = strchr(time_string, '\n');
53       if(newline)
54         newline[0] = 0;
55     }
56   }
57   return time_string;
58 }
59
60 enum syslog_facility_enum { USER = LOG_USER, MAIL = LOG_MAIL,
61                             DAEMON = LOG_DAEMON, AUTH = LOG_AUTH,
62                             SYSLOG = LOG_SYSLOG, LPR = LOG_LPR,
63                             NEWS = LOG_NEWS, UUCP = LOG_UUCP,
64                             CRON = LOG_CRON, AUTHPRIV = LOG_AUTHPRIV,
65                             FTP = LOG_FTP, LOCAL0 = LOG_LOCAL0,
66                             LOCAL1 = LOG_LOCAL1, LOCAL2 = LOG_LOCAL2,
67                             LOCAL3 = LOG_LOCAL3, LOCAL4 = LOG_LOCAL4,
68                             LOCAL5 = LOG_LOCAL5, LOCAL6 = LOG_LOCAL6,
69                             LOCAL7 = LOG_LOCAL7 };
70 typedef enum syslog_facility_enum syslog_facility_t;
71
72 struct log_target_syslog_param_struct {
73   char* logname_;
74   syslog_facility_t facility_;
75 };
76 typedef struct log_target_syslog_param_struct log_target_syslog_param_t;
77
78 int log_target_syslog_init(log_target_t* self, const char* conf)
79 {
80   if(!self || (conf && conf[0] == 0))
81     return -1;
82   
83   self->param_ = malloc(sizeof(log_target_syslog_param_t));
84   if(!self->param_)
85     return -2;
86
87   char* logname;
88   const char* end = NULL;
89   if(!conf)
90     logname = strdup("uanytun");
91   else {
92     end = strchr(conf, ',');
93     if(end) {
94       size_t len = (size_t)(end - conf);
95       if(!len) {
96         free(self->param_);
97         return -1;
98       }  
99       logname = malloc(len+1);
100       if(logname) {
101         strncpy(logname, conf, len);
102         logname[len] = 0;
103       }
104     }
105     else
106       logname = strdup(conf);
107   }
108
109   if(!logname) {
110     free(self->param_);
111     return -2;
112   }
113   ((log_target_syslog_param_t*)(self->param_))->logname_ = logname;
114
115   if(!end) {
116     ((log_target_syslog_param_t*)(self->param_))->facility_ = DAEMON;
117     return 0;
118   }
119   
120   if(end[1] == 0 || end[1] == ',') {
121     free(logname);
122     free(self->param_);
123     return -1;
124   }
125     
126   const char* start = end + 1;
127   end = strchr(start, ',');
128   int i;
129   for(i=0;;++i) {
130     if(facilitynames[i].c_name == NULL) {
131       free(logname);
132       free(self->param_);
133       return -1;
134     }
135
136     if(( end && !strncmp(start, facilitynames[i].c_name, (size_t)(end - start)) && facilitynames[i].c_name[(size_t)(end-start)] == 0) ||
137        (!end && !strcmp(start, facilitynames[i].c_name))) {
138         ((log_target_syslog_param_t*)(self->param_))->facility_ = facilitynames[i].c_val;
139         break;
140     }
141   }
142
143   return 0;
144 }
145
146 void log_target_syslog_open(log_target_t* self)
147 {
148   if(!self || !self->param_)
149     return;
150
151   openlog(((log_target_syslog_param_t*)(self->param_))->logname_, LOG_PID, ((log_target_syslog_param_t*)(self->param_))->facility_);
152   self->opened_ = 1;
153 }
154
155 void log_target_syslog_log(log_target_t* self, log_prio_t prio, const char* msg)
156 {
157   if(!self || !self->param_ || !self->opened_)
158     return;
159
160   syslog((prio + 2) | ((log_target_syslog_param_t*)(self->param_))->facility_, "%s", msg);  
161 }
162
163 void log_target_syslog_close(log_target_t* self)
164 {
165   closelog();
166   self->opened_ = 0;
167 }
168
169 void log_target_syslog_clear(log_target_t* self)
170 {
171   if(!self || !self->param_)
172     return;
173
174   if(((log_target_syslog_param_t*)(self->param_))->logname_)
175     free(((log_target_syslog_param_t*)(self->param_))->logname_);
176
177   free(self->param_);
178 }
179
180 log_target_t* log_target_syslog_new()
181 {
182   log_target_t* tmp = malloc(sizeof(log_target_t));
183   if(!tmp)
184     return NULL;
185
186   tmp->type_ = TARGET_SYSLOG;
187   tmp->init = &log_target_syslog_init;
188   tmp->open = &log_target_syslog_open;
189   tmp->log = &log_target_syslog_log;
190   tmp->close = &log_target_syslog_close;
191   tmp->clear = &log_target_syslog_clear;
192   tmp->opened_ = 0;
193   tmp->enabled_ = 0;
194   tmp->max_prio_ = NOTICE;
195   tmp->param_ = NULL;
196   tmp->next_ = NULL;
197
198   return tmp;
199 }
200
201
202 struct log_target_file_param_struct {
203   char* logfilename_;
204   FILE* file_;
205 };
206 typedef struct log_target_file_param_struct log_target_file_param_t;
207
208 int log_target_file_init(log_target_t* self, const char* conf)
209 {
210   if(!self || (conf && conf[0] == 0))
211     return -1;
212   
213   self->param_ = malloc(sizeof(log_target_file_param_t));
214   if(!self->param_)
215     return -2;
216
217   char* logfilename;
218   if(!conf)
219     logfilename = strdup("uanytun.log");
220   else {
221     const char* end = strchr(conf, ',');
222     if(end) {
223       size_t len = (size_t)(end - conf);
224       if(!len) {
225         free(self->param_);
226         return -1;
227       }  
228       logfilename = malloc(len+1);
229       if(logfilename) {
230         strncpy(logfilename, conf, len);
231         logfilename[len] = 0;
232       }
233     }
234     else
235       logfilename = strdup(conf);
236   }
237
238   if(!logfilename) {
239     free(self->param_);
240     return -2;
241   }
242   ((log_target_file_param_t*)(self->param_))->logfilename_ = logfilename;
243   ((log_target_file_param_t*)(self->param_))->file_ = NULL;
244
245   return 0;
246 }
247
248 void log_target_file_open(log_target_t* self)
249 {
250   if(!self || !self->param_)
251     return;
252
253   ((log_target_file_param_t*)(self->param_))->file_ = fopen(((log_target_file_param_t*)(self->param_))->logfilename_, "w");
254   if(((log_target_file_param_t*)(self->param_))->file_)
255     self->opened_ = 1;
256 }
257
258 void log_target_file_log(log_target_t* self, log_prio_t prio, const char* msg)
259 {
260   if(!self || !self->param_ || !self->opened_)
261     return;
262
263   fprintf(((log_target_file_param_t*)(self->param_))->file_, "%s %s: %s\n", get_time_formatted(), log_prio_to_string(prio), msg);
264   fflush(((log_target_file_param_t*)(self->param_))->file_);
265 }
266
267 void log_target_file_close(log_target_t* self)
268 {
269   if(!self || !self->param_)
270     return;
271
272   fclose(((log_target_file_param_t*)(self->param_))->file_);
273   self->opened_ = 0;
274 }
275
276 void log_target_file_clear(log_target_t* self)
277 {
278   if(!self || !self->param_)
279     return;
280
281   if(((log_target_file_param_t*)(self->param_))->logfilename_)
282     free(((log_target_file_param_t*)(self->param_))->logfilename_);
283
284   free(self->param_);
285 }
286
287
288 log_target_t* log_target_file_new()
289 {
290   log_target_t* tmp = malloc(sizeof(log_target_t));
291   if(!tmp)
292     return NULL;
293
294   tmp->type_ = TARGET_FILE;
295   tmp->init = &log_target_file_init;
296   tmp->open = &log_target_file_open;
297   tmp->log = &log_target_file_log;
298   tmp->close = &log_target_file_close;
299   tmp->clear = &log_target_file_clear;
300   tmp->opened_ = 0;
301   tmp->enabled_ = 0;
302   tmp->max_prio_ = NOTICE;
303   tmp->param_ = NULL;
304   tmp->next_ = NULL;
305
306   return tmp;
307 }
308
309
310 void log_target_stdout_log(log_target_t* self, log_prio_t prio, const char* msg)
311 {
312   printf("%s %s: %s\n", get_time_formatted(), log_prio_to_string(prio), msg);
313 }
314
315 log_target_t* log_target_stdout_new()
316 {
317   log_target_t* tmp = malloc(sizeof(log_target_t));
318   if(!tmp)
319     return NULL;
320
321   tmp->type_ = TARGET_STDOUT;
322   tmp->init = NULL;
323   tmp->open = NULL;
324   tmp->log = &log_target_stdout_log;
325   tmp->close = NULL;
326   tmp->clear = NULL;
327   tmp->opened_ = 0;
328   tmp->enabled_ = 0;
329   tmp->max_prio_ = NOTICE;
330   tmp->param_ = NULL;
331   tmp->next_ = NULL;
332
333   return tmp;
334 }
335
336
337 void log_target_stderr_log(log_target_t* self, log_prio_t prio, const char* msg)
338 {
339   fprintf(stderr, "%s %s: %s\n", get_time_formatted(), log_prio_to_string(prio), msg);
340 }
341
342 log_target_t* log_target_stderr_new()
343 {
344   log_target_t* tmp = malloc(sizeof(log_target_t));
345   if(!tmp)
346     return NULL;
347
348   tmp->type_ = TARGET_STDERR;
349   tmp->init = NULL;
350   tmp->open = NULL;
351   tmp->log = &log_target_stderr_log;
352   tmp->close = NULL;
353   tmp->clear = NULL;
354   tmp->opened_ = 0;
355   tmp->enabled_ = 0;
356   tmp->max_prio_ = NOTICE;
357   tmp->param_ = NULL;
358   tmp->next_ = NULL;
359
360   return tmp;
361 }
362
363 #endif