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*45277Sbostic static char sccsid[] = "@(#)syslog.c 5.30 (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> 1745264Sbostic #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 3045264Sbostic /* 3145264Sbostic * syslog, vsyslog -- 3245264Sbostic * print message on log file; output is intended for syslogd(8). 3345264Sbostic */ 3436440Sbostic syslog(pri, fmt, args) 3536440Sbostic int pri, args; 3612742Ssam char *fmt; 3712742Ssam { 3845264Sbostic 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 52*45277Sbostic /* check for invalid bits or no priority set */ 53*45277Sbostic if (!LOG_PRI(pri) || (pri &~ (LOG_PRIMASK|LOG_FACMASK))) { 54*45277Sbostic errno = EINVAL; 55*45277Sbostic return(-1); 56*45277Sbostic } 57*45277Sbostic 5836443Sbostic saved_errno = errno; 5936443Sbostic 6024846Seric /* set default facility if none specified */ 6124846Seric if ((pri & LOG_FACMASK) == 0) 6224846Seric pri |= LogFacility; 6324846Seric 6424846Seric /* build the message */ 6536440Sbostic (void)time(&now); 6636440Sbostic (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4); 6736440Sbostic for (p = tbuf; *p; ++p); 6836792Sbostic if (LogStat & LOG_PERROR) 6936792Sbostic stdp = p; 7016414Sralph if (LogTag) { 7136440Sbostic (void)strcpy(p, LogTag); 7236440Sbostic for (; *p; ++p); 7316414Sralph } 7416414Sralph if (LogStat & LOG_PID) { 7536440Sbostic (void)sprintf(p, "[%d]", getpid()); 7636440Sbostic for (; *p; ++p); 7716414Sralph } 7824846Seric if (LogTag) { 7936440Sbostic *p++ = ':'; 8036440Sbostic *p++ = ' '; 8124846Seric } 8212742Ssam 8336443Sbostic /* substitute error message for %m */ 8436443Sbostic { 8536443Sbostic register char ch, *t1, *t2; 8636443Sbostic char *strerror(); 8724846Seric 8836443Sbostic for (t1 = fmt_cpy; ch = *fmt; ++fmt) 8936443Sbostic if (ch == '%' && fmt[1] == 'm') { 9036443Sbostic ++fmt; 9136443Sbostic for (t2 = strerror(saved_errno); 9236443Sbostic *t1 = *t2++; ++t1); 9336443Sbostic } 9436443Sbostic else 9536443Sbostic *t1++ = ch; 9636583Sbostic *t1 = '\0'; 9736443Sbostic } 9836443Sbostic 9936443Sbostic (void)vsprintf(p, fmt_cpy, ap); 10036443Sbostic 10136792Sbostic cnt = strlen(tbuf); 10236792Sbostic 10336792Sbostic /* output to stderr if requested */ 10436792Sbostic if (LogStat & LOG_PERROR) { 10536792Sbostic struct iovec iov[2]; 10636792Sbostic register struct iovec *v = iov; 10736792Sbostic 10836792Sbostic v->iov_base = stdp; 10936792Sbostic v->iov_len = cnt - (stdp - tbuf); 11036792Sbostic ++v; 11136792Sbostic v->iov_base = "\n"; 11236792Sbostic v->iov_len = 1; 11336792Sbostic (void)writev(2, iov, 2); 11436792Sbostic } 11536792Sbostic 11645264Sbostic /* get connected, output the message to the local logger */ 11745264Sbostic if ((connected || !openlog(LogTag, LogStat | LOG_NDELAY, 0)) && 11845264Sbostic send(LogFile, tbuf, cnt, 0) >= 0) 11945264Sbostic return(0); 12024846Seric 12145264Sbostic /* see if should attempt the console */ 12245264Sbostic if (!(LogStat&LOG_CONS)) 12345264Sbostic return(-1); 12445264Sbostic 12538567Sbostic /* 12645264Sbostic * Output the message to the console; don't worry about blocking, 12745264Sbostic * if console blocks everything will. Make sure the error reported 12845264Sbostic * is the one from the syslogd failure. 12938567Sbostic */ 13045264Sbostic saved_errno = errno; 13145264Sbostic if ((fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { 13245264Sbostic (void)strcat(tbuf, "\r\n"); 13345264Sbostic cnt += 2; 13445264Sbostic p = index(tbuf, '>') + 1; 13545264Sbostic (void)write(fd, p, cnt - (p - tbuf)); 13645264Sbostic (void)close(fd); 13745264Sbostic } else 13845264Sbostic errno = saved_errno; 13945264Sbostic return(-1); 14012742Ssam } 14112742Ssam 14236440Sbostic static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 14345264Sbostic 14424846Seric openlog(ident, logstat, logfac) 14512742Ssam char *ident; 14624846Seric int logstat, logfac; 14712742Ssam { 14845264Sbostic int saved_errno; 14945264Sbostic 15024846Seric if (ident != NULL) 15124846Seric LogTag = ident; 15212742Ssam LogStat = logstat; 15333786Skarels if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) 15433786Skarels LogFacility = logfac; 15545264Sbostic 15634563Skarels if (LogFile == -1) { 15734563Skarels SyslogAddr.sa_family = AF_UNIX; 15845264Sbostic (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, 15938557Sbostic sizeof(SyslogAddr.sa_data)); 16034563Skarels if (LogStat & LOG_NDELAY) { 16145264Sbostic if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) 16245264Sbostic return(-1); 16345264Sbostic (void)fcntl(LogFile, F_SETFD, 1); 16434563Skarels } 16517918Sralph } 16645264Sbostic if (LogFile != -1 && !connected) 16745264Sbostic if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { 16845264Sbostic saved_errno = errno; 16945264Sbostic (void)close(LogFile); 17045264Sbostic errno = saved_errno; 17145264Sbostic LogFile = -1; 17245264Sbostic return(-1); 17345264Sbostic } else 17445264Sbostic connected = 1; 17545264Sbostic return(0); 17612742Ssam } 17712742Ssam 17812742Ssam closelog() 17912742Ssam { 18045264Sbostic int rval; 18145264Sbostic 18245264Sbostic rval = close(LogFile); 18312742Ssam LogFile = -1; 18434563Skarels connected = 0; 18545264Sbostic return(rval); 18612742Ssam } 18716414Sralph 18836440Sbostic static int LogMask = 0xff; /* mask of priorities to be logged */ 18945264Sbostic 19045264Sbostic /* setlogmask -- set the log mask level */ 19117526Sralph setlogmask(pmask) 19217526Sralph int pmask; 19316414Sralph { 19417526Sralph int omask; 19516414Sralph 19617526Sralph omask = LogMask; 19717526Sralph if (pmask != 0) 19817526Sralph LogMask = pmask; 19917526Sralph return (omask); 20016414Sralph } 201