📄 syslogd.c
字号:
if (writev(f->f_file, iov, 6) < 0) { int e = errno; /* If a named pipe is full, just ignore it for now */ if (f->f_type == F_PIPE && e == EAGAIN) break; /* If the filesystem is filled up, just ignore it for now and continue writing when possible */ if (f->f_type == F_FILE && e == ENOSPC) 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_type == F_FILE && (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[sizeof (_PATH_DEV) + UNAMESZ]; register int i; int ttyf, len; static int reenter = 0; struct utmp ut; struct utmp *uptr; char greetings[200]; (void) &len; 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);#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 != USER_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) signal(SIGALRM, endtty); (void) alarm(15); /* open the terminal */ ttyf = open(p, O_WRONLY|O_NOCTTY); if (ttyf >= 0) { struct stat statb; if (fstat(ttyf, &statb) == 0 && (statb.st_mode & S_IWRITE)) (void) writev(ttyf, iov, 6); close(ttyf); ttyf = -1; } } (void) alarm(0); } exit(0); } /* close the user login file */ endutent(); reenter = 0;}void reapchild(){ int saved_errno = errno;#if defined(SYSV) && !defined(linux) (void) signal(SIGCHLD, reapchild); /* reset signal handler -ASP */ wait ((int *)0);#else union wait status; while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0) ;#endif#ifdef linux (void) signal(SIGCHLD, reapchild); /* reset signal handler -ASP */#endif errno = saved_errno;}/* * Return a printable representation of a host address. */const char *cvthname(f) struct sockaddr_in *f;{ struct hostent *hp; register char *p; int count; if (f->sin_family != AF_INET) { dprintf("Malformed from address.\n"); return ("???"); } hp = gethostbyaddr((char *) &f->sin_addr, sizeof(struct in_addr), \ f->sin_family); if (hp == 0) { dprintf("Host name for your address (%s) unknown.\n", inet_ntoa(f->sin_addr)); return (inet_ntoa(f->sin_addr)); } /* * Convert to lower case, just like LocalDomain above */ for (p = (char *)hp->h_name; *p ; p++) if (isupper(*p)) *p = tolower(*p); /* * Notice that the string still contains the fqdn, but your * hostname and domain are separated by a '\0'. */ if ((p = strchr(hp->h_name, '.'))) { if (strcmp(p + 1, LocalDomain) == 0) { *p = '\0'; return (hp->h_name); } else { if (StripDomains) { count=0; while (StripDomains[count]) { if (strcmp(p + 1, StripDomains[count]) == 0) { *p = '\0'; return (hp->h_name); } count++; } } if (LocalHosts) { count=0; while (LocalHosts[count]) { if (!strcmp(hp->h_name, LocalHosts[count])) { *p = '\0'; return (hp->h_name); } count++; } } } } return (hp->h_name);}void domark(){ register struct filed *f;#ifdef SYSV int lognum;#endif if (MarkInterval > 0) { now = time(0); MarkSeq += TIMERINTVL; if (MarkSeq >= MarkInterval) { logmsg(LOG_MARK|LOG_INFO, "-- MARK --", LocalHostName, ADDDATE|MARK); MarkSeq = 0; }#ifdef SYSV for (lognum = 0; lognum <= nlogs; lognum++) { f = &Files[lognum];#else for (f = Files; f; f = f->f_next) {#endif if (f->f_prevcount && now >= REPEATTIME(f)) { dprintf("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) signal(SIGALRM, domark); (void) alarm(TIMERINTVL);}void debug_switch(){ dprintf("Switching debugging_on to %s\n", (debugging_on == 0) ? "true" : "false"); debugging_on = (debugging_on == 0) ? 1 : 0; signal(SIGUSR1, debug_switch);}/* * Print syslogd errors some place. */void logerror(type) char *type;{ char buf[100]; dprintf("Called logerr, msg: %s\n", type); if (errno == 0) (void) snprintf(buf, sizeof(buf), "syslogd: %s", type); else (void) snprintf(buf, sizeof(buf), "syslogd: %s: %s", type, strerror(errno)); errno = 0; logmsg(LOG_SYSLOG|LOG_ERR, buf, LocalHostName, ADDDATE); return;}void die(sig) int sig; { register struct filed *f; char buf[100]; int lognum; int i; int was_initialized = Initialized; Initialized = 0; /* Don't log SIGCHLDs in case we receive one during exiting */ for (lognum = 0; lognum <= nlogs; lognum++) { f = &Files[lognum]; /* flush any pending output */ if (f->f_prevcount) fprintlog(f, LocalHostName, 0, (char *)NULL); } Initialized = was_initialized; if (sig) { dprintf("syslogd: exiting on signal %d\n", sig); (void) snprintf(buf, sizeof(buf), "exiting on signal %d", sig); errno = 0; logmsg(LOG_SYSLOG|LOG_INFO, buf, LocalHostName, ADDDATE); } /* Close the UNIX sockets. */ for (i = 0; i < nfunix; i++) if (funix[i] != -1) close(funix[i]); /* Close the inet socket. */ if (InetInuse) close(inetm); /* Clean-up files. */ for (i = 0; i < nfunix; i++) if (funixn[i] && funix[i] != -1) (void)unlink(funixn[i]);#ifndef TESTING (void) remove_pid(PidFile);#endif exit(0);}/* * Signal handler to terminate the parent process. */#ifndef TESTINGvoid doexit(sig) int sig;{ exit (0);}#endif/* * INIT -- Initialize syslogd from configuration table */void init(){ register int i, lognum; register FILE *cf; register struct filed *f;#ifndef TESTING#ifndef SYSV register struct filed **nextp = (struct filed **) 0;#endif#endif register char *p; register unsigned int Forwarding = 0;#ifdef CONT_LINE char cbuf[BUFSIZ]; char *cline;#else char cline[BUFSIZ];#endif struct servent *sp; sp = getservbyname("syslog", "udp"); if (sp == NULL) { if (errno == ENOENT) { errno = 0; logerror("The file /etc/services does not seem exist."); } errno = 0; logerror("network logging disabled (syslog/udp service unknown)."); logerror("see syslogd(8) for details of whether and how to enable it."); LogPort = 0; } else LogPort = sp->s_port; /* * Close all open log files and free log descriptor array. */ dprintf("Called init.\n"); Initialized = 0; if ( nlogs > -1 ) { dprintf("Initializing log structures.\n"); for (lognum = 0; lognum <= nlogs; lognum++ ) { f = &Files[lognum]; /* flush any pending output */ if (f->f_prevcount) fprintlog(f, LocalHostName, 0, (char *)NULL); switch (f->f_type) { case F_FILE: case F_PIPE: case F_TTY: case F_CONSOLE: (void) close(f->f_file); break; } } /* * This is needed especially when HUPing syslogd as the * structure would grow infinitively. -Joey */ nlogs = -1; free((void *) Files); Files = (struct filed *) 0; } #ifdef SYSV lognum = 0;#else f = NULL;#endif /* open the configuration file */ if ((cf = fopen(ConfFile, "r")) == NULL) { dprintf("cannot open %s.\n", ConfFile);#ifdef SYSV allocate_log(); f = &Files[lognum++];#ifndef TESTING cfline("*.err\t" _PATH_CONSOLE, f);#else snprintf(cbuf,sizeof(cbuf), "*.*\t%s", ttyname(0)); cfline(cbuf, f);#endif#else *nextp = (struct filed *)calloc(1, sizeof(*f)); cfline("*.ERR\t" _PATH_CONSOLE, *nextp); (*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f)) /* ASP */ cfline("*.PANIC\t*", (*nextp)->f_next);#endif Initialized = 1; return; } /* * Foreach line in the conf table, open that file. */#if CONT_LINE cl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -