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*45264Sbostic static char sccsid[] = "@(#)syslog.c 5.29 (Berkeley) 09/30/90"; 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> 17*45264Sbostic #include <sys/errno.h> 1812742Ssam #include <netdb.h> 1942025Sbostic #include <string.h> 2036442Sbostic #include <varargs.h> 2138557Sbostic #include <paths.h> 2236440Sbostic #include <stdio.h> 2312742Ssam 2416414Sralph static int LogFile = -1; /* fd for log */ 2534563Skarels static int connected; /* have done connect */ 2636440Sbostic static int LogStat = 0; /* status bits, set by openlog() */ 2724846Seric static char *LogTag = "syslog"; /* string to tag the entry with */ 2824846Seric static int LogFacility = LOG_USER; /* default facility code */ 2912742Ssam 30*45264Sbostic /* 31*45264Sbostic * syslog, vsyslog -- 32*45264Sbostic * print message on log file; output is intended for syslogd(8). 33*45264Sbostic */ 3436440Sbostic syslog(pri, fmt, args) 3536440Sbostic int pri, args; 3612742Ssam char *fmt; 3712742Ssam { 38*45264Sbostic return(vsyslog(pri, fmt, &args)); 3936442Sbostic } 4036442Sbostic 4136442Sbostic vsyslog(pri, fmt, ap) 4236442Sbostic int pri; 4336443Sbostic register char *fmt; 4436442Sbostic va_list ap; 4536442Sbostic { 4636440Sbostic register int cnt; 4736440Sbostic register char *p; 4836440Sbostic time_t now, time(); 4938567Sbostic int fd, saved_errno; 5036792Sbostic char tbuf[2048], fmt_cpy[1024], *stdp, *ctime(); 5112742Ssam 5236443Sbostic saved_errno = errno; 5336443Sbostic 54*45264Sbostic /* discard if invalid bits or no priority set */ 55*45264Sbostic if (!LOG_PRI(pri) || (pri &~ (LOG_PRIMASK|LOG_FACMASK))) 56*45264Sbostic return(0); 5724846Seric 5824846Seric /* set default facility if none specified */ 5924846Seric if ((pri & LOG_FACMASK) == 0) 6024846Seric pri |= LogFacility; 6124846Seric 6224846Seric /* build the message */ 6336440Sbostic (void)time(&now); 6436440Sbostic (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4); 6536440Sbostic for (p = tbuf; *p; ++p); 6636792Sbostic if (LogStat & LOG_PERROR) 6736792Sbostic stdp = p; 6816414Sralph if (LogTag) { 6936440Sbostic (void)strcpy(p, LogTag); 7036440Sbostic for (; *p; ++p); 7116414Sralph } 7216414Sralph if (LogStat & LOG_PID) { 7336440Sbostic (void)sprintf(p, "[%d]", getpid()); 7436440Sbostic for (; *p; ++p); 7516414Sralph } 7624846Seric if (LogTag) { 7736440Sbostic *p++ = ':'; 7836440Sbostic *p++ = ' '; 7924846Seric } 8012742Ssam 8136443Sbostic /* substitute error message for %m */ 8236443Sbostic { 8336443Sbostic register char ch, *t1, *t2; 8436443Sbostic char *strerror(); 8524846Seric 8636443Sbostic for (t1 = fmt_cpy; ch = *fmt; ++fmt) 8736443Sbostic if (ch == '%' && fmt[1] == 'm') { 8836443Sbostic ++fmt; 8936443Sbostic for (t2 = strerror(saved_errno); 9036443Sbostic *t1 = *t2++; ++t1); 9136443Sbostic } 9236443Sbostic else 9336443Sbostic *t1++ = ch; 9436583Sbostic *t1 = '\0'; 9536443Sbostic } 9636443Sbostic 9736443Sbostic (void)vsprintf(p, fmt_cpy, ap); 9836443Sbostic 9936792Sbostic cnt = strlen(tbuf); 10036792Sbostic 10136792Sbostic /* output to stderr if requested */ 10236792Sbostic if (LogStat & LOG_PERROR) { 10336792Sbostic struct iovec iov[2]; 10436792Sbostic register struct iovec *v = iov; 10536792Sbostic 10636792Sbostic v->iov_base = stdp; 10736792Sbostic v->iov_len = cnt - (stdp - tbuf); 10836792Sbostic ++v; 10936792Sbostic v->iov_base = "\n"; 11036792Sbostic v->iov_len = 1; 11136792Sbostic (void)writev(2, iov, 2); 11236792Sbostic } 11336792Sbostic 114*45264Sbostic /* get connected, output the message to the local logger */ 115*45264Sbostic if ((connected || !openlog(LogTag, LogStat | LOG_NDELAY, 0)) && 116*45264Sbostic send(LogFile, tbuf, cnt, 0) >= 0) 117*45264Sbostic return(0); 11824846Seric 119*45264Sbostic /* see if should attempt the console */ 120*45264Sbostic if (!(LogStat&LOG_CONS)) 121*45264Sbostic return(-1); 122*45264Sbostic 12338567Sbostic /* 124*45264Sbostic * Output the message to the console; don't worry about blocking, 125*45264Sbostic * if console blocks everything will. Make sure the error reported 126*45264Sbostic * is the one from the syslogd failure. 12738567Sbostic */ 128*45264Sbostic saved_errno = errno; 129*45264Sbostic if ((fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { 130*45264Sbostic (void)strcat(tbuf, "\r\n"); 131*45264Sbostic cnt += 2; 132*45264Sbostic p = index(tbuf, '>') + 1; 133*45264Sbostic (void)write(fd, p, cnt - (p - tbuf)); 134*45264Sbostic (void)close(fd); 135*45264Sbostic } else 136*45264Sbostic errno = saved_errno; 137*45264Sbostic return(-1); 13812742Ssam } 13912742Ssam 14036440Sbostic static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 141*45264Sbostic 14224846Seric openlog(ident, logstat, logfac) 14312742Ssam char *ident; 14424846Seric int logstat, logfac; 14512742Ssam { 146*45264Sbostic int saved_errno; 147*45264Sbostic 14824846Seric if (ident != NULL) 14924846Seric LogTag = ident; 15012742Ssam LogStat = logstat; 15133786Skarels if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) 15233786Skarels LogFacility = logfac; 153*45264Sbostic 15434563Skarels if (LogFile == -1) { 15534563Skarels SyslogAddr.sa_family = AF_UNIX; 156*45264Sbostic (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, 15738557Sbostic sizeof(SyslogAddr.sa_data)); 15834563Skarels if (LogStat & LOG_NDELAY) { 159*45264Sbostic if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) 160*45264Sbostic return(-1); 161*45264Sbostic (void)fcntl(LogFile, F_SETFD, 1); 16234563Skarels } 16317918Sralph } 164*45264Sbostic if (LogFile != -1 && !connected) 165*45264Sbostic if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { 166*45264Sbostic saved_errno = errno; 167*45264Sbostic (void)close(LogFile); 168*45264Sbostic errno = saved_errno; 169*45264Sbostic LogFile = -1; 170*45264Sbostic return(-1); 171*45264Sbostic } else 172*45264Sbostic connected = 1; 173*45264Sbostic return(0); 17412742Ssam } 17512742Ssam 17612742Ssam closelog() 17712742Ssam { 178*45264Sbostic int rval; 179*45264Sbostic 180*45264Sbostic rval = close(LogFile); 18112742Ssam LogFile = -1; 18234563Skarels connected = 0; 183*45264Sbostic return(rval); 18412742Ssam } 18516414Sralph 18636440Sbostic static int LogMask = 0xff; /* mask of priorities to be logged */ 187*45264Sbostic 188*45264Sbostic /* setlogmask -- set the log mask level */ 18917526Sralph setlogmask(pmask) 19017526Sralph int pmask; 19116414Sralph { 19217526Sralph int omask; 19316414Sralph 19417526Sralph omask = LogMask; 19517526Sralph if (pmask != 0) 19617526Sralph LogMask = pmask; 19717526Sralph return (omask); 19816414Sralph } 199