diff options
author | 2009-11-18 07:43:22 +0000 | |
---|---|---|
committer | 2009-11-18 07:43:22 +0000 | |
commit | 2359975197ffa00213482093de8f8c5905ec9577 (patch) | |
tree | e19ea759830bca154c1208a7276418b8f1d3e688 /lib/libc/gen/syslog.c | |
parent | improve the bpf path. packets we send out via the bridge are seen, but (diff) | |
download | wireguard-openbsd-2359975197ffa00213482093de8f8c5905ec9577.tar.xz wireguard-openbsd-2359975197ffa00213482093de8f8c5905ec9577.zip |
More shrinkage, a bit for ramdisks but mostly for static binaries:
- wrap with #ifndef NO_LOG_BAD_DNS_RESPONSES libc code that uses
p_class() and p_type() for diagnostics, then add that define to
libstub to avoid pulling in res_debug_syms.o
- split rcmd() and ruserok() into separate files, as nothing uses both
- split readdir_r() to its own file
- split syslog_r() from syslog(), as the latter needs localtime(); many
binaries no longer need to pull in all the time code after this; switch
from usleep() to nanosleep() while we're at it
(The profit of analysis of -Wl,-M,--cref output)
Chops 888kB from /bin and /sbin on i386
ok deraadt@, miod@
Diffstat (limited to 'lib/libc/gen/syslog.c')
-rw-r--r-- | lib/libc/gen/syslog.c | 279 |
1 files changed, 13 insertions, 266 deletions
diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c index 87f838decb0..46c04a08ddd 100644 --- a/lib/libc/gen/syslog.c +++ b/lib/libc/gen/syslog.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syslog.c,v 1.29 2007/11/09 18:40:19 millert Exp $ */ +/* $OpenBSD: syslog.c,v 1.30 2009/11/18 07:43:22 guenther Exp $ */ /* * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. @@ -46,10 +46,18 @@ static struct syslog_data sdata = SYSLOG_DATA_INIT; -extern char *__progname; /* Program name, from crt0. */ +void __vsyslog_r(int pri, struct syslog_data *, size_t (*)(char *, size_t), + const char *, va_list); + +static size_t +gettime(char *buf, size_t maxsize) +{ + time_t now; + + (void)time(&now); + return (strftime(buf, maxsize, "%h %e %T ", localtime(&now))); +} -static void disconnectlog_r(struct syslog_data *); /* disconnect from syslogd */ -static void connectlog_r(struct syslog_data *); /* (re)connect to syslogd */ /* * syslog, vsyslog -- @@ -68,7 +76,7 @@ syslog(int pri, const char *fmt, ...) void vsyslog(int pri, const char *fmt, va_list ap) { - vsyslog_r(pri, &sdata, fmt, ap); + __vsyslog_r(pri, &sdata, &gettime, fmt, ap); } void @@ -90,267 +98,6 @@ setlogmask(int pmask) return setlogmask_r(pmask, &sdata); } -/* Reentrant version of syslog, i.e. syslog_r() */ - -void -syslog_r(int pri, struct syslog_data *data, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vsyslog_r(pri, data, fmt, ap); - va_end(ap); -} - -void -vsyslog_r(int pri, struct syslog_data *data, const char *fmt, va_list ap) -{ - int cnt; - char ch, *p, *t; - time_t now; - int fd, saved_errno, error; -#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)) { - if (data == &sdata) { - syslog(INTERNALLOG, - "syslog: unknown facility/priority: %x", pri); - } else { - syslog_r(INTERNALLOG, data, - "syslog_r: unknown facility/priority: %x", pri); - } - pri &= LOG_PRIMASK|LOG_FACMASK; - } - - /* Check priority against setlogmask values. */ - if (!(LOG_MASK(LOG_PRI(pri)) & data->log_mask)) - return; - - saved_errno = errno; - - /* Set default facility if none specified. */ - if ((pri & LOG_FACMASK) == 0) - pri |= data->log_fac; - - /* If we have been called through syslog(), no need for reentrancy. */ - if (data == &sdata) - (void)time(&now); - - p = tbuf; - tbuf_left = TBUF_LEN; - -#define DEC() \ - do { \ - if (prlen < 0) \ - prlen = 0; \ - if (prlen >= tbuf_left) \ - prlen = tbuf_left - 1; \ - p += prlen; \ - tbuf_left -= prlen; \ - } while (0) - - prlen = snprintf(p, tbuf_left, "<%d>", pri); - DEC(); - - /* - * syslogd will expand time automagically for reentrant case, and - * for normal case, just do like before - */ - if (data == &sdata) { - prlen = strftime(p, tbuf_left, "%h %e %T ", localtime(&now)); - DEC(); - } - - if (data->log_stat & LOG_PERROR) - stdp = p; - if (data->log_tag == NULL) - data->log_tag = __progname; - if (data->log_tag != NULL) { - prlen = snprintf(p, tbuf_left, "%s", data->log_tag); - DEC(); - } - if (data->log_stat & LOG_PID) { - prlen = snprintf(p, tbuf_left, "[%ld]", (long)getpid()); - DEC(); - } - if (data->log_tag != NULL) { - if (tbuf_left > 1) { - *p++ = ':'; - tbuf_left--; - } - if (tbuf_left > 1) { - *p++ = ' '; - tbuf_left--; - } - } - - /* strerror() is not reentrant */ - - for (t = fmt_cpy, fmt_left = FMT_LEN; (ch = *fmt); ++fmt) { - if (ch == '%' && fmt[1] == 'm') { - ++fmt; - if (data == &sdata) { - prlen = snprintf(t, fmt_left, "%s", - strerror(saved_errno)); - } else { - prlen = snprintf(t, fmt_left, "Error %d", - saved_errno); - } - if (prlen < 0) - prlen = 0; - if (prlen >= fmt_left) - prlen = fmt_left - 1; - t += prlen; - fmt_left -= prlen; - } else if (ch == '%' && fmt[1] == '%' && fmt_left > 2) { - *t++ = '%'; - *t++ = '%'; - fmt++; - fmt_left -= 2; - } else { - if (fmt_left > 1) { - *t++ = ch; - fmt_left--; - } - } - } - *t = '\0'; - - prlen = vsnprintf(p, tbuf_left, fmt_cpy, ap); - DEC(); - cnt = p - tbuf; - - /* Output to stderr if requested. */ - if (data->log_stat & LOG_PERROR) { - struct iovec iov[2]; - - iov[0].iov_base = stdp; - iov[0].iov_len = cnt - (stdp - tbuf); - iov[1].iov_base = "\n"; - iov[1].iov_len = 1; - (void)writev(STDERR_FILENO, iov, 2); - } - - /* Get connected, output the message to the local logger. */ - if (!data->opened) - openlog_r(data->log_tag, data->log_stat, 0, data); - connectlog_r(data); - - /* - * If the send() failed, there are two likely scenarios: - * 1) syslogd was restarted - * 2) /dev/log is out of socket buffer space - * We attempt to reconnect to /dev/log to take care of - * case #1 and keep send()ing data to cover case #2 - * to give syslogd a chance to empty its socket buffer. - */ - if ((error = send(data->log_file, tbuf, cnt, 0)) < 0) { - if (errno != ENOBUFS) { - disconnectlog_r(data); - connectlog_r(data); - } - do { - usleep(1); - if ((error = send(data->log_file, tbuf, cnt, 0)) >= 0) - break; - } while (errno == ENOBUFS); - } - - /* - * Output the message to the console; try not to block - * as a blocking console should not stop other processes. - * Make sure the error reported is the one from the syslogd failure. - */ - if (error == -1 && (data->log_stat & LOG_CONS) && - (fd = open(_PATH_CONSOLE, O_WRONLY|O_NONBLOCK, 0)) >= 0) { - struct iovec iov[2]; - - p = strchr(tbuf, '>') + 1; - iov[0].iov_base = p; - iov[0].iov_len = cnt - (p - tbuf); - iov[1].iov_base = "\r\n"; - iov[1].iov_len = 2; - (void)writev(fd, iov, 2); - (void)close(fd); - } - - if (data != &sdata) { - /* preserve log_tag from being cleared by closelog_r() */ - const char *ident = data->log_tag; - closelog_r(data); - data->log_tag = ident; - } -} - -static void -disconnectlog_r(struct syslog_data *data) -{ - /* - * If the user closed the FD and opened another in the same slot, - * that's their problem. They should close it before calling on - * system services. - */ - if (data->log_file != -1) { - close(data->log_file); - data->log_file = -1; - } - data->connected = 0; /* retry connect */ -} - -static void -connectlog_r(struct syslog_data *data) -{ - struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */ - - if (data->log_file == -1) { - if ((data->log_file = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) - return; - (void)fcntl(data->log_file, F_SETFD, 1); - } - if (data->log_file != -1 && !data->connected) { - memset(&SyslogAddr, '\0', sizeof(SyslogAddr)); - SyslogAddr.sun_len = sizeof(SyslogAddr); - SyslogAddr.sun_family = AF_UNIX; - strlcpy(SyslogAddr.sun_path, _PATH_LOG, - sizeof(SyslogAddr.sun_path)); - if (connect(data->log_file, (struct sockaddr *)&SyslogAddr, - sizeof(SyslogAddr)) == -1) { - (void)close(data->log_file); - data->log_file = -1; - } else - data->connected = 1; - } -} - -void -openlog_r(const char *ident, int logstat, int logfac, struct syslog_data *data) -{ - if (ident != NULL) - data->log_tag = ident; - data->log_stat = logstat; - if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) - data->log_fac = logfac; - - if (data->log_stat & LOG_NDELAY) /* open immediately */ - connectlog_r(data); - - data->opened = 1; /* ident and facility has been set */ -} - -void -closelog_r(struct syslog_data *data) -{ - (void)close(data->log_file); - data->log_file = -1; - data->connected = 0; - data->log_tag = NULL; -} - /* setlogmask -- set the log mask level */ int setlogmask_r(int pmask, struct syslog_data *data) |