📄 syslogd.c
字号:
/* Try to resolve the domainname by calling DNS. */ host_ent = gethostbyname (LocalHostName); if (host_ent) { /* Override what we had */ if (LocalHostName) free (LocalHostName); LocalHostName = strdup (host_ent->h_name); p = strchr (LocalHostName, '.'); if (p != NULL) { *p++ = '\0'; LocalDomain = p; } } if (LocalDomain == NULL) LocalDomain = strdup (""); } consfile.f_type = F_CONSOLE; consfile.f_un.f_fname = strdup (ctty); (void) signal (SIGTERM, die); (void) signal (SIGINT, Debug ? die : SIG_IGN); (void) signal (SIGQUIT, Debug ? die : SIG_IGN); (void) signal (SIGALRM, domark); (void) signal (SIGUSR1, Debug ? dbg_toggle : SIG_IGN); (void) alarm (TIMERINTVL); /* We add 2 = 1(klog) + 1(inet), even if they may be not use. */ fdarray = (struct pollfd *) malloc ((nfunix + 2) * sizeof (*fdarray)); if (fdarray == NULL) { fprintf (stderr, "%s: can't allocate fd table: %s\n", __progname, strerror (errno)); exit (2); }#ifdef PATH_KLOG /* Initialize kernel logging and add to the list. */ if (!NoKLog) { fklog = open (PATH_KLOG, O_RDONLY, 0); if (fklog >= 0) { fdarray[nfds].fd = fklog; fdarray[nfds].events = POLLIN | POLLPRI; nfds++; dbg_printf ("Klog open %s\n", PATH_KLOG); } else dbg_printf ("Can't open %s: %s\n", PATH_KLOG, strerror (errno)); }#endif /* Initialize unix sockets. */ if (!NoUnixAF) { for (i = 0; i < nfunix; i++) { funix[i].fd = create_unix_socket (funix[i].name); if (funix[i].fd >= 0) { fdarray[nfds].fd = funix[i].fd; fdarray[nfds].events = POLLIN | POLLPRI; nfds++; dbg_printf ("Opened UNIX socket `%s'.\n", funix[i].name); } else dbg_printf ("Can't open %s: %s\n", funix[i].name, strerror (errno)); } } /* Initialize inet socket and add them to the list. */ if (AcceptRemote || (!NoForward)) { finet = create_inet_socket (); if (finet >= 0) { fdarray[nfds].fd = finet; fdarray[nfds].events = POLLIN | POLLPRI; nfds++; dbg_printf ("Opened syslog UDP port.\n"); } else dbg_printf ("Can't open UDP port: %s\n", strerror (errno)); } /* read configuration file */ init (0); /* Tuck my process id away. */ fp = fopen (PidFile, "w"); if (fp != NULL) { fprintf (fp, "%d\n", getpid ()); (void) fclose (fp); } dbg_printf ("off & running....\n"); (void) signal (SIGHUP, trigger_restart); if (Debug) { dbg_printf ("Debugging disabled, send SIGUSR1 to turn on debugging.\n"); dbg_output = 0; } /* If we're doing waitdaemon(), tell the parent to exit, we are ready to roll. */ if (ppid) kill (ppid, SIGALRM); for (;;) { int nready; nready = poll (fdarray, nfds, -1); if (nready == 0) /* ?? noop */ continue; /* Sighup was dropped. */ if (restart) { dbg_printf ("\nReceived SIGHUP, restarting syslogd.\n"); init (0); restart = 0; continue; } if (nready < 0) { if (errno != EINTR) logerror ("poll"); continue; } /*dbg_printf ("got a message (%d)\n", nready);*/ for (i = 0; i < nfds; i++) if (fdarray[i].revents & (POLLIN | POLLPRI)) { int result; size_t len; if (fdarray[i].fd == -1) continue; else if (fdarray[i].fd == fklog) { /* Set to 1 if the kline possibly contains a log message. */ int log_kline = 0; /*dbg_printf ("klog message\n");*/ if (kline_len == sizeof (kline) - 1) { /* We are trying to find the end of an earlier logged partial line. */ result = read (fdarray[i].fd, kline, sizeof (kline) - 1); if (result > 0) { char *eol; kline[result] = '\0'; eol = strchr (kline, '\n'); if (eol) { eol++; kline_len = result - (eol - kline); memmove (kline, eol, kline_len); log_kline = 1; } } else if (result < 0 && errno != EINTR) { logerror ("klog"); fdarray[i].fd = fklog = -1; } } else { result = read (fdarray[i].fd, &kline[kline_len], sizeof (kline) - kline_len - 1); if (result > 0) { kline_len += result; log_kline = 1; } else if (result < 0 && errno != EINTR) { logerror ("klog"); fdarray[i].fd = fklog = -1; } } if (log_kline) { char *eol; kline[kline_len] = '\0'; while ((eol = strchr (kline, '\n'))) { *(eol++) = '\0'; printsys (kline); kline_len -= (eol - kline); memmove (kline, eol, kline_len); } if (kline_len == sizeof (kline) - 1) /* Log the beginning of a partial line. */ printsys (kline); } } else if (fdarray[i].fd == finet) { struct sockaddr_in frominet; /*dbg_printf ("inet message\n");*/ len = sizeof (frominet); memset (line, '\0', sizeof (line)); result = recvfrom (fdarray[i].fd, line, MAXLINE, 0, (struct sockaddr *) &frominet, &len); if (result > 0) { line[result] = '\0'; printline (cvthname (&frominet), line); } else if (result < 0 && errno != EINTR) logerror ("recvfrom inet"); } else { struct sockaddr_un fromunix; /*dbg_printf ("unix message\n");*/ len = sizeof (fromunix); result = recvfrom (fdarray[i].fd, line, MAXLINE, 0, (struct sockaddr *) &fromunix, &len); if (result > 0) { line[result] = '\0'; printline (LocalHostName, line); } else if (result < 0 && errno != EINTR) logerror ("recvfrom unix"); } } else if (fdarray[i].revents & POLLNVAL) { logerror ("poll nval\n"); fdarray[i].fd = -1; } else if (fdarray[i].revents & POLLERR) logerror ("poll err\n"); else if (fdarray[i].revents & POLLHUP) logerror ("poll hup\n"); } /* for (;;) */} /* main */#ifndef SUN_LEN#define SUN_LEN(unp) (strlen((unp)->sun_path) + 3)#endifstatic voidadd_funix (const char *name){ funix = realloc (funix, (nfunix + 1)*sizeof(*funix)); if (funix == NULL) { fprintf (stderr, "%s: cannot allocate space for unix sockets: %s\n", __progname, strerror (errno)); exit (1); } funix[nfunix].name = name; funix[nfunix].fd = -1; nfunix++;}static intcreate_unix_socket (const char *path){ int fd; struct sockaddr_un sunx; char line[MAXLINE + 1]; if (path[0] == '\0') return -1; (void) unlink (path); memset (&sunx, 0, sizeof (sunx)); sunx.sun_family = AF_UNIX; (void) strncpy (sunx.sun_path, path, sizeof (sunx.sun_path)); fd = socket (AF_UNIX, SOCK_DGRAM, 0); if (fd < 0 || bind(fd, (struct sockaddr *) &sunx, SUN_LEN (&sunx)) < 0 || chmod(path, 0666) < 0) { snprintf (line, sizeof (line), "cannot create %s", path); logerror (line); dbg_printf ("cannot create %s: %s\n", path, strerror (errno)); close (fd); } return fd;}static intcreate_inet_socket (){ int fd; struct sockaddr_in sin; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { logerror ("unknown protocol, suspending inet service"); return fd; } memset (&sin, 0, sizeof (sin)); sin.sin_family = AF_INET; sin.sin_port = LogPort; if (bind(fd, (struct sockaddr *) &sin, sizeof (sin)) < 0) { logerror("bind, suspending inet"); close(fd); return -1; } return fd;}char **crunch_list (char **oldlist, char *list){ int count, i; char *p, *q; p = list; /* Strip off trailing delimiters. */ while (p[strlen (p) - 1] == LIST_DELIMITER) { p[strlen (p) - 1] = '\0'; } /* Cut off leading delimiters. */ while (p[0] == LIST_DELIMITER) { p++; } /* Bailout early the string is empty. */ if (*p == '\0') return oldlist; /* Count delimiters to calculate elements. */ for (count = 1, i = 0; p[i]; i++) if (p[i] == LIST_DELIMITER) count++; /* Count how many we add in the old list. */ for (i = 0; oldlist && oldlist[i]; i++) ; /* allocate enough space */ oldlist = (char **) realloc (oldlist, (i + count + 1) * sizeof (*oldlist)); if (oldlist == NULL) { fprintf (stderr, "%s: can't allocate memory: %s", __progname, strerror (errno)); exit (1); } /* We now can assume that the first and last characters are different from any delimiters, so we don't have to care about it anymore. */ /* Start from where we left last time. */ for (count = i; (q = strchr (p, LIST_DELIMITER)) != NULL; count++, p = q, p++) { oldlist[count] = (char *) malloc ((q - p + 1) * sizeof(char)); if (oldlist[count] == NULL) { fprintf (stderr, "%s: can't allocate memory: %s", __progname, strerror (errno)); exit (1); } strncpy (oldlist[count], p, q - p); oldlist[count][q - p] = '\0'; } /* take the last one */ oldlist[count] = (char *) malloc ((strlen (p) + 1) * sizeof (char)); if (oldlist[count] == NULL) { fprintf (stderr, "%s: can't allocate memory: %s", __progname, strerror (errno)); exit(1); } strcpy (oldlist[count], p); oldlist[++count] = NULL; /* terminate the array with a NULL */ if (Debug) { for (count = 0; oldlist[count]; count++) printf ("#%d: %s\n", count, oldlist[count]); } return oldlist;}/* Take a raw input line, decode the message, and print the message on the appropriate log files. */voidprintline (const char *hname, const char *msg){ int c, pri; const char *p; char *q, line[MAXLINE + 1]; /* test for special codes */ pri = DEFUPRI; p = msg; if (*p == '<') { pri = 0; while (isdigit (*++p)) pri = 10 * pri + (*p - '0'); if (*p == '>') ++p; } if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) pri = DEFUPRI; /* don't allow users to log kernel messages */ if (LOG_FAC (pri) == LOG_KERN) pri = LOG_MAKEPRI (LOG_USER, LOG_PRI (pri)); q = line; while ((c = *p++) != '\0' && q < &line[sizeof (line) - 1]) if (iscntrl(c)) if (c == '\n') *q++ = ' '; else if (c == '\t') *q++ = '\t'; else if (c >= 0177) *q++ = c; else { *q++ = '^'; *q++ = c ^ 0100; } else *q++ = c; *q = '\0'; /* This for the default behaviour on GNU/Linux syslogd who sync on every line. */ if (force_sync) logmsg (pri, line, hname, SYNC_FILE); logmsg (pri, line, hname, 0);}/* Take a raw input line from /dev/klog, split and format similar to syslog(). */voidprintsys (const char *msg){ int c, pri, flags; char *lp, *q, line[MAXLINE + 1]; const char *p; (void) strcpy (line, "vmunix: "); lp = line + strlen (line); for (p = msg; *p != '\0'; ) { flags = SYNC_FILE | ADDDATE; /* Fsync after write. */ pri = DEFSPRI; if (*p == '<') { pri = 0; while (isdigit (*++p)) pri = 10 * pri + (*p - '0'); if (*p == '>') ++p; } else { /* kernel printf's come out on console */ flags |= IGN_CONS; } if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) pri = DEFSPRI; q = lp; while (*p != '\0' && (c = *p++) != '\n' && q < &line[MAXLINE]) *q++ = c; *q = '\0'; logmsg (pri, line, LocalHostName, flags); }}/* Decode a priority into textual information like auth.emerg. */char *textpri (int pri){ static char res[20]; CODE *c_pri, *c_fac; for (c_fac = facilitynames; c_fac->c_name && !(c_fac->c_val == LOG_FAC (pri) << 3); c_fac++); for (c_pri = prioritynames; c_pri->c_name && !(c_pri->c_val == LOG_PRI (pri)); c_pri++);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -