+
+/*
+ * INIT -- Initialize syslogd from configuration table
+ */
+
+init()
+{
+ register int i;
+ register FILE *cf;
+ register struct filed *f;
+ register char *p;
+ char cline[BUFSIZ];
+
+ dprintf("init\n");
+
+ /* flush any pending output */
+ flushmsg();
+
+ /*
+ * Close all open log files.
+ */
+ for (f = Files; f < &Files[NLOGS]; f++) {
+ if (f->f_type == F_FILE || f->f_type == F_TTY)
+ (void) close(f->f_file);
+ f->f_type = F_UNUSED;
+ }
+
+ /* open the configuration file */
+ if ((cf = fopen(ConfFile, "r")) == NULL) {
+ dprintf("cannot open %s\n", ConfFile);
+ cfline("*.ERR\t/dev/console", &Files[0]);
+ cfline("*.PANIC\t*", &Files[1]);
+ return;
+ }
+
+ /*
+ * Foreach line in the conf table, open that file.
+ */
+ f = Files;
+ while (fgets(cline, sizeof cline, cf) != NULL && f < &Files[NLOGS]) {
+ /* check for end-of-section */
+ if (cline[0] == '\n' || cline[0] == '#')
+ continue;
+
+ /* strip off newline character */
+ p = index(cline, '\n');
+ if (p)
+ *p = '\0';
+
+ cfline(cline, f++);
+ }
+
+ /* close the configuration file */
+ (void) fclose(cf);
+
+ Initialized = 1;
+
+ if (Debug) {
+ for (f = Files; f < &Files[NLOGS]; f++) {
+ 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_DAEMON|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,
+ NULL, -1
+};
+
+struct code FacNames[] = {
+ "kern", LOG_KERN,
+ "user", LOG_USER,
+ "mail", LOG_MAIL,
+ "auth", LOG_AUTH,
+ "security", LOG_AUTH,
+ "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);
+
+ /* 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)) {
+ int i;
+
+ 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) {
+ char buf[100];
+
+ (void) sprintf(buf, "unknown host %s", p);
+ errno = 0;
+ logerror(buf);
+ 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_file = socket(AF_INET, SOCK_DGRAM, 0);
+ if (f->f_file < 0) {
+ logerror("socket");
+ break;
+ }
+ 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) {
+ 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);
+}