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*66369Sbostic static char sccsid[] = "@(#)syslog.c 8.2 (Berkeley) 03/17/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() */ 3546597Sdonn static const char *LogTag = "syslog"; /* 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 */ 3812742Ssam 3945264Sbostic /* 4045264Sbostic * syslog, vsyslog -- 4145264Sbostic * print message on log file; output is intended for syslogd(8). 4245264Sbostic */ 4346597Sdonn void 4446597Sdonn #if __STDC__ 4546597Sdonn syslog(int pri, const char *fmt, ...) 4646597Sdonn #else 4746597Sdonn syslog(pri, fmt, va_alist) 4846597Sdonn int pri; 4912742Ssam char *fmt; 5046597Sdonn va_dcl 5146597Sdonn #endif 5212742Ssam { 5346597Sdonn va_list ap; 5446597Sdonn 5546597Sdonn #if __STDC__ 5646597Sdonn va_start(ap, fmt); 5746597Sdonn #else 5846597Sdonn va_start(ap); 5946597Sdonn #endif 6046597Sdonn vsyslog(pri, fmt, ap); 6146597Sdonn va_end(ap); 6236442Sbostic } 6336442Sbostic 6446597Sdonn void 6536442Sbostic vsyslog(pri, fmt, ap) 6636442Sbostic int pri; 6746597Sdonn register const char *fmt; 6836442Sbostic va_list ap; 6936442Sbostic { 7036440Sbostic register int cnt; 7136440Sbostic register char *p; 7254367Sbostic time_t now; 7338567Sbostic int fd, saved_errno; 7454367Sbostic char *stdp, tbuf[2048], fmt_cpy[1024]; 7512742Ssam 7654367Sbostic #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID 7754367Sbostic /* Check for invalid bits. */ 7854367Sbostic if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { 7954367Sbostic syslog(INTERNALLOG, 8054367Sbostic "syslog: unknown facility/priority: %x", pri); 8154367Sbostic pri &= LOG_PRIMASK|LOG_FACMASK; 8254367Sbostic } 8354367Sbostic 8454367Sbostic /* Check priority against setlogmask values. */ 8554367Sbostic if (!LOG_MASK(LOG_PRI(pri)) & LogMask) 8645430Sbostic return; 8745277Sbostic 8836443Sbostic saved_errno = errno; 8936443Sbostic 9024846Seric /* set default facility if none specified */ 9124846Seric if ((pri & LOG_FACMASK) == 0) 9224846Seric pri |= LogFacility; 9324846Seric 9424846Seric /* build the message */ 9536440Sbostic (void)time(&now); 96*66369Sbostic p = tbuf + sprintf(tbuf, "<%d>", pri); 97*66369Sbostic p += strftime(p, sizeof (tbuf) - (p - tbuf), "%h %e %T ", 98*66369Sbostic localtime(&now)); 9936792Sbostic if (LogStat & LOG_PERROR) 10036792Sbostic stdp = p; 10116414Sralph if (LogTag) { 10236440Sbostic (void)strcpy(p, LogTag); 10336440Sbostic for (; *p; ++p); 10416414Sralph } 105*66369Sbostic if (LogStat & LOG_PID) 106*66369Sbostic p += sprintf(p, "[%d]", getpid()); 10724846Seric if (LogTag) { 10836440Sbostic *p++ = ':'; 10936440Sbostic *p++ = ' '; 11024846Seric } 11112742Ssam 11236443Sbostic /* substitute error message for %m */ 11336443Sbostic { 11436443Sbostic register char ch, *t1, *t2; 11524846Seric 11636443Sbostic for (t1 = fmt_cpy; ch = *fmt; ++fmt) 11736443Sbostic if (ch == '%' && fmt[1] == 'm') { 11836443Sbostic ++fmt; 11936443Sbostic for (t2 = strerror(saved_errno); 12036443Sbostic *t1 = *t2++; ++t1); 12136443Sbostic } 12236443Sbostic else 12336443Sbostic *t1++ = ch; 12436583Sbostic *t1 = '\0'; 12536443Sbostic } 12636443Sbostic 127*66369Sbostic p += vsprintf(p, fmt_cpy, ap); 128*66369Sbostic cnt = p - tbuf; 12936443Sbostic 13036792Sbostic /* output to stderr if requested */ 13136792Sbostic if (LogStat & LOG_PERROR) { 13236792Sbostic struct iovec iov[2]; 13336792Sbostic register struct iovec *v = iov; 13436792Sbostic 13536792Sbostic v->iov_base = stdp; 13636792Sbostic v->iov_len = cnt - (stdp - tbuf); 13736792Sbostic ++v; 13836792Sbostic v->iov_base = "\n"; 13936792Sbostic v->iov_len = 1; 14045646Sbostic (void)writev(STDERR_FILENO, iov, 2); 14136792Sbostic } 14236792Sbostic 14345264Sbostic /* get connected, output the message to the local logger */ 14446597Sdonn if (!connected) 14546597Sdonn openlog(LogTag, LogStat | LOG_NDELAY, 0); 14646597Sdonn if (send(LogFile, tbuf, cnt, 0) >= 0) 14745430Sbostic return; 14824846Seric 14945264Sbostic /* see if should attempt the console */ 15045264Sbostic if (!(LogStat&LOG_CONS)) 15145430Sbostic return; 15245264Sbostic 15338567Sbostic /* 15445264Sbostic * Output the message to the console; don't worry about blocking, 15545264Sbostic * if console blocks everything will. Make sure the error reported 15645264Sbostic * is the one from the syslogd failure. 15738567Sbostic */ 15845264Sbostic if ((fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { 15945264Sbostic (void)strcat(tbuf, "\r\n"); 16045264Sbostic cnt += 2; 16145264Sbostic p = index(tbuf, '>') + 1; 16245264Sbostic (void)write(fd, p, cnt - (p - tbuf)); 16345264Sbostic (void)close(fd); 16445430Sbostic } 16512742Ssam } 16612742Ssam 16736440Sbostic static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 16845264Sbostic 16946597Sdonn void 17024846Seric openlog(ident, logstat, logfac) 17146597Sdonn const char *ident; 17224846Seric int logstat, logfac; 17312742Ssam { 17424846Seric if (ident != NULL) 17524846Seric LogTag = ident; 17612742Ssam LogStat = logstat; 17733786Skarels if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) 17833786Skarels LogFacility = logfac; 17945264Sbostic 18034563Skarels if (LogFile == -1) { 18134563Skarels SyslogAddr.sa_family = AF_UNIX; 18245264Sbostic (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, 18338557Sbostic sizeof(SyslogAddr.sa_data)); 18434563Skarels if (LogStat & LOG_NDELAY) { 18545264Sbostic if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) 18645430Sbostic return; 18745264Sbostic (void)fcntl(LogFile, F_SETFD, 1); 18834563Skarels } 18917918Sralph } 19045264Sbostic if (LogFile != -1 && !connected) 19145264Sbostic if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { 19245264Sbostic (void)close(LogFile); 19345264Sbostic LogFile = -1; 19445264Sbostic } else 19545264Sbostic connected = 1; 19612742Ssam } 19712742Ssam 19846597Sdonn void 19912742Ssam closelog() 20012742Ssam { 20145430Sbostic (void)close(LogFile); 20212742Ssam LogFile = -1; 20334563Skarels connected = 0; 20412742Ssam } 20516414Sralph 20645264Sbostic /* setlogmask -- set the log mask level */ 20754367Sbostic int 20817526Sralph setlogmask(pmask) 20917526Sralph int pmask; 21016414Sralph { 21117526Sralph int omask; 21216414Sralph 21317526Sralph omask = LogMask; 21417526Sralph if (pmask != 0) 21517526Sralph LogMask = pmask; 21617526Sralph return (omask); 21716414Sralph } 218