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*50158Smckusick static char sccsid[] = "@(#)syslog.c 5.34 (Berkeley) 06/26/91"; 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 */ 35*50158Smckusick 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; 7036440Sbostic time_t now, time(); 7138567Sbostic int fd, saved_errno; 7236792Sbostic char tbuf[2048], fmt_cpy[1024], *stdp, *ctime(); 7312742Ssam 7445277Sbostic /* check for invalid bits or no priority set */ 75*50158Smckusick if (!LOG_PRI(pri) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)) || 76*50158Smckusick !(LOG_MASK(pri) & LogMask)) 7745430Sbostic return; 7845277Sbostic 7936443Sbostic saved_errno = errno; 8036443Sbostic 8124846Seric /* set default facility if none specified */ 8224846Seric if ((pri & LOG_FACMASK) == 0) 8324846Seric pri |= LogFacility; 8424846Seric 8524846Seric /* build the message */ 8636440Sbostic (void)time(&now); 8736440Sbostic (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4); 8836440Sbostic for (p = tbuf; *p; ++p); 8936792Sbostic if (LogStat & LOG_PERROR) 9036792Sbostic stdp = p; 9116414Sralph if (LogTag) { 9236440Sbostic (void)strcpy(p, LogTag); 9336440Sbostic for (; *p; ++p); 9416414Sralph } 9516414Sralph if (LogStat & LOG_PID) { 9636440Sbostic (void)sprintf(p, "[%d]", getpid()); 9736440Sbostic for (; *p; ++p); 9816414Sralph } 9924846Seric if (LogTag) { 10036440Sbostic *p++ = ':'; 10136440Sbostic *p++ = ' '; 10224846Seric } 10312742Ssam 10436443Sbostic /* substitute error message for %m */ 10536443Sbostic { 10636443Sbostic register char ch, *t1, *t2; 10736443Sbostic char *strerror(); 10824846Seric 10936443Sbostic for (t1 = fmt_cpy; ch = *fmt; ++fmt) 11036443Sbostic if (ch == '%' && fmt[1] == 'm') { 11136443Sbostic ++fmt; 11236443Sbostic for (t2 = strerror(saved_errno); 11336443Sbostic *t1 = *t2++; ++t1); 11436443Sbostic } 11536443Sbostic else 11636443Sbostic *t1++ = ch; 11736583Sbostic *t1 = '\0'; 11836443Sbostic } 11936443Sbostic 12036443Sbostic (void)vsprintf(p, fmt_cpy, ap); 12136443Sbostic 12236792Sbostic cnt = strlen(tbuf); 12336792Sbostic 12436792Sbostic /* output to stderr if requested */ 12536792Sbostic if (LogStat & LOG_PERROR) { 12636792Sbostic struct iovec iov[2]; 12736792Sbostic register struct iovec *v = iov; 12836792Sbostic 12936792Sbostic v->iov_base = stdp; 13036792Sbostic v->iov_len = cnt - (stdp - tbuf); 13136792Sbostic ++v; 13236792Sbostic v->iov_base = "\n"; 13336792Sbostic v->iov_len = 1; 13445646Sbostic (void)writev(STDERR_FILENO, iov, 2); 13536792Sbostic } 13636792Sbostic 13745264Sbostic /* get connected, output the message to the local logger */ 13846597Sdonn if (!connected) 13946597Sdonn openlog(LogTag, LogStat | LOG_NDELAY, 0); 14046597Sdonn if (send(LogFile, tbuf, cnt, 0) >= 0) 14145430Sbostic return; 14224846Seric 14345264Sbostic /* see if should attempt the console */ 14445264Sbostic if (!(LogStat&LOG_CONS)) 14545430Sbostic return; 14645264Sbostic 14738567Sbostic /* 14845264Sbostic * Output the message to the console; don't worry about blocking, 14945264Sbostic * if console blocks everything will. Make sure the error reported 15045264Sbostic * is the one from the syslogd failure. 15138567Sbostic */ 15245264Sbostic if ((fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { 15345264Sbostic (void)strcat(tbuf, "\r\n"); 15445264Sbostic cnt += 2; 15545264Sbostic p = index(tbuf, '>') + 1; 15645264Sbostic (void)write(fd, p, cnt - (p - tbuf)); 15745264Sbostic (void)close(fd); 15845430Sbostic } 15912742Ssam } 16012742Ssam 16136440Sbostic static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 16245264Sbostic 16346597Sdonn void 16424846Seric openlog(ident, logstat, logfac) 16546597Sdonn const char *ident; 16624846Seric int logstat, logfac; 16712742Ssam { 16824846Seric if (ident != NULL) 16924846Seric LogTag = ident; 17012742Ssam LogStat = logstat; 17133786Skarels if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) 17233786Skarels LogFacility = logfac; 17345264Sbostic 17434563Skarels if (LogFile == -1) { 17534563Skarels SyslogAddr.sa_family = AF_UNIX; 17645264Sbostic (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, 17738557Sbostic sizeof(SyslogAddr.sa_data)); 17834563Skarels if (LogStat & LOG_NDELAY) { 17945264Sbostic if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) 18045430Sbostic return; 18145264Sbostic (void)fcntl(LogFile, F_SETFD, 1); 18234563Skarels } 18317918Sralph } 18445264Sbostic if (LogFile != -1 && !connected) 18545264Sbostic if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { 18645264Sbostic (void)close(LogFile); 18745264Sbostic LogFile = -1; 18845264Sbostic } else 18945264Sbostic connected = 1; 19012742Ssam } 19112742Ssam 19246597Sdonn void 19312742Ssam closelog() 19412742Ssam { 19545430Sbostic (void)close(LogFile); 19612742Ssam LogFile = -1; 19734563Skarels connected = 0; 19812742Ssam } 19916414Sralph 20045264Sbostic /* setlogmask -- set the log mask level */ 20117526Sralph setlogmask(pmask) 20217526Sralph int pmask; 20316414Sralph { 20417526Sralph int omask; 20516414Sralph 20617526Sralph omask = LogMask; 20717526Sralph if (pmask != 0) 20817526Sralph LogMask = pmask; 20917526Sralph return (omask); 21016414Sralph } 211