0ea8e83c12f356362ebf89cd8f8b2ba6d6f7cf6f
[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-2008 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 version 3 as
24  *  published by the Free Software Foundation.
25  *
26  *  uAnytun is distributed in the hope that it will be useful,
27  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
28  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  *  GNU General Public License for more details.
30  *
31  *  You should have received a copy of the GNU General Public License
32  *  along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
33  */
34
35 enum syslog_facility_enum { USER = LOG_USER, MAIL = LOG_MAIL,
36                             DAEMON = LOG_DAEMON, AUTH = LOG_AUTH,
37                             SYSLOG = LOG_SYSLOG, LPR = LOG_LPR,
38                             NEWS = LOG_NEWS, UUCP = LOG_UUCP,
39                             CRON = LOG_CRON, AUTHPRIV = LOG_AUTHPRIV,
40                             FTP = LOG_FTP, LOCAL0 = LOG_LOCAL0,
41                             LOCAL1 = LOG_LOCAL1, LOCAL2 = LOG_LOCAL2,
42                             LOCAL3 = LOG_LOCAL3, LOCAL4 = LOG_LOCAL4,
43                             LOCAL5 = LOG_LOCAL5, LOCAL6 = LOG_LOCAL6,
44                             LOCAL7 = LOG_LOCAL7 };
45 typedef enum syslog_facility_enum syslog_facility_t;
46
47 struct log_target_syslog_param_struct {
48   char* logname_;
49   syslog_facility_t facility_;
50 };
51 typedef struct log_target_syslog_param_struct log_target_syslog_param_t;
52
53 int log_target_syslog_init(log_target_t* self, const char* conf)
54 {
55   if(!self || (conf && conf[0] == 0))
56     return -1;
57   
58   self->param_ = malloc(sizeof(log_target_syslog_param_t));
59   if(!self->param_)
60     return -2;
61
62   char* logname;
63   const char* end = NULL;
64   if(!conf)
65     logname = strdup("uanytun");
66   else {
67     end = strchr(conf, ',');
68     if(end) {
69       size_t len = (size_t)(end - conf);
70       if(!len) {
71         free(self->param_);
72         return -1;
73       }  
74       logname = malloc(len+1);
75       if(logname) {
76         strncpy(logname, conf, len);
77         logname[len] = 0;
78       }
79     }
80     else
81       logname = strdup(conf);
82   }
83
84   if(!logname) {
85     free(self->param_);
86     return -2;
87   }
88   ((log_target_syslog_param_t*)(self->param_))->logname_ = logname;
89
90   if(!end) {
91     ((log_target_syslog_param_t*)(self->param_))->facility_ = DAEMON;
92     return 0;
93   }
94   
95   if(end[1] == 0 || end[1] == ',') {
96     free(logname);
97     free(self->param_);
98     return -1;
99   }
100     
101   const char* start = end + 1;
102   end = strchr(start, ',');
103   int i;
104   for(i=0;;++i) {
105     if(facilitynames[i].c_name == NULL) {
106       free(logname);
107       free(self->param_);
108       return -1;
109     }
110
111     if(( end && !strncmp(start, facilitynames[i].c_name, (size_t)(end - start)) && facilitynames[i].c_name[(size_t)(end-start)] == 0) ||
112        (!end && !strcmp(start, facilitynames[i].c_name))) {
113         ((log_target_syslog_param_t*)(self->param_))->facility_ = facilitynames[i].c_val;
114         break;
115     }
116   }
117
118   return 0;
119 }
120
121 void log_target_syslog_open(log_target_t* self)
122 {
123   if(!self || !self->param_)
124     return;
125
126   openlog(((log_target_syslog_param_t*)(self->param_))->logname_, LOG_PID, ((log_target_syslog_param_t*)(self->param_))->facility_);
127   self->opened_ = 1;
128 }
129
130 void log_target_syslog_log(log_target_t* self, log_prio_t prio, const char* msg)
131 {
132   if(!self || !self->param_ || !self->opened_)
133     return;
134
135   syslog((prio + 2) | ((log_target_syslog_param_t*)(self->param_))->facility_, "%s", msg);  
136 }
137
138 void log_target_syslog_close(log_target_t* self)
139 {
140   closelog();
141   self->opened_ = 0;
142 }
143
144 void log_target_syslog_clear(log_target_t* self)
145 {
146   if(!self || !self->param_)
147     return;
148
149   if(((log_target_syslog_param_t*)(self->param_))->logname_)
150     free(((log_target_syslog_param_t*)(self->param_))->logname_);
151
152   free(self->param_);
153 }
154
155 log_target_t* log_target_syslog_new()
156 {
157   log_target_t* tmp = malloc(sizeof(log_target_t));
158   if(!tmp)
159     return NULL;
160
161   tmp->type_ = TARGET_SYSLOG;
162   tmp->init = &log_target_syslog_init;
163   tmp->open = &log_target_syslog_open;
164   tmp->log = &log_target_syslog_log;
165   tmp->close = &log_target_syslog_close;
166   tmp->clear = &log_target_syslog_clear;
167   tmp->opened_ = 0;
168   tmp->enabled_ = 0;
169   tmp->max_prio_ = NOTICE;
170   tmp->param_ = NULL;
171   tmp->next_ = NULL;
172
173   return tmp;
174 }
175
176
177 struct log_target_file_param_struct {
178   char* logfilename_;
179   FILE* file_;
180 };
181 typedef struct log_target_file_param_struct log_target_file_param_t;
182
183 int log_target_file_init(log_target_t* self, const char* conf)
184 {
185   if(!self || (conf && conf[0] == 0))
186     return -1;
187   
188   self->param_ = malloc(sizeof(log_target_file_param_t));
189   if(!self->param_)
190     return -2;
191
192   char* logfilename;
193   if(!conf)
194     logfilename = strdup("uanytun.log");
195   else {
196     const char* end = strchr(conf, ',');
197     if(end) {
198       size_t len = (size_t)(end - conf);
199       if(!len) {
200         free(self->param_);
201         return -1;
202       }  
203       logfilename = malloc(len+1);
204       if(logfilename) {
205         strncpy(logfilename, conf, len);
206         logfilename[len] = 0;
207       }
208     }
209     else
210       logfilename = strdup(conf);
211   }
212
213   if(!logfilename) {
214     free(self->param_);
215     return -2;
216   }
217   ((log_target_file_param_t*)(self->param_))->logfilename_ = logfilename;
218   ((log_target_file_param_t*)(self->param_))->file_ = NULL;
219
220   return 0;
221 }
222
223 void log_target_file_open(log_target_t* self)
224 {
225   if(!self || !self->param_)
226     return;
227
228   ((log_target_file_param_t*)(self->param_))->file_ = fopen(((log_target_file_param_t*)(self->param_))->logfilename_, "w");
229   if(((log_target_file_param_t*)(self->param_))->file_)
230     self->opened_ = 1;
231 }
232
233 void log_target_file_log(log_target_t* self, log_prio_t prio, const char* msg)
234 {
235   if(!self || !self->param_ || !self->opened_)
236     return;
237
238   fprintf(((log_target_file_param_t*)(self->param_))->file_, "%s-%s\n", log_prio_to_string(prio), msg);
239   fflush(((log_target_file_param_t*)(self->param_))->file_);
240 }
241
242 void log_target_file_close(log_target_t* self)
243 {
244   if(!self || !self->param_)
245     return;
246
247   fclose(((log_target_file_param_t*)(self->param_))->file_);
248   self->opened_ = 0;
249 }
250
251 void log_target_file_clear(log_target_t* self)
252 {
253   if(!self || !self->param_)
254     return;
255
256   if(((log_target_file_param_t*)(self->param_))->logfilename_)
257     free(((log_target_file_param_t*)(self->param_))->logfilename_);
258
259   free(self->param_);
260 }
261
262
263 log_target_t* log_target_file_new()
264 {
265   log_target_t* tmp = malloc(sizeof(log_target_t));
266   if(!tmp)
267     return NULL;
268
269   tmp->type_ = TARGET_FILE;
270   tmp->init = &log_target_file_init;
271   tmp->open = &log_target_file_open;
272   tmp->log = &log_target_file_log;
273   tmp->close = &log_target_file_close;
274   tmp->clear = &log_target_file_clear;
275   tmp->opened_ = 0;
276   tmp->enabled_ = 0;
277   tmp->max_prio_ = NOTICE;
278   tmp->param_ = NULL;
279   tmp->next_ = NULL;
280
281   return tmp;
282 }
283
284
285 void log_target_stdout_log(log_target_t* self, log_prio_t prio, const char* msg)
286 {
287   printf("%s-%s\n", log_prio_to_string(prio), msg);
288 }
289
290 log_target_t* log_target_stdout_new()
291 {
292   log_target_t* tmp = malloc(sizeof(log_target_t));
293   if(!tmp)
294     return NULL;
295
296   tmp->type_ = TARGET_STDOUT;
297   tmp->init = NULL;
298   tmp->open = NULL;
299   tmp->log = &log_target_stdout_log;
300   tmp->close = NULL;
301   tmp->clear = NULL;
302   tmp->opened_ = 0;
303   tmp->enabled_ = 0;
304   tmp->max_prio_ = NOTICE;
305   tmp->param_ = NULL;
306   tmp->next_ = NULL;
307
308   return tmp;
309 }
310
311
312 void log_target_stderr_log(log_target_t* self, log_prio_t prio, const char* msg)
313 {
314   fprintf(stderr, "%s-%s\n", log_prio_to_string(prio), msg);
315 }
316
317 log_target_t* log_target_stderr_new()
318 {
319   log_target_t* tmp = malloc(sizeof(log_target_t));
320   if(!tmp)
321     return NULL;
322
323   tmp->type_ = TARGET_STDERR;
324   tmp->init = NULL;
325   tmp->open = NULL;
326   tmp->log = &log_target_stderr_log;
327   tmp->close = NULL;
328   tmp->clear = NULL;
329   tmp->opened_ = 0;
330   tmp->enabled_ = 0;
331   tmp->max_prio_ = NOTICE;
332   tmp->param_ = NULL;
333   tmp->next_ = NULL;
334
335   return tmp;
336 }