121362Sdist /* 261111Sbostic * Copyright (c) 1983, 1988, 1993 361111Sbostic * The Regents of the University of California. All rights reserved. 433786Skarels * 542626Sbostic * %sccs.include.redist.c% 621362Sdist */ 721362Sdist 826602Sdonn #if defined(LIBC_SCCS) && !defined(lint) 9*66376Sbostic static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 03/18/94"; 1033786Skarels #endif /* LIBC_SCCS and not lint */ 1112742Ssam 1212742Ssam #include <sys/types.h> 1312742Ssam #include <sys/socket.h> 1426870Skarels #include <sys/syslog.h> 1536792Sbostic #include <sys/uio.h> 1612742Ssam #include <netdb.h> 1756411Sbostic 1856411Sbostic #include <errno.h> 1956411Sbostic #include <fcntl.h> 2056411Sbostic #include <paths.h> 2156411Sbostic #include <stdio.h> 2242025Sbostic #include <string.h> 2356411Sbostic #include <time.h> 2456411Sbostic #include <unistd.h> 2556411Sbostic 2646597Sdonn #if __STDC__ 2746597Sdonn #include <stdarg.h> 2846597Sdonn #else 2936442Sbostic #include <varargs.h> 3046597Sdonn #endif 3112742Ssam 3216414Sralph static int LogFile = -1; /* fd for log */ 3334563Skarels static int connected; /* have done connect */ 3436440Sbostic static int LogStat = 0; /* status bits, set by openlog() */ 3566370Seric static const char *LogTag = NULL; /* string to tag the entry with */ 3624846Seric static int LogFacility = LOG_USER; /* default facility code */ 3750158Smckusick static int LogMask = 0xff; /* mask of priorities to be logged */ 3866370Seric extern char *__progname; /* Program name, from crt0. */ 3912742Ssam 4045264Sbostic /* 4145264Sbostic * syslog, vsyslog -- 4245264Sbostic * print message on log file; output is intended for syslogd(8). 4345264Sbostic */ 4446597Sdonn void 4546597Sdonn #if __STDC__ 4646597Sdonn syslog(int pri, const char *fmt, ...) 4746597Sdonn #else 4846597Sdonn syslog(pri, fmt, va_alist) 4946597Sdonn int pri; 5012742Ssam char *fmt; 5146597Sdonn va_dcl 5246597Sdonn #endif 5312742Ssam { 5446597Sdonn va_list ap; 5546597Sdonn 5646597Sdonn #if __STDC__ 5746597Sdonn va_start(ap, fmt); 5846597Sdonn #else 5946597Sdonn va_start(ap); 6046597Sdonn #endif 6146597Sdonn vsyslog(pri, fmt, ap); 6246597Sdonn va_end(ap); 6336442Sbostic } 6436442Sbostic 6546597Sdonn void 6636442Sbostic vsyslog(pri, fmt, ap) 6736442Sbostic int pri; 6846597Sdonn register const char *fmt; 6936442Sbostic va_list ap; 7036442Sbostic { 7136440Sbostic register int cnt; 72*66376Sbostic register char ch, *p, *t; 7354367Sbostic time_t now; 7438567Sbostic int fd, saved_errno; 7554367Sbostic char *stdp, tbuf[2048], fmt_cpy[1024]; 7612742Ssam 7754367Sbostic #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID 7854367Sbostic /* Check for invalid bits. */ 7954367Sbostic if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { 8054367Sbostic syslog(INTERNALLOG, 8154367Sbostic "syslog: unknown facility/priority: %x", pri); 8254367Sbostic pri &= LOG_PRIMASK|LOG_FACMASK; 8354367Sbostic } 8454367Sbostic 8554367Sbostic /* Check priority against setlogmask values. */ 8654367Sbostic if (!LOG_MASK(LOG_PRI(pri)) & LogMask) 8745430Sbostic return; 8845277Sbostic 8936443Sbostic saved_errno = errno; 9036443Sbostic 91*66376Sbostic /* Set default facility if none specified. */ 9224846Seric if ((pri & LOG_FACMASK) == 0) 9324846Seric pri |= LogFacility; 9424846Seric 95*66376Sbostic /* Build the message. */ 9636440Sbostic (void)time(&now); 9766369Sbostic p = tbuf + sprintf(tbuf, "<%d>", pri); 9866369Sbostic p += strftime(p, sizeof (tbuf) - (p - tbuf), "%h %e %T ", 9966369Sbostic localtime(&now)); 10036792Sbostic if (LogStat & LOG_PERROR) 10136792Sbostic stdp = p; 102*66376Sbostic if (LogTag == NULL) 10366370Seric LogTag = __progname; 104*66376Sbostic if (LogTag != NULL) 105*66376Sbostic p += sprintf(p, "%s", LogTag); 10666369Sbostic if (LogStat & LOG_PID) 10766369Sbostic p += sprintf(p, "[%d]", getpid()); 108*66376Sbostic if (LogTag != NULL) { 10936440Sbostic *p++ = ':'; 11036440Sbostic *p++ = ' '; 11124846Seric } 11212742Ssam 113*66376Sbostic /* Substitute error message for %m. */ 114*66376Sbostic for (t = fmt_cpy; ch = *fmt; ++fmt) 115*66376Sbostic if (ch == '%' && fmt[1] == 'm') { 116*66376Sbostic ++fmt; 117*66376Sbostic t += sprintf(t, "%s", strerror(saved_errno)); 118*66376Sbostic } else 119*66376Sbostic *t++ = ch; 120*66376Sbostic *t = '\0'; 12124846Seric 12266369Sbostic p += vsprintf(p, fmt_cpy, ap); 12366369Sbostic cnt = p - tbuf; 12436443Sbostic 125*66376Sbostic /* Output to stderr if requested. */ 12636792Sbostic if (LogStat & LOG_PERROR) { 12736792Sbostic struct iovec iov[2]; 12836792Sbostic register struct iovec *v = iov; 12936792Sbostic 13036792Sbostic v->iov_base = stdp; 13136792Sbostic v->iov_len = cnt - (stdp - tbuf); 13236792Sbostic ++v; 13336792Sbostic v->iov_base = "\n"; 13436792Sbostic v->iov_len = 1; 13545646Sbostic (void)writev(STDERR_FILENO, iov, 2); 13636792Sbostic } 13736792Sbostic 138*66376Sbostic /* Get connected, output the message to the local logger. */ 13946597Sdonn if (!connected) 14046597Sdonn openlog(LogTag, LogStat | LOG_NDELAY, 0); 14146597Sdonn if (send(LogFile, tbuf, cnt, 0) >= 0) 14245430Sbostic return; 14324846Seric 14438567Sbostic /* 14545264Sbostic * Output the message to the console; don't worry about blocking, 14645264Sbostic * if console blocks everything will. Make sure the error reported 14745264Sbostic * is the one from the syslogd failure. 14838567Sbostic */ 149*66376Sbostic if (LogStat & LOG_CONS && 150*66376Sbostic (fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { 15145264Sbostic (void)strcat(tbuf, "\r\n"); 15245264Sbostic cnt += 2; 15345264Sbostic p = index(tbuf, '>') + 1; 15445264Sbostic (void)write(fd, p, cnt - (p - tbuf)); 15545264Sbostic (void)close(fd); 15645430Sbostic } 15712742Ssam } 15812742Ssam 15936440Sbostic static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 16045264Sbostic 16146597Sdonn void 16224846Seric openlog(ident, logstat, logfac) 16346597Sdonn const char *ident; 16424846Seric int logstat, logfac; 16512742Ssam { 16624846Seric if (ident != NULL) 16724846Seric LogTag = ident; 16812742Ssam LogStat = logstat; 16933786Skarels if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) 17033786Skarels LogFacility = logfac; 17145264Sbostic 17234563Skarels if (LogFile == -1) { 17334563Skarels SyslogAddr.sa_family = AF_UNIX; 17445264Sbostic (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, 17538557Sbostic sizeof(SyslogAddr.sa_data)); 17634563Skarels if (LogStat & LOG_NDELAY) { 17745264Sbostic if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) 17845430Sbostic return; 17945264Sbostic (void)fcntl(LogFile, F_SETFD, 1); 18034563Skarels } 18117918Sralph } 18245264Sbostic if (LogFile != -1 && !connected) 18345264Sbostic if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { 18445264Sbostic (void)close(LogFile); 18545264Sbostic LogFile = -1; 18645264Sbostic } else 18745264Sbostic connected = 1; 18812742Ssam } 18912742Ssam 19046597Sdonn void 19112742Ssam closelog() 19212742Ssam { 19345430Sbostic (void)close(LogFile); 19412742Ssam LogFile = -1; 19534563Skarels connected = 0; 19612742Ssam } 19716414Sralph 19845264Sbostic /* setlogmask -- set the log mask level */ 19954367Sbostic int 20017526Sralph setlogmask(pmask) 20117526Sralph int pmask; 20216414Sralph { 20317526Sralph int omask; 20416414Sralph 20517526Sralph omask = LogMask; 20617526Sralph if (pmask != 0) 20717526Sralph LogMask = pmask; 20817526Sralph return (omask); 20916414Sralph } 210