comparison toys/pending/syslogd.c @ 1027:4b0ad1c7af42 draft

syslogd: cleanup - fix bugs in previous cleanups - remove config from struct logfile - simplify parse_config()
author Felix Janda <felix.janda at posteo.de>
date Sat, 24 Aug 2013 12:04:45 +0200
parents 09cc81f6e411
children 58bfd974216d
comparison
equal deleted inserted replaced
1026:09cc81f6e411 1027:4b0ad1c7af42
47 47
48 // Log file entry to log into. 48 // Log file entry to log into.
49 struct logfile { 49 struct logfile {
50 struct logfile *next; 50 struct logfile *next;
51 char *filename; 51 char *filename;
52 char *config;
53 int isNetwork; 52 int isNetwork;
54 uint32_t facility[8]; 53 uint32_t facility[8];
55 uint8_t level[LOG_NFACILITIES]; 54 uint8_t level[LOG_NFACILITIES];
56 int logfd; 55 int logfd;
57 struct sockaddr_in saddr; 56 struct sockaddr_in saddr;
144 143
145 /* 144 /*
146 * recurses the logfile list and resolves config 145 * recurses the logfile list and resolves config
147 * for evry file and updates facilty and log level bits. 146 * for evry file and updates facilty and log level bits.
148 */ 147 */
149 static int resolve_config(struct logfile *file) 148 static int resolve_config(struct logfile *file, char *config)
150 { 149 {
151 char *tk, *tmp = xstrdup(file->config); 150 char *tk;
152 151
153 for (tk = strtok(tmp, "; \0"); tk; tk = strtok(NULL, "; \0")) { 152 for (tk = strtok(config, "; \0"); tk; tk = strtok(NULL, "; \0")) {
154 char *fac = tk, *lvl; 153 char *fac = tk, *lvl;
155 int i = 0; 154 int i = 0;
156 unsigned facval = 0; 155 unsigned facval = 0;
157 uint8_t set, levval, bits = 0; 156 uint8_t set, levval, bits = 0;
158 157
175 if (nfac) fac = nfac + 1; 174 if (nfac) fac = nfac + 1;
176 else break; 175 else break;
177 } 176 }
178 177
179 levval = 0; 178 levval = 0;
180 for (tk = "!=*"; tk; tk++, bits <<= 1) { 179 for (tk = "!=*"; *tk; tk++, bits <<= 1) {
181 if (*lvl == *tk) { 180 if (*lvl == *tk) {
182 bits++; 181 bits++;
183 lvl++; 182 lvl++;
184 } 183 }
185 } 184 }
193 for (i = 0, set = levval; set; set >>= 1, i++) 192 for (i = 0, set = levval; set; set >>= 1, i++)
194 if (set & 0x1) file->facility[i] |= facval; 193 if (set & 0x1) file->facility[i] |= facval;
195 for (i = 0; i < LOG_NFACILITIES; facval >>= 1, i++) 194 for (i = 0; i < LOG_NFACILITIES; facval >>= 1, i++)
196 if (facval & 0x1) file->level[i] |= levval; 195 if (facval & 0x1) file->level[i] |= levval;
197 } 196 }
198 free(tmp);
199 197
200 return 0; 198 return 0;
201 } 199 }
202 200
203 // Parse config file and update the log file list. 201 // Parse config file and update the log file list.
204 static int parse_config_file(void) 202 static int parse_config_file(void)
205 { 203 {
206 struct logfile *file; 204 struct logfile *file;
207 FILE *fp; 205 FILE *fp;
208 char *confline = NULL, *tk = NULL, *tokens[2] = {NULL, NULL}; 206 char *confline, *tk[2];
209 int len, tcount, lineno = 0; 207 int len, lineno = 0;
210 size_t linelen; 208 size_t linelen;
211 /* 209 /*
212 * if -K then open only /dev/kmsg 210 * if -K then open only /dev/kmsg
213 * all other log files are neglected 211 * all other log files are neglected
214 * thus no need to open config either. 212 * thus no need to open config either.
215 */ 213 */
216 if (toys.optflags & FLAG_K) { 214 if (toys.optflags & FLAG_K) {
217 file = xzalloc(sizeof(struct logfile)); 215 file = xzalloc(sizeof(struct logfile));
218 file->filename = "/dev/kmsg"; 216 file->filename = "/dev/kmsg";
219 file->config = "*.*";
220 memset(file->level, 0xFF, sizeof(file->level)); 217 memset(file->level, 0xFF, sizeof(file->level));
221 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); 218 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility));
222 TT.lfiles = file; 219 TT.lfiles = file;
223 return 0; 220 return 0;
224 } 221 }
230 */ 227 */
231 if (toys.optflags & FLAG_R) { 228 if (toys.optflags & FLAG_R) {
232 file = xzalloc(sizeof(struct logfile)); 229 file = xzalloc(sizeof(struct logfile));
233 file->filename = xmsprintf("@%s",TT.remote_log); 230 file->filename = xmsprintf("@%s",TT.remote_log);
234 file->isNetwork = 1; 231 file->isNetwork = 1;
235 file->config = "*.*";
236 memset(file->level, 0xFF, sizeof(file->level)); 232 memset(file->level, 0xFF, sizeof(file->level));
237 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); 233 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility));
238 TT.lfiles = file; 234 TT.lfiles = file;
239 if (!(toys.optflags & FLAG_L)) return 0; 235 if (!(toys.optflags & FLAG_L)) return 0;
240 } 236 }
244 */ 240 */
245 fp = fopen(TT.config_file, "r"); 241 fp = fopen(TT.config_file, "r");
246 if (!fp && (toys.optflags & FLAG_f)) 242 if (!fp && (toys.optflags & FLAG_f))
247 perror_exit("can't open '%s'", TT.config_file); 243 perror_exit("can't open '%s'", TT.config_file);
248 244
249 for (len = 0, linelen = 0; fp;) { 245 for (linelen = 0; fp;) {
246 confline = NULL;
250 len = getline(&confline, &linelen, fp); 247 len = getline(&confline, &linelen, fp);
251 if (len <= 0) break; 248 if (len <= 0) break;
252 lineno++; 249 lineno++;
253 for (; *confline == ' '; confline++, len--) ; 250 for (; *confline == ' '; confline++, len--) ;
254 if ((confline[0] == '#') || (confline[0] == '\n')) continue; 251 if ((confline[0] == '#') || (confline[0] == '\n')) continue;
255 for (tcount = 0, tk = strtok(confline, " \t"); tk && (tcount < 2); tk = 252 tk[0] = confline;
256 strtok(NULL, " \t"), tcount++) { 253 for (; len && !(*tk[0]==' ' || *tk[0]=='\t'); tk[0]++, len--);
257 if (tcount == 2) { 254 for (tk[1] = tk[0]; len && (*tk[1]==' ' || *tk[1]=='\t'); tk[1]++, len--);
258 error_msg("error in '%s' at line %d", TT.config_file, lineno); 255 if (!len || (len == 1 && *tk[1] == '\n')) {
259 return -1; 256 error_msg("error in '%s' at line %d", TT.config_file, lineno);
260 }
261 tokens[tcount] = xstrdup(tk);
262 }
263 if (tcount <= 1 || tcount > 2) {
264 if (tokens[0]) free(tokens[0]);
265 error_msg("bad line %d: 1 tokens found, 2 needed", lineno);
266 return -1; 257 return -1;
267 } 258 }
268 tk = (tokens[1] + (strlen(tokens[1]) - 1)); 259 else if (*(tk[1] + len - 1) == '\n') *(tk[1] + len - 1) = '\0';
269 if (*tk == '\n') *tk = '\0'; 260 *tk[0] = '\0';
270 if (*tokens[1] == '\0') { 261 if (*tk[1] != '*') {
271 error_msg("bad line %d: 1 tokens found, 2 needed", lineno);
272 return -1;
273 }
274 if (*tokens[1] != '*') {
275 file = TT.lfiles; 262 file = TT.lfiles;
276 while (file && !strcmp(file->filename, tokens[1])) file = file->next; 263 while (file && strcmp(file->filename, tk[1])) file = file->next;
277 if (!file) { 264 if (!file) {
278 file = xzalloc(sizeof(struct logfile)); 265 file = xzalloc(sizeof(struct logfile));
279 file->config = xstrdup(tokens[0]); 266 file->filename = xstrdup(tk[1]);
280 if (resolve_config(file)==-1) {
281 error_msg("error in '%s' at line %d", TT.config_file, lineno);
282 return -1;
283 }
284 file->filename = xstrdup(tokens[1]);
285 if (*file->filename == '@') file->isNetwork = 1; 267 if (*file->filename == '@') file->isNetwork = 1;
286 file->next = TT.lfiles; 268 file->next = TT.lfiles;
287 TT.lfiles = file; 269 TT.lfiles = file;
288 } else { 270 }
289 int rel = strlen(file->config) + strlen(tokens[0]) + 2; 271 if (resolve_config(file, confline) == -1) {
290 file->config = xrealloc(file->config, rel); 272 error_msg("error in '%s' at line %d", TT.config_file, lineno);
291 sprintf(file->config, "%s;%s", file->config, tokens[0]); 273 return -1;
292 } 274 }
293 } 275 }
294 if (tokens[0]) free(tokens[0]);
295 if (tokens[1]) free(tokens[1]);
296 free(confline); 276 free(confline);
297 confline = NULL;
298 } 277 }
299 /* 278 /*
300 * Can't open config file or support is not enabled 279 * Can't open config file or support is not enabled
301 * adding default logfile to the head of list. 280 * adding default logfile to the head of list.
302 */ 281 */
303 if (!fp){ 282 if (!fp){
304 file = xzalloc(sizeof(struct logfile)); 283 file = xzalloc(sizeof(struct logfile));
305 file->filename = (toys.optflags & FLAG_O) ? 284 file->filename = (toys.optflags & FLAG_O) ?
306 TT.logfile : "/var/log/messages"; //DEFLOGFILE 285 TT.logfile : "/var/log/messages"; //DEFLOGFILE
307 file->config = "*.*";
308 memset(file->level, 0xFF, sizeof(file->level)); 286 memset(file->level, 0xFF, sizeof(file->level));
309 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); 287 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility));
310 file->next = TT.lfiles; 288 file->next = TT.lfiles;
311 TT.lfiles = file; 289 TT.lfiles = file;
312 } else fclose(fp); 290 } else fclose(fp);
419 fac = LOG_FAC(pri); 397 fac = LOG_FAC(pri);
420 lvl = LOG_PRI(pri); 398 lvl = LOG_PRI(pri);
421 399
422 if (toys.optflags & FLAG_K) len = sprintf(toybuf, "<%d> %s\n", pri, msg); 400 if (toys.optflags & FLAG_K) len = sprintf(toybuf, "<%d> %s\n", pri, msg);
423 else { 401 else {
424 facstr = dec(LOG_FAC(pri), facilitynames); 402 facstr = dec(pri & LOG_FACMASK, facilitynames);
425 lvlstr = dec(LOG_PRI(pri), prioritynames); 403 lvlstr = dec(LOG_PRI(pri), prioritynames);
426 404
427 p = "local"; 405 p = "local";
428 if (!uname(&uts)) p = uts.nodename; 406 if (!uname(&uts)) p = uts.nodename;
429 if (toys.optflags & FLAG_S) len = sprintf(toybuf, "%s %s\n", ts, msg); 407 if (toys.optflags & FLAG_S) len = sprintf(toybuf, "%s %s\n", ts, msg);