]> git.saurik.com Git - apple/libc.git/blobdiff - gen/syslog.c
Libc-391.1.21.tar.gz
[apple/libc.git] / gen / syslog.c
index 216ce85accd1b3c86c4bd13e33db281f48b34a4b..75e47729fd863f4e5b7a4cc5dac8933840980237 100644 (file)
@@ -3,8 +3,6 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
- * 
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
 #include <fcntl.h>
 #include <paths.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#include <notify.h>
 
 #ifdef __STDC__
 #include <stdarg.h>
 #endif
 
 #include <crt_externs.h>
-static int     LogFile = -1;           /* fd for log */
-static int     connected;              /* have done connect */
-static int     LogStat = 0;            /* status bits, set by openlog() */
-static const char *LogTag = NULL;      /* string to tag the entry with */
-static int     LogFacility = LOG_USER; /* default facility code */
-static int     LogMask = 0xff;         /* mask of priorities to be logged */
+
+#define        LOG_NO_NOTIFY   0x1000
+
+#ifdef BUILDING_VARIANT
+__private_extern__ int _sl_LogFile;            /* fd for log */
+__private_extern__ int _sl_connected;          /* have done connect */
+__private_extern__ int _sl_LogStat;            /* status bits, set by openlog() */
+__private_extern__ const char *_sl_LogTag;     /* string to tag the entry with */
+__private_extern__ int _sl_LogFacility;        /* default facility code */
+__private_extern__ int _sl_LogMask;            /* mask of priorities to be logged */
+__private_extern__ int  _sl_NotifyToken;       /* for remote control of priority filter */
+__private_extern__ int  _sl_NotifyMaster;      /* for remote control of priority filter */
+#else /* !BUILDING_VARIANT */
+__private_extern__ int _sl_LogFile = -1;               /* fd for log */
+__private_extern__ int _sl_connected = 0;              /* have done connect */
+__private_extern__ int _sl_LogStat = 0;                /* status bits, set by openlog() */
+__private_extern__ const char *_sl_LogTag = NULL;      /* string to tag the entry with */
+__private_extern__ int _sl_LogFacility = LOG_USER;     /* default facility code */
+__private_extern__ int _sl_LogMask = 0xff;             /* mask of priorities to be logged */
+__private_extern__ int  _sl_NotifyToken = -1;  /* for remote control of max logged priority */
+__private_extern__ int  _sl_NotifyMaster = -1; /* for remote control of max logged priority */
+#endif /* BUILDING_VARIANT */
+
+__private_extern__ void _sl_init_notify();
+
+#define NOTIFY_SYSTEM_MASTER "com.apple.system.syslog.master"
+#define NOTIFY_PREFIX_SYSTEM "com.apple.system.syslog"
+#define NOTIFY_PREFIX_USER "user.syslog"
+#define NOTIFY_STATE_OFFSET 1000
+
+/* notify SPI */
+uint32_t notify_get_state(int token, int *state);
+uint32_t notify_register_plain(const char *name, int *out_token);
 
 /*
  * syslog, vsyslog --
@@ -119,29 +145,56 @@ vsyslog(pri, fmt, ap)
        register int cnt;
        register char ch, *p, *t;
        time_t now;
-       int fd, saved_errno;
+       int fd, saved_errno, filter, cval, rc_filter, primask;
 #define        TBUF_LEN        2048
 #define        FMT_LEN         1024
        char *stdp, tbuf[TBUF_LEN], fmt_cpy[FMT_LEN];
        int tbuf_left, fmt_left, prlen;
-
+       
 #define        INTERNALLOG     LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
        /* Check for invalid bits. */
-       if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
-               syslog(INTERNALLOG,
-                   "syslog: unknown facility/priority: %x", pri);
+       if (pri & ~(LOG_PRIMASK|LOG_FACMASK))
+       {
+               syslog(INTERNALLOG, "syslog: unknown facility/priority: %x", pri);
                pri &= LOG_PRIMASK|LOG_FACMASK;
        }
 
-       /* Check priority against setlogmask values. */
-       if (!(LOG_MASK(LOG_PRI(pri)) & LogMask))
-               return;
+       /* Get remote-control priority filter */
+       filter = _sl_LogMask;
+       rc_filter = 0;
+
+       _sl_init_notify();
+
+       if (_sl_NotifyToken >= 0) 
+       {
+               if (notify_get_state(_sl_NotifyToken, &cval) == NOTIFY_STATUS_OK)
+               {
+                       if (cval != 0)
+                       {
+                               filter = cval;
+                               rc_filter = 1;
+                       }
+               }
+       }
+
+       if ((rc_filter == 0) && (_sl_NotifyMaster >= 0))
+       {
+               if (notify_get_state(_sl_NotifyMaster, &cval) == NOTIFY_STATUS_OK)
+               {
+                       if (cval != 0)
+                       {
+                               filter = cval;
+                       }
+               }
+       }
+
+       primask = LOG_MASK(LOG_PRI(pri));
+       if ((primask & filter) == 0) return;
 
        saved_errno = errno;
 
        /* Set default facility if none specified. */
-       if ((pri & LOG_FACMASK) == 0)
-               pri |= LogFacility;
+       if ((pri & LOG_FACMASK) == 0) pri |= _sl_LogFacility;
 
        /* Build the message. */
        
@@ -172,24 +225,31 @@ vsyslog(pri, fmt, ap)
        prlen = strftime(p, tbuf_left, "%h %e %T ", localtime(&now));
        DEC();
 
-       if (LogStat & LOG_PERROR)
-               stdp = p;
-       if (LogTag == NULL)
-               LogTag = *(*_NSGetArgv());
-       if (LogTag != NULL) {
-               prlen = snprintf(p, tbuf_left, "%s", LogTag);
+       if (_sl_LogStat & LOG_PERROR) stdp = p;
+
+       if (_sl_LogTag == NULL) _sl_LogTag = *(*_NSGetArgv());
+
+       if (_sl_LogTag != NULL) 
+       {
+               prlen = snprintf(p, tbuf_left, "%s", _sl_LogTag);
                DEC();
        }
-       if (LogStat & LOG_PID) {
+
+       if (_sl_LogStat & LOG_PID)
+       {
                prlen = snprintf(p, tbuf_left, "[%d]", getpid());
                DEC();
        }
-       if (LogTag != NULL) {
-               if (tbuf_left > 1) {
+
+       if (_sl_LogTag != NULL)
+       {
+               if (tbuf_left > 1)
+               {
                        *p++ = ':';
                        tbuf_left--;
                }
-               if (tbuf_left > 1) {
+               if (tbuf_left > 1)
+               {
                        *p++ = ' ';
                        tbuf_left--;
                }
@@ -199,22 +259,26 @@ vsyslog(pri, fmt, ap)
         * We wouldn't need this mess if printf handled %m, or if 
         * strerror() had been invented before syslog().
         */
-       for (t = fmt_cpy, fmt_left = FMT_LEN; (ch = *fmt); ++fmt) {
-               if (ch == '%' && fmt[1] == 'm') {
+       for (t = fmt_cpy, fmt_left = FMT_LEN; (ch = *fmt); ++fmt)
+       {
+               if (ch == '%' && fmt[1] == 'm')
+               {
                        ++fmt;
-                       prlen = snprintf(t, fmt_left, "%s",
-                           strerror(saved_errno));
-                       if (prlen >= fmt_left)
-                               prlen = fmt_left - 1;
+                       prlen = snprintf(t, fmt_left, "%s", strerror(saved_errno));
+                       if (prlen >= fmt_left) prlen = fmt_left - 1;
                        t += prlen;
                        fmt_left -= prlen;
-               } else {
-                       if (fmt_left > 1) {
+               }
+               else
+               {
+                       if (fmt_left > 1)
+                       {
                                *t++ = ch;
                                fmt_left--;
                        }
                }
        }
+
        *t = '\0';
 
        prlen = vsnprintf(p, tbuf_left, fmt_cpy, ap);
@@ -222,7 +286,8 @@ vsyslog(pri, fmt, ap)
        cnt = p - tbuf;
 
        /* Output to stderr if requested. */
-       if (LogStat & LOG_PERROR) {
+       if (_sl_LogStat & LOG_PERROR)
+       {
                struct iovec iov[2];
 
                iov[0].iov_base = stdp;
@@ -233,18 +298,16 @@ vsyslog(pri, fmt, ap)
        }
 
        /* Get connected, output the message to the local logger. */
-       if (!connected)
-               openlog(LogTag, LogStat | LOG_NDELAY, 0);
-       if (send(LogFile, tbuf, cnt, 0) >= 0)
-               return;
+       if (_sl_connected == 0) openlog(_sl_LogTag, _sl_LogStat | LOG_NDELAY, 0);
+       if (send(_sl_LogFile, tbuf, cnt, 0) >= 0) return;
 
        /*
         * Output the message to the console; don't worry about blocking,
         * if console blocks everything will.  Make sure the error reported
         * is the one from the syslogd failure.
         */
-       if (LogStat & LOG_CONS &&
-           (fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) {
+       if (_sl_LogStat & LOG_CONS && (fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0)
+       {
                struct iovec iov[2];
                
                p = strchr(tbuf, '>') + 1;
@@ -257,43 +320,92 @@ vsyslog(pri, fmt, ap)
        }
 }
 
+#ifndef BUILDING_VARIANT
+
 static struct sockaddr_un SyslogAddr;  /* AF_UNIX address of local logger */
 
+__private_extern__ void
+_sl_init_notify()
+{
+       int status;
+       char *notify_name;
+       const char *prefix;
+       
+       if (_sl_LogStat & LOG_NO_NOTIFY)
+       {
+               _sl_NotifyMaster = -2;
+               _sl_NotifyToken = -2;
+               return;
+       }
+       
+       if (_sl_NotifyMaster == -1)
+       {
+               status = notify_register_plain(NOTIFY_SYSTEM_MASTER, &_sl_NotifyMaster);
+               if (status != NOTIFY_STATUS_OK) _sl_NotifyMaster = -2;
+       }
+       
+       if (_sl_NotifyToken == -1)
+       {
+               _sl_NotifyToken = -2;
+               
+               notify_name = NULL;
+               prefix = NOTIFY_PREFIX_USER;
+               if (getuid() == 0) prefix = NOTIFY_PREFIX_SYSTEM;
+               asprintf(&notify_name, "%s.%d", prefix, getpid());
+               
+               if (notify_name != NULL)
+               {
+                       status = notify_register_plain(notify_name, &_sl_NotifyToken);
+                       free(notify_name);
+                       if (status != NOTIFY_STATUS_OK) _sl_NotifyToken = -2;
+               }
+       }
+}
+
 void
 openlog(ident, logstat, logfac)
        const char *ident;
        int logstat, logfac;
 {
-       if (ident != NULL)
-               LogTag = ident;
-       LogStat = logstat;
-       if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
-               LogFacility = logfac;
+       if (ident != NULL) _sl_LogTag = ident;
+
+       _sl_LogStat = logstat;
+
+       if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) _sl_LogFacility = logfac;
 
-       if (LogFile == -1) {
+       if (_sl_LogFile == -1)
+       {
                SyslogAddr.sun_family = AF_UNIX;
-               (void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
-                   sizeof(SyslogAddr.sun_path));
-               if (LogStat & LOG_NDELAY) {
-                       if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
-                               return;
-                       (void)fcntl(LogFile, F_SETFD, 1);
+               (void)strncpy(SyslogAddr.sun_path, _PATH_LOG, sizeof(SyslogAddr.sun_path));
+               if (_sl_LogStat & LOG_NDELAY)
+               {
+                       if ((_sl_LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) return;
+                       (void)fcntl(_sl_LogFile, F_SETFD, 1);
                }
        }
-       if (LogFile != -1 && !connected)
-               if (connect(LogFile, (struct sockaddr *)&SyslogAddr, sizeof(SyslogAddr)) == -1) {
-                       (void)close(LogFile);
-                       LogFile = -1;
-               } else
-                       connected = 1;
+
+       if ((_sl_LogFile != -1) && (_sl_connected == 0))
+       {
+               if (connect(_sl_LogFile, (struct sockaddr *)&SyslogAddr, sizeof(SyslogAddr)) == -1)
+               {
+                       (void)close(_sl_LogFile);
+                       _sl_LogFile = -1;
+               }
+               else
+               {
+                       _sl_connected = 1;
+               }
+       }
+
+       _sl_init_notify();
 }
 
 void
 closelog()
 {
-       (void)close(LogFile);
-       LogFile = -1;
-       connected = 0;
+       (void)close(_sl_LogFile);
+       _sl_LogFile = -1;
+       _sl_connected = 0;
 }
 
 /* setlogmask -- set the log mask level */
@@ -303,8 +415,9 @@ setlogmask(pmask)
 {
        int omask;
 
-       omask = LogMask;
-       if (pmask != 0)
-               LogMask = pmask;
+       omask = _sl_LogMask;
+       if (pmask != 0) _sl_LogMask = pmask;
        return (omask);
 }
+
+#endif /* !BUILDING_VARIANT */