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*56411Sbostic static char sccsid[] = "@(#)syslog.c 5.36 (Berkeley) 10/04/92"; 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> 17*56411Sbostic 18*56411Sbostic #include <errno.h> 19*56411Sbostic #include <fcntl.h> 20*56411Sbostic #include <paths.h> 21*56411Sbostic #include <stdio.h> 2242025Sbostic #include <string.h> 23*56411Sbostic #include <time.h> 24*56411Sbostic #include <unistd.h> 25*56411Sbostic 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); 9636440Sbostic (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4); 9736440Sbostic for (p = tbuf; *p; ++p); 9836792Sbostic if (LogStat & LOG_PERROR) 9936792Sbostic stdp = p; 10016414Sralph if (LogTag) { 10136440Sbostic (void)strcpy(p, LogTag); 10236440Sbostic for (; *p; ++p); 10316414Sralph } 10416414Sralph if (LogStat & LOG_PID) { 10536440Sbostic (void)sprintf(p, "[%d]", getpid()); 10636440Sbostic for (; *p; ++p); 10716414Sralph } 10824846Seric if (LogTag) { 10936440Sbostic *p++ = ':'; 11036440Sbostic *p++ = ' '; 11124846Seric } 11212742Ssam 11336443Sbostic /* substitute error message for %m */ 11436443Sbostic { 11536443Sbostic register char ch, *t1, *t2; 11636443Sbostic char *strerror(); 11724846Seric 11836443Sbostic for (t1 = fmt_cpy; ch = *fmt; ++fmt) 11936443Sbostic if (ch == '%' && fmt[1] == 'm') { 12036443Sbostic ++fmt; 12136443Sbostic for (t2 = strerror(saved_errno); 12236443Sbostic *t1 = *t2++; ++t1); 12336443Sbostic } 12436443Sbostic else 12536443Sbostic *t1++ = ch; 12636583Sbostic *t1 = '\0'; 12736443Sbostic } 12836443Sbostic 12936443Sbostic (void)vsprintf(p, fmt_cpy, ap); 13036443Sbostic 13136792Sbostic cnt = strlen(tbuf); 13236792Sbostic 13336792Sbostic /* output to stderr if requested */ 13436792Sbostic if (LogStat & LOG_PERROR) { 13536792Sbostic struct iovec iov[2]; 13636792Sbostic register struct iovec *v = iov; 13736792Sbostic 13836792Sbostic v->iov_base = stdp; 13936792Sbostic v->iov_len = cnt - (stdp - tbuf); 14036792Sbostic ++v; 14136792Sbostic v->iov_base = "\n"; 14236792Sbostic v->iov_len = 1; 14345646Sbostic (void)writev(STDERR_FILENO, iov, 2); 14436792Sbostic } 14536792Sbostic 14645264Sbostic /* get connected, output the message to the local logger */ 14746597Sdonn if (!connected) 14846597Sdonn openlog(LogTag, LogStat | LOG_NDELAY, 0); 14946597Sdonn if (send(LogFile, tbuf, cnt, 0) >= 0) 15045430Sbostic return; 15124846Seric 15245264Sbostic /* see if should attempt the console */ 15345264Sbostic if (!(LogStat&LOG_CONS)) 15445430Sbostic return; 15545264Sbostic 15638567Sbostic /* 15745264Sbostic * Output the message to the console; don't worry about blocking, 15845264Sbostic * if console blocks everything will. Make sure the error reported 15945264Sbostic * is the one from the syslogd failure. 16038567Sbostic */ 16145264Sbostic if ((fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { 16245264Sbostic (void)strcat(tbuf, "\r\n"); 16345264Sbostic cnt += 2; 16445264Sbostic p = index(tbuf, '>') + 1; 16545264Sbostic (void)write(fd, p, cnt - (p - tbuf)); 16645264Sbostic (void)close(fd); 16745430Sbostic } 16812742Ssam } 16912742Ssam 17036440Sbostic static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 17145264Sbostic 17246597Sdonn void 17324846Seric openlog(ident, logstat, logfac) 17446597Sdonn const char *ident; 17524846Seric int logstat, logfac; 17612742Ssam { 17724846Seric if (ident != NULL) 17824846Seric LogTag = ident; 17912742Ssam LogStat = logstat; 18033786Skarels if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) 18133786Skarels LogFacility = logfac; 18245264Sbostic 18334563Skarels if (LogFile == -1) { 18434563Skarels SyslogAddr.sa_family = AF_UNIX; 18545264Sbostic (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, 18638557Sbostic sizeof(SyslogAddr.sa_data)); 18734563Skarels if (LogStat & LOG_NDELAY) { 18845264Sbostic if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) 18945430Sbostic return; 19045264Sbostic (void)fcntl(LogFile, F_SETFD, 1); 19134563Skarels } 19217918Sralph } 19345264Sbostic if (LogFile != -1 && !connected) 19445264Sbostic if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { 19545264Sbostic (void)close(LogFile); 19645264Sbostic LogFile = -1; 19745264Sbostic } else 19845264Sbostic connected = 1; 19912742Ssam } 20012742Ssam 20146597Sdonn void 20212742Ssam closelog() 20312742Ssam { 20445430Sbostic (void)close(LogFile); 20512742Ssam LogFile = -1; 20634563Skarels connected = 0; 20712742Ssam } 20816414Sralph 20945264Sbostic /* setlogmask -- set the log mask level */ 21054367Sbostic int 21117526Sralph setlogmask(pmask) 21217526Sralph int pmask; 21316414Sralph { 21417526Sralph int omask; 21516414Sralph 21617526Sralph omask = LogMask; 21717526Sralph if (pmask != 0) 21817526Sralph LogMask = pmask; 21917526Sralph return (omask); 22016414Sralph } 221