+
+/*
+ * INIT -- Initialize syslogd from configuration table
+ */
+
+init()
+{
+ register int i;
+ register FILE *cf;
+ register struct filed *f, *next, **nextp;
+ register char *p;
+ char cline[BUFSIZ];
+
+ dprintf("init\n");
+
+ /*
+ * Close all open log files.
+ */
+ Initialized = 0;
+ for (f = Files; f != NULL; f = next) {
+ /* flush any pending output */
+ if (f->f_prevcount)
+ fprintlog(f, 0, (char *)NULL);
+
+ switch (f->f_type) {
+ case F_FILE:
+ case F_TTY:
+ case F_CONSOLE:
+ (void) close(f->f_file);
+ break;
+ }
+ next = f->f_next;
+ free((char *) f);
+ }
+ Files = NULL;
+ nextp = &Files;
+
+ /* open the configuration file */
+ if ((cf = fopen(ConfFile, "r")) == NULL) {
+ dprintf("cannot open %s\n", ConfFile);
+ *nextp = (struct filed *)calloc(1, sizeof(*f));
+ cfline("*.ERR\t/dev/console", *nextp);
+ (*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f));
+ cfline("*.PANIC\t*", (*nextp)->f_next);
+ Initialized = 1;
+ return;
+ }
+
+ /*
+ * Foreach line in the conf table, open that file.
+ */
+ f = NULL;
+ while (fgets(cline, sizeof cline, cf) != NULL) {
+ /*
+ * check for end-of-section, comments, strip off trailing
+ * spaces and newline character.
+ */
+ for (p = cline; isspace(*p); ++p);
+ if (*p == NULL || *p == '#')
+ continue;
+ for (p = index(cline, '\0'); isspace(*--p););
+ *++p = '\0';
+ f = (struct filed *)calloc(1, sizeof(*f));
+ *nextp = f;
+ nextp = &f->f_next;
+ cfline(cline, f);
+ }
+
+ /* close the configuration file */
+ (void) fclose(cf);
+
+ Initialized = 1;
+
+ if (Debug) {
+ for (f = Files; f; f = f->f_next) {
+ for (i = 0; i <= LOG_NFACILITIES; i++)
+ if (f->f_pmask[i] == NOPRI)
+ printf("X ");
+ else
+ printf("%d ", f->f_pmask[i]);
+ printf("%s: ", TypeNames[f->f_type]);
+ switch (f->f_type) {
+ case F_FILE:
+ case F_TTY:
+ case F_CONSOLE:
+ printf("%s", f->f_un.f_fname);
+ break;
+
+ case F_FORW:
+ printf("%s", f->f_un.f_forw.f_hname);
+ break;
+
+ case F_USERS:
+ for (i = 0; i < MAXUNAMES && *f->f_un.f_uname[i]; i++)
+ printf("%s, ", f->f_un.f_uname[i]);
+ break;
+ }
+ printf("\n");
+ }
+ }
+
+ logmsg(LOG_SYSLOG|LOG_INFO, "syslogd: restart", LocalHostName, ADDDATE);
+ dprintf("syslogd: restarted\n");
+}
+
+/*
+ * Crack a configuration file line
+ */
+
+struct code {
+ char *c_name;
+ int c_val;
+};
+
+struct code PriNames[] = {
+ "panic", LOG_EMERG,
+ "emerg", LOG_EMERG,
+ "alert", LOG_ALERT,
+ "crit", LOG_CRIT,
+ "err", LOG_ERR,
+ "error", LOG_ERR,
+ "warn", LOG_WARNING,
+ "warning", LOG_WARNING,
+ "notice", LOG_NOTICE,
+ "info", LOG_INFO,
+ "debug", LOG_DEBUG,
+ "none", NOPRI,
+ NULL, -1
+};
+
+struct code FacNames[] = {
+ "kern", LOG_KERN,
+ "user", LOG_USER,
+ "mail", LOG_MAIL,
+ "daemon", LOG_DAEMON,
+ "auth", LOG_AUTH,
+ "security", LOG_AUTH,
+ "mark", LOG_MARK,
+ "syslog", LOG_SYSLOG,
+ "lpr", LOG_LPR,
+ "news", LOG_NEWS,
+ "uucp", LOG_UUCP,
+ "local0", LOG_LOCAL0,
+ "local1", LOG_LOCAL1,
+ "local2", LOG_LOCAL2,
+ "local3", LOG_LOCAL3,
+ "local4", LOG_LOCAL4,
+ "local5", LOG_LOCAL5,
+ "local6", LOG_LOCAL6,
+ "local7", LOG_LOCAL7,
+ NULL, -1
+};
+
+cfline(line, f)
+ char *line;
+ register struct filed *f;
+{
+ register char *p;
+ register char *q;
+ register int i;
+ char *bp;
+ int pri;
+ struct hostent *hp;
+ char buf[MAXLINE];
+
+ dprintf("cfline(%s)\n", line);
+
+ errno = 0; /* keep sys_errlist stuff out of logerror messages */
+
+ /* clear out file entry */
+ bzero((char *) f, sizeof *f);
+ for (i = 0; i <= LOG_NFACILITIES; i++)
+ f->f_pmask[i] = NOPRI;
+
+ /* scan through the list of selectors */
+ for (p = line; *p && *p != '\t';) {
+
+ /* find the end of this facility name list */
+ for (q = p; *q && *q != '\t' && *q++ != '.'; )
+ continue;
+
+ /* collect priority name */
+ for (bp = buf; *q && !index("\t,;", *q); )
+ *bp++ = *q++;
+ *bp = '\0';
+
+ /* skip cruft */
+ while (index(", ;", *q))
+ q++;
+
+ /* decode priority name */
+ pri = decode(buf, PriNames);
+ if (pri < 0) {
+ char xbuf[200];
+
+ (void) sprintf(xbuf, "unknown priority name \"%s\"", buf);
+ logerror(xbuf);
+ return;
+ }
+
+ /* scan facilities */
+ while (*p && !index("\t.;", *p)) {
+ for (bp = buf; *p && !index("\t,;.", *p); )
+ *bp++ = *p++;
+ *bp = '\0';
+ if (*buf == '*')
+ for (i = 0; i < LOG_NFACILITIES; i++)
+ f->f_pmask[i] = pri;
+ else {
+ i = decode(buf, FacNames);
+ if (i < 0) {
+ char xbuf[200];
+
+ (void) sprintf(xbuf, "unknown facility name \"%s\"", buf);
+ logerror(xbuf);
+ return;
+ }
+ f->f_pmask[i >> 3] = pri;
+ }
+ while (*p == ',' || *p == ' ')
+ p++;
+ }
+
+ p = q;
+ }
+
+ /* skip to action part */
+ while (*p == '\t')
+ p++;
+
+ switch (*p)
+ {
+ case '@':
+ if (!InetInuse)
+ break;
+ (void) strcpy(f->f_un.f_forw.f_hname, ++p);
+ hp = gethostbyname(p);
+ if (hp == NULL) {
+ extern int h_errno, h_nerr;
+ extern char **h_errlist;
+
+ logerror((u_int)h_errno < h_nerr ?
+ h_errlist[h_errno] : "Unknown error");
+ break;
+ }
+ bzero((char *) &f->f_un.f_forw.f_addr,
+ sizeof f->f_un.f_forw.f_addr);
+ f->f_un.f_forw.f_addr.sin_family = AF_INET;
+ f->f_un.f_forw.f_addr.sin_port = LogPort;
+ bcopy(hp->h_addr, (char *) &f->f_un.f_forw.f_addr.sin_addr, hp->h_length);
+ f->f_type = F_FORW;
+ break;
+
+ case '/':
+ (void) strcpy(f->f_un.f_fname, p);
+ if ((f->f_file = open(p, O_WRONLY|O_APPEND)) < 0) {
+ f->f_file = F_UNUSED;
+ logerror(p);
+ break;
+ }
+ if (isatty(f->f_file)) {
+ f->f_type = F_TTY;
+ untty();
+ }
+ else
+ f->f_type = F_FILE;
+ if (strcmp(p, ctty) == 0)
+ f->f_type = F_CONSOLE;
+ break;
+
+ case '*':
+ f->f_type = F_WALL;
+ break;
+
+ default:
+ for (i = 0; i < MAXUNAMES && *p; i++) {
+ for (q = p; *q && *q != ','; )
+ q++;
+ (void) strncpy(f->f_un.f_uname[i], p, UNAMESZ);
+ if ((q - p) > UNAMESZ)
+ f->f_un.f_uname[i][UNAMESZ] = '\0';
+ else
+ f->f_un.f_uname[i][q - p] = '\0';
+ while (*q == ',' || *q == ' ')
+ q++;
+ p = q;
+ }
+ f->f_type = F_USERS;
+ break;
+ }
+}
+
+
+/*
+ * Decode a symbolic name to a numeric value
+ */
+
+decode(name, codetab)
+ char *name;
+ struct code *codetab;
+{
+ register struct code *c;
+ register char *p;
+ char buf[40];
+
+ if (isdigit(*name))
+ return (atoi(name));
+
+ (void) strcpy(buf, name);
+ for (p = buf; *p; p++)
+ if (isupper(*p))
+ *p = tolower(*p);
+ for (c = codetab; c->c_name; c++)
+ if (!strcmp(buf, c->c_name))
+ return (c->c_val);
+
+ return (-1);
+}