introduced printf() specifiers for:
[strongswan.git] / src / charon / bus / listeners / file_logger.c
1 /**
2 * @file file_logger.c
3 *
4 * @brief Implementation of file_logger_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2006 Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 /* for fmemopen() */
24 #define _GNU_SOURCE
25 #include <stdio.h>
26 #include <string.h>
27
28 #include "file_logger.h"
29
30 #include <bus/listeners/stream_logger.h>
31
32
33 typedef struct private_file_logger_t private_file_logger_t;
34
35 /**
36 * Private data of a file_logger_t object
37 */
38 struct private_file_logger_t {
39
40 /**
41 * Public data.
42 */
43 file_logger_t public;
44
45 /**
46 * output file
47 */
48 FILE *out;
49
50 /**
51 * Internal used stream logger that does the dirty work
52 */
53 stream_logger_t *logger;
54
55 /**
56 * Memory stream used for stream_logger
57 */
58 FILE *stream;
59
60 /**
61 * Underlying buffer for stream
62 */
63 char buffer[4096];
64 };
65
66
67 /**
68 * Implementation of bus_listener_t.signal.
69 */
70 static void signal_(private_file_logger_t *this, int thread, ike_sa_t* ike_sa,
71 signal_t signal, level_t level,
72 char *format, va_list args)
73 {
74 char line[512];
75 char *prefix;
76 FILE *reader;
77
78 switch (signal)
79 {
80 case SIG_IKE_UP:
81 case SIG_IKE_DOWN:
82 case SIG_IKE_REKEY:
83 case SIG_DBG_IKE:
84 prefix = "IKE";
85 break;
86 case SIG_DBG_CHD:
87 prefix = "CHD";
88 break;
89 case SIG_DBG_JOB:
90 prefix = "JOG";
91 break;
92 case SIG_DBG_CFG:
93 prefix = "CFG";
94 break;
95 case SIG_DBG_KNL:
96 prefix = "KNL";
97 break;
98 case SIG_DBG_NET:
99 prefix = "NET";
100 break;
101 case SIG_DBG_ENC:
102 prefix = "ENC";
103 break;
104 default:
105 prefix = "???";
106 break;
107 }
108
109 flockfile(this->stream);
110 /* reset memory stream */
111 rewind(this->stream);
112 memset(this->buffer, '\0', sizeof(this->buffer));
113 /* log to memstream */
114 this->logger->listener.signal(&this->logger->listener, thread, ike_sa,
115 signal, level, format, args);
116 /* flush is needed to append a '\0' */
117 fflush(this->stream);
118
119 /* create a reader stream that reads out line by line */
120 reader = fmemopen(this->buffer, sizeof(this->buffer), "r");
121
122 while (fgets(line, sizeof(line), reader))
123 {
124 if (line[0] == '\0')
125 {
126 /* abort on EOF */
127 break;
128 }
129 else if (line[0] != '\n')
130 {
131 fprintf(this->out, "%.2d[%s] %s", thread, prefix, line);
132 }
133 }
134 fclose(reader);
135 funlockfile(this->stream);
136 }
137
138 /**
139 * Implementation of file_logger_t.set_level.
140 */
141 static void set_level(private_file_logger_t *this, signal_t signal, level_t max)
142 {
143 this->logger->set_level(this->logger, signal, max);
144 }
145
146 /**
147 * Implementation of file_logger_t.destroy.
148 */
149 static void destroy(private_file_logger_t *this)
150 {
151 fclose(this->stream);
152 this->logger->destroy(this->logger);
153 free(this);
154 }
155
156 /*
157 * Described in header.
158 */
159 file_logger_t *file_logger_create(FILE *out)
160 {
161 private_file_logger_t *this = malloc_thing(private_file_logger_t);
162
163 /* public functions */
164 this->public.listener.signal = (void(*)(bus_listener_t*,int,ike_sa_t*,signal_t,level_t,char*,va_list))signal_;
165 this->public.set_level = (void(*)(file_logger_t*,signal_t,level_t))set_level;
166 this->public.destroy = (void(*)(file_logger_t*))destroy;
167
168 /* private variables */
169 this->out = out;
170 this->stream = fmemopen(this->buffer, sizeof(this->buffer), "w");
171 if (this->stream == NULL)
172 {
173 /* fallback to stderr */
174 this->stream = stderr;
175 }
176 this->logger = stream_logger_create(this->stream);
177
178 return &this->public;
179 }