c29c9f2e4383b4e2d045b0721f0fb4631a3cb42b
[strongswan.git] / src / libcharon / bus / listeners / sys_logger.c
1 /*
2 * Copyright (C) 2006 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <syslog.h>
19
20 #include "sys_logger.h"
21
22
23 typedef struct private_sys_logger_t private_sys_logger_t;
24
25 /**
26 * Private data of a sys_logger_t object
27 */
28 struct private_sys_logger_t {
29
30 /**
31 * Public data.
32 */
33 sys_logger_t public;
34
35 /**
36 * syslog facility to use
37 */
38 int facility;
39
40 /**
41 * Maximum level to log, for each group
42 */
43 level_t levels[DBG_MAX];
44
45 /**
46 * Print the name/# of the IKE_SA?
47 */
48 bool ike_name;
49 };
50
51 METHOD(listener_t, log_, bool,
52 private_sys_logger_t *this, debug_t group, level_t level, int thread,
53 ike_sa_t* ike_sa, char *format, va_list args)
54 {
55 if (level <= this->levels[group])
56 {
57 char buffer[8192], groupstr[4], namestr[128] = "";
58 char *current = buffer, *next;
59
60 /* write in memory buffer first */
61 vsnprintf(buffer, sizeof(buffer), format, args);
62 /* cache group name */
63 snprintf(groupstr, sizeof(groupstr), "%N", debug_names, group);
64
65 if (this->ike_name && ike_sa)
66 {
67 if (ike_sa->get_peer_cfg(ike_sa))
68 {
69 snprintf(namestr, sizeof(namestr), " <%s|%d>",
70 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
71 }
72 else
73 {
74 snprintf(namestr, sizeof(namestr), " <%d>",
75 ike_sa->get_unique_id(ike_sa));
76 }
77 }
78
79 /* do a syslog with every line */
80 while (current)
81 {
82 next = strchr(current, '\n');
83 if (next)
84 {
85 *(next++) = '\0';
86 }
87 syslog(this->facility|LOG_INFO, "%.2d[%s]%s %s\n",
88 thread, groupstr, namestr, current);
89 current = next;
90 }
91 }
92 /* always stay registered */
93 return TRUE;
94 }
95
96 METHOD(sys_logger_t, set_level, void,
97 private_sys_logger_t *this, debug_t group, level_t level)
98 {
99 if (group < DBG_ANY)
100 {
101 this->levels[group] = level;
102 }
103 else
104 {
105 for (group = 0; group < DBG_MAX; group++)
106 {
107 this->levels[group] = level;
108 }
109 }
110 }
111
112 METHOD(sys_logger_t, destroy, void,
113 private_sys_logger_t *this)
114 {
115 closelog();
116 free(this);
117 }
118
119 /*
120 * Described in header.
121 */
122 sys_logger_t *sys_logger_create(int facility, bool ike_name)
123 {
124 private_sys_logger_t *this;
125
126 INIT(this,
127 .public = {
128 .listener = {
129 .log = _log_,
130 },
131 .set_level = _set_level,
132 .destroy = _destroy,
133 },
134 .facility = facility,
135 .ike_name = ike_name,
136 );
137
138 set_level(this, DBG_ANY, LEVEL_SILENT);
139
140 return &this->public;
141 }