📄 syslogd.c
字号:
strcpy(tmpline, parts[fd]); free(parts[fd]); parts[fd] = (char *) 0; if ( (strlen(msg) + strlen(tmpline)) > MAXLINE ) { logerror("Cannot glue message parts together"); printline(hname, tmpline); start = msg; } else { dprintf("Previous: %s\n", tmpline); dprintf("Next: %s\n", msg); strcat(tmpline, msg); /* length checked above */ printline(hname, tmpline); if ( (strlen(msg) + 1) == len ) return; else start = strchr(msg, '\0') + 1; } } if ( msg[len-1] != '\0' ) { msg[len] = '\0'; for(p= msg+len-1; *p != '\0' && p > msg; ) --p; if(*p == '\0') p++; ptlngth = strlen(p); if ( (parts[fd] = malloc(ptlngth + 1)) == (char *) 0 ) logerror("Cannot allocate memory for message part."); else { strcpy(parts[fd], p); dprintf("Saving partial msg: %s\n", parts[fd]); memset(p, '\0', ptlngth); } } do { end = strchr(start + 1, '\0'); printline(hname, start); start = end + 1; } while ( *start != '\0' ); return;}/* * Take a raw input line, decode the message, and print the message * on the appropriate log files. */void printline(hname, msg) const char *hname; char *msg;{ register char *p, *q; register unsigned char c; char line[MAXLINE + 1]; int pri; /* 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; memset (line, 0, sizeof(line)); q = line; while ((c = *p++) && q < &line[sizeof(line) - 4]) { if (c == '\n' || c == 127) *q++ = ' '; else if (c < 040) { *q++ = '^'; *q++ = c ^ 0100; } else *q++ = c; } *q = '\0'; logmsg(pri, line, hname, SYNC_FILE); return;}/* * Take a raw input line from /dev/klog, split and format similar to syslog(). */void printsys(msg) char *msg;{ 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;#ifdef __gnu_linux__ sigset_t mask;#else#ifndef SYSV sigset_t omask;#endif#endif dprintf("logmsg: %s, flags %x, from %s, msg %s\n", textpri(pri), flags, from, msg);#ifdef __gnu_linux__ sigemptyset(&mask); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGALRM); sigprocmask(SIG_BLOCK, &mask, NULL);#else#ifndef SYSV omask = sigblock(sigmask(SIGHUP)|sigmask(SIGALRM));#endif#endif /* * Check to see if msg looks non-standard. * * A message looks like * Nov 17 11:42:33 CRON[ * 01234567890123456 * ^ ^ ^ ^ ^ * * Remote messages are not accompanied by a timestamp. * Local messages are accompanied by a timestamp (program's timezone) */ msglen = strlen(msg); if (!(msglen < 16 || msg[3] != ' ' || msg[6] != ' ' || msg[9] != ':' || msg[12] != ':' || msg[15] != ' ')) { msg += 16; msglen -= 16; } (void) time(&now); timestamp = ctime(&now) + 4; /* extract facility and priority level */ 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; }#ifdef __gnu_linux__ sigprocmask(SIG_UNBLOCK, &mask, NULL);#else#ifndef SYSV (void) sigsetmask(omask);#endif#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); } } }#ifdef __gnu_linux__ sigprocmask(SIG_UNBLOCK, &mask, NULL);#else#ifndef SYSV (void) sigsetmask(omask);#endif#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[6]; 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 = 1; 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", 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 we couldn't open the file at startup. */ if (f->f_file == -1) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -