📄 syslogd.c
字号:
{ register char *p, *q; register int c; char line[MAXLINE + 1]; int pri, flags; char *lp; (void) snprintf(line, sizeof(line), "vmunix: "); lp = line + strlen(line); for (p = msg; *p != '\0'; ) { flags = ADDDATE; 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); } return;}/* * Decode a priority into textual information like auth.emerg. */char *textpri(pri) 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++); snprintf (res, sizeof(res), "%s.%s<%d>", c_fac->c_name, c_pri->c_name, pri); return res;}time_t now;/* * Log a message to the appropriate log files, users, etc. based on * the priority. */void logmsg(pri, msg, from, flags) int pri; char *msg; const char *from; int flags;{ register struct filed *f; int fac, prilev, lognum; int msglen; char *timestamp; dprintf("logmsg: %s, flags %x, from %s, msg %s\n", textpri(pri), flags, from, msg);#ifndef SYSV 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|O_NOCTTY); if (f->f_file >= 0) { untty(); fprintlog(f, (char *)from, flags, msg); (void) close(f->f_file); f->f_file = -1; }#ifndef SYSV (void) sigsetmask(omask);#endif return; }#ifdef SYSV for (lognum = 0; lognum <= nlogs; lognum++) { f = &Files[lognum];#else for (f = Files; f; f = f->f_next) {#endif /* skip messages that are incorrect priority */ if ( (f->f_pmask[fac] == TABLE_NOPRI) || \ ((f->f_pmask[fac] & (1<<prilev)) == 0) ) 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 && !strcmp(msg, f->f_prevline) && !strcmp(from, f->f_prevhost)) { (void) strncpy(f->f_lasttime, timestamp, 15); f->f_prevcount++; dprintf("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, (char *)from, flags, (char *)NULL); BACKOFF(f); } } else { /* new line, save it */ if (f->f_prevcount) fprintlog(f, (char *)from, 0, (char *)NULL); f->f_prevpri = pri; f->f_repeatcount = 0; (void) strncpy(f->f_lasttime, timestamp, 15); (void) strncpy(f->f_prevhost, from, sizeof(f->f_prevhost)); if (msglen < MAXSVLINE) { f->f_prevlen = msglen; (void) strcpy(f->f_prevline, msg); fprintlog(f, (char *)from, flags, (char *)NULL); } else { f->f_prevline[0] = 0; f->f_prevlen = 0; fprintlog(f, (char *)from, flags, msg); } } }#ifndef SYSV (void) sigsetmask(omask);#endif}#if FALSE} /* balance parentheses for emacs */#endifvoid fprintlog(f, from, flags, msg) register struct filed *f; char *from; int flags; char *msg;{ struct iovec iov[3]; register struct iovec *v = iov; char repbuf[80];#ifdef SYSLOG_INET register int l; char line[MAXLINE + 1]; time_t fwd_suspend; struct hostent *hp;#endif dprintf("Called fprintlog, "); /* v->iov_base = f->f_lasttime; v->iov_len = 15; v++; v->iov_base = " "; v->iov_len = 1; v++; v->iov_base = f->f_prevhost; v->iov_len = strlen(v->iov_base); v++; */ v->iov_base = ""; v->iov_len = 0; v++; if (msg) { v->iov_base = msg; v->iov_len = strlen(msg); } else if (f->f_prevcount > 1) { (void) snprintf(repbuf, sizeof(repbuf), "last message repeated %d times", f->f_prevcount); v->iov_base = repbuf; v->iov_len = strlen(repbuf); } else { v->iov_base = f->f_prevline; v->iov_len = f->f_prevlen; } v++; dprintf("logging to %s", TypeNames[f->f_type]); switch (f->f_type) { case F_UNUSED: f->f_time = now; dprintf("\n"); break;#ifdef SYSLOG_INET case F_FORW_SUSP: fwd_suspend = time((time_t *) 0) - f->f_time; if ( fwd_suspend >= INET_SUSPEND_TIME ) { dprintf("\nForwarding suspension over, " \ "retrying FORW "); f->f_type = F_FORW; goto f_forw; } else { dprintf(" %s\n", f->f_un.f_forw.f_hname); dprintf("Forwarding suspension not over, time " \ "left: %d.\n", INET_SUSPEND_TIME - \ fwd_suspend); } break; /* * The trick is to wait some time, then retry to get the * address. If that fails retry x times and then give up. * * You'll run into this problem mostly if the name server you * need for resolving the address is on the same machine, but * is started after syslogd. */ case F_FORW_UNKN: dprintf(" %s\n", f->f_un.f_forw.f_hname); fwd_suspend = time((time_t *) 0) - f->f_time; if ( fwd_suspend >= INET_SUSPEND_TIME ) { dprintf("Forwarding suspension to unknown over, retrying\n"); if ( (hp = gethostbyname(f->f_un.f_forw.f_hname)) == NULL ) { dprintf("Failure: %s\n", sys_h_errlist[h_errno]); dprintf("Retries: %d\n", f->f_prevcount); if ( --f->f_prevcount < 0 ) { dprintf("Giving up.\n"); f->f_type = F_UNUSED; } else dprintf("Left retries: %d\n", f->f_prevcount); } else { dprintf("%s found, resuming.\n", f->f_un.f_forw.f_hname); memcpy((char *) &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 dprintf("Forwarding suspension not over, time " \ "left: %d\n", INET_SUSPEND_TIME - fwd_suspend); break; case F_FORW: /* * Don't send any message to a remote host if it * already comes from one. (we don't care 'bout who * sent the message, we don't send it anyway) -Joey */ f_forw: dprintf(" %s\n", f->f_un.f_forw.f_hname); if ( strcmp(from, LocalHostName) && NoHops ) dprintf("Not sending message to remote.\n"); else { f->f_time = now; (void) snprintf(line, sizeof(line), "<%d>%s\n", f->f_prevpri, \ (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; dprintf("INET sendto error: %d = %s.\n", e, strerror(e)); f->f_type = F_FORW_SUSP; errno = e; logerror("sendto"); } } break;#endif case F_CONSOLE: f->f_time = now;#ifdef UNIXPC if (1) {#else if (flags & IGN_CONS) { #endif dprintf(" (ignored).\n"); break; } /* FALLTHROUGH */ case F_TTY: case F_FILE: case F_PIPE: f->f_time = now; dprintf(" %s\n", f->f_un.f_fname); if (f->f_type == F_TTY || f->f_type == F_CONSOLE) { v->iov_base = "\r\n"; v->iov_len = 2; } else { v->iov_base = "\n"; v->iov_len = 1; } again: /* f->f_file == -1 is an indicator that the we couldn't open the file at startup. */ if (f->f_file == -1) break; if (writev(f->f_file, iov, 3) < 0) { int e = errno; /* If a named pipe is full, just ignore it for now - mrn 24 May 96 */ if (f->f_type == F_PIPE && e == EAGAIN) break; (void) close(f->f_file); /* * Check for EBADF on TTY's due to vhangup() XXX * Linux uses EIO instead (mrn 12 May 96) */ if ((f->f_type == F_TTY || f->f_type == F_CONSOLE)#ifdef linux && e == EIO) {#else && e == EBADF) {#endif f->f_file = open(f->f_un.f_fname, O_WRONLY|O_APPEND|O_NOCTTY); if (f->f_file < 0) { f->f_type = F_UNUSED; logerror(f->f_un.f_fname); } else { untty(); goto again; } } else { f->f_type = F_UNUSED; errno = e; logerror(f->f_un.f_fname); } } else if (f->f_flags & SYNC_FILE) (void) fsync(f->f_file); break; case F_USERS: case F_WALL: f->f_time = now; dprintf("\n"); v->iov_base = "\r\n"; v->iov_len = 2; wallmsg(f, iov); break; } /* switch */ if (f->f_type != F_FORW_UNKN) f->f_prevcount = 0; return; }#if FALSE}} /* balance parentheses for emacs */#endifjmp_buf ttybuf;void endtty(){ longjmp(ttybuf, 1);}/* * WALLMSG -- Write a message to the world at large * * Write the specified message to either the entire * world, or a list of approved users. */void wallmsg(f, iov) register struct filed *f; struct iovec *iov;{ char p[6 + UNAMESZ]; register int i; int ttyf, len; static int reenter = 0; struct utmp ut; struct utmp *uptr; char greetings[200]; if (reenter++) return; /* open the user login file */ setutent(); /* * Might as well fork instead of using nonblocking I/O * and doing notty(). */ if (fork() == 0) { (void) signal(SIGTERM, SIG_DFL); (void) alarm(0); (void) signal(SIGALRM, endtty);#ifndef SYSV (void) signal(SIGTTOU, SIG_IGN); (void) sigsetmask(0);#endif (void) snprintf(greetings, sizeof(greetings), "\r\n\7Message from syslogd@%s at %.24s ...\r\n", (char *) iov[2].iov_base, ctime(&now)); len = strlen(greetings); /* scan the user login file */ while ((uptr = getutent())) { memcpy(&ut, uptr, sizeof(ut)); /* is this slot used? */ if (ut.ut_name[0] == '\0') continue; if (ut.ut_type == LOGIN_PROCESS) continue; if (!(strcmp (ut.ut_name,"LOGIN"))) /* paranoia */ continue; /* should we send the message to this user? */ if (f->f_type == F_USERS) { for (i = 0; i < MAXUNAMES; i++) { if (!f->f_un.f_uname[i][0]) { i = MAXUNAMES; break; } if (strncmp(f->f_un.f_uname[i], ut.ut_name, UNAMESZ) == 0) break; } if (i >= MAXUNAMES) continue; } /* compute the device name */ strcpy(p, _PATH_DEV); strncat(p, ut.ut_line, UNAMESZ); if (f->f_type == F_WALL) { iov[0].iov_base = greetings; iov[0].iov_len = len; iov[1].iov_len = 0; } if (setjmp(ttybuf) == 0) { (void) alarm(15);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -