X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/5b2abdfbf4211b6592cdd02b9507555a0ecbb04b..311854206c50ea4207e7e1faa4efeb20f1bc8290:/gen/syslog.c diff --git a/gen/syslog.c b/gen/syslog.c index cd3985f..75e4772 100644 --- a/gen/syslog.c +++ b/gen/syslog.c @@ -3,19 +3,20 @@ * * @APPLE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * 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 + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -63,9 +64,11 @@ #include #include #include +#include #include #include #include +#include #ifdef __STDC__ #include @@ -74,13 +77,39 @@ #endif #include - -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 -- @@ -116,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. */ @@ -169,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--; } @@ -196,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); @@ -219,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; @@ -230,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; @@ -254,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(¬ify_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; - if (LogFile == -1) { + _sl_LogStat = logstat; + + if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) _sl_LogFacility = logfac; + + 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, &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 */ @@ -300,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 */