BSD 4_3_Reno release
[unix-history] / usr / src / lib / libc / gen / syslog.c
index 08c3ceb..7763ea2 100644 (file)
@@ -2,35 +2,36 @@
  * Copyright (c) 1983, 1988 Regents of the University of California.
  * All rights reserved.
  *
  * 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.
+ * Redistribution and use in source and binary forms are permitted provided
+ * that: (1) source distributions retain this entire copyright notice and
+ * comment, and (2) distributions including binaries display the following
+ * acknowledgement:  ``This product includes software developed by the
+ * University of California, Berkeley and its contributors'' in the
+ * documentation or other materials provided with the distribution and in
+ * all advertising materials mentioning features or use of this software.
+ * 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)syslog.c   5.16 (Berkeley) 6/27/88";
+static char sccsid[] = "@(#)syslog.c   5.28 (Berkeley) 6/27/90";
 #endif /* LIBC_SCCS and not lint */
 
 /*
  * SYSLOG -- print message on log file
  *
 #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.
- * Also:
+ * This routine looks a lot like printf, except that it outputs to the
+ * log file instead of the standard output.  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.
  *
  *     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/syslogd.
+ * The output of this routine is intended to be read by syslogd(8).
  *
  * Author: Eric Allman
  * Modified to use UNIX domain IPC by Ralph Campbell
  *
  * Author: Eric Allman
  * Modified to use UNIX domain IPC by Ralph Campbell
@@ -41,43 +42,45 @@ static char sccsid[] = "@(#)syslog.c        5.16 (Berkeley) 6/27/88";
 #include <sys/file.h>
 #include <sys/signal.h>
 #include <sys/syslog.h>
 #include <sys/file.h>
 #include <sys/signal.h>
 #include <sys/syslog.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
 #include <netdb.h>
 #include <netdb.h>
-#include <strings.h>
+#include <string.h>
+#include <varargs.h>
+#include <paths.h>
+#include <stdio.h>
 
 
-#define        MAXLINE 1024                    /* max message size */
-#define NULL   0                       /* manifest */
-
-#define IMPORTANT      LOG_ERR
-
-static char    logname[] = "/dev/log";
-static char    ctty[] = "/dev/console";
+#define        _PATH_LOGNAME   "/dev/log"
 
 static int     LogFile = -1;           /* fd for log */
 static int     connected;              /* have done connect */
 
 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 = "syslog";     /* string to tag the entry with */
 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 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[];
+syslog(pri, fmt, args)
+       int pri, args;
+       char *fmt;
+{
+       vsyslog(pri, fmt, &args);
+}
 
 
-syslog(pri, fmt, p0, p1, p2, p3, p4)
+vsyslog(pri, fmt, ap)
        int pri;
        int pri;
-       char *fmt;
+       register char *fmt;
+       va_list ap;
 {
 {
-       char buf[MAXLINE + 1], outline[MAXLINE + 1];
-       register char *b, *f, *o;
-       register int c;
-       long now;
-       int pid, olderrno = errno;
+       extern int errno;
+       register int cnt;
+       register char *p;
+       time_t now, time();
+       int fd, saved_errno;
+       char tbuf[2048], fmt_cpy[1024], *stdp, *ctime();
+
+       saved_errno = errno;
 
        /* see if we should just throw out this message */
 
        /* see if we should just throw out this message */
-       if ((unsigned) LOG_FAC(pri) >= LOG_NFACILITIES ||
-           LOG_MASK(LOG_PRI(pri)) == 0 ||
-           (pri &~ (LOG_PRIMASK|LOG_FACMASK)) != 0)
+       if (!LOG_MASK(LOG_PRI(pri)) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)))
                return;
        if (LogFile < 0 || !connected)
                openlog(LogTag, LogStat | LOG_NDELAY, 0);
                return;
        if (LogFile < 0 || !connected)
                openlog(LogTag, LogStat | LOG_NDELAY, 0);
@@ -87,83 +90,78 @@ syslog(pri, fmt, p0, p1, p2, p3, p4)
                pri |= LogFacility;
 
        /* build the message */
                pri |= LogFacility;
 
        /* build the message */
-       o = outline;
-       (void)sprintf(o, "<%d>", pri);
-       o += strlen(o);
-       time(&now);
-       (void)sprintf(o, "%.15s ", ctime(&now) + 4);
-       o += strlen(o);
+       (void)time(&now);
+       (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4);
+       for (p = tbuf; *p; ++p);
+       if (LogStat & LOG_PERROR)
+               stdp = p;
        if (LogTag) {
        if (LogTag) {
-               strcpy(o, LogTag);
-               o += strlen(o);
+               (void)strcpy(p, LogTag);
+               for (; *p; ++p);
        }
        if (LogStat & LOG_PID) {
        }
        if (LogStat & LOG_PID) {
-               (void)sprintf(o, "[%d]", getpid());
-               o += strlen(o);
+               (void)sprintf(p, "[%d]", getpid());
+               for (; *p; ++p);
        }
        if (LogTag) {
        }
        if (LogTag) {
-               strcpy(o, ": ");
-               o += 2;
+               *p++ = ':';
+               *p++ = ' ';
        }
 
        }
 
-       b = buf;
-       f = fmt;
-       while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
-               if (c != '%') {
-                       *b++ = c;
-                       continue;
-               }
-               if ((c = *f++) != 'm') {
-                       *b++ = '%';
-                       *b++ = c;
-                       continue;
-               }
-               if ((unsigned)olderrno > sys_nerr)
-                       (void)sprintf(b, "error %d", olderrno);
-               else
-                       strcpy(b, sys_errlist[olderrno]);
-               b += strlen(b);
+       /* substitute error message for %m */
+       {
+               register char ch, *t1, *t2;
+               char *strerror();
+
+               for (t1 = fmt_cpy; ch = *fmt; ++fmt)
+                       if (ch == '%' && fmt[1] == 'm') {
+                               ++fmt;
+                               for (t2 = strerror(saved_errno);
+                                   *t1 = *t2++; ++t1);
+                       }
+                       else
+                               *t1++ = ch;
+               *t1 = '\0';
+       }
+
+       (void)vsprintf(p, fmt_cpy, ap);
+
+       cnt = strlen(tbuf);
+
+       /* output to stderr if requested */
+       if (LogStat & LOG_PERROR) {
+               struct iovec iov[2];
+               register struct iovec *v = iov;
+
+               v->iov_base = stdp;
+               v->iov_len = cnt - (stdp - tbuf);
+               ++v;
+               v->iov_base = "\n";
+               v->iov_len = 1;
+               (void)writev(2, iov, 2);
        }
        }
-       *b++ = '\n';
-       *b = '\0';
-       (void)sprintf(o, buf, p0, p1, p2, p3, p4);
-       c = strlen(outline);
-       if (c > MAXLINE)
-               c = MAXLINE;
 
        /* output the message to the local logger */
 
        /* output the message to the local logger */
-       if (send(LogFile, outline, c, 0) >= 0)
-               return;
-       if (!(LogStat & LOG_CONS))
+       if (send(LogFile, tbuf, cnt, 0) >= 0 || !(LogStat&LOG_CONS))
                return;
 
                return;
 
-       /* output the message to the console */
-       pid = vfork();
-       if (pid == -1)
+       /*
+        * output the message to the console; don't worry about
+        * blocking, if console blocks everything will.
+        */
+       if ((fd = open(_PATH_CONSOLE, O_WRONLY, 0)) < 0)
                return;
                return;
-       if (pid == 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);
-       }
-       if (!(LogStat & LOG_NOWAIT))
-               while ((c = wait((int *)0)) > 0 && c != pid)
-                       ;
+       (void)strcat(tbuf, "\r\n");
+       cnt += 2;
+       p = index(tbuf, '>') + 1;
+       (void)write(fd, p, cnt - (p - tbuf));
+       (void)close(fd);
 }
 
 }
 
+static struct sockaddr SyslogAddr;     /* AF_UNIX address of local logger */
 /*
  * OPENLOG -- open system log
  */
 /*
  * OPENLOG -- open system log
  */
-
 openlog(ident, logstat, logfac)
        char *ident;
        int logstat, logfac;
 openlog(ident, logstat, logfac)
        char *ident;
        int logstat, logfac;
@@ -175,7 +173,8 @@ openlog(ident, logstat, logfac)
                LogFacility = logfac;
        if (LogFile == -1) {
                SyslogAddr.sa_family = AF_UNIX;
                LogFacility = logfac;
        if (LogFile == -1) {
                SyslogAddr.sa_family = AF_UNIX;
-               strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
+               strncpy(SyslogAddr.sa_data, _PATH_LOGNAME,
+                   sizeof(SyslogAddr.sa_data));
                if (LogStat & LOG_NDELAY) {
                        LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
                        fcntl(LogFile, F_SETFD, 1);
                if (LogStat & LOG_NDELAY) {
                        LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
                        fcntl(LogFile, F_SETFD, 1);
@@ -189,15 +188,14 @@ openlog(ident, logstat, logfac)
 /*
  * CLOSELOG -- close the system log
  */
 /*
  * CLOSELOG -- close the system log
  */
-
 closelog()
 {
 closelog()
 {
-
        (void) close(LogFile);
        LogFile = -1;
        connected = 0;
 }
 
        (void) close(LogFile);
        LogFile = -1;
        connected = 0;
 }
 
+static int     LogMask = 0xff;         /* mask of priorities to be logged */
 /*
  * SETLOGMASK -- set the log mask level
  */
 /*
  * SETLOGMASK -- set the log mask level
  */