📄 syslogd.c
字号:
snprintf (res, sizeof (res), "%s.%s", c_fac->c_name, c_pri->c_name); return res;}/* Log a message to the appropriate log files, users, etc. based on the priority. */voidlogmsg (int pri, const char *msg, const char *from, int flags){ struct filed *f; int fac, msglen, prilev;#ifdef HAVE_SIGACTION sigset_t sigs, osigs;#else int omask;#endif const char *timestamp; dbg_printf ("(logmsg): %s (%d), flags %x, from %s, msg %s\n", textpri (pri), pri, flags, from, msg);#ifdef HAVE_SIGACTION sigemptyset (&sigs); sigaddset (&sigs, SIGHUP); sigaddset (&sigs, SIGALRM); sigprocmask (SIG_BLOCK, &sigs, &osigs);#else omask = sigblock (sigmask (SIGHUP) | sigmask (SIGALRM));#endif /* Check to see if msg looks non-standard. */ msglen = strlen (msg); if (msglen < 16 || msg[3] != ' ' || msg[6] != ' ' || msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') flags |= ADDDATE; (void) time (&now); if (flags & ADDDATE) timestamp = ctime (&now) + 4; else { timestamp = msg; msg += 16; msglen -= 16; } /* Extract facility and priority level. */ if (flags & MARK) fac = LOG_NFACILITIES; else fac = LOG_FAC (pri); prilev = LOG_PRI (pri); /* Log the message to the particular outputs. */ if (!Initialized) { f = &consfile; f->f_file = open (ctty, O_WRONLY, 0); f->f_prevhost = strdup (LocalHostName); if (f->f_file >= 0) { fprintlog (f, from, flags, msg); (void) close (f->f_file); }#ifdef HAVE_SIGACTION sigprocmask (SIG_SETMASK, &osigs, 0);#else (void) sigsetmask (omask);#endif return; } for (f = Files; f; f = f->f_next) { /* Skip messages that are incorrect priority. */ if (!(f->f_pmask[fac] & LOG_MASK (prilev)) || f->f_pmask[fac] == INTERNAL_NOPRI) continue; if (f->f_type == F_CONSOLE && (flags & IGN_CONS)) continue; /* Don't output marks to recently written files. */ if ((flags & MARK) && (now - f->f_time) < MarkInterval / 2) continue; /* Suppress duplicate lines to this file. */ if ((flags & MARK) == 0 && msglen == f->f_prevlen && f->f_prevhost && !strcmp (msg, f->f_prevline) && !strcmp (from, f->f_prevhost)) { (void) strncpy (f->f_lasttime, timestamp, sizeof (f->f_lasttime) - 1); f->f_prevcount++; dbg_printf ("msg repeated %d times, %ld sec of %d\n", f->f_prevcount, now - f->f_time, repeatinterval[f->f_repeatcount]); /* If domark would have logged this by now, flush it now (so we don't hold isolated messages), but back off so we'll flush less often in the future. */ if (now > REPEATTIME (f)) { fprintlog (f, from, flags, (char *)NULL); BACKOFF (f); } } else { /* New line, save it. */ if (f->f_prevcount) fprintlog (f, from, 0, (char *)NULL); f->f_repeatcount = 0; (void) strncpy (f->f_lasttime, timestamp, sizeof (f->f_lasttime) - 1); if (f->f_prevhost) free (f->f_prevhost); f->f_prevhost = strdup (from); if (msglen < MAXSVLINE) { f->f_prevlen = msglen; f->f_prevpri = pri; (void) strcpy (f->f_prevline, msg); fprintlog (f, from, flags, (char *)NULL); } else { f->f_prevline[0] = 0; f->f_prevlen = 0; fprintlog (f, from, flags, msg); } } }#ifdef HAVE_SIGACTION sigprocmask (SIG_SETMASK, &osigs, 0);#else (void) sigsetmask (omask);#endif}voidfprintlog (struct filed *f, const char *from, int flags, const char *msg){ struct iovec iov[IOVCNT]; struct iovec *v; int l; char line[MAXLINE + 1], repbuf[80], greetings[200]; time_t fwd_suspend; struct hostent *hp; v = iov; /* Be paranoid. */ memset (v, 0, sizeof (struct iovec) * IOVCNT ); if (f->f_type == F_WALL) { v->iov_base = greetings; snprintf (greetings, sizeof (greetings), "\r\n\7Message from syslogd@%s at %.24s ...\r\n", f->f_prevhost, ctime (&now)); v->iov_len = strlen (greetings); v++; v->iov_base = (char *)""; v->iov_len = 0; v++; } else { v->iov_base = f->f_lasttime; v->iov_len = sizeof (f->f_lasttime) - 1; v++; v->iov_base = (char *)" "; v->iov_len = 1; v++; } v->iov_base = f->f_prevhost; v->iov_len = strlen (v->iov_base); v++; v->iov_base = (char *)" "; v->iov_len = 1; v++; if (msg) { v->iov_base = (char *)msg; v->iov_len = strlen (msg); } else if (f->f_prevcount > 1) { v->iov_base = repbuf; snprintf (repbuf, sizeof (repbuf), "last message repeated %d times", f->f_prevcount); v->iov_len = strlen (repbuf); } else { v->iov_base = f->f_prevline; v->iov_len = f->f_prevlen; } v++; dbg_printf ("Logging to %s", TypeNames[f->f_type]); switch (f->f_type) { case F_UNUSED: f->f_time = now; dbg_printf ("\n"); break; case F_FORW_SUSP: fwd_suspend = time((time_t *) 0) - f->f_time; if ( fwd_suspend >= INET_SUSPEND_TIME ) { dbg_printf ("\nForwarding suspension over, retrying FORW "); f->f_type = F_FORW; goto f_forw; } else { dbg_printf (" %s\n", f->f_un.f_forw.f_hname); dbg_printf ("Forwarding suspension not over, time left: %d.\n", INET_SUSPEND_TIME - fwd_suspend); } break; case F_FORW_UNKN: dbg_printf (" %s\n", f->f_un.f_forw.f_hname); fwd_suspend = time ((time_t *) 0) - f->f_time; if (fwd_suspend >= INET_SUSPEND_TIME) { hp = gethostbyname (f->f_un.f_forw.f_hname); if (hp == NULL) { extern int h_errno; dbg_printf ("Failure: %s\n", hstrerror (h_errno)); dbg_printf ("Retries: %d\n", f->f_prevcount); if ( --f->f_prevcount < 0 ) f->f_type = F_UNUSED; } else { dbg_printf ("%s found, resuming.\n", f->f_un.f_forw.f_hname); memcpy (&f->f_un.f_forw.f_addr.sin_addr, hp->h_addr, hp->h_length); f->f_prevcount = 0; f->f_type = F_FORW; goto f_forw; } } else dbg_printf ("Forwarding suspension not over, time left: %d\n", INET_SUSPEND_TIME - fwd_suspend); break; case F_FORW: f_forw: dbg_printf (" %s\n", f->f_un.f_forw.f_hname); if (strcasecmp (from, LocalHostName) && NoHops) dbg_printf ("Not forwarding remote message.\n"); else if (!NoForward) dbg_printf ("Not forwarding because forwarding is disabled.\n"); else if (finet < 0) dbg_printf ("Not forwarding because of invalid inet fd.\n"); else { f->f_time = now; snprintf (line, sizeof (line), "<%d>%.15s %s", f->f_prevpri, (char *)iov[0].iov_base, (char *)iov[4].iov_base); l = strlen (line); if (l > MAXLINE) l = MAXLINE; if (sendto (finet, line, l, 0, (struct sockaddr *)&f->f_un.f_forw.f_addr, sizeof(f->f_un.f_forw.f_addr)) != l) { int e = errno; dbg_printf ("INET sendto error: %d = %s.\n", e, strerror(e)); f->f_type = F_FORW_SUSP; errno = e; logerror ("sendto"); } } break; case F_CONSOLE: f->f_time = now; if (flags & IGN_CONS) { dbg_printf (" (ignored)\n"); break; } /* FALLTHROUGH */ case F_TTY: case F_FILE: case F_PIPE: f->f_time = now; dbg_printf (" %s\n", f->f_un.f_fname); if (f->f_type == F_TTY || f->f_type == F_CONSOLE) { v->iov_base = (char *)"\r\n"; v->iov_len = 2; } else { v->iov_base = (char *)"\n"; v->iov_len = 1; } again: if (writev (f->f_file, iov, IOVCNT) < 0) { int e = errno; /* XXX: If a named pipe is full, ignore it. */ if (f->f_type == F_PIPE && e == EAGAIN) break; (void) close (f->f_file); /* Check for errors on TTY's due to loss of tty. */ if ((e == EIO || e == EBADF) && (f->f_type == F_TTY || f->f_type == F_CONSOLE)) { f->f_file = open (f->f_un.f_fname, O_WRONLY|O_APPEND, 0); if (f->f_file < 0) { f->f_type = F_UNUSED; logerror (f->f_un.f_fname); } else goto again; } else { f->f_type = F_UNUSED; errno = e; logerror (f->f_un.f_fname); } } else if ((flags & SYNC_FILE) && !(f->f_flags & OMIT_SYNC)) (void) fsync (f->f_file); break; case F_USERS: case F_WALL: f->f_time = now; dbg_printf ("\n"); v->iov_base = (char *)"\r\n"; v->iov_len = 2; wallmsg (f, iov); break; } if (f->f_type != F_FORW_UNKN) f->f_prevcount = 0;}/* Write the specified message to either the entire world, or a list of approved users. */voidwallmsg (struct filed *f, struct iovec *iov){ static int reenter; /* avoid calling ourselves */ UTMP *utp; int i; char *p; char line[sizeof(utp->ut_line) + 1]; if (reenter++) return; SETUTENT(); while ((utp = GETUTENT ()) != NULL) { /* We only want interrested to send to actual process, USER_PROCESS where somebody might listen. */ if (utp->ut_user[0] == '\0' || utp->ut_line[0] == '\0' || utp->ut_type != USER_PROCESS) continue; strncpy (line, utp->ut_line, sizeof (utp->ut_line)); line[sizeof (utp->ut_line)] = '\0'; if (f->f_type == F_WALL) { /* Note we're using our own version of ttymsg which does a double fork () to not have zombies. No need to waitpid(). */ p = ttymsg (iov, IOVCNT, line, TTYMSGTIME); if (p != NULL) { errno = 0; /* Already in message. */ logerror (p); } continue; } /* Should we send the message to this user? */ for (i = 0; i < f->f_un.f_user.f_nusers; i++) if (!strncmp (f->f_un.f_user.f_unames[i], utp->ut_user, sizeof (utp->ut_user))) { p = ttymsg (iov, IOVCNT, line, TTYMSGTIME); if (p != NULL) { errno = 0; /* Already in message. */ logerror (p); } break; } } ENDUTENT (); reenter = 0;}/* Return a printable representation of a host address. */const char *cvthname (struct sockaddr_in *f){ struct hostent *hp; char *p; dbg_printf ("cvthname(%s)\n", inet_ntoa (f->sin_addr)); if (f->sin_family != AF_INET) { dbg_printf ("Malformed from address.\n"); return "???"; } hp = gethostbyaddr ((char *) &f->sin_addr, sizeof (struct in_addr), f->sin_family); if (hp == 0) { dbg_printf ("Host name for your address (%s) unknown.\n", inet_ntoa (f->sin_addr)); return inet_ntoa (f->sin_addr); } p = strchr (hp->h_name, '.'); if (p != NULL) { if (strcasecmp (p + 1, LocalDomain) == 0) *p = '\0'; else { int count; if (StripDomains) { count=0; while (StripDomains[count]) { if (strcasecmp (p + 1, StripDomains[count]) == 0) { *p = '\0'; return hp->h_name; } count++; } } if (LocalHosts) { count=0; while (LocalHosts[count]) { if (strcasecmp (hp->h_name, LocalHosts[count]) == 0) { *p = '\0'; return hp->h_name; } count++; } } } } return hp->h_name;}voiddomark (int signo){ struct filed *f; (void)signo; /* Ignored. */ now = time ((time_t *) NULL); if (MarkInterval > 0) { MarkSeq += TIMERINTVL; if (MarkSeq >= MarkInterval) { logmsg (LOG_INFO, "-- MARK --", LocalHostName, ADDDATE|MARK); MarkSeq = 0; } } for (f = Files; f; f = f->f_next) { if (f->f_prevcount && now >= REPEATTIME(f)) { dbg_printf ("flush %s: repeated %d times, %d sec.\n", TypeNames[f->f_type], f->f_prevcount, repeatinterval[f->f_repeatcount]); fprintlog (f, LocalHostName, 0, (char *)NULL); BACKOFF (f); } } (void) alarm (TIMERINTVL);}/* Print syslogd errors some place. */voidlogerror (const char *type){ char buf[100];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -