BSD 4_3_Tahoe release
[unix-history] / usr / src / lib / libc / gen / syslog.c
index 638d48e..08c3ceb 100644 (file)
@@ -1,6 +1,23 @@
-#ifndef lint
-static char SccsId[] = "@(#)syslog.c   4.2 (Berkeley) %G%";
-#endif
+/*
+ * Copyright (c) 1983, 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)syslog.c   5.16 (Berkeley) 6/27/88";
+#endif /* LIBC_SCCS and not lint */
 
 /*
  * SYSLOG -- print message on log file
 
 /*
  * SYSLOG -- print message on log file
@@ -14,26 +31,35 @@ static char SccsId[] =      "@(#)syslog.c   4.2 (Berkeley) %G%";
  *     adds a newline on the end of the message.
  *
  * The output of this routine is intended to be read by /etc/syslogd.
  *     adds a newline on the end of the message.
  *
  * 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/file.h>
  */
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/file.h>
-#include <syslog.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 NULL   0                       /* manifest */
 
+#define IMPORTANT      LOG_ERR
+
 static char    logname[] = "/dev/log";
 static char    ctty[] = "/dev/console";
 
 static int     LogFile = -1;           /* fd for log */
 static char    logname[] = "/dev/log";
 static char    ctty[] = "/dev/console";
 
 static int     LogFile = -1;           /* fd for log */
+static int     connected;              /* have done connect */
 static int     LogStat = 0;            /* status bits, set by openlog() */
 static int     LogStat = 0;            /* status bits, set by openlog() */
-static char    *LogTag = NULL;         /* string to tag the entry with */
-static int     LogMask = LOG_DEBUG;    /* lowest priority to be logged */
+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;
+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[];
@@ -46,29 +72,39 @@ syslog(pri, fmt, p0, p1, p2, p3, p4)
        register char *b, *f, *o;
        register int c;
        long now;
        register char *b, *f, *o;
        register int c;
        long now;
-       int pid;
+       int pid, olderrno = errno;
 
        /* see if we should just throw out this message */
 
        /* see if we should just throw out this message */
-       if (pri > LogMask)
+       if ((unsigned) LOG_FAC(pri) >= LOG_NFACILITIES ||
+           LOG_MASK(LOG_PRI(pri)) == 0 ||
+           (pri &~ (LOG_PRIMASK|LOG_FACMASK)) != 0)
                return;
                return;
-       if (LogFile < 0)
-               openlog(NULL, 0, 0);
+       if (LogFile < 0 || !connected)
+               openlog(LogTag, LogStat | LOG_NDELAY, 0);
+
+       /* set default facility if none specified */
+       if ((pri & LOG_FACMASK) == 0)
+               pri |= LogFacility;
+
+       /* build the message */
        o = outline;
        o = outline;
-       if (pri > 0) {
-               sprintf(o, "<%d>", pri);
-               o += strlen(o);
-       }
+       (void)sprintf(o, "<%d>", pri);
+       o += strlen(o);
+       time(&now);
+       (void)sprintf(o, "%.15s ", ctime(&now) + 4);
+       o += strlen(o);
        if (LogTag) {
                strcpy(o, LogTag);
                o += strlen(o);
        }
        if (LogStat & LOG_PID) {
        if (LogTag) {
                strcpy(o, LogTag);
                o += strlen(o);
        }
        if (LogStat & LOG_PID) {
-               sprintf(o, " (%d)", getpid());
+               (void)sprintf(o, "[%d]", getpid());
                o += strlen(o);
        }
                o += strlen(o);
        }
-       time(&now);
-       sprintf(o, " %.15s -- ", ctime(&now) + 4);
-       o += strlen(o);
+       if (LogTag) {
+               strcpy(o, ": ");
+               o += 2;
+       }
 
        b = buf;
        f = fmt;
 
        b = buf;
        f = fmt;
@@ -82,73 +118,96 @@ syslog(pri, fmt, p0, p1, p2, p3, p4)
                        *b++ = c;
                        continue;
                }
                        *b++ = c;
                        continue;
                }
-               if ((unsigned)errno > sys_nerr)
-                       sprintf(b, "error %d", errno);
+               if ((unsigned)olderrno > sys_nerr)
+                       (void)sprintf(b, "error %d", olderrno);
                else
                else
-                       strcpy(b, sys_errlist[errno]);
+                       strcpy(b, sys_errlist[olderrno]);
                b += strlen(b);
        }
        *b++ = '\n';
        *b = '\0';
                b += strlen(b);
        }
        *b++ = '\n';
        *b = '\0';
-       sprintf(o, buf, p0, p1, p2, p3, p4);
+       (void)sprintf(o, buf, p0, p1, p2, p3, p4);
        c = strlen(outline);
        if (c > MAXLINE)
                c = MAXLINE;
        c = strlen(outline);
        if (c > MAXLINE)
                c = MAXLINE;
-       if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0)
+
+       /* output the message to the local logger */
+       if (send(LogFile, outline, c, 0) >= 0)
                return;
                return;
-       if (pri > LOG_CRIT)
+       if (!(LogStat & LOG_CONS))
                return;
                return;
-       pid = fork();
+
+       /* output the message to the console */
+       pid = vfork();
        if (pid == -1)
                return;
        if (pid == 0) {
        if (pid == -1)
                return;
        if (pid == 0) {
-               LogFile = open(ctty, O_RDWR);
-               write(LogFile, outline, c);
-               close(LogFile);
-               exit(0);
+               int fd;
+
+               signal(SIGALRM, SIG_DFL);
+               sigsetmask(sigblock(0L) & ~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);
        }
        }
-       while (wait((int *)0) != pid)
-               ;
+       if (!(LogStat & LOG_NOWAIT))
+               while ((c = wait((int *)0)) > 0 && c != pid)
+                       ;
 }
 
 /*
  * OPENLOG -- open system log
  */
 }
 
 /*
  * OPENLOG -- open system log
  */
-openlog(ident, logstat, logmask)
+
+openlog(ident, logstat, logfac)
        char *ident;
        char *ident;
-       int logstat, logmask;
+       int logstat, logfac;
 {
 {
-
-       LogTag = ident;
+       if (ident != NULL)
+               LogTag = ident;
        LogStat = logstat;
        LogStat = logstat;
-       if (logmask > 0 && logmask <= LOG_DEBUG)
-               LogMask = logmask;
-       if (LogFile >= 0)
-               return;
-       SyslogAddr.sa_family = AF_UNIX;
-       strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
-       LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
+       if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
+               LogFacility = logfac;
+       if (LogFile == -1) {
+               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);
+               }
+       }
+       if (LogFile != -1 && !connected &&
+           connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) != -1)
+               connected = 1;
 }
 
 /*
  * CLOSELOG -- close the system log
  */
 }
 
 /*
  * CLOSELOG -- close the system log
  */
+
 closelog()
 {
 
        (void) close(LogFile);
        LogFile = -1;
 closelog()
 {
 
        (void) close(LogFile);
        LogFile = -1;
+       connected = 0;
 }
 
 /*
  * SETLOGMASK -- set the log mask level
  */
 }
 
 /*
  * SETLOGMASK -- set the log mask level
  */
-setlogmask(pri)
-       int pri;
+setlogmask(pmask)
+       int pmask;
 {
 {
-       int opri;
+       int omask;
 
 
-       opri = LogMask;
-       LogMask = pri;
-       return (opri);
+       omask = LogMask;
+       if (pmask != 0)
+               LogMask = pmask;
+       return (omask);
 }
 }