1 #include "config/log_conf.h"
2
3 #include <getopt.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <syslog.h>
7
8 #include "log.h"
9 #include "config/str.h"
10
11 #define LOG_LEVEL_VALUE_ERROR "error"
12 #define LOG_LEVEL_VALUE_WARNING "warning"
13 #define LOG_LEVEL_VALUE_INFO "info"
14 #define LOG_LEVEL_VALUE_DEBUG "debug"
15
16 #define LOG_OUTPUT_VALUE_SYSLOG "syslog"
17 #define LOG_OUTPUT_VALUE_CONSOLE "console"
18
19 #define LOG_FACILITY_VALUE_AUTH "auth"
20 #define LOG_FACILITY_VALUE_AUTHPRIV "authpriv"
21 #define LOG_FACILITY_VALUE_CRON "cron"
22 #define LOG_FACILITY_VALUE_DAEMON "daemon"
23 #define LOG_FACILITY_VALUE_FTP "ftp"
24 #define LOG_FACILITY_VALUE_KERN "kern"
25 #define LOG_FACILITY_VALUE_LPR "lpr"
26 #define LOG_FACILITY_VALUE_MAIL "mail"
27 #define LOG_FACILITY_VALUE_NEWS "news"
28 #define LOG_FACILITY_VALUE_SYSLOG "syslog"
29 #define LOG_FACILITY_VALUE_USER "user"
30 #define LOG_FACILITY_VALUE_UUCP "uucp"
31 #define LOG_FACILITY_VALUE_LOCAL0 "local0"
32 #define LOG_FACILITY_VALUE_LOCAL1 "local1"
33 #define LOG_FACILITY_VALUE_LOCAL2 "local2"
34 #define LOG_FACILITY_VALUE_LOCAL3 "local3"
35 #define LOG_FACILITY_VALUE_LOCAL4 "local4"
36 #define LOG_FACILITY_VALUE_LOCAL5 "local5"
37 #define LOG_FACILITY_VALUE_LOCAL6 "local6"
38 #define LOG_FACILITY_VALUE_LOCAL7 "local7"
39
40 #define DEREFERENCE_UINT(void_value) (*((uint8_t *) void_value))
41 #define DEREFERENCE_ENUM(void_value) (*((enum log_output *) void_value))
42 #define DEREFERENCE_UINT32(void_value) (*((uint32_t *) void_value))
43
44 static void
print_log_level(struct option_field const * field,void * value)45 print_log_level(struct option_field const *field, void *value)
46 {
47 char const *str = "<unknown>";
48
49 switch (DEREFERENCE_UINT(value)) {
50 case LOG_ERR:
51 str = LOG_LEVEL_VALUE_ERROR;
52 break;
53 case LOG_WARNING:
54 str = LOG_LEVEL_VALUE_WARNING;
55 break;
56 case LOG_INFO:
57 str = LOG_LEVEL_VALUE_INFO;
58 break;
59 case LOG_DEBUG:
60 str = LOG_LEVEL_VALUE_DEBUG;
61 break;
62 }
63
64 pr_op_info("%s: %s", field->name, str);
65 }
66
67 static void
print_log_output(struct option_field const * field,void * value)68 print_log_output(struct option_field const *field, void *value)
69 {
70 char const *str = "<unknown>";
71
72 switch (DEREFERENCE_ENUM(value)) {
73 case SYSLOG:
74 str = LOG_OUTPUT_VALUE_SYSLOG;
75 break;
76 case CONSOLE:
77 str = LOG_OUTPUT_VALUE_CONSOLE;
78 break;
79 }
80
81 pr_op_info("%s: %s", field->name, str);
82 }
83
84 static void
print_log_facility(struct option_field const * field,void * value)85 print_log_facility(struct option_field const *field, void *value)
86 {
87 char const *str = "<unknown>";
88
89 switch (DEREFERENCE_UINT32(value)) {
90 case LOG_USER:
91 str = LOG_FACILITY_VALUE_USER;
92 break;
93 case LOG_MAIL:
94 str = LOG_FACILITY_VALUE_MAIL;
95 break;
96 case LOG_DAEMON:
97 str = LOG_FACILITY_VALUE_DAEMON;
98 break;
99 case LOG_AUTH:
100 str = LOG_FACILITY_VALUE_AUTH;
101 break;
102 case LOG_LPR:
103 str = LOG_FACILITY_VALUE_LPR;
104 break;
105 case LOG_NEWS:
106 str = LOG_FACILITY_VALUE_NEWS;
107 break;
108 case LOG_UUCP:
109 str = LOG_FACILITY_VALUE_UUCP;
110 break;
111 case LOG_CRON:
112 str = LOG_FACILITY_VALUE_CRON;
113 break;
114 case LOG_AUTHPRIV:
115 str = LOG_FACILITY_VALUE_AUTHPRIV;
116 break;
117 case LOG_FTP:
118 str = LOG_FACILITY_VALUE_FTP;
119 break;
120 case LOG_LOCAL0:
121 str = LOG_FACILITY_VALUE_LOCAL0;
122 break;
123 case LOG_LOCAL1:
124 str = LOG_FACILITY_VALUE_LOCAL1;
125 break;
126 case LOG_LOCAL2:
127 str = LOG_FACILITY_VALUE_LOCAL2;
128 break;
129 case LOG_LOCAL3:
130 str = LOG_FACILITY_VALUE_LOCAL3;
131 break;
132 case LOG_LOCAL4:
133 str = LOG_FACILITY_VALUE_LOCAL4;
134 break;
135 case LOG_LOCAL5:
136 str = LOG_FACILITY_VALUE_LOCAL5;
137 break;
138 case LOG_LOCAL6:
139 str = LOG_FACILITY_VALUE_LOCAL6;
140 break;
141 case LOG_LOCAL7:
142 str = LOG_FACILITY_VALUE_LOCAL7;
143 break;
144 }
145
146 pr_op_info("%s: %s", field->name, str);
147 }
148
149 static int
parse_argv_log_level(struct option_field const * field,char const * str,void * result)150 parse_argv_log_level(struct option_field const *field, char const *str,
151 void *result)
152 {
153 if (strcmp(str, LOG_LEVEL_VALUE_ERROR) == 0)
154 DEREFERENCE_UINT(result) = LOG_ERR;
155 else if (strcmp(str, LOG_LEVEL_VALUE_WARNING) == 0)
156 DEREFERENCE_UINT(result) = LOG_WARNING;
157 else if (strcmp(str, LOG_LEVEL_VALUE_INFO) == 0)
158 DEREFERENCE_UINT(result) = LOG_INFO;
159 else if (strcmp(str, LOG_LEVEL_VALUE_DEBUG) == 0)
160 DEREFERENCE_UINT(result) = LOG_DEBUG;
161 else
162 return pr_op_err("Unknown %s: '%s'", field->name, str);
163
164 return 0;
165 }
166
167 static int
parse_argv_log_output(struct option_field const * field,char const * str,void * result)168 parse_argv_log_output(struct option_field const *field, char const *str,
169 void *result)
170 {
171 if (strcmp(str, LOG_OUTPUT_VALUE_SYSLOG) == 0)
172 DEREFERENCE_ENUM(result) = SYSLOG;
173 else if (strcmp(str, LOG_OUTPUT_VALUE_CONSOLE) == 0)
174 DEREFERENCE_ENUM(result) = CONSOLE;
175 else
176 return pr_op_err("Unknown %s: '%s'", field->name, str);
177
178 return 0;
179 }
180
181 static int
parse_argv_log_facility(struct option_field const * field,char const * str,void * result)182 parse_argv_log_facility(struct option_field const *field, char const *str,
183 void *result)
184 {
185 if (strcmp(str, LOG_FACILITY_VALUE_AUTH) == 0)
186 DEREFERENCE_UINT32(result) = LOG_AUTH;
187 else if (strcmp(str, LOG_FACILITY_VALUE_AUTHPRIV) == 0)
188 DEREFERENCE_UINT32(result) = LOG_AUTHPRIV;
189 else if (strcmp(str, LOG_FACILITY_VALUE_CRON) == 0)
190 DEREFERENCE_UINT32(result) = LOG_CRON;
191 else if (strcmp(str, LOG_FACILITY_VALUE_DAEMON) == 0)
192 DEREFERENCE_UINT32(result) = LOG_DAEMON;
193 else if (strcmp(str, LOG_FACILITY_VALUE_FTP) == 0)
194 DEREFERENCE_UINT32(result) = LOG_FTP;
195 else if (strcmp(str, LOG_FACILITY_VALUE_LPR) == 0)
196 DEREFERENCE_UINT32(result) = LOG_LPR;
197 else if (strcmp(str, LOG_FACILITY_VALUE_MAIL) == 0)
198 DEREFERENCE_UINT32(result) = LOG_MAIL;
199 else if (strcmp(str, LOG_FACILITY_VALUE_NEWS) == 0)
200 DEREFERENCE_UINT32(result) = LOG_NEWS;
201 else if (strcmp(str, LOG_FACILITY_VALUE_USER) == 0)
202 DEREFERENCE_UINT32(result) = LOG_USER;
203 else if (strcmp(str, LOG_FACILITY_VALUE_UUCP) == 0)
204 DEREFERENCE_UINT32(result) = LOG_UUCP;
205 else if (strcmp(str, LOG_FACILITY_VALUE_LOCAL0) == 0)
206 DEREFERENCE_UINT32(result) = LOG_LOCAL0;
207 else if (strcmp(str, LOG_FACILITY_VALUE_LOCAL1) == 0)
208 DEREFERENCE_UINT32(result) = LOG_LOCAL1;
209 else if (strcmp(str, LOG_FACILITY_VALUE_LOCAL2) == 0)
210 DEREFERENCE_UINT32(result) = LOG_LOCAL2;
211 else if (strcmp(str, LOG_FACILITY_VALUE_LOCAL3) == 0)
212 DEREFERENCE_UINT32(result) = LOG_LOCAL3;
213 else if (strcmp(str, LOG_FACILITY_VALUE_LOCAL4) == 0)
214 DEREFERENCE_UINT32(result) = LOG_LOCAL4;
215 else if (strcmp(str, LOG_FACILITY_VALUE_LOCAL5) == 0)
216 DEREFERENCE_UINT32(result) = LOG_LOCAL5;
217 else if (strcmp(str, LOG_FACILITY_VALUE_LOCAL6) == 0)
218 DEREFERENCE_UINT32(result) = LOG_LOCAL6;
219 else if (strcmp(str, LOG_FACILITY_VALUE_LOCAL7) == 0)
220 DEREFERENCE_UINT32(result) = LOG_LOCAL7;
221 else if (strcmp(str, LOG_FACILITY_VALUE_KERN) == 0 ||
222 strcmp(str, LOG_FACILITY_VALUE_SYSLOG) == 0)
223 return pr_op_err("Unsupported %s: '%s', use another value",
224 field->name, str);
225 else
226 return pr_op_err("Unknown %s: '%s'", field->name, str);
227
228 return 0;
229 }
230
231 static int
parse_json_log_level(struct option_field const * opt,json_t * json,void * result)232 parse_json_log_level(struct option_field const *opt, json_t *json,
233 void *result)
234 {
235 char const *string;
236 int error;
237
238 error = parse_json_string(json, opt->name, &string);
239 return error ? error : parse_argv_log_level(opt, string, result);
240 }
241
242 static int
parse_json_log_output(struct option_field const * opt,json_t * json,void * result)243 parse_json_log_output(struct option_field const *opt, json_t *json,
244 void *result)
245 {
246 char const *string;
247 int error;
248
249 error = parse_json_string(json, opt->name, &string);
250 return error ? error : parse_argv_log_output(opt, string, result);
251 }
252
253 static int
parse_json_log_facility(struct option_field const * opt,json_t * json,void * result)254 parse_json_log_facility(struct option_field const *opt, json_t *json,
255 void *result)
256 {
257 char const *string;
258 int error;
259
260 error = parse_json_string(json, opt->name, &string);
261 return error ? error : parse_argv_log_facility(opt, string, result);
262 }
263
264 const struct global_type gt_log_level = {
265 .has_arg = required_argument,
266 .size = sizeof(uint8_t),
267 .print = print_log_level,
268 .parse.argv = parse_argv_log_level,
269 .parse.json = parse_json_log_level,
270 .arg_doc = LOG_LEVEL_VALUE_ERROR
271 "|" LOG_LEVEL_VALUE_WARNING
272 "|" LOG_LEVEL_VALUE_INFO
273 "|" LOG_LEVEL_VALUE_DEBUG,
274 };
275
276 const struct global_type gt_log_output = {
277 .has_arg = required_argument,
278 .size = sizeof(enum log_output),
279 .print = print_log_output,
280 .parse.argv = parse_argv_log_output,
281 .parse.json = parse_json_log_output,
282 .arg_doc = LOG_OUTPUT_VALUE_SYSLOG "|" LOG_OUTPUT_VALUE_CONSOLE,
283 };
284
285 const struct global_type gt_log_facility = {
286 .has_arg = required_argument,
287 .size = sizeof(uint32_t),
288 .print = print_log_facility,
289 .parse.argv = parse_argv_log_facility,
290 .parse.json = parse_json_log_facility,
291 .arg_doc = LOG_FACILITY_VALUE_AUTH
292 "|" LOG_FACILITY_VALUE_AUTHPRIV
293 "|" LOG_FACILITY_VALUE_CRON
294 "|" LOG_FACILITY_VALUE_DAEMON
295 "|" LOG_FACILITY_VALUE_FTP
296 "|" LOG_FACILITY_VALUE_LPR
297 "|" LOG_FACILITY_VALUE_MAIL
298 "|" LOG_FACILITY_VALUE_NEWS
299 "|" LOG_FACILITY_VALUE_USER
300 "|" LOG_FACILITY_VALUE_UUCP
301 "|" LOG_FACILITY_VALUE_LOCAL0
302 "|" LOG_FACILITY_VALUE_LOCAL1
303 "|" LOG_FACILITY_VALUE_LOCAL2
304 "|" LOG_FACILITY_VALUE_LOCAL3
305 "|" LOG_FACILITY_VALUE_LOCAL4
306 "|" LOG_FACILITY_VALUE_LOCAL5
307 "|" LOG_FACILITY_VALUE_LOCAL6
308 "|" LOG_FACILITY_VALUE_LOCAL7,
309 };
310