📄 syslogd.c
字号:
if (signo) { dbg_printf ("%s: exiting on signal %d\n", program_name, signo); snprintf (buf, sizeof (buf), "exiting on signal %d", signo); errno = 0; logerror (buf); } if (fklog >= 0) close (fklog); for (i = 0; i < nfunix; i++) if (funix[i].fd >= 0) { close (funix[i].fd); if (funix[i].name) unlink (funix[i].name); } if (finet >= 0) close (finet); exit (0);}/* INIT -- Initialize syslogd from configuration table. */RETSIGTYPEinit (int signo){ FILE *cf; struct filed *f, *next, **nextp; char *p;#ifndef LINE_MAX#define LINE_MAX 2048#endif size_t line_max = LINE_MAX; char *cbuf; char *cline; int cont_line = 0; struct servent *sp; dbg_printf ("init\n"); sp = getservbyname ("syslog", "udp"); if (sp == NULL) { errno = 0; logerror ("network logging disabled (syslog/udp service unknown)."); logerror ("see syslogd(8) for details of whether and how to enable it."); return; } LogPort = sp->s_port; /* Close all open log files. */ Initialized = 0; for (f = Files; f != NULL; f = next) { /* Flush any pending output. */ if (f->f_prevcount) fprintlog (f, LocalHostName, 0, (char *)NULL); switch (f->f_type) { case F_FILE: case F_TTY: case F_CONSOLE: case F_PIPE: close (f->f_file); break; } next = f->f_next; free (f); } Files = NULL; nextp = &Files; facilities_seen = 0; /* Open the configuration file. */ cf = fopen (ConfFile, "r"); if (cf == NULL) { dbg_printf ("cannot open %s\n", ConfFile); *nextp = (struct filed *) calloc (1, sizeof(*f)); cfline ("*.ERR\t" PATH_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; /* Allocate a buffer for line parsing. */ cbuf = malloc (line_max); if (cbuf == NULL) { /* There is no graceful recovery here. */ dbg_printf ("cannot allocate space for configuration\n"); return; } cline = cbuf; /* Line parsing : - skip comments, - strip off trailing spaces, - skip empty lines, - glob leading spaces, - readjust buffer if line is too big, - deal with continuation lines, last char is '\' . */ while (fgets (cline, line_max - (cline - cbuf), cf) != NULL) { size_t len = strlen (cline); /* If this is a continuation line, skip leading whitespace for compatibility with sysklogd. Note that this requires whitespace before the backslash in the previous line if you want to separate the selector from the action. */ if (cont_line) { char *start = cline; while (*start == ' ' || *start == '\t') start++; len = len - (start - cline); memmove (cline, start, len + 1); cont_line = 0; } /* No newline, so the line is too big for the buffer. Readjust. */ if (strchr (cline, '\n') == NULL) { size_t offset = cline - cbuf; char *tmp; tmp = realloc (cbuf, line_max * 2); if (tmp == NULL) { /* Sigh ... */ dbg_printf ("cannot allocate space configuration\n"); free (cbuf); return; } else cbuf = tmp; line_max *= 2; cline = cbuf + offset + len - 1; continue; } else cline = cbuf; /* Glob the leading spaces. */ for (p = cline; isspace (*p); ++p) ; /* Skip comments and empty line. */ if (*p == '\0' || *p == '#') continue; strcpy (cline, p); /* Cut the trailing spaces. */ for (p = strchr (cline, '\0'); isspace (*--p);) ; /* if '\', indicates continuation on the next line. */ if (*p == '\\') { *p = '\0'; cline = p; cont_line = 1; continue; } *++p = '\0'; /* Send the line for more parsing. */ f = (struct filed *) calloc (1, sizeof (*f)); *nextp = f; nextp = &f->f_next; cfline (cbuf, f); } /* Close the configuration file. */ fclose (cf); free (cbuf); Initialized = 1; if (Debug) { for (f = Files; f; f = f->f_next) { int i; for (i = 0; i <= LOG_NFACILITIES; i++) if (f->f_pmask[i] == 0) dbg_printf(" X "); else dbg_printf("%2x ", f->f_pmask[i]); dbg_printf("%s: ", TypeNames[f->f_type]); switch (f->f_type) { case F_FILE: case F_TTY: case F_CONSOLE: case F_PIPE: dbg_printf ("%s", f->f_un.f_fname); break; case F_FORW: case F_FORW_SUSP: case F_FORW_UNKN: dbg_printf ("%s", f->f_un.f_forw.f_hname); break; case F_USERS: for (i = 0; i < f->f_un.f_user.f_nusers; i++) dbg_printf ("%s, ", f->f_un.f_user.f_unames[i]); break; } dbg_printf ("\n"); } } if (AcceptRemote) logmsg (LOG_SYSLOG | LOG_INFO, "syslogd (" PACKAGE_NAME \ " " PACKAGE_VERSION "): restart (remote reception)", LocalHostName, ADDDATE); else logmsg (LOG_SYSLOG | LOG_INFO, "syslogd (" PACKAGE_NAME \ " " PACKAGE_VERSION "): restart", LocalHostName, ADDDATE); dbg_printf ("syslogd: restarted\n");}/* Crack a configuration file line. */voidcfline (const char *line, struct filed *f){ struct hostent *hp; int i, pri, negate_pri, excl_pri; unsigned int pri_set, pri_clear; char *bp; const char *p, *q; char buf[MAXLINE], ebuf[200]; dbg_printf ("cfline(%s)\n", line); errno = 0; /* keep strerror() stuff out of logerror messages */ /* Clear out file entry. */ memset (f, 0, sizeof (*f)); for (i = 0; i <= LOG_NFACILITIES; i++) { f->f_pmask[i] = 0; f->f_flags = 0; } /* Scan through the list of selectors. */ for (p = line; *p && *p != '\t' && *p != ' ';) { /* Find the end of this facility name list. */ for (q = p; *q && *q != '\t' && *q++ != '.'; ) continue; /* Collect priority name. */ for (bp = buf; *q && ! strchr ("\t ,;", *q); ) *bp++ = *q++; *bp = '\0'; /* Skip cruft. */ while (strchr(",;", *q)) q++; bp = buf; negate_pri = excl_pri = 0; while (*bp == '!' || *bp == '=') switch (*bp++) { case '!': negate_pri = 1; break; case '=': excl_pri = 1; break; } /* Decode priority name and set up bit masks. */ if (*bp == '*') { pri_clear = 0; pri_set = LOG_UPTO (LOG_PRIMASK); } else { pri = decode (bp, prioritynames); if (pri < 0) { snprintf (ebuf, sizeof (ebuf), "unknown priority name \"%s\"", bp); logerror (ebuf); return; } if (pri == INTERNAL_NOPRI) { pri_clear = 255; pri_set = 0; } else { pri_clear = 0; pri_set = excl_pri ? LOG_MASK (pri) : LOG_UPTO (pri); } } if (negate_pri) { unsigned int exchange = pri_set; pri_set = pri_clear; pri_clear = exchange; } /* Scan facilities. */ while (*p && !strchr ("\t .;", *p)) { for (bp = buf; *p && ! strchr ("\t ,;.", *p); ) *bp++ = *p++; *bp = '\0'; if (*buf == '*') for (i = 0; i <= LOG_NFACILITIES; i++) { /* make "**" act as a wildcard only for facilities not * specified elsewhere */ if (buf[1] == '*' && ((1 << i) & facilities_seen)) continue; f->f_pmask[i] &= ~pri_clear; f->f_pmask[i] |= pri_set; } else { i = decode (buf, facilitynames); facilities_seen |= (1 << LOG_FAC(i)); if (i < 0) { snprintf (ebuf, sizeof (ebuf), "unknown facility name \"%s\"", buf); logerror (ebuf); return; } f->f_pmask[LOG_FAC(i)] &= ~pri_clear; f->f_pmask[LOG_FAC(i)] |= pri_set; } while (*p == ',' || *p == ' ') p++; } p = q; } /* Skip to action part. */ while (*p == '\t' || *p == ' ') p++; if (*p == '-') { f->f_flags |= OMIT_SYNC; p++; } switch (*p) { case '@': f->f_un.f_forw.f_hname = strdup (++p); hp = gethostbyname (p); if (hp == NULL) { f->f_type = F_FORW_UNKN; f->f_prevcount = INET_RETRY_MAX; f->f_time = time ( (time_t *)0 ); } else f->f_type = F_FORW; memset (&f->f_un.f_forw.f_addr, 0, 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; if (f->f_type == F_FORW) memcpy (&f->f_un.f_forw.f_addr.sin_addr, hp->h_addr, hp->h_length); break; case '|': f->f_un.f_fname = strdup (p); if ((f->f_file = open (++p, O_RDWR|O_NONBLOCK)) < 0) { f->f_type = F_UNUSED; logerror (p); break; } if (strcmp (p, ctty) == 0) f->f_type = F_CONSOLE; else if (isatty (f->f_file)) f->f_type = F_TTY; else f->f_type = F_PIPE; break; case '/': f->f_un.f_fname = strdup (p); if ((f->f_file = open (p, O_WRONLY|O_APPEND|O_CREAT, 0644)) < 0) { f->f_type = F_UNUSED; logerror (p); break; } if (strcmp (p, ctty) == 0) f->f_type = F_CONSOLE; else if (isatty (f->f_file)) f->f_type = F_TTY; else f->f_type = F_FILE; break; case '*': f->f_type = F_WALL; break; default: f->f_un.f_user.f_nusers = 1; for (q = p; *q; q++) if (*q == ',') f->f_un.f_user.f_nusers++; f->f_un.f_user.f_unames = (char **) malloc (f->f_un.f_user.f_nusers * sizeof (char *)); for (i = 0; *p; i++) { for (q = p; *q && *q != ','; ) q++; f->f_un.f_user.f_unames[i] = malloc (q - p + 1); if (f->f_un.f_user.f_unames[i]) { strncpy (f->f_un.f_user.f_unames[i], p, q - p); f->f_un.f_user.f_unames[i][q - p] = '\0'; } while (*q == ',' || *q == ' ') q++; p = q; } f->f_type = F_USERS; break; }}/* Decode a symbolic name to a numeric value. */intdecode (const char *name, CODE *codetab){ CODE *c; if (isdigit (*name)) return atoi (name); for (c = codetab; c->c_name; c++) if (!strcasecmp (name, c->c_name)) return c->c_val; return -1;}RETSIGTYPEdbg_toggle(int signo ARG_UNUSED){ int dbg_save = dbg_output; dbg_output = 1; dbg_printf ("Switching dbg_output to %s.\n", dbg_save == 0 ? "true" : "false"); dbg_output = (dbg_save == 0) ? 1 : 0;}/* Ansi2knr will always change ... to va_list va_dcl */static voiddbg_printf (const char *fmt, ...){ va_list ap; if (!(Debug && dbg_output)) return;#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ va_start (ap, fmt);#else va_start (ap);#endif va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap); fflush (stdout);}/* The following function is resposible for handling a SIGHUP signal. Since we are now doing mallocs/free as part of init we had better not being doing this during a signal handler. Instead we simply set a flag variable which will tell the main loop to go through a restart. */RETSIGTYPEtrigger_restart (int signo ARG_UNUSED){ restart = 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -