summaryrefslogtreecommitdiffstats
path: root/syslogd/syslogd.c
diff options
context:
space:
mode:
Diffstat (limited to 'syslogd/syslogd.c')
-rw-r--r--syslogd/syslogd.c1406
1 files changed, 0 insertions, 1406 deletions
diff --git a/syslogd/syslogd.c b/syslogd/syslogd.c
deleted file mode 100644
index 733e3a693..000000000
--- a/syslogd/syslogd.c
+++ /dev/null
@@ -1,1406 +0,0 @@
-/*
- * Copyright (c) 1983, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Wed Sep 14 21:56:59 1994: Applied patches from Alan Modra
- * (alan@spri.levels.unisa.edu.au):
- * 1) Add O_CREAT to open flags so that syslogd doesn't complain about
- * non-existent files
- * 2) Modified f_pmask initialisation and testing to allow logging of
- * messages at a particular priority level, rather that all messages
- * at or above a given priority level.
- *
- * Sat Jun 3 12:48:16 1995: Applied patches from
- * Jochen.Hein@informatik.tu-clausthal.de to allow spaces *AND* tabs to
- * separate the selector from the action. This means that no whitespace is
- * allowed inside the selector.
- * */
-
-#ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-static char sccsid[] = "@(#)syslogd.c 5.45 (Berkeley) 3/2/91";
-#endif /* not lint */
-
-/*
- * syslogd -- log system messages
- *
- * This program implements a system log. It takes a series of lines.
- * Each line may have a priority, signified as "<n>" as
- * the first characters of the line. If this is
- * not present, a default priority is used.
- *
- * To kill syslogd, send a signal 15 (terminate). A signal 1 (hup) will
- * cause it to reread its configuration file.
- *
- * Defined Constants:
- *
- * MAXLINE -- the maximimum line length that can be handled.
- * DEFUPRI -- the default priority for user messages
- * DEFSPRI -- the default priority for kernel messages
- *
- * Author: Eric Allman
- * extensive changes by Ralph Campbell
- * more extensive changes by Eric Allman (again)
- *
- * Modified, Sun Mar 7 15:21:13 1993, faith@cs.unc.edu for Linux:
- *
- * SUN_LEN_MISSING: struct sockaddr does not have sun_len
- * SYSLOG_STREAM: syslog is implemented using stream sockets
- * SYSLOG_INET: support inet logging
- * KLOG_STREAM: kernel logging uses a stream device
- * STATUS_BROKEN: use "int status" instead of "union wait status"
- * RE_INSTALL_SIGNAL: signal() does *not* remain installed
- * SYS_MSGBUF_H_MISSING: sys/msgbuf.h is missing
- * FSYNC_MISSING: fsync() is missing
- * KERNEL_NAME: what the kernel is usually called
- *
- * Original Linux version by Rik Faith <faith@cs.unc.edu>
- * with changes by Rick Sladkey <jrs@world.std.com> and
- * Rick <pclink@qus102.qld.npb.telecom.com.au>. Anyone else
- * named Rick who wants to chip in? :-)
- * More corrections by Neal Becker <neal@ctd.comsat.com> Sun Jan 16, 1994
- * Patches from Jochen Hein (Jochen.Hein@informatik.tu-clausthal.de) to treat
- * spaces and tabs the same, applied Sat Mar 11 10:09:24 1995
- */
-
-#ifdef __linux__
-#define SUN_LEN_MISSING
-#define SYSLOG_STREAM
-#define SYSLOG_INET
-#define KLOG_STREAM
-#undef STATUS_BROKEN
-#define RE_INSTALL_SIGNAL
-#define SYS_MSGBUF_H_MISSING
-#undef FSYNC_MISSING
-#define KERNEL_NAME "linux"
-#endif
-
-#define MAXLINE 1024 /* maximum line length */
-#define MAXSVLINE 120 /* maximum saved line length */
-#define DEFUPRI (LOG_USER|LOG_NOTICE)
-#define DEFSPRI (LOG_KERN|LOG_CRIT)
-#define TIMERINTVL 30 /* interval for checking flush, mark */
-
-#include <sys/param.h>
-#include <sys/errno.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#ifdef SYS_MSGBUF_H_MISSING
-#define MSG_BSIZE (MAXLINE*2)
-#else
-#include <sys/msgbuf.h>
-#endif
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/signal.h>
-
-#include <netinet/in.h>
-#include <netdb.h>
-
-#include <utmp.h>
-#include <setjmp.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <unistd.h>
-#include <paths.h>
-
-#define SYSLOG_NAMES
-#include <sys/syslog.h>
-
-char *LogName = _PATH_LOG;
-char *ConfFile = _PATH_LOGCONF;
-
-#ifdef __linux__
-#define CONFORM_TO_FSSTND
-#include "pathnames.h"
-#endif
-
-#ifdef CONFORM_TO_FSSTND
-char *PidFile = "/var/run/syslog.pid";
-#else
-char *PidFile = _PATH_LOGPID;
-#endif
-
-char ctty[] = _PATH_CONSOLE;
-
-#define FDMASK(fd) (1 << (fd))
-
-#define dprintf if (Debug) printf
-
-#define MAXUNAMES 20 /* maximum number of user names */
-
-/*
- * Flags to logmsg().
- */
-
-#define IGN_CONS 0x001 /* don't print on console */
-#define SYNC_FILE 0x002 /* do fsync on file after printing */
-#define ADDDATE 0x004 /* add a date to the message */
-#define MARK 0x008 /* this message is a mark */
-
-/*
- * This structure represents the files that will have log
- * copies printed.
- */
-
-struct filed {
- struct filed *f_next; /* next in linked list */
- short f_type; /* entry type, see below */
- short f_file; /* file descriptor */
- time_t f_time; /* time this was last written */
- u_char f_pmask[LOG_NFACILITIES+1]; /* priority mask */
- union {
- char f_uname[MAXUNAMES][UT_NAMESIZE+1];
- struct {
- char f_hname[MAXHOSTNAMELEN+1];
- struct sockaddr_in f_addr;
- } f_forw; /* forwarding address */
- char f_fname[MAXPATHLEN];
- } f_un;
- char f_prevline[MAXSVLINE]; /* last message logged */
- char f_lasttime[16]; /* time of last occurrence */
- char f_prevhost[MAXHOSTNAMELEN+1]; /* host from which recd. */
- int f_prevpri; /* pri of f_prevline */
- int f_prevlen; /* length of f_prevline */
- int f_prevcount; /* repetition cnt of prevline */
- int f_repeatcount; /* number of "repeated" msgs */
-};
-
-/*
- * Intervals at which we flush out "message repeated" messages,
- * in seconds after previous message is logged. After each flush,
- * we move to the next interval until we reach the largest.
- */
-int repeatinterval[] = { 30, 120, 600 }; /* # of secs before flush */
-#define MAXREPEAT ((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1)
-#define REPEATTIME(f) ((f)->f_time + repeatinterval[(f)->f_repeatcount])
-#define BACKOFF(f) { if (++(f)->f_repeatcount > MAXREPEAT) \
- (f)->f_repeatcount = MAXREPEAT; \
- }
-
-/* values for f_type */
-#define F_UNUSED 0 /* unused entry */
-#define F_FILE 1 /* regular file */
-#define F_TTY 2 /* terminal */
-#define F_CONSOLE 3 /* console terminal */
-#define F_FORW 4 /* remote machine */
-#define F_USERS 5 /* list of users */
-#define F_WALL 6 /* everyone logged on */
-
-char *TypeNames[7] = {
- "UNUSED", "FILE", "TTY", "CONSOLE",
- "FORW", "USERS", "WALL"
-};
-
-struct filed *Files;
-struct filed consfile;
-
-int Debug; /* debug flag */
-char LocalHostName[MAXHOSTNAMELEN+1]; /* our hostname */
-char *LocalDomain; /* our local domain name */
-int InetInuse = 0; /* non-zero if INET sockets are being used */
-#ifdef SYSLOG_INET
-int finet; /* Internet datagram socket */
-#endif /* SYSLOG_INET */
-int LogPort; /* port number for INET connections */
-int Initialized = 0; /* set when we have initialized ourselves */
-int MarkInterval = 20 * 60; /* interval between marks in seconds */
-int MarkSeq = 0; /* mark sequence number */
-
-extern int errno;
-extern char *ctime(), *index(), *calloc();
-
-main(argc, argv)
- int argc;
- char **argv;
-{
- register int i;
- register char *p;
- int funix, fklog, len;
- struct sockaddr_un sunx, fromunix;
- struct sockaddr_in sin, frominet;
- FILE *fp;
- int ch;
- char line[MSG_BSIZE + 1];
- extern int optind;
- extern char *optarg;
- void die(), domark(), init(), reapchild();
-#ifdef SYSLOG_STREAM
- fd_set unixm;
- int fd;
-#endif /* SYSLOG_STREAM */
-
- while ((ch = getopt(argc, argv, "df:m:p:")) != EOF)
- switch((char)ch) {
- case 'd': /* debug */
- Debug++;
- break;
- case 'f': /* configuration file */
- ConfFile = optarg;
- break;
- case 'm': /* mark interval */
- MarkInterval = atoi(optarg) * 60;
- break;
- case 'p': /* path */
- LogName = optarg;
- break;
- case '?':
- default:
- usage();
- }
- if (argc -= optind)
- usage();
-
- if (!Debug)
- daemon(0, 0);
- else
- setlinebuf(stdout);
-
- consfile.f_type = F_CONSOLE;
- (void) strcpy(consfile.f_un.f_fname, ctty);
- (void) gethostname(LocalHostName, sizeof LocalHostName);
- if (p = index(LocalHostName, '.')) {
- *p++ = '\0';
- LocalDomain = p;
- }
- else
- LocalDomain = "";
- (void) signal(SIGTERM, die);
- (void) signal(SIGINT, Debug ? die : SIG_IGN);
- (void) signal(SIGQUIT, Debug ? die : SIG_IGN);
- (void) signal(SIGCHLD, reapchild);
- (void) signal(SIGALRM, domark);
- (void) alarm(TIMERINTVL);
- (void) unlink(LogName);
-
- bzero((char *)&sunx, sizeof(sunx));
- sunx.sun_family = AF_UNIX;
- (void) strncpy(sunx.sun_path, LogName, sizeof sunx.sun_path);
-#ifdef SYSLOG_STREAM
- funix = socket(AF_UNIX, SOCK_STREAM, 0);
- if (funix < 0 || bind(funix, (struct sockaddr *) &sunx,
- sizeof(sunx)) < 0 || listen(funix, 5) < 0 ||
-#else /* !SYSLOG_STREAM */
- funix = socket(AF_UNIX, SOCK_DGRAM, 0);
- if (funix < 0 || bind(funix, (struct sockaddr *) &sunx,
- sizeof(sunx.sun_family)+sizeof(sunx.sun_len)+
- strlen(sunx.sun_path)) < 0 ||
-#endif /* !SYSLOG_STREAM */
- chmod(LogName, 0666) < 0) {
- (void) sprintf(line, "cannot create %s", LogName);
- logerror(line);
- dprintf("cannot create %s (%d)\n", LogName, errno);
- die(0);
- }
-#ifdef SYSLOG_INET
- finet = socket(AF_INET, SOCK_DGRAM, 0);
- if (finet >= 0) {
- struct servent *sp;
-
- sp = getservbyname("syslog", "udp");
- if (sp == NULL) {
- errno = 0;
- logerror("syslog/udp: unknown service");
- }
- else {
- bzero((char *) &sin, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = LogPort = sp->s_port;
- if (bind(finet, (struct sockaddr *) &sin,
- sizeof(sin)) < 0)
- logerror("bind");
- else
- InetInuse = 1;
- }
- if (!InetInuse)
- finet = -1;
- }
-#endif /* SYSLOG_INET */
- if ((fklog = open(_PATH_KLOG, O_RDONLY, 0)) < 0)
- dprintf("can't open %s (%d)\n", _PATH_KLOG, errno);
-
- /* tuck my process id away */
- fp = fopen(PidFile, "w");
- if (fp != NULL) {
- fprintf(fp, "%d\n", getpid());
- (void) fclose(fp);
- }
-
- dprintf("off & running....\n");
-
- init();
-#ifndef RE_INSTALL_SIGNAL /* init installs itself as the handler */
- (void) signal(SIGHUP, init);
-#endif /* !RE_INSTALL_SIGNAL */
-#ifdef SYSLOG_STREAM
- FD_ZERO(&unixm);
-#endif /* SYSLOG_STREAM */
-
- for (;;) {
- int nfds;
- fd_set readfds;
-
-#ifdef SYSLOG_STREAM
- readfds = unixm;
-#else /* !SYSLOG_STREAM */
- FD_ZERO(&readfds);
-#endif /* !SYSLOG_STREAM */
- if (funix >= 0)
- FD_SET(funix, &readfds);
- if (fklog >= 0)
- FD_SET(fklog, &readfds);
-#ifdef SYSLOG_INET
- if (finet >= 0)
- FD_SET(finet, &readfds);
-#endif /* SYSLOG_INET */
-
- errno = 0;
- dprintf("readfds = %#x\n", *((long *)&readfds));
- nfds = select(FD_SETSIZE, &readfds, (fd_set *) NULL,
- (fd_set *) NULL, (struct timeval *) NULL);
- if (nfds == 0)
- continue;
- if (nfds < 0) {
- if (errno != EINTR)
- logerror("select");
- continue;
- }
- dprintf("got a message (%d, %#x)\n", nfds, *((long *)&readfds));
-
-#ifdef KLOG_STREAM
- if (FD_ISSET(fklog, &readfds)) {
- nfds--;
- for (;;) {
- i = klogread(fklog, line, sizeof(line) - 1);
- if (i > 0) {
- line[i] = '\0';
- printsys(line);
- }
- else {
- if (i < 0 && errno != EINTR) {
- logerror("klog");
- fklog = -1;
- }
- break;
- }
- }
- }
-#else /* !KLOG_STREAM */
- if (FD_ISSET(fklog, &readfds)) {
- nfds--;
- i = read(fklog, line, sizeof(line) - 1);
- if (i > 0) {
- line[i] = '\0';
- printsys(line);
- } else if (i < 0 && errno != EINTR) {
- logerror("klog");
- fklog = -1;
- }
- }
-#endif /* !KLOG_STREAM */
-
-#ifdef SYSLOG_STREAM
- /* Accept a new unix connection. */
- if (FD_ISSET(funix, &readfds)) {
- nfds--;
- len = sizeof fromunix;
- if ((fd = accept(funix, (struct sockaddr *) &fromunix,
- &len)) >= 0) {
- FD_SET(fd, &unixm);
- dprintf("new stream connect (%d)\n", fd);
- }
- else
- logerror("accept");
- }
- /* Recv from existing connections. */
- for (fd = 0; nfds > 0 && fd < FD_SETSIZE; fd++) {
- if (FD_ISSET(fd, &unixm) && FD_ISSET(fd, &readfds)) {
- nfds--;
- dprintf("message from stream (%d)\n", fd);
- i = read(fd, line, MAXLINE);
- if (i > 0) {
- line[i] = '\0';
- printmulti(LocalHostName, line, i);
- }
- else if (i == 0) {
- dprintf("stream closed (%d)\n", fd);
- close(fd);
- FD_CLR(fd, &unixm);
- }
- else if (i < 0 && errno != EINTR) {
- logerror("recv stream");
- close(fd);
- FD_CLR(fd, &unixm);
- }
- }
- }
-#else /* !SYSLOG_STREAM */
- if (FD_ISSET(funix, &readfds)) {
- nfds--;
- len = sizeof fromunix;
- i = recvfrom(funix, line, MAXLINE, 0,
- (struct sockaddr *) &fromunix, &len);
- if (i > 0) {
- line[i] = '\0';
- printmulti(LocalHostName, line,i);
- } else if (i < 0 && errno != EINTR)
- logerror("recvfrom unix");
- }
-#endif /* !SYSLOG_STREAM */
-
-#ifdef SYSLOG_INET
- if (FD_ISSET(finet, &readfds)) {
- nfds--;
- len = sizeof frominet;
- i = recvfrom(finet, line, MAXLINE, 0,
- (struct sockaddr *) &frominet, &len);
- if (i > 0) {
- extern char *cvthname();
-
- line[i] = '\0';
- printmulti(cvthname(&frominet), line,i);
- } else if (i < 0 && errno != EINTR)
- logerror("recvfrom inet");
- }
-#endif /* SYSLOG_INET */
- if (nfds != 0)
- logerror("loose cannon");
- }
-}
-
-usage()
-{
- (void) fprintf(stderr,
- "usage: syslogd [-f conffile] [-m markinterval] [-p logpath]\n");
- exit(1);
-}
-
-/*
- * Break up null terminated lines for printline.
- */
-
-printmulti(hname, msg, len)
- char *hname;
- char *msg;
- int len;
-{
- int i;
- char *pt;
-
- dprintf("strlen = %d, len = %d\n", strlen(msg), len );
- for (pt = msg, i = 0; i < len; i++) {
- if (msg[i] == '\0') {
- printline(hname,pt);
- pt = &msg[i+1];
- }
- }
-}
-
-/*
- * Take a raw input line, decode the message, and print the message
- * on the appropriate log files.
- */
-
-printline(hname, msg)
- char *hname;
- char *msg;
-{
- register char *p, *q;
- register int 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;
-
- /* 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++ & 0177) != '\0' &&
- q < &line[sizeof(line) - 1])
- if (iscntrl(c)) {
- if (c == '\n')
- *q++ = ' ';
- else if (c == '\r')
- *q++ = ' ';
- else if (c == '\t')
- *q++ = '\t';
- else {
- *q++ = '^';
- *q++ = c ^ 0100;
- }
- }
- else
- *q++ = c;
- *q = '\0';
-
- logmsg(pri, line, hname, 0);
-}
-
-/*
- * Take a raw input line from /dev/klog, split and format similar to syslog().
- */
-
-printsys(msg)
- char *msg;
-{
- register char *p, *q;
- register int c;
- char line[MAXLINE + 1];
- int pri, flags;
- char *lp;
-
-#ifdef KERNEL_NAME
- (void) sprintf(line, "%s: ", KERNEL_NAME);
-#else /* !KERNEL_NAME */
- (void) strcpy(line, "vmunix: ");
-#endif /* !KERNEL_NAME */
-
- lp = line + strlen(line);
- for (p = msg; *p != '\0'; ) {
- flags = SYNC_FILE | ADDDATE; /* fsync file 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])
- if (iscntrl(c)) {
- if (c == '\n')
- *q++ = ' ';
- else if (c == '\r')
- *q++ = ' ';
- else if (c == '\t')
- *q++ = '\t';
- else {
- *q++ = '^';
- *q++ = c ^ 0100;
- }
- }
- else
- *q++ = c;
- *q = '\0';
- logmsg(pri, line, LocalHostName, flags);
- }
-}
-
-time_t now;
-
-/*
- * Log a message to the appropriate log files, users, etc. based on
- * the priority.
- */
-
-logmsg(pri, msg, from, flags)
- int pri;
- char *msg, *from;
- int flags;
-{
- register struct filed *f;
- int fac, prilev;
- int omask, msglen;
- char *timestamp;
- time_t time();
-
- dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n",
- pri, flags, from, msg);
-
- omask = sigblock(sigmask(SIGHUP)|sigmask(SIGALRM));
-
- /*
- * 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 = 1 << (LOG_PRIMASK - LOG_PRI(pri));
-
- /* log the message to the particular outputs */
- if (!Initialized) {
- f = &consfile;
-#ifdef O_NOCTTY
- f->f_file = open(ctty, O_WRONLY|O_NOCTTY, 0);
-#else /* !O_NOCTTY */
- f->f_file = open(ctty, O_WRONLY, 0);
-#endif /* !O_NOCTTY */
-
- if (f->f_file >= 0) {
- fprintlog(f, flags, msg);
- (void) close(f->f_file);
- }
- (void) sigsetmask(omask);
- return;
- }
- for (f = Files; f; f = f->f_next) {
- /* skip messages that are incorrect priority */
- if (!(f->f_pmask[fac] & prilev))
- 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, flags, (char *)NULL);
- BACKOFF(f);
- }
- } else {
- /* new line, save it */
- if (f->f_prevcount)
- fprintlog(f, 0, (char *)NULL);
- 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;
- f->f_prevpri = pri;
- (void) strcpy(f->f_prevline, msg);
- fprintlog(f, flags, (char *)NULL);
- } else {
- f->f_prevline[0] = 0;
- f->f_prevlen = 0;
- fprintlog(f, flags, msg);
- }
- }
- }
- (void) sigsetmask(omask);
-}
-
-fprintlog(f, flags, msg)
- register struct filed *f;
- int flags;
- char *msg;
-{
- struct iovec iov[6];
- register struct iovec *v;
- register int l;
- char line[MAXLINE + 1], repbuf[80], greetings[200];
-
- v = iov;
- if (f->f_type == F_WALL) {
- v->iov_base = greetings;
- v->iov_len = sprintf(greetings,
- "\r\n\7Message from syslogd@%s at %.24s ...\r\n",
- f->f_prevhost, ctime(&now));
- v++;
- v->iov_base = "";
- v->iov_len = 0;
- v++;
- } else {
- 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) {
- v->iov_base = repbuf;
- v->iov_len = sprintf(repbuf, "last message repeated %d times",
- f->f_prevcount);
- } else {
- v->iov_base = f->f_prevline;
- v->iov_len = f->f_prevlen;
- }
- v++;
-
- dprintf("Logging to %s", TypeNames[f->f_type]);
- f->f_time = now;
-
- switch (f->f_type) {
- case F_UNUSED:
- dprintf("\n");
- break;
-
- case F_FORW:
- dprintf(" %s\n", f->f_un.f_forw.f_hname);
- l = sprintf(line, "<%d>%.15s %s", f->f_prevpri,
- iov[0].iov_base, iov[4].iov_base);
- 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;
- (void) close(f->f_file);
- f->f_type = F_UNUSED;
- errno = e;
- logerror("sendto");
- }
- break;
-
- case F_CONSOLE:
- if (flags & IGN_CONS) {
- dprintf(" (ignored)\n");
- break;
- }
- /* FALLTHROUGH */
-
- case F_TTY:
- case F_FILE:
- dprintf(" %s\n", f->f_un.f_fname);
- if (f->f_type != F_FILE) {
- v->iov_base = "\r\n";
- v->iov_len = 2;
- } else {
- v->iov_base = "\n";
- v->iov_len = 1;
- }
- again:
- if (writev(f->f_file, iov, 6) < 0) {
- int e = errno;
- (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_FILE) {
- 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);
- }
- }
-#ifdef FSYNC_MISSING
- else if (flags & SYNC_FILE)
- (void) sync();
-#else
- else if (flags & SYNC_FILE)
- (void) fsync(f->f_file);
-#endif
- break;
-
- case F_USERS:
- case F_WALL:
- dprintf("\n");
- v->iov_base = "\r\n";
- v->iov_len = 2;
- wallmsg(f, iov);
- break;
- }
- f->f_prevcount = 0;
-}
-
-/*
- * WALLMSG -- Write a message to the world at large
- *
- * Write the specified message to either the entire
- * world, or a list of approved users.
- */
-
-wallmsg(f, iov)
- register struct filed *f;
- struct iovec *iov;
-{
- static int reenter; /* avoid calling ourselves */
- register FILE *uf;
- register int i;
- struct utmp ut;
- char *p, *ttymsg();
-
- if (reenter++)
- return;
- if ((uf = fopen(_PATH_UTMP, "r")) == NULL) {
- logerror(_PATH_UTMP);
- reenter = 0;
- return;
- }
- /* NOSTRICT */
- while (fread((char *) &ut, sizeof ut, 1, uf) == 1) {
- if (ut.ut_name[0] == '\0')
- continue;
-#ifdef USER_PROCESS
- if (ut.ut_type != USER_PROCESS)
- continue;
-#endif
- if (f->f_type == F_WALL) {
- if (p = ttymsg(iov, 6, ut.ut_line, 1)) {
- errno = 0; /* already in msg */
- logerror(p);
- }
- continue;
- }
- /* should we send the message to this user? */
- for (i = 0; i < MAXUNAMES; i++) {
- if (!f->f_un.f_uname[i][0])
- break;
- if (!strncmp(f->f_un.f_uname[i], ut.ut_name,
- UT_NAMESIZE)) {
- if (p = ttymsg(iov, 6, ut.ut_line, 1)) {
- errno = 0; /* already in msg */
- logerror(p);
- }
- break;
- }
- }
- }
- (void) fclose(uf);
- reenter = 0;
-}
-
-void
-reapchild()
-{
-#ifdef STATUS_BROKEN
- int status;
-#else
- union wait status;
-#endif
-
- while (wait3((int *)&status, WNOHANG, (struct rusage *) NULL) > 0)
- ;
-}
-
-/*
- * Return a printable representation of a host address.
- */
-char *
-cvthname(f)
- struct sockaddr_in *f;
-{
- struct hostent *hp;
- register char *p;
- extern char *inet_ntoa();
-
- dprintf("cvthname(%s)\n", inet_ntoa(f->sin_addr));
-
- 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));
- }
- if ((p = index(hp->h_name, '.')) && strcmp(p + 1, LocalDomain) == 0)
- *p = '\0';
- return ((char *) hp->h_name);
-}
-
-void
-domark()
-{
- register struct filed *f;
- time_t time();
-
- now = time((time_t *)NULL);
- 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)) {
- dprintf("flush %s: repeated %d times, %d sec.\n",
- TypeNames[f->f_type], f->f_prevcount,
- repeatinterval[f->f_repeatcount]);
- fprintlog(f, 0, (char *)NULL);
- BACKOFF(f);
- }
- }
-#ifdef RE_INSTALL_SIGNAL
- (void) signal(SIGALRM, domark);
-#endif
- (void) alarm(TIMERINTVL);
-}
-
-/*
- * Print syslogd errors some place.
- */
-logerror(type)
- char *type;
-{
- char buf[100], *strerror();
-
- if (errno)
- (void) sprintf(buf, "syslogd: %s: %s", type, strerror(errno));
- else
- (void) sprintf(buf, "syslogd: %s", type);
- errno = 0;
- dprintf("%s\n", buf);
- logmsg(LOG_SYSLOG|LOG_ERR, buf, LocalHostName, ADDDATE);
-}
-
-void
-die(sig)
-{
- register struct filed *f;
- char buf[100];
-
- for (f = Files; f != NULL; f = f->f_next) {
- /* flush any pending output */
- if (f->f_prevcount)
- fprintlog(f, 0, (char *)NULL);
- }
- if (sig) {
- dprintf("syslogd: exiting on signal %d\n", sig);
- (void) sprintf(buf, "exiting on signal %d", sig);
- errno = 0;
- logerror(buf);
- }
- (void) unlink(LogName);
- exit(0);
-}
-
-/*
- * INIT -- Initialize syslogd from configuration table
- */
-
-void
-init()
-{
- register int i;
- register FILE *cf;
- register struct filed *f, *next, **nextp;
- register char *p;
- char cline[BUFSIZ];
-
- dprintf("init\n");
-
- /*
- * Close all open log files.
- */
- Initialized = 0;
- for (f = Files; f != NULL; f = next) {
- /* flush any pending output */
- if (f->f_prevcount)
- fprintlog(f, 0, (char *)NULL);
-
- switch (f->f_type) {
- case F_FILE:
- case F_TTY:
- case F_CONSOLE:
- case F_FORW:
- (void) close(f->f_file);
- break;
- }
- next = f->f_next;
- free((char *) f);
- }
- Files = NULL;
- nextp = &Files;
-
- /* open the configuration file */
- if ((cf = fopen(ConfFile, "r")) == NULL) {
- dprintf("cannot open %s\n", ConfFile);
- *nextp = (struct filed *)calloc(1, sizeof(*f));
- cfline("*.ERR\t/dev/console", *nextp);
- (*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f));
- cfline("*.PANIC\t*", (*nextp)->f_next);
- Initialized = 1;
- return;
- }
-
- /*
- * Foreach line in the conf table, open that file.
- */
- f = NULL;
- while (fgets(cline, sizeof cline, cf) != NULL) {
- /*
- * check for end-of-section, comments, strip off trailing
- * spaces and newline character.
- */
- for (p = cline; isspace(*p); ++p);
- if (*p == '\0' || *p == '#')
- continue;
- for (p = index(cline, '\0'); isspace(*--p););
- *++p = '\0';
- f = (struct filed *)calloc(1, sizeof(*f));
- *nextp = f;
- nextp = &f->f_next;
- cfline(cline, f);
- }
-
- /* close the configuration file */
- (void) fclose(cf);
-
- Initialized = 1;
-
- if (Debug) {
- for (f = Files; f; f = f->f_next) {
- for (i = 0; i <= LOG_NFACILITIES; i++)
- if (f->f_pmask[i] == 0)
- printf("X ");
- else
- printf("0x%02x ", f->f_pmask[i]);
- printf("%s: ", TypeNames[f->f_type]);
- switch (f->f_type) {
- case F_FILE:
- case F_TTY:
- case F_CONSOLE:
- printf("%s", f->f_un.f_fname);
- break;
-
- case F_FORW:
- printf("%s", f->f_un.f_forw.f_hname);
- break;
-
- case F_USERS:
- for (i = 0; i < MAXUNAMES && *f->f_un.f_uname[i]; i++)
- printf("%s, ", f->f_un.f_uname[i]);
- break;
- }
- printf("\n");
- }
- }
-
- logmsg(LOG_SYSLOG|LOG_INFO, "syslogd: restart", LocalHostName, ADDDATE);
- dprintf("syslogd: restarted\n");
-#ifdef RE_INSTALL_SIGNAL
- (void) signal(SIGHUP, init);
-#endif /* RE_INSTALL_SIGNAL */
-}
-
-/*
- * Crack a configuration file line
- */
-
-cfline(line, f)
- char *line;
- register struct filed *f;
-{
- register char *p;
- register char *q;
- register int i;
- char *bp;
- int pri;
- struct hostent *hp;
- char buf[MAXLINE], ebuf[100];
-
- dprintf("cfline(%s)\n", line);
-
- errno = 0; /* keep strerror() stuff out of logerror messages */
-
- /* clear out file entry */
- bzero((char *) f, sizeof *f);
- for (i = 0; i <= LOG_NFACILITIES; i++)
- f->f_pmask[i] = 0;
-
- /* scan through the list of selectors */
- for (p = line; *p && *p != '\t' && *p != ' ';) {
-
- /* find the end of this facility name list */
- for (q = p; *q && *q != '\t' && *q != ' ' && *q++ != '.'; )
- continue;
-
- /* collect priority name */
- for (bp = buf; *q && !index("\t,; ", *q); )
- *bp++ = *q++;
- *bp = '\0';
-
- /* skip cruft */
- while (index(",;", *q)) /* spaces no longer allowed! */
- q++;
-
- /* decode priority name */
- if (*buf == '*')
- pri = -1;
- else {
- pri = decode(*buf == '=' ? buf+1 : buf, prioritynames);
- if (pri == INTERNAL_NOPRI)
- pri = 0;
- else if (pri < 0 || pri > LOG_PRIMASK) {
- (void) sprintf(ebuf,
- "unknown priority name \"%s\"", buf);
- logerror(ebuf);
- return;
- }
- else
- pri = (*buf == '=' ? 1 : -1) << (LOG_PRIMASK - pri);
-
- }
-
- /* scan facilities */
- while (*p && !index("\t.; ", *p)) {
- for (bp = buf; *p && !index("\t,;. ", *p); )
- *bp++ = *p++;
- *bp = '\0';
- if (*buf == '*')
- for (i = 0; i < LOG_NFACILITIES; i++)
- if (pri == 0)
- f->f_pmask[i] = pri;
- else
- f->f_pmask[i] |= pri;
- else {
- i = decode(buf, facilitynames);
- if (i < 0) {
- (void) sprintf(ebuf,
- "unknown facility name \"%s\"",
- buf);
- logerror(ebuf);
- return;
- }
- if (pri == 0)
- f->f_pmask[i >> 3] = pri;
- else
- f->f_pmask[i >> 3] |= pri;
- }
- while (*p == ',' || *p == ' ')
- p++;
- }
-
- p = q;
- }
-
- /* skip to action part */
- while (*p == '\t' || *p == ' ')
- p++;
-
- switch (*p)
- {
- case '@':
- if (!InetInuse)
- break;
- (void) strcpy(f->f_un.f_forw.f_hname, ++p);
- hp = gethostbyname(p);
- if (hp == NULL) {
- extern int h_errno, h_nerr;
- extern char **h_errlist;
-
- logerror((u_int)h_errno < h_nerr ?
- h_errlist[h_errno] : "Unknown error");
- break;
- }
- bzero((char *) &f->f_un.f_forw.f_addr,
- sizeof f->f_un.f_forw.f_addr);
- f->f_un.f_forw.f_addr.sin_family = AF_INET;
- f->f_un.f_forw.f_addr.sin_port = LogPort;
- bcopy(hp->h_addr, (char *) &f->f_un.f_forw.f_addr.sin_addr, hp->h_length);
- f->f_type = F_FORW;
- break;
-
- case '/':
- (void) strcpy(f->f_un.f_fname, p);
-#ifdef O_NOCTTY
- if ((f->f_file = open(p,
- O_CREAT|O_WRONLY|O_APPEND|O_NOCTTY,
- 0644)) < 0) {
-#else /* !O_NOCTTY */
- if ((f->f_file = open(p,
- O_CREAT|O_WRONLY|O_APPEND, 0644)) < 0) {
-#endif /* !O_NOCTTY */
- f->f_file = F_UNUSED;
- logerror(p);
- break;
- }
- if (isatty(f->f_file))
- f->f_type = F_TTY;
- else
- f->f_type = F_FILE;
- if (strcmp(p, ctty) == 0)
- f->f_type = F_CONSOLE;
- break;
-
- case '*':
- f->f_type = F_WALL;
- break;
-
- default:
- for (i = 0; i < MAXUNAMES && *p; i++) {
- for (q = p; *q && *q != ','; )
- q++;
- (void) strncpy(f->f_un.f_uname[i], p, UT_NAMESIZE);
- if ((q - p) > UT_NAMESIZE)
- f->f_un.f_uname[i][UT_NAMESIZE] = '\0';
- else
- f->f_un.f_uname[i][q - p] = '\0';
- while (*q == ',' || *q == ' ')
- q++;
- p = q;
- }
- f->f_type = F_USERS;
- break;
- }
-}
-
-
-/*
- * Decode a symbolic name to a numeric value
- */
-
-decode(name, codetab)
- char *name;
- CODE *codetab;
-{
- register CODE *c;
- register char *p;
- char buf[40];
-
- if (isdigit(*name))
- return (atoi(name));
-
- (void) strcpy(buf, name);
- for (p = buf; *p; p++)
- if (isupper(*p))
- *p = tolower(*p);
- for (c = codetab; c->c_name; c++)
- if (!strcmp(buf, c->c_name))
- return (c->c_val);
-
- return (-1);
-}
-
-#ifdef KLOG_STREAM
-
-int klogread(fd, buf, size)
- int fd;
- char *buf;
- int size;
-{
- static char line[MAXLINE];
- static char *pos = line;
-
- int i;
- char *obuf = buf;
- char *s;
- char *end;
- *pos = '\0';
- if (!(end = strchr(line, '\n'))) {
- struct timeval tv;
- fd_set readfds;
-
- tv.tv_sec = tv.tv_usec = 0;
- FD_ZERO(&readfds);
- FD_SET(fd, &readfds);
- i = select(fd + 1, (fd_set *) &readfds, (fd_set *) NULL,
- (fd_set *) NULL, &tv);
- if (i <= 0)
- return i;
- i = read(fd, pos, sizeof(line) - 1 - (pos - line));
- if (i <= 0)
- return i;
- pos += i;
- *pos = '\0';
- if (!(end = strchr(line, '\n')))
- return 0;
- }
- for (s = line; s < end; s++)
- if (*s != '\r')
- *buf++ = *s;
- end++;
- for (s = line; end < pos; s++)
- *s = *end++;
- pos = s;
- return (buf - obuf);
-}
-
-#endif /* KLOG_STREAM */