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 712742Ssam #ifndef lint 8*25187Seric static char sccsid[] = "@(#)syslog.c 5.4 (Berkeley) 10/13/85"; 921362Sdist #endif 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> 3124880Seric #include <signal.h> 3212742Ssam #include <syslog.h> 3312742Ssam #include <netdb.h> 3412742Ssam 3516414Sralph #define MAXLINE 1024 /* max message size */ 3616414Sralph #define NULL 0 /* manifest */ 3712742Ssam 3824846Seric #define PRIMASK(p) (1 << ((p) & LOG_PRIMASK)) 3924846Seric #define PRIFAC(p) (((p) & LOG_FACMASK) >> 3) 4024846Seric #define IMPORTANT LOG_ERR 4117918Sralph 4216414Sralph static char logname[] = "/dev/log"; 4316414Sralph static char ctty[] = "/dev/console"; 4412742Ssam 4516414Sralph static int LogFile = -1; /* fd for log */ 4616414Sralph static int LogStat = 0; /* status bits, set by openlog() */ 4724846Seric static char *LogTag = "syslog"; /* string to tag the entry with */ 4824846Seric static int LogMask = 0xff; /* mask of priorities to be logged */ 4924846Seric static int LogFacility = LOG_USER; /* default facility code */ 5012742Ssam 5124846Seric static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 5216414Sralph 5312742Ssam extern int errno, sys_nerr; 5412742Ssam extern char *sys_errlist[]; 5512742Ssam 5612742Ssam syslog(pri, fmt, p0, p1, p2, p3, p4) 5712742Ssam int pri; 5812742Ssam char *fmt; 5912742Ssam { 6016414Sralph char buf[MAXLINE + 1], outline[MAXLINE + 1]; 6116414Sralph register char *b, *f, *o; 6216414Sralph register int c; 6316414Sralph long now; 6416943Sralph int pid, olderrno = errno; 6512742Ssam 6612742Ssam /* see if we should just throw out this message */ 6724846Seric if (pri <= 0 || PRIFAC(pri) >= LOG_NFACILITIES || (PRIMASK(pri) & LogMask) == 0) 6812742Ssam return; 6916414Sralph if (LogFile < 0) 70*25187Seric openlog(LogTag, LogStat | LOG_NDELAY, 0); 7124846Seric 7224846Seric /* set default facility if none specified */ 7324846Seric if ((pri & LOG_FACMASK) == 0) 7424846Seric pri |= LogFacility; 7524846Seric 7624846Seric /* build the message */ 7716414Sralph o = outline; 7816943Sralph sprintf(o, "<%d>", pri); 7916943Sralph o += strlen(o); 8024846Seric time(&now); 8124846Seric sprintf(o, "%.15s ", ctime(&now) + 4); 8224846Seric o += strlen(o); 8316414Sralph if (LogTag) { 8416414Sralph strcpy(o, LogTag); 8516414Sralph o += strlen(o); 8616414Sralph } 8716414Sralph if (LogStat & LOG_PID) { 8816943Sralph sprintf(o, "[%d]", getpid()); 8916414Sralph o += strlen(o); 9016414Sralph } 9124846Seric if (LogTag) { 9224846Seric strcpy(o, ": "); 9324846Seric o += 2; 9424846Seric } 9512742Ssam 9616414Sralph b = buf; 9716414Sralph f = fmt; 9816414Sralph while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) { 9916414Sralph if (c != '%') { 10016414Sralph *b++ = c; 10116414Sralph continue; 10212742Ssam } 10316414Sralph if ((c = *f++) != 'm') { 10416414Sralph *b++ = '%'; 10516414Sralph *b++ = c; 10616414Sralph continue; 10712742Ssam } 10816943Sralph if ((unsigned)olderrno > sys_nerr) 10916943Sralph sprintf(b, "error %d", olderrno); 11012742Ssam else 11116943Sralph strcpy(b, sys_errlist[olderrno]); 11216414Sralph b += strlen(b); 11312742Ssam } 11416414Sralph *b++ = '\n'; 11516414Sralph *b = '\0'; 11616414Sralph sprintf(o, buf, p0, p1, p2, p3, p4); 11716414Sralph c = strlen(outline); 11816414Sralph if (c > MAXLINE) 11916414Sralph c = MAXLINE; 12024846Seric 12124846Seric /* output the message to the local logger */ 12216414Sralph if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) 12316414Sralph return; 12424846Seric if (!(LogStat & LOG_CONS) && (pri & LOG_PRIMASK) <= LOG_ERR) 12516414Sralph return; 12624846Seric 12724846Seric /* output the message to the console */ 12816414Sralph pid = fork(); 12916414Sralph if (pid == -1) 13016414Sralph return; 13116414Sralph if (pid == 0) { 13224880Seric signal(SIGALRM, SIG_DFL); 13324880Seric sigsetmask(sigblock(0) & ~sigmask(SIGALRM)); 13424880Seric alarm(5); 13524846Seric LogFile = open(ctty, O_WRONLY); 13624880Seric alarm(0); 13717918Sralph strcat(o, "\r"); 13817918Sralph write(LogFile, outline, c+1); 13916414Sralph close(LogFile); 14016414Sralph exit(0); 14116414Sralph } 14216943Sralph while ((c = wait((int *)0)) > 0 && c != pid) 14316414Sralph ; 14412742Ssam } 14512742Ssam 14612742Ssam /* 14712742Ssam * OPENLOG -- open system log 14812742Ssam */ 14924846Seric 15024846Seric openlog(ident, logstat, logfac) 15112742Ssam char *ident; 15224846Seric int logstat, logfac; 15312742Ssam { 15424846Seric if (ident != NULL) 15524846Seric LogTag = ident; 15612742Ssam LogStat = logstat; 15724846Seric if (logfac != 0) 15824846Seric LogFacility = logfac & LOG_FACMASK; 15912742Ssam if (LogFile >= 0) 16012742Ssam return; 16116414Sralph SyslogAddr.sa_family = AF_UNIX; 16216414Sralph strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); 163*25187Seric if (LogStat & LOG_NDELAY) { 16417918Sralph LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); 16517918Sralph fcntl(LogFile, F_SETFD, 1); 16617918Sralph } 16712742Ssam } 16812742Ssam 16912742Ssam /* 17012742Ssam * CLOSELOG -- close the system log 17112742Ssam */ 172*25187Seric 17312742Ssam closelog() 17412742Ssam { 17512742Ssam 17612742Ssam (void) close(LogFile); 17712742Ssam LogFile = -1; 17812742Ssam } 17916414Sralph 18016414Sralph /* 18116414Sralph * SETLOGMASK -- set the log mask level 18216414Sralph */ 18317526Sralph setlogmask(pmask) 18417526Sralph int pmask; 18516414Sralph { 18617526Sralph int omask; 18716414Sralph 18817526Sralph omask = LogMask; 18917526Sralph if (pmask != 0) 19017526Sralph LogMask = pmask; 19117526Sralph return (omask); 19216414Sralph } 193