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