comparison toys/pending/syslogd.c @ 1025:f19286ac3e7f draft

syslogd: cleanup - simplify resolveconfig() -> now logger_lookup is also used in syslogd.c - inline addrfds - small cosmetical changes in parse_config_file()
author Felix Janda <felix.janda at posteo.de>
date Fri, 23 Aug 2013 22:19:55 +0200
parents 63b8e54d2c6f
children 09cc81f6e411
comparison
equal deleted inserted replaced
1024:63b8e54d2c6f 1025:f19286ac3e7f
72 uint8_t level[LOG_NFACILITIES]; 72 uint8_t level[LOG_NFACILITIES];
73 int logfd; 73 int logfd;
74 struct sockaddr_in saddr; 74 struct sockaddr_in saddr;
75 }; 75 };
76 76
77 // Lookup numerical code from name
78 // Also used in logger
79 int logger_lookup(int where, char *key)
80 {
81 CODE *w = ((CODE *[]){facilitynames, prioritynames})[where];
82
83 for (; w->c_name; w++)
84 if (!strcasecmp(key, w->c_name)) return w->c_val;
85
86 return -1;
87 }
88
89 //search the given name and return its value
90 static char *dec(int val, CODE *clist)
91 {
92 for (; clist->c_name; clist++)
93 if (val == clist->c_val) return clist->c_name;
94 return itoa(val);
95 }
96
77 // Adds opened socks to rfds for select() 97 // Adds opened socks to rfds for select()
78 static int addrfds(void) 98 static int addrfds(void)
79 { 99 {
80 struct unsocks *sock; 100 struct unsocks *sock;
81 int ret = 0; 101 int ret = 0;
140 * recurses the logfile list and resolves config 160 * recurses the logfile list and resolves config
141 * for evry file and updates facilty and log level bits. 161 * for evry file and updates facilty and log level bits.
142 */ 162 */
143 static int resolve_config(struct logfile *file) 163 static int resolve_config(struct logfile *file)
144 { 164 {
145 char *tk, *fac, *lvl, *tmp, *nfac; 165 char *tk, *tmp = xstrdup(file->config);
146 int count = 0; 166
147 unsigned facval = 0;
148 uint8_t set, levval, neg;
149 CODE *val = NULL;
150
151 tmp = xstrdup(file->config);
152 for (tk = strtok(tmp, "; \0"); tk; tk = strtok(NULL, "; \0")) { 167 for (tk = strtok(tmp, "; \0"); tk; tk = strtok(NULL, "; \0")) {
153 fac = tk; 168 char *fac = tk, *lvl;
169 int i = 0;
170 unsigned facval = 0;
171 uint8_t set, levval, bits = 0;
172
154 tk = strchr(fac, '.'); 173 tk = strchr(fac, '.');
155 if (!tk) return -1; 174 if (!tk) return -1;
156 *tk = '\0'; 175 *tk = '\0';
157 lvl = tk + 1; 176 lvl = tk + 1;
158 177
159 while(1) { 178 for (;;) {
160 count = 0; 179 char *nfac = strchr(fac, ',');
180
181 if (nfac) *nfac = '\0';
161 if (*fac == '*') { 182 if (*fac == '*') {
162 facval = 0xFFFFFFFF; 183 facval = 0xFFFFFFFF;
163 fac++; 184 if (fac[1]) return -1;
164 } 185 } else {
165 nfac = strchr(fac, ','); 186 if ((i = logger_lookup(0, fac)) == -1) return -1;
166 if (nfac) *nfac = '\0'; 187 facval |= (1 << LOG_FAC(i));
167 while (*fac && ((CODE*) &facilitynames[count])->c_name) { 188 }
168 val = (CODE*) &facilitynames[count]; 189 if (nfac) fac = nfac + 1;
169 if (!strcmp(fac, val->c_name)) {
170 facval |= (1<<LOG_FAC(val->c_val));
171 break;
172 }
173 count++;
174 }
175 if (((CODE*) &facilitynames[count])->c_val == -1)
176 return -1;
177
178 if (nfac) fac = nfac+1;
179 else break; 190 else break;
180 } 191 }
181 192
182 count = 0;
183 set = 0;
184 levval = 0; 193 levval = 0;
185 neg = 0; 194 for (tk = "!=*"; tk; tk++, bits <<= 1) {
186 if (*lvl == '!') { 195 if (*lvl == *tk) {
187 neg = 1; 196 bits++;
188 lvl++; 197 lvl++;
189 } 198 }
190 if (*lvl == '=') { 199 }
191 set = 1; 200 if (bits & 1) levval = 0xff;
192 lvl++; 201 if (lvl) {
193 } 202 if ((i = logger_lookup(1, lvl)) == -1) return -1;
194 if (*lvl == '*') { 203 levval |= (bits & 2) ? LOG_MASK(i) : LOG_UPTO(i);
195 levval = 0xFF; 204 if (bits & 4) levval = ~levval;
196 lvl++; 205 }
197 } 206
198 while (*lvl && ((CODE*) &prioritynames[count])->c_name) { 207 for (i = 0, set = levval; set; set >>= 1, i++)
199 val = (CODE*) &prioritynames[count]; 208 if (set & 0x1) file->facility[i] |= facval;
200 if (!strcmp(lvl, val->c_name)) { 209 for (i = 0; i < LOG_NFACILITIES; facval >>= 1, i++)
201 levval |= set ? LOG_MASK(val->c_val):LOG_UPTO(val->c_val); 210 if (facval & 0x1) file->level[i] |= levval;
202 if (neg) levval = ~levval;
203 break;
204 }
205 count++;
206 }
207 if (((CODE*) &prioritynames[count])->c_val == -1) return -1;
208
209 count = 0;
210 set = levval;
211 while(set) {
212 if (set & 0x1) file->facility[count] |= facval;
213 set >>= 1;
214 count++;
215 }
216 for (count = 0; count < LOG_NFACILITIES; count++) {
217 if (facval & 0x1) file->level[count] |= levval;
218 facval >>= 1;
219 }
220 } 211 }
221 free(tmp); 212 free(tmp);
222 213
223 return 0; 214 return 0;
224 } 215 }
225 216
226 // Parse config file and update the log file list. 217 // Parse config file and update the log file list.
227 static int parse_config_file(void) 218 static int parse_config_file(void)
228 { 219 {
229 struct logfile *file; 220 struct logfile *file;
230 FILE *fp = NULL; 221 FILE *fp;
231 char *confline = NULL, *tk = NULL, *tokens[2] = {NULL, NULL}; 222 char *confline = NULL, *tk = NULL, *tokens[2] = {NULL, NULL};
232 int len, linelen, tcount, lineno = 0; 223 int len, tcount, lineno = 0;
224 size_t linelen;
233 struct arg_list *node; 225 struct arg_list *node;
234 /* 226 /*
235 * if -K then open only /dev/kmsg 227 * if -K then open only /dev/kmsg
236 * all other log files are neglected 228 * all other log files are neglected
237 * thus no need to open config either. 229 * thus no need to open config either.
251 * if -R then add remote host to log list 243 * if -R then add remote host to log list
252 * if -L is not provided all other log 244 * if -L is not provided all other log
253 * files are neglected thus no need to 245 * files are neglected thus no need to
254 * open config either so just return. 246 * open config either so just return.
255 */ 247 */
256 if (toys.optflags & FLAG_R) { 248 if (toys.optflags & FLAG_R) {
257 node = xzalloc(sizeof(struct arg_list)); 249 node = xzalloc(sizeof(struct arg_list));
258 file = xzalloc(sizeof(struct logfile)); 250 file = xzalloc(sizeof(struct logfile));
259 file->filename = xmsprintf("@%s",TT.remote_log); 251 file->filename = xmsprintf("@%s",TT.remote_log);
260 file->isNetwork = 1; 252 file->isNetwork = 1;
261 file->config = "*.*"; 253 file->config = "*.*";
262 memset(file->level, 0xFF, sizeof(file->level)); 254 memset(file->level, 0xFF, sizeof(file->level));
263 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); 255 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility));
264 node->arg = (char*) file; 256 node->arg = (char*) file;
265 TT.lfiles = node; 257 TT.lfiles = node;
266 if (!(toys.optflags & FLAG_L))return 0; 258 if (!(toys.optflags & FLAG_L)) return 0;
267 } 259 }
268 /* 260 /*
269 * Read config file and add logfiles to the list 261 * Read config file and add logfiles to the list
270 * with their configuration. 262 * with their configuration.
271 */ 263 */
272 fp = fopen(TT.config_file, "r"); 264 fp = fopen(TT.config_file, "r");
273 if (!fp && (toys.optflags & FLAG_f)) 265 if (!fp && (toys.optflags & FLAG_f))
274 perror_exit("can't open '%s'", TT.config_file); 266 perror_exit("can't open '%s'", TT.config_file);
275 267
276 for (len = 0, linelen = 0; fp;) { 268 for (len = 0, linelen = 0; fp;) {
277 len = getline(&confline, (size_t*) &linelen, fp); 269 len = getline(&confline, &linelen, fp);
278 if (len <= 0) break; 270 if (len <= 0) break;
279 lineno++; 271 lineno++;
280 for (; *confline == ' '; confline++, len--) ; 272 for (; *confline == ' '; confline++, len--) ;
281 if ((confline[0] == '#') || (confline[0] == '\n')) continue; 273 if ((confline[0] == '#') || (confline[0] == '\n')) continue;
282 for (tcount = 0, tk = strtok(confline, " \t"); tk && (tcount < 2); tk = 274 for (tcount = 0, tk = strtok(confline, " \t"); tk && (tcount < 2); tk =
332 if (!fp){ 324 if (!fp){
333 node = xzalloc(sizeof(struct arg_list)); 325 node = xzalloc(sizeof(struct arg_list));
334 file = xzalloc(sizeof(struct logfile)); 326 file = xzalloc(sizeof(struct logfile));
335 file->filename = (toys.optflags & FLAG_O) ? 327 file->filename = (toys.optflags & FLAG_O) ?
336 TT.logfile : "/var/log/messages"; //DEFLOGFILE 328 TT.logfile : "/var/log/messages"; //DEFLOGFILE
337 file->isNetwork = 0;
338 file->config = "*.*"; 329 file->config = "*.*";
339 memset(file->level, 0xFF, sizeof(file->level)); 330 memset(file->level, 0xFF, sizeof(file->level));
340 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); 331 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility));
341 node->arg = (char*) file; 332 node->arg = (char*) file;
342 node->next = TT.lfiles; 333 node->next = TT.lfiles;
343 TT.lfiles = node; 334 TT.lfiles = node;
344 } 335 } else fclose(fp);
345 if (fp) {
346 fclose(fp);
347 fp = NULL;
348 }
349 return 0; 336 return 0;
350 } 337 }
351 338
352 // open every log file in list. 339 // open every log file in list.
353 static void open_logfiles(void) 340 static void open_logfiles(void)
422 } 409 }
423 } 410 }
424 return write(tf->logfd, toybuf, len); 411 return write(tf->logfd, toybuf, len);
425 } 412 }
426 413
427 // Lookup numerical code from name
428 // Only used in logger
429 int logger_lookup(int where, char *key)
430 {
431 CODE *w = ((CODE *[]){facilitynames, prioritynames})[where];
432
433 for (; w->c_name; w++)
434 if (!strcasecmp(key, w->c_name)) return w->c_val;
435
436 return -1;
437 }
438
439 //search the given name and return its value
440 static char *dec(int val, CODE *clist)
441 {
442 const CODE *c;
443
444 for (c = clist; c->c_name; c++)
445 if (val == c->c_val) return c->c_name;
446 return itoa(val);
447 }
448
449 // Compute priority from "facility.level" pair
450 static void priority_to_string(int pri, char **facstr, char **lvlstr)
451 {
452 int fac,lev;
453
454 fac = LOG_FAC(pri);
455 lev = LOG_PRI(pri);
456 *facstr = dec(fac<<3, facilitynames);
457 *lvlstr = dec(lev, prioritynames);
458 }
459
460 //Parse messege and write to file. 414 //Parse messege and write to file.
461 static void logmsg(char *msg, int len) 415 static void logmsg(char *msg, int len)
462 { 416 {
463 time_t now; 417 time_t now;
464 char *p, *ts, *lvlstr, *facstr; 418 char *p, *ts, *lvlstr, *facstr;
489 fac = LOG_FAC(pri); 443 fac = LOG_FAC(pri);
490 lvl = LOG_PRI(pri); 444 lvl = LOG_PRI(pri);
491 445
492 if (toys.optflags & FLAG_K) len = sprintf(toybuf, "<%d> %s\n", pri, msg); 446 if (toys.optflags & FLAG_K) len = sprintf(toybuf, "<%d> %s\n", pri, msg);
493 else { 447 else {
494 priority_to_string(pri, &facstr, &lvlstr); 448 facstr = dec(LOG_FAC(pri), facilitynames);
449 lvlstr = dec(LOG_PRI(pri), prioritynames);
495 450
496 p = "local"; 451 p = "local";
497 if (!uname(&uts)) p = uts.nodename; 452 if (!uname(&uts)) p = uts.nodename;
498 if (toys.optflags & FLAG_S) len = sprintf(toybuf, "%s %s\n", ts, msg); 453 if (toys.optflags & FLAG_S) len = sprintf(toybuf, "%s %s\n", ts, msg);
499 else len = sprintf(toybuf, "%s %s %s.%s %s\n", ts, p, facstr, lvlstr, msg); 454 else len = sprintf(toybuf, "%s %s %s.%s %s\n", ts, p, facstr, lvlstr, msg);