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*26870Skarels static char sccsid[] = "@(#)syslog.c 5.7 (Berkeley) 03/13/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> 31*26870Skarels #include <sys/signal.h> 32*26870Skarels #include <sys/syslog.h> 3312742Ssam #include <netdb.h> 34*26870Skarels #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; 12524846Seric if (!(LogStat & LOG_CONS) && (pri & LOG_PRIMASK) <= LOG_ERR) 12616414Sralph return; 12724846Seric 12824846Seric /* output the message to the console */ 12926508Skarels pid = vfork(); 13016414Sralph if (pid == -1) 13116414Sralph return; 13216414Sralph if (pid == 0) { 13324880Seric signal(SIGALRM, SIG_DFL); 13424880Seric sigsetmask(sigblock(0) & ~sigmask(SIGALRM)); 13524880Seric alarm(5); 13624846Seric LogFile = open(ctty, O_WRONLY); 13724880Seric alarm(0); 13817918Sralph strcat(o, "\r"); 139*26870Skarels o = index(outline, '>') + 1; 14026508Skarels write(LogFile, outline, c + 1 - (o - outline)); 14116414Sralph close(LogFile); 14216414Sralph exit(0); 14316414Sralph } 14416943Sralph while ((c = wait((int *)0)) > 0 && c != pid) 14516414Sralph ; 14612742Ssam } 14712742Ssam 14812742Ssam /* 14912742Ssam * OPENLOG -- open system log 15012742Ssam */ 15124846Seric 15224846Seric openlog(ident, logstat, logfac) 15312742Ssam char *ident; 15424846Seric int logstat, logfac; 15512742Ssam { 15624846Seric if (ident != NULL) 15724846Seric LogTag = ident; 15812742Ssam LogStat = logstat; 15924846Seric if (logfac != 0) 16024846Seric LogFacility = logfac & LOG_FACMASK; 16112742Ssam if (LogFile >= 0) 16212742Ssam return; 16316414Sralph SyslogAddr.sa_family = AF_UNIX; 16416414Sralph strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); 16525187Seric if (LogStat & LOG_NDELAY) { 16617918Sralph LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); 16717918Sralph fcntl(LogFile, F_SETFD, 1); 16817918Sralph } 16912742Ssam } 17012742Ssam 17112742Ssam /* 17212742Ssam * CLOSELOG -- close the system log 17312742Ssam */ 17425187Seric 17512742Ssam closelog() 17612742Ssam { 17712742Ssam 17812742Ssam (void) close(LogFile); 17912742Ssam LogFile = -1; 18012742Ssam } 18116414Sralph 18216414Sralph /* 18316414Sralph * SETLOGMASK -- set the log mask level 18416414Sralph */ 18517526Sralph setlogmask(pmask) 18617526Sralph int pmask; 18716414Sralph { 18817526Sralph int omask; 18916414Sralph 19017526Sralph omask = LogMask; 19117526Sralph if (pmask != 0) 19217526Sralph LogMask = pmask; 19317526Sralph return (omask); 19416414Sralph } 195