--- syslogd.c-2.2 Tue Oct 30 17:33:46 2001 +++ syslogd.c Tue Oct 30 16:51:46 2001 @@ -572,8 +572,6 @@ #define MAXUNAMES 20 /* maximum number of user names */ #define MAXFNAME 200 /* max file pathname length */ -#define TABLE_NOPRI 0 /* Value to indicate no priority in f_pmask */ -#define TABLE_ALLPRI 0xFF /* Value to indicate all priorities in f_pmask */ #ifndef LOG_MAKEPRI #define LOG_MAKEPRI(f,p) (((f) << 3) + (p)) #endif @@ -613,6 +611,7 @@ struct filed { struct filed *f_next; /* next in linked list */ + int f_num; /* For debugging */ short f_type; /* entry type, see below */ short f_file; /* file descriptor */ time_t f_time; /* time this was last written */ @@ -635,6 +634,17 @@ int f_flags; /* store some additional flags */ }; + +/* + * Map (facility, pri) into a list of files + * + */ + +#define LOG_MAXPRI LOG_MAKEPRI (LOG_NFACILITIES + 1, 0) + +struct filed *Null_File = NULL; /* Should never change */ +struct filed **file_map [LOG_MAXPRI]; + /* * Intervals at which we flush out "message repeated" messages, * in seconds after previous message is logged. After each flush, @@ -682,6 +692,10 @@ #define INTERNAL_NOPRI 0x10 /* the "no priority" priority */ #define INTERNAL_MARK LOG_MAKEPRI(LOG_NFACILITIES, 0) /* mark "facility" */ +#ifndef LOG_NPRI +#define LOG_NPRI LOG_MAKEPRI (1, 0) +#endif + typedef struct code { char *c_name; int c_val; @@ -700,7 +714,6 @@ {"panic", LOG_EMERG}, /* DEPRECATED */ {"warn", LOG_WARNING}, /* DEPRECATED */ {"warning", LOG_WARNING}, - {"*", TABLE_ALLPRI}, {NULL, -1} }; @@ -1552,8 +1565,7 @@ const char *from; int flags; { - struct filed *f; - int fac, prilev; + struct filed *f, **pf; int msglen; char *timestamp; @@ -1581,11 +1593,7 @@ } /* extract facility and priority level */ - if (flags & MARK) - fac = LOG_NFACILITIES; - else - fac = LOG_FAC(pri); - prilev = LOG_PRI(pri); + if (pri >= LOG_MAXPRI) pri = DEFUPRI; /* log the message to the particular outputs */ if (!Initialized) { @@ -1602,12 +1610,10 @@ #endif return; } - for (f = Files; f; f = f->f_next) { - /* skip messages that are incorrect priority */ - if ( (f->f_pmask[fac] == TABLE_NOPRI) || \ - ((f->f_pmask[fac] & (1<f_type == F_CONSOLE && (flags & IGN_CONS)) continue; @@ -2076,7 +2082,8 @@ now = time(0); MarkSeq += TIMERINTVL; if (MarkSeq >= MarkInterval) { - logmsg(LOG_INFO, "-- MARK --", LocalHostName, ADDDATE|MARK); + logmsg(LOG_INFO|INTERNAL_MARK, + "-- MARK --", LocalHostName, ADDDATE|MARK); MarkSeq = 0; } @@ -2194,6 +2201,7 @@ #else char cline[BUFSIZ]; #endif + int files; struct servent *sp; sp = getservbyname("syslog", "udp"); @@ -2212,6 +2220,15 @@ Initialized = 0; dprintf("Initializing log structures.\n"); + + Null_File = NULL; + + for (i = 0; i < LOG_MAXPRI; ++i) { + if (file_map[i] && file_map[i] != &Null_File) + free (file_map[i]); + file_map[i] = &Null_File; + } + for (f = Files; f; f = next) { /* flush any pending output */ @@ -2256,6 +2273,10 @@ /* * Foreach line in the conf table, open that file. */ + + files = 1; + f = NULL; + #if CONT_LINE cline = cbuf; while (fgets(cline, sizeof(cbuf) - (cline - cbuf), cf) != NULL) { @@ -2287,19 +2308,27 @@ cline = cbuf; #endif *++p = '\0'; - f = (struct filed *)calloc(1, sizeof(*f)); - *nextp = f; - nextp = &f->f_next; + if (!f) f = (struct filed *) malloc(sizeof(*f)); #if CONT_LINE cfline(cbuf, f); #else cfline(cline, f); #endif + if (f->f_type == F_UNUSED) continue; + if (f->f_type == F_FORW || f->f_type == F_FORW_SUSP || f->f_type == F_FORW_UNKN) { Forwarding++; } + + f->f_num = files++; + *nextp = f; + nextp = &f->f_next; + + f = NULL; } + if (f) free (f); + /* close the configuration file */ (void) fclose(cf); @@ -2334,16 +2363,40 @@ inetm = finet; #endif + /* Work our (fac,pri)->file map */ + + files *= sizeof (struct filed *); + + for (f = Files; f; f = f->f_next) { + int fac; + for (fac = 0; fac < LOG_NFACILITIES + 1; ++fac) { + u_char mask = f->f_pmask [fac]; + int pri; + for (pri = 0; pri < LOG_NPRI; ++pri) { + int facpri; + struct filed **pf; + if (!(mask & (1 << pri))) continue; + facpri = LOG_MAKEPRI (fac, pri); + if (file_map [facpri] == &Null_File) { + pf = file_map [facpri] = malloc(files); + } + else { + for (pf = file_map[facpri]; *pf; ++pf); + } + *pf++ = f; + *pf = NULL; + } + } + } + Initialized = 1; if ( Debug ) { - int lognum = 0; - - for (f = Files; f; f = f->f_next, ++lognum) { + for (f = Files; f; f = f->f_next) { if (f->f_type != F_UNUSED) { - printf ("%2d: ", lognum); + printf ("%2d: ", f->f_num); for (i = 0; i <= LOG_NFACILITIES; i++) - if (f->f_pmask[i] == TABLE_NOPRI) + if (!f->f_pmask[i]) printf(" X "); else printf("%2X ", f->f_pmask[i]); @@ -2370,6 +2423,16 @@ printf("\n"); } } + + for (i = 0; i < LOG_MAXPRI; ++i) { + struct filed **pf; + if (file_map [i] == &Null_File) continue; + printf ("%s => ",textpri (i)); + for (pf = file_map [i]; (f = *pf); ++pf) { + printf ("%d, ", f->f_num); + } + printf ("\n"); + } } if ( AcceptRemote ) @@ -2393,9 +2456,6 @@ (void) signal(SIGHUP, sighup_handler); dprintf("syslogd: restarted.\n"); } -#if FALSE - }}} /* balance parentheses for emacs */ -#endif /* * Crack a configuration file line @@ -2407,11 +2467,9 @@ { char *p; char *q; - int i, i2; + int i; char *bp; int pri; - int singlpri = 0; - int ignorepri = 0; int syncfile; #ifdef SYSLOG_INET struct hostent *hp; @@ -2424,21 +2482,52 @@ errno = 0; /* keep strerror() stuff out of logerror messages */ /* clear out file entry */ -#ifndef SYSV + memset((char *) f, 0, sizeof(*f)); -#endif - for (i = 0; i <= LOG_NFACILITIES; i++) { - f->f_pmask[i] = TABLE_NOPRI; - f->f_flags = 0; - } /* scan through the list of selectors */ for (p = line; *p && *p != '\t' && *p != ' ';) { + enum PRI_CMP {PRI_LT = 1, PRI_EQ = 2, PRI_GT = 4} cmp, not; + int done; + /* find the end of this facility name list */ for (q = p; *q && *q != '\t' && *q++ != '.'; ) continue; + /* get the priority comparison */ + + not = 0; + if (*q == '!') { + not = PRI_LT|PRI_EQ|PRI_GT; + q++; + } + + cmp = 0; + for (done = 0; !done;) { + switch (*q) { + case '<': + cmp |= PRI_LT; + q++; + break; + case '=': + cmp |= PRI_EQ; + q++; + break; + case '>': + cmp |= PRI_GT; + q++; + break; + default: + done++; + break; + } + } + + if (!cmp) cmp = PRI_EQ | PRI_GT; + + cmp ^= not; + /* collect priority name */ for (bp = buf; *q && !strchr("\t ,;", *q); ) *bp++ = *q++; @@ -2449,104 +2538,46 @@ q++; /* decode priority name */ - if ( *buf == '!' ) { - ignorepri = 1; - for (bp=buf; *(bp+1); bp++) - *bp=*(bp+1); - *bp='\0'; - } - else { - ignorepri = 0; - } - if ( *buf == '=' ) - { - singlpri = 1; - pri = decode(&buf[1], prioritynames); - } + if (*buf == '*') + pri = LOG_PRIMASK + 1; else { - singlpri = 0; pri = decode(buf, prioritynames); - } - - if (pri < 0) { - (void) snprintf(xbuf, sizeof(xbuf), "unknown priority name \"%s\"", buf); - logerror(xbuf); - return; + if (pri < 0) { + (void) snprintf(xbuf, sizeof(xbuf), "unknown priority name \"%s\"", buf); + logerror(xbuf); + return; + } } /* scan facilities */ while (*p && !strchr("\t .;", *p)) { + int from, to; for (bp = buf; *p && !strchr("\t ,;.", *p); ) *bp++ = *p++; *bp = '\0'; if (*buf == '*') { - for (i = 0; i <= LOG_NFACILITIES; i++) { - if ( pri == INTERNAL_NOPRI ) { - if ( ignorepri ) - f->f_pmask[i] = TABLE_ALLPRI; - else - f->f_pmask[i] = TABLE_NOPRI; - } - else if ( singlpri ) { - if ( ignorepri ) - f->f_pmask[i] &= ~(1<f_pmask[i] |= (1<f_pmask[i] = TABLE_NOPRI; - else - f->f_pmask[i] = TABLE_ALLPRI; - } - else - { - if ( ignorepri ) - for (i2= 0; i2 <= pri; ++i2) - f->f_pmask[i] &= ~(1<f_pmask[i] |= (1<f_pmask[i >> 3] = TABLE_ALLPRI; - else - f->f_pmask[i >> 3] = TABLE_NOPRI; - } else if ( singlpri ) { - if ( ignorepri ) - f->f_pmask[i >> 3] &= ~(1<f_pmask[i >> 3] |= (1<f_pmask[i >> 3] = TABLE_NOPRI; - else - f->f_pmask[i >> 3] = TABLE_ALLPRI; - } else { - if ( ignorepri ) - for (i2= 0; i2 <= pri; ++i2) - f->f_pmask[i >> 3] &= ~(1<f_pmask[i >> 3] |= (1< j)))) + f->f_pmask[i] |= (1 << j); + } + while (*p == ',' || *p == ' ') p++; }