121362Sdist /* 233786Skarels * Copyright (c) 1983, 1988 Regents of the University of California. 333786Skarels * All rights reserved. 433786Skarels * 542626Sbostic * %sccs.include.redist.c% 621362Sdist */ 721362Sdist 826602Sdonn #if defined(LIBC_SCCS) && !defined(lint) 9*54367Sbostic static char sccsid[] = "@(#)syslog.c 5.35 (Berkeley) 06/24/92"; 1033786Skarels #endif /* LIBC_SCCS and not lint */ 1112742Ssam 1212742Ssam #include <sys/types.h> 1312742Ssam #include <sys/socket.h> 1416414Sralph #include <sys/file.h> 1526870Skarels #include <sys/syslog.h> 1636792Sbostic #include <sys/uio.h> 1745264Sbostic #include <sys/errno.h> 1812742Ssam #include <netdb.h> 1942025Sbostic #include <string.h> 2046597Sdonn #if __STDC__ 2146597Sdonn #include <stdarg.h> 2246597Sdonn #else 2336442Sbostic #include <varargs.h> 2446597Sdonn #endif 2546597Sdonn #include <time.h> 2646597Sdonn #include <unistd.h> 2738557Sbostic #include <paths.h> 2836440Sbostic #include <stdio.h> 2912742Ssam 3016414Sralph static int LogFile = -1; /* fd for log */ 3134563Skarels static int connected; /* have done connect */ 3236440Sbostic static int LogStat = 0; /* status bits, set by openlog() */ 3346597Sdonn static const char *LogTag = "syslog"; /* string to tag the entry with */ 3424846Seric static int LogFacility = LOG_USER; /* default facility code */ 3550158Smckusick static int LogMask = 0xff; /* mask of priorities to be logged */ 3612742Ssam 3745264Sbostic /* 3845264Sbostic * syslog, vsyslog -- 3945264Sbostic * print message on log file; output is intended for syslogd(8). 4045264Sbostic */ 4146597Sdonn void 4246597Sdonn #if __STDC__ 4346597Sdonn syslog(int pri, const char *fmt, ...) 4446597Sdonn #else 4546597Sdonn syslog(pri, fmt, va_alist) 4646597Sdonn int pri; 4712742Ssam char *fmt; 4846597Sdonn va_dcl 4946597Sdonn #endif 5012742Ssam { 5146597Sdonn va_list ap; 5246597Sdonn 5346597Sdonn #if __STDC__ 5446597Sdonn va_start(ap, fmt); 5546597Sdonn #else 5646597Sdonn va_start(ap); 5746597Sdonn #endif 5846597Sdonn vsyslog(pri, fmt, ap); 5946597Sdonn va_end(ap); 6036442Sbostic } 6136442Sbostic 6246597Sdonn void 6336442Sbostic vsyslog(pri, fmt, ap) 6436442Sbostic int pri; 6546597Sdonn register const char *fmt; 6636442Sbostic va_list ap; 6736442Sbostic { 6836440Sbostic register int cnt; 6936440Sbostic register char *p; 70*54367Sbostic time_t now; 7138567Sbostic int fd, saved_errno; 72*54367Sbostic char *stdp, tbuf[2048], fmt_cpy[1024]; 7312742Ssam 74*54367Sbostic #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID 75*54367Sbostic /* Check for invalid bits. */ 76*54367Sbostic if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { 77*54367Sbostic syslog(INTERNALLOG, 78*54367Sbostic "syslog: unknown facility/priority: %x", pri); 79*54367Sbostic pri &= LOG_PRIMASK|LOG_FACMASK; 80*54367Sbostic } 81*54367Sbostic 82*54367Sbostic /* Check priority against setlogmask values. */ 83*54367Sbostic if (!LOG_MASK(LOG_PRI(pri)) & LogMask) 8445430Sbostic return; 8545277Sbostic 8636443Sbostic saved_errno = errno; 8736443Sbostic 8824846Seric /* set default facility if none specified */ 8924846Seric if ((pri & LOG_FACMASK) == 0) 9024846Seric pri |= LogFacility; 9124846Seric 9224846Seric /* build the message */ 9336440Sbostic (void)time(&now); 9436440Sbostic (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4); 9536440Sbostic for (p = tbuf; *p; ++p); 9636792Sbostic if (LogStat & LOG_PERROR) 9736792Sbostic stdp = p; 9816414Sralph if (LogTag) { 9936440Sbostic (void)strcpy(p, LogTag); 10036440Sbostic for (; *p; ++p); 10116414Sralph } 10216414Sralph if (LogStat & LOG_PID) { 10336440Sbostic (void)sprintf(p, "[%d]", getpid()); 10436440Sbostic for (; *p; ++p); 10516414Sralph } 10624846Seric if (LogTag) { 10736440Sbostic *p++ = ':'; 10836440Sbostic *p++ = ' '; 10924846Seric } 11012742Ssam 11136443Sbostic /* substitute error message for %m */ 11236443Sbostic { 11336443Sbostic register char ch, *t1, *t2; 11436443Sbostic char *strerror(); 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 12736443Sbostic (void)vsprintf(p, fmt_cpy, ap); 12836443Sbostic 12936792Sbostic cnt = strlen(tbuf); 13036792Sbostic 13136792Sbostic /* output to stderr if requested */ 13236792Sbostic if (LogStat & LOG_PERROR) { 13336792Sbostic struct iovec iov[2]; 13436792Sbostic register struct iovec *v = iov; 13536792Sbostic 13636792Sbostic v->iov_base = stdp; 13736792Sbostic v->iov_len = cnt - (stdp - tbuf); 13836792Sbostic ++v; 13936792Sbostic v->iov_base = "\n"; 14036792Sbostic v->iov_len = 1; 14145646Sbostic (void)writev(STDERR_FILENO, iov, 2); 14236792Sbostic } 14336792Sbostic 14445264Sbostic /* get connected, output the message to the local logger */ 14546597Sdonn if (!connected) 14646597Sdonn openlog(LogTag, LogStat | LOG_NDELAY, 0); 14746597Sdonn if (send(LogFile, tbuf, cnt, 0) >= 0) 14845430Sbostic return; 14924846Seric 15045264Sbostic /* see if should attempt the console */ 15145264Sbostic if (!(LogStat&LOG_CONS)) 15245430Sbostic return; 15345264Sbostic 15438567Sbostic /* 15545264Sbostic * Output the message to the console; don't worry about blocking, 15645264Sbostic * if console blocks everything will. Make sure the error reported 15745264Sbostic * is the one from the syslogd failure. 15838567Sbostic */ 15945264Sbostic if ((fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { 16045264Sbostic (void)strcat(tbuf, "\r\n"); 16145264Sbostic cnt += 2; 16245264Sbostic p = index(tbuf, '>') + 1; 16345264Sbostic (void)write(fd, p, cnt - (p - tbuf)); 16445264Sbostic (void)close(fd); 16545430Sbostic } 16612742Ssam } 16712742Ssam 16836440Sbostic static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 16945264Sbostic 17046597Sdonn void 17124846Seric openlog(ident, logstat, logfac) 17246597Sdonn const char *ident; 17324846Seric int logstat, logfac; 17412742Ssam { 17524846Seric if (ident != NULL) 17624846Seric LogTag = ident; 17712742Ssam LogStat = logstat; 17833786Skarels if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) 17933786Skarels LogFacility = logfac; 18045264Sbostic 18134563Skarels if (LogFile == -1) { 18234563Skarels SyslogAddr.sa_family = AF_UNIX; 18345264Sbostic (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, 18438557Sbostic sizeof(SyslogAddr.sa_data)); 18534563Skarels if (LogStat & LOG_NDELAY) { 18645264Sbostic if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) 18745430Sbostic return; 18845264Sbostic (void)fcntl(LogFile, F_SETFD, 1); 18934563Skarels } 19017918Sralph } 19145264Sbostic if (LogFile != -1 && !connected) 19245264Sbostic if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { 19345264Sbostic (void)close(LogFile); 19445264Sbostic LogFile = -1; 19545264Sbostic } else 19645264Sbostic connected = 1; 19712742Ssam } 19812742Ssam 19946597Sdonn void 20012742Ssam closelog() 20112742Ssam { 20245430Sbostic (void)close(LogFile); 20312742Ssam LogFile = -1; 20434563Skarels connected = 0; 20512742Ssam } 20616414Sralph 20745264Sbostic /* setlogmask -- set the log mask level */ 208*54367Sbostic int 20917526Sralph setlogmask(pmask) 21017526Sralph int pmask; 21116414Sralph { 21217526Sralph int omask; 21316414Sralph 21417526Sralph omask = LogMask; 21517526Sralph if (pmask != 0) 21617526Sralph LogMask = pmask; 21717526Sralph return (omask); 21816414Sralph } 219