BSD 4_3 release
[unix-history] / usr / src / lib / libc / gen / syslog.c
index a368fb6..f0dcc80 100644 (file)
@@ -1,37 +1,55 @@
-#ifndef lint
-static char SccsId[] = "@(#)syslog.c   4.1 (Berkeley) 5/27/83";
-#endif
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)syslog.c   5.9 (Berkeley) 5/7/86";
+#endif LIBC_SCCS and not lint
 
 /*
  * SYSLOG -- print message on log file
  *
  * This routine looks a lot like printf, except that it
  * outputs to the log file instead of the standard output.
 
 /*
  * SYSLOG -- print message on log file
  *
  * This routine looks a lot like printf, except that it
  * outputs to the log file instead of the standard output.
- * Also, it prints the module name in front of lines,
- * and has some other formatting types (or will sometime).
- * Also, it adds a newline on the end of messages.
+ * Also:
+ *     adds a timestamp,
+ *     prints the module name in front of the message,
+ *     has some other formatting types (or will sometime),
+ *     adds a newline on the end of the message.
  *
  *
- * The output of this routine is intended to be read by
- * /etc/syslog, which will add timestamps.
+ * The output of this routine is intended to be read by /etc/syslogd.
+ *
+ * Author: Eric Allman
+ * Modified to use UNIX domain IPC by Ralph Campbell
  */
  */
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <syslog.h>
+#include <sys/file.h>
+#include <sys/signal.h>
+#include <sys/syslog.h>
 #include <netdb.h>
 #include <netdb.h>
+#include <strings.h>
+
+#define        MAXLINE 1024                    /* max message size */
+#define NULL   0                       /* manifest */
 
 
-#define        MAXLINE 1024            /* max message size */
-#define BUFSLOP        20              /* space to allow for "extra stuff" */
-#define NULL   0               /* manifest */
+#define PRIMASK(p)     (1 << ((p) & LOG_PRIMASK))
+#define PRIFAC(p)      (((p) & LOG_FACMASK) >> 3)
+#define IMPORTANT      LOG_ERR
 
 
-int    LogFile = -1;           /* fd for log */
-int    LogStat = 0;            /* status bits, set by initlog */
-char   *LogTag = NULL;         /* string to tag the entry with */
-int    LogMask = LOG_DEBUG;    /* lowest priority to be logged */
+static char    logname[] = "/dev/log";
+static char    ctty[] = "/dev/console";
 
 
-struct sockaddr_in SyslogAddr;
-static char *SyslogHost = LOG_HOST;
+static int     LogFile = -1;           /* fd for log */
+static int     LogStat = 0;            /* status bits, set by openlog() */
+static char    *LogTag = "syslog";     /* string to tag the entry with */
+static int     LogMask = 0xff;         /* mask of priorities to be logged */
+static int     LogFacility = LOG_USER; /* default facility code */
+
+static struct sockaddr SyslogAddr;     /* AF_UNIX address of local logger */
 
 extern int errno, sys_nerr;
 extern char *sys_errlist[];
 
 extern int errno, sys_nerr;
 extern char *sys_errlist[];
@@ -40,106 +58,140 @@ syslog(pri, fmt, p0, p1, p2, p3, p4)
        int pri;
        char *fmt;
 {
        int pri;
        char *fmt;
 {
-       char buf[MAXLINE+BUFSLOP], outline[MAXLINE + 1];
-       register char *b, *f;
+       char buf[MAXLINE + 1], outline[MAXLINE + 1];
+       register char *b, *f, *o;
+       register int c;
+       long now;
+       int pid, olderrno = errno;
 
 
-       if (LogFile < 0)
-               openlog(0, 0);
        /* see if we should just throw out this message */
        /* see if we should just throw out this message */
-       if (pri > LogMask)
+       if (pri <= 0 || PRIFAC(pri) >= LOG_NFACILITIES || (PRIMASK(pri) & LogMask) == 0)
                return;
                return;
-       for (b = buf, f = fmt; f && *f; b = buf) {
-               register char c;
+       if (LogFile < 0)
+               openlog(LogTag, LogStat | LOG_NDELAY, 0);
 
 
-               if (pri > 0 && (LogStat & LOG_COOLIT) == 0) {
-                       sprintf(b, "<%d>", pri);
-                       b += strlen(b);
-               }
-               if (LogStat & LOG_PID) {
-                       sprintf(b, "%d ", getpid());
-                       b += strlen(b);
-               }
-               if (LogTag) {
-                       sprintf(b, "%s: ", LogTag);
-                       b += strlen(b);
+       /* set default facility if none specified */
+       if ((pri & LOG_FACMASK) == 0)
+               pri |= LogFacility;
+
+       /* build the message */
+       o = outline;
+       sprintf(o, "<%d>", pri);
+       o += strlen(o);
+       time(&now);
+       sprintf(o, "%.15s ", ctime(&now) + 4);
+       o += strlen(o);
+       if (LogTag) {
+               strcpy(o, LogTag);
+               o += strlen(o);
+       }
+       if (LogStat & LOG_PID) {
+               sprintf(o, "[%d]", getpid());
+               o += strlen(o);
+       }
+       if (LogTag) {
+               strcpy(o, ": ");
+               o += 2;
+       }
+
+       b = buf;
+       f = fmt;
+       while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
+               if (c != '%') {
+                       *b++ = c;
+                       continue;
                }
                }
-               while ((c = *f++) != '\0' && c != '\n' && b < buf + MAXLINE) {
-                       if (c != '%') {
-                               *b++ = c;
-                               continue;
-                       }
-                       c = *f++;
-                       if (c != 'm') {
-                               *b++ = '%', *b++ = c, *b++ = '\0';
-                               continue;
-                       }
-                       if ((unsigned)errno > sys_nerr)
-                               sprintf(b, "error %d", errno);
-                       else
-                               strcat(b, sys_errlist[errno]);
-                       b += strlen(b);
+               if ((c = *f++) != 'm') {
+                       *b++ = '%';
+                       *b++ = c;
+                       continue;
                }
                }
-               if (c == '\0')
-                       f--;
-               *b++ = '\n', *b = '\0';
-               sprintf(outline, buf, p0, p1, p2, p3, p4);
-               errno = 0;
-               if (LogStat & LOG_DGRAM)
-                       (void) sendto(LogFile, outline, strlen(outline), 0,
-                                  &SyslogAddr, sizeof SyslogAddr);
+               if ((unsigned)olderrno > sys_nerr)
+                       sprintf(b, "error %d", olderrno);
                else
                else
-                       (void) write(LogFile, outline, strlen(outline));
-               if (errno)
-                       perror("syslog: sendto");
+                       strcpy(b, sys_errlist[olderrno]);
+               b += strlen(b);
        }
        }
+       *b++ = '\n';
+       *b = '\0';
+       sprintf(o, buf, p0, p1, p2, p3, p4);
+       c = strlen(outline);
+       if (c > MAXLINE)
+               c = MAXLINE;
+
+       /* output the message to the local logger */
+       if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0)
+               return;
+       if (!(LogStat & LOG_CONS))
+               return;
+
+       /* output the message to the console */
+       pid = vfork();
+       if (pid == -1)
+               return;
+       if (pid == 0) {
+               int fd;
+
+               signal(SIGALRM, SIG_DFL);
+               sigsetmask(sigblock(0) & ~sigmask(SIGALRM));
+               alarm(5);
+               fd = open(ctty, O_WRONLY);
+               alarm(0);
+               strcat(o, "\r");
+               o = index(outline, '>') + 1;
+               write(fd, o, c + 1 - (o - outline));
+               close(fd);
+               _exit(0);
+       }
+       if (!(LogStat & LOG_NOWAIT))
+               while ((c = wait((int *)0)) > 0 && c != pid)
+                       ;
 }
 
 /*
  * OPENLOG -- open system log
  */
 }
 
 /*
  * OPENLOG -- open system log
  */
-openlog(ident, logstat)
+
+openlog(ident, logstat, logfac)
        char *ident;
        char *ident;
-       int logstat;
+       int logstat, logfac;
 {
 {
-       struct servent *sp;
-       struct hostent *hp;
-
-       LogTag = ident;
+       if (ident != NULL)
+               LogTag = ident;
        LogStat = logstat;
        LogStat = logstat;
+       if (logfac != 0)
+               LogFacility = logfac & LOG_FACMASK;
        if (LogFile >= 0)
                return;
        if (LogFile >= 0)
                return;
-       sp = getservbyname("syslog", "udp");
-       hp = gethostbyname(SyslogHost);
-       if (sp == NULL || hp == NULL)
-               goto bad;
-       LogFile = socket(AF_INET, SOCK_DGRAM, 0);
-       if (LogFile < 0) {
-               perror("syslog: socket");
-               goto bad;
-       }
-       bzero(&SyslogAddr, sizeof SyslogAddr);
-       SyslogAddr.sin_family = hp->h_addrtype;
-       bcopy(hp->h_addr, (char *)&SyslogAddr.sin_addr, hp->h_length);
-       SyslogAddr.sin_port = sp->s_port;
-       LogStat |= LOG_DGRAM;
-       return;
-bad:
-       LogStat |= LOG_COOLIT;
-       LogStat &= ~LOG_DGRAM;
-       LogMask = LOG_CRIT;
-       LogFile = open("/dev/console", 1);
-       if (LogFile < 0) {
-               perror("syslog: /dev/console");
-               LogFile = 2;
+       SyslogAddr.sa_family = AF_UNIX;
+       strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
+       if (LogStat & LOG_NDELAY) {
+               LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
+               fcntl(LogFile, F_SETFD, 1);
        }
 }
 
 /*
  * CLOSELOG -- close the system log
  */
        }
 }
 
 /*
  * CLOSELOG -- close the system log
  */
+
 closelog()
 {
 
        (void) close(LogFile);
        LogFile = -1;
 }
 closelog()
 {
 
        (void) close(LogFile);
        LogFile = -1;
 }
+
+/*
+ * SETLOGMASK -- set the log mask level
+ */
+setlogmask(pmask)
+       int pmask;
+{
+       int omask;
+
+       omask = LogMask;
+       if (pmask != 0)
+               LogMask = pmask;
+       return (omask);
+}