121362Sdist /* 221362Sdist * Copyright (c) 1983 Regents of the University of California. 321362Sdist * All rights reserved. The Berkeley software License Agreement 421362Sdist * specifies the terms and conditions for redistribution. 521362Sdist */ 621362Sdist 726602Sdonn #if defined(LIBC_SCCS) && !defined(lint) 8*27795Skarels static char sccsid[] = "@(#)syslog.c 5.9 (Berkeley) 05/07/86"; 926602Sdonn #endif LIBC_SCCS and not lint 1012742Ssam 1112742Ssam /* 1212742Ssam * SYSLOG -- print message on log file 1312742Ssam * 1412742Ssam * This routine looks a lot like printf, except that it 1512742Ssam * outputs to the log file instead of the standard output. 1616414Sralph * Also: 1716414Sralph * adds a timestamp, 1816414Sralph * prints the module name in front of the message, 1916414Sralph * has some other formatting types (or will sometime), 2016414Sralph * adds a newline on the end of the message. 2112742Ssam * 2216414Sralph * The output of this routine is intended to be read by /etc/syslogd. 2316943Sralph * 2416943Sralph * Author: Eric Allman 2516943Sralph * Modified to use UNIX domain IPC by Ralph Campbell 2612742Ssam */ 2716414Sralph 2812742Ssam #include <sys/types.h> 2912742Ssam #include <sys/socket.h> 3016414Sralph #include <sys/file.h> 3126870Skarels #include <sys/signal.h> 3226870Skarels #include <sys/syslog.h> 3312742Ssam #include <netdb.h> 3426870Skarels #include <strings.h> 3512742Ssam 3616414Sralph #define MAXLINE 1024 /* max message size */ 3716414Sralph #define NULL 0 /* manifest */ 3812742Ssam 3924846Seric #define PRIMASK(p) (1 << ((p) & LOG_PRIMASK)) 4024846Seric #define PRIFAC(p) (((p) & LOG_FACMASK) >> 3) 4124846Seric #define IMPORTANT LOG_ERR 4217918Sralph 4316414Sralph static char logname[] = "/dev/log"; 4416414Sralph static char ctty[] = "/dev/console"; 4512742Ssam 4616414Sralph static int LogFile = -1; /* fd for log */ 4716414Sralph static int LogStat = 0; /* status bits, set by openlog() */ 4824846Seric static char *LogTag = "syslog"; /* string to tag the entry with */ 4924846Seric static int LogMask = 0xff; /* mask of priorities to be logged */ 5024846Seric static int LogFacility = LOG_USER; /* default facility code */ 5112742Ssam 5224846Seric static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 5316414Sralph 5412742Ssam extern int errno, sys_nerr; 5512742Ssam extern char *sys_errlist[]; 5612742Ssam 5712742Ssam syslog(pri, fmt, p0, p1, p2, p3, p4) 5812742Ssam int pri; 5912742Ssam char *fmt; 6012742Ssam { 6116414Sralph char buf[MAXLINE + 1], outline[MAXLINE + 1]; 6216414Sralph register char *b, *f, *o; 6316414Sralph register int c; 6416414Sralph long now; 6516943Sralph int pid, olderrno = errno; 6612742Ssam 6712742Ssam /* see if we should just throw out this message */ 6824846Seric if (pri <= 0 || PRIFAC(pri) >= LOG_NFACILITIES || (PRIMASK(pri) & LogMask) == 0) 6912742Ssam return; 7016414Sralph if (LogFile < 0) 7125187Seric openlog(LogTag, LogStat | LOG_NDELAY, 0); 7224846Seric 7324846Seric /* set default facility if none specified */ 7424846Seric if ((pri & LOG_FACMASK) == 0) 7524846Seric pri |= LogFacility; 7624846Seric 7724846Seric /* build the message */ 7816414Sralph o = outline; 7916943Sralph sprintf(o, "<%d>", pri); 8016943Sralph o += strlen(o); 8124846Seric time(&now); 8224846Seric sprintf(o, "%.15s ", ctime(&now) + 4); 8324846Seric o += strlen(o); 8416414Sralph if (LogTag) { 8516414Sralph strcpy(o, LogTag); 8616414Sralph o += strlen(o); 8716414Sralph } 8816414Sralph if (LogStat & LOG_PID) { 8916943Sralph sprintf(o, "[%d]", getpid()); 9016414Sralph o += strlen(o); 9116414Sralph } 9224846Seric if (LogTag) { 9324846Seric strcpy(o, ": "); 9424846Seric o += 2; 9524846Seric } 9612742Ssam 9716414Sralph b = buf; 9816414Sralph f = fmt; 9916414Sralph while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) { 10016414Sralph if (c != '%') { 10116414Sralph *b++ = c; 10216414Sralph continue; 10312742Ssam } 10416414Sralph if ((c = *f++) != 'm') { 10516414Sralph *b++ = '%'; 10616414Sralph *b++ = c; 10716414Sralph continue; 10812742Ssam } 10916943Sralph if ((unsigned)olderrno > sys_nerr) 11016943Sralph sprintf(b, "error %d", olderrno); 11112742Ssam else 11216943Sralph strcpy(b, sys_errlist[olderrno]); 11316414Sralph b += strlen(b); 11412742Ssam } 11516414Sralph *b++ = '\n'; 11616414Sralph *b = '\0'; 11716414Sralph sprintf(o, buf, p0, p1, p2, p3, p4); 11816414Sralph c = strlen(outline); 11916414Sralph if (c > MAXLINE) 12016414Sralph c = MAXLINE; 12124846Seric 12224846Seric /* output the message to the local logger */ 12316414Sralph if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) 12416414Sralph return; 12527343Skarels if (!(LogStat & LOG_CONS)) 12616414Sralph return; 12724846Seric 12824846Seric /* output the message to the console */ 12926508Skarels pid = vfork(); 13016414Sralph if (pid == -1) 13116414Sralph return; 13216414Sralph if (pid == 0) { 133*27795Skarels int fd; 134*27795Skarels 13524880Seric signal(SIGALRM, SIG_DFL); 13624880Seric sigsetmask(sigblock(0) & ~sigmask(SIGALRM)); 13724880Seric alarm(5); 138*27795Skarels fd = open(ctty, O_WRONLY); 13924880Seric alarm(0); 14017918Sralph strcat(o, "\r"); 14126870Skarels o = index(outline, '>') + 1; 142*27795Skarels write(fd, o, c + 1 - (o - outline)); 143*27795Skarels close(fd); 144*27795Skarels _exit(0); 14516414Sralph } 14627343Skarels if (!(LogStat & LOG_NOWAIT)) 14727343Skarels while ((c = wait((int *)0)) > 0 && c != pid) 14827343Skarels ; 14912742Ssam } 15012742Ssam 15112742Ssam /* 15212742Ssam * OPENLOG -- open system log 15312742Ssam */ 15424846Seric 15524846Seric openlog(ident, logstat, logfac) 15612742Ssam char *ident; 15724846Seric int logstat, logfac; 15812742Ssam { 15924846Seric if (ident != NULL) 16024846Seric LogTag = ident; 16112742Ssam LogStat = logstat; 16224846Seric if (logfac != 0) 16324846Seric LogFacility = logfac & LOG_FACMASK; 16412742Ssam if (LogFile >= 0) 16512742Ssam return; 16616414Sralph SyslogAddr.sa_family = AF_UNIX; 16716414Sralph strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); 16825187Seric if (LogStat & LOG_NDELAY) { 16917918Sralph LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); 17017918Sralph fcntl(LogFile, F_SETFD, 1); 17117918Sralph } 17212742Ssam } 17312742Ssam 17412742Ssam /* 17512742Ssam * CLOSELOG -- close the system log 17612742Ssam */ 17725187Seric 17812742Ssam closelog() 17912742Ssam { 18012742Ssam 18112742Ssam (void) close(LogFile); 18212742Ssam LogFile = -1; 18312742Ssam } 18416414Sralph 18516414Sralph /* 18616414Sralph * SETLOGMASK -- set the log mask level 18716414Sralph */ 18817526Sralph setlogmask(pmask) 18917526Sralph int pmask; 19016414Sralph { 19117526Sralph int omask; 19216414Sralph 19317526Sralph omask = LogMask; 19417526Sralph if (pmask != 0) 19517526Sralph LogMask = pmask; 19617526Sralph return (omask); 19716414Sralph } 198