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*46597Sdonn static char sccsid[] = "@(#)syslog.c 5.33 (Berkeley) 02/23/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> 20*46597Sdonn #if __STDC__ 21*46597Sdonn #include <stdarg.h> 22*46597Sdonn #else 2336442Sbostic #include <varargs.h> 24*46597Sdonn #endif 25*46597Sdonn #include <time.h> 26*46597Sdonn #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() */ 33*46597Sdonn static const char *LogTag = "syslog"; /* string to tag the entry with */ 3424846Seric static int LogFacility = LOG_USER; /* default facility code */ 3512742Ssam 3645264Sbostic /* 3745264Sbostic * syslog, vsyslog -- 3845264Sbostic * print message on log file; output is intended for syslogd(8). 3945264Sbostic */ 40*46597Sdonn void 41*46597Sdonn #if __STDC__ 42*46597Sdonn syslog(int pri, const char *fmt, ...) 43*46597Sdonn #else 44*46597Sdonn syslog(pri, fmt, va_alist) 45*46597Sdonn int pri; 4612742Ssam char *fmt; 47*46597Sdonn va_dcl 48*46597Sdonn #endif 4912742Ssam { 50*46597Sdonn va_list ap; 51*46597Sdonn 52*46597Sdonn #if __STDC__ 53*46597Sdonn va_start(ap, fmt); 54*46597Sdonn #else 55*46597Sdonn va_start(ap); 56*46597Sdonn #endif 57*46597Sdonn vsyslog(pri, fmt, ap); 58*46597Sdonn va_end(ap); 5936442Sbostic } 6036442Sbostic 61*46597Sdonn void 6236442Sbostic vsyslog(pri, fmt, ap) 6336442Sbostic int pri; 64*46597Sdonn register const char *fmt; 6536442Sbostic va_list ap; 6636442Sbostic { 6736440Sbostic register int cnt; 6836440Sbostic register char *p; 6936440Sbostic time_t now, time(); 7038567Sbostic int fd, saved_errno; 7136792Sbostic char tbuf[2048], fmt_cpy[1024], *stdp, *ctime(); 7212742Ssam 7345277Sbostic /* check for invalid bits or no priority set */ 7445430Sbostic if (!LOG_PRI(pri) || (pri &~ (LOG_PRIMASK|LOG_FACMASK))) 7545430Sbostic return; 7645277Sbostic 7736443Sbostic saved_errno = errno; 7836443Sbostic 7924846Seric /* set default facility if none specified */ 8024846Seric if ((pri & LOG_FACMASK) == 0) 8124846Seric pri |= LogFacility; 8224846Seric 8324846Seric /* build the message */ 8436440Sbostic (void)time(&now); 8536440Sbostic (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4); 8636440Sbostic for (p = tbuf; *p; ++p); 8736792Sbostic if (LogStat & LOG_PERROR) 8836792Sbostic stdp = p; 8916414Sralph if (LogTag) { 9036440Sbostic (void)strcpy(p, LogTag); 9136440Sbostic for (; *p; ++p); 9216414Sralph } 9316414Sralph if (LogStat & LOG_PID) { 9436440Sbostic (void)sprintf(p, "[%d]", getpid()); 9536440Sbostic for (; *p; ++p); 9616414Sralph } 9724846Seric if (LogTag) { 9836440Sbostic *p++ = ':'; 9936440Sbostic *p++ = ' '; 10024846Seric } 10112742Ssam 10236443Sbostic /* substitute error message for %m */ 10336443Sbostic { 10436443Sbostic register char ch, *t1, *t2; 10536443Sbostic char *strerror(); 10624846Seric 10736443Sbostic for (t1 = fmt_cpy; ch = *fmt; ++fmt) 10836443Sbostic if (ch == '%' && fmt[1] == 'm') { 10936443Sbostic ++fmt; 11036443Sbostic for (t2 = strerror(saved_errno); 11136443Sbostic *t1 = *t2++; ++t1); 11236443Sbostic } 11336443Sbostic else 11436443Sbostic *t1++ = ch; 11536583Sbostic *t1 = '\0'; 11636443Sbostic } 11736443Sbostic 11836443Sbostic (void)vsprintf(p, fmt_cpy, ap); 11936443Sbostic 12036792Sbostic cnt = strlen(tbuf); 12136792Sbostic 12236792Sbostic /* output to stderr if requested */ 12336792Sbostic if (LogStat & LOG_PERROR) { 12436792Sbostic struct iovec iov[2]; 12536792Sbostic register struct iovec *v = iov; 12636792Sbostic 12736792Sbostic v->iov_base = stdp; 12836792Sbostic v->iov_len = cnt - (stdp - tbuf); 12936792Sbostic ++v; 13036792Sbostic v->iov_base = "\n"; 13136792Sbostic v->iov_len = 1; 13245646Sbostic (void)writev(STDERR_FILENO, iov, 2); 13336792Sbostic } 13436792Sbostic 13545264Sbostic /* get connected, output the message to the local logger */ 136*46597Sdonn if (!connected) 137*46597Sdonn openlog(LogTag, LogStat | LOG_NDELAY, 0); 138*46597Sdonn if (send(LogFile, tbuf, cnt, 0) >= 0) 13945430Sbostic return; 14024846Seric 14145264Sbostic /* see if should attempt the console */ 14245264Sbostic if (!(LogStat&LOG_CONS)) 14345430Sbostic return; 14445264Sbostic 14538567Sbostic /* 14645264Sbostic * Output the message to the console; don't worry about blocking, 14745264Sbostic * if console blocks everything will. Make sure the error reported 14845264Sbostic * is the one from the syslogd failure. 14938567Sbostic */ 15045264Sbostic if ((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 161*46597Sdonn void 16224846Seric openlog(ident, logstat, logfac) 163*46597Sdonn 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 190*46597Sdonn void 19112742Ssam closelog() 19212742Ssam { 19345430Sbostic (void)close(LogFile); 19412742Ssam LogFile = -1; 19534563Skarels connected = 0; 19612742Ssam } 19716414Sralph 19836440Sbostic static int LogMask = 0xff; /* mask of priorities to be logged */ 19945264Sbostic 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