Branch data Line data Source code
1 : : /**
2 : : * \file server/log_msg.c
3 : : *
4 : : * \brief General logging routine that can write to syslog and/or stderr
5 : : * and can take varibale number of args.
6 : : */
7 : :
8 : : /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'.
9 : : * Copyright (C) 2009-2015 fwknop developers and contributors. For a full
10 : : * list of contributors, see the file 'CREDITS'.
11 : : *
12 : : * License (GNU General Public License):
13 : : *
14 : : * This program is free software; you can redistribute it and/or
15 : : * modify it under the terms of the GNU General Public License
16 : : * as published by the Free Software Foundation; either version 2
17 : : * of the License, or (at your option) any later version.
18 : : *
19 : : * This program is distributed in the hope that it will be useful,
20 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 : : * GNU General Public License for more details.
23 : : *
24 : : * You should have received a copy of the GNU General Public License
25 : : * along with this program; if not, write to the Free Software
26 : : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 : : * USA
28 : : *
29 : : *****************************************************************************
30 : : */
31 : : #include "fwknopd_common.h"
32 : : #include "utils.h"
33 : : #include "log_msg.h"
34 : :
35 : : /* The default log facility (can be overridden via config file directive).
36 : : */
37 : : static int syslog_fac = LOG_DAEMON;
38 : :
39 : : /* This value is or'ed with the log level on all logging calls. This allows
40 : : * for force log to stderr instead of syslog simply be setting this to the
41 : : * appropriate value (which is done at init_logging().
42 : : */
43 : : static int static_log_flag = LOG_STDERR_ONLY;
44 : :
45 : : /* The name to use for ID in log messages. This defaults to fwknopd.
46 : : */
47 : : static char *log_name = NULL;
48 : :
49 : : /* The value of the default verbosity used by the log module */
50 : : static int verbosity = LOG_DEFAULT_VERBOSITY;
51 : :
52 : : /* Free resources allocated for logging.
53 : : */
54 : : void
55 : 11797 : free_logging(void)
56 : : {
57 [ + + ]: 11797 : if(log_name != NULL)
58 : 4676 : free(log_name);
59 : 11797 : }
60 : :
61 : : /* Initialize logging sets the name used for syslog.
62 : : */
63 : : void
64 : 4681 : init_logging(fko_srv_options_t *opts) {
65 : 4681 : char *my_name = NULL;
66 : 4681 : int is_syslog = 0;
67 : :
68 : : /* In case this is a re-init.
69 : : */
70 : 4681 : free_logging();
71 : :
72 : : /* Allocate memory for the log_name and set the my_name to point to the
73 : : * appropriate name. The name should already be set in the config struct
74 : : * but if it is not, fallback to the default as defined by 'MY_NAME'.
75 : : */
76 [ + - ]: 4681 : if(opts->config[CONF_SYSLOG_IDENTITY] != NULL
77 [ + - ]: 4681 : && opts->config[CONF_SYSLOG_IDENTITY][0] != '\0')
78 : : {
79 : 4681 : my_name = opts->config[CONF_SYSLOG_IDENTITY];
80 : 4681 : log_name = calloc(1, strlen(opts->config[CONF_SYSLOG_IDENTITY])+1);
81 : 4681 : is_syslog = 1;
82 : : }
83 : : else
84 : : {
85 : 0 : my_name = (char*)&MY_NAME;
86 : 0 : log_name = calloc(1, strlen(MY_NAME)+1);
87 : : }
88 : :
89 [ + + ]: 4681 : if(log_name == NULL)
90 : : {
91 : 4 : fprintf(stderr, "Memory allocation error setting log_name!\n");
92 : 4 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
93 : : }
94 : :
95 : : /* Set our name.
96 : : */
97 [ + - ]: 4677 : if (is_syslog)
98 : 4677 : strlcpy(log_name, my_name, strlen(opts->config[CONF_SYSLOG_IDENTITY])+1);
99 : : else
100 : 0 : strlcpy(log_name, my_name, strlen(MY_NAME)+1);
101 : :
102 : 4677 : static_log_flag = LOG_SYSLOG_ONLY;
103 : :
104 : : /* If we are running in the foreground or performing firewall operations,
105 : : * all logging will go to stderr.
106 : : */
107 [ + + ]: 4677 : if(opts->foreground != 0
108 [ + + ]: 3019 : || opts->fw_flush != 0
109 : : || opts->fw_list != 0
110 [ + + ]: 3000 : || opts->fw_list_all != 0)
111 : 4657 : static_log_flag = LOG_STDERR_ONLY;
112 : :
113 : : /* If the user forces syslog using --syslog-enable, we remove the
114 : : * LOG_WITHOUT_SYSLOG flag. It means all messages will go through syslog */
115 [ + + ]: 4677 : if (opts->syslog_enable != 0)
116 : 1 : static_log_flag &= ~LOG_WITHOUT_SYSLOG;
117 : :
118 : : /* Parse the log facility as specified in the config struct. If, for some
119 : : * reason, it is not, fac will already be set to LOG_DAEMON.
120 : : */
121 [ + - ]: 4677 : if(opts->config[CONF_SYSLOG_FACILITY] != NULL
122 [ + - ]: 4677 : && opts->config[CONF_SYSLOG_FACILITY][0] != '\0')
123 : : {
124 [ + + ]: 4677 : if(!strcasecmp(opts->config[CONF_SYSLOG_FACILITY], "LOG_DAEMON"))
125 : 4668 : syslog_fac = LOG_DAEMON;
126 [ + + ]: 9 : else if(!strcasecmp(opts->config[CONF_SYSLOG_FACILITY], "LOG_LOCAL0"))
127 : 1 : syslog_fac = LOG_LOCAL0;
128 [ + + ]: 8 : else if(!strcasecmp(opts->config[CONF_SYSLOG_FACILITY], "LOG_LOCAL1"))
129 : 1 : syslog_fac = LOG_LOCAL1;
130 [ + + ]: 7 : else if(!strcasecmp(opts->config[CONF_SYSLOG_FACILITY], "LOG_LOCAL2"))
131 : 1 : syslog_fac = LOG_LOCAL2;
132 [ + + ]: 6 : else if(!strcasecmp(opts->config[CONF_SYSLOG_FACILITY], "LOG_LOCAL3"))
133 : 1 : syslog_fac = LOG_LOCAL3;
134 [ + + ]: 5 : else if(!strcasecmp(opts->config[CONF_SYSLOG_FACILITY], "LOG_LOCAL4"))
135 : 1 : syslog_fac = LOG_LOCAL4;
136 [ + + ]: 4 : else if(!strcasecmp(opts->config[CONF_SYSLOG_FACILITY], "LOG_LOCAL5"))
137 : 1 : syslog_fac = LOG_LOCAL5;
138 [ + + ]: 3 : else if(!strcasecmp(opts->config[CONF_SYSLOG_FACILITY], "LOG_LOCAL6"))
139 : 1 : syslog_fac = LOG_LOCAL6;
140 [ + + ]: 2 : else if(!strcasecmp(opts->config[CONF_SYSLOG_FACILITY], "LOG_LOCAL7"))
141 : 1 : syslog_fac = LOG_LOCAL7;
142 : : else
143 : : {
144 : 1 : fprintf(stderr, "Invalid SYSLOG_FACILITY setting '%s'\n",
145 : : opts->config[CONF_SYSLOG_FACILITY]);
146 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
147 : : }
148 : : }
149 : :
150 : 4676 : verbosity = LOG_DEFAULT_VERBOSITY + opts->verbose;
151 : 4676 : }
152 : :
153 : : /* Syslog message function. It uses default set at initialization, and also
154 : : * takes variable args to accommodate printf-like formatting and expansion.
155 : : */
156 : : void
157 : 151349 : log_msg(int level, char* msg, ...)
158 : : {
159 : : va_list ap, apse;
160 : :
161 : : /* Make sure the level is in the right range */
162 [ + + ]: 151349 : if ((level & LOG_VERBOSITY_MASK) > verbosity)
163 : 150952 : return;
164 : :
165 : 147009 : va_start(ap, msg);
166 : :
167 : 147009 : level |= static_log_flag;
168 : :
169 : : /* Print msg to stderr if the level was or'ed with LOG_STDERR
170 : : */
171 [ + + ]: 147009 : if(LOG_STDERR & level)
172 : : {
173 : : /* Need to make a copy of our va_list so we don't screw
174 : : * up the message going to syslog after we print it to stderr.
175 : : */
176 : 146612 : va_copy(apse, ap);
177 : :
178 : 146612 : vfprintf(stderr, msg, apse);
179 : 146612 : fprintf(stderr, "\n");
180 : 146612 : fflush(stderr);
181 : :
182 : 146612 : va_end(apse);
183 : : }
184 : :
185 : : /* If the message has not to be printed to the syslog, we return */
186 [ + + ]: 147009 : if (LOG_WITHOUT_SYSLOG & level)
187 : : {
188 : 146612 : va_end(ap);
189 : 146612 : return;
190 : : }
191 : :
192 : : /* Remove the static log flags from the level */
193 : 397 : level &= LOG_VERBOSITY_MASK;
194 : :
195 : : /* Send the message to syslog.
196 : : */
197 : 397 : openlog(log_name, LOG_PID, syslog_fac);
198 : :
199 : : vsyslog(level, msg, ap);
200 : :
201 : 397 : va_end(ap);
202 : : }
203 : :
204 : : /**
205 : : * Set the verbosity level for the current context of the log module.
206 : : *
207 : : * The verbosity levels used by the module are defined by the syslog module.
208 : : *
209 : : * @param level verbosity level to set (LOG_INFO, LOG_NOTICE ...)
210 : : */
211 : : void
212 : 4676 : log_set_verbosity(int level)
213 : : {
214 : 4676 : verbosity = level;
215 : 4676 : }
216 : :
217 : : /***EOF***/
|