1*21362Sdist /* 2*21362Sdist * Copyright (c) 1983 Regents of the University of California. 3*21362Sdist * All rights reserved. The Berkeley software License Agreement 4*21362Sdist * specifies the terms and conditions for redistribution. 5*21362Sdist */ 6*21362Sdist 712742Ssam #ifndef lint 8*21362Sdist static char sccsid[] = "@(#)syslog.c 5.1 (Berkeley) 05/30/85"; 9*21362Sdist #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> 3112742Ssam #include <syslog.h> 3212742Ssam #include <netdb.h> 3312742Ssam 3416414Sralph #define MAXLINE 1024 /* max message size */ 3516414Sralph #define NULL 0 /* manifest */ 3612742Ssam 3717918Sralph #define mask(p) (1 << (p)) 3817918Sralph #define IMPORTANT (mask(KERN_EMERG)|mask(KERN_ALERT)|mask(KERN_ERR)|mask(KERN_FAIL)\ 3917918Sralph |mask(KERN_RECOV)|mask(KERN_INFO)|mask(LOG_EMERG)|mask(LOG_ALERT)\ 4017918Sralph |mask(LOG_CRIT)|mask(LOG_ERR)|mask(LOG_FAIL)) 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() */ 4716414Sralph static char *LogTag = NULL; /* string to tag the entry with */ 4818020Sralph /* mask of priorities to be logged */ 4918020Sralph static int LogMask = ~(mask(KERN_EMERG)|mask(KERN_ALERT)|mask(KERN_ERR)| 5018020Sralph mask(KERN_FAIL)|mask(KERN_RECOV)|mask(KERN_INFO)); 5112742Ssam 5216414Sralph static struct sockaddr SyslogAddr; 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 */ 6817918Sralph if (pri <= 0 || pri >= 32 || (mask(pri) & LogMask) == 0) 6912742Ssam return; 7016414Sralph if (LogFile < 0) 7117918Sralph openlog(LogTag, LogStat & ~LOG_ODELAY, 0); 7216414Sralph o = outline; 7316943Sralph sprintf(o, "<%d>", pri); 7416943Sralph o += strlen(o); 7516414Sralph if (LogTag) { 7616414Sralph strcpy(o, LogTag); 7716414Sralph o += strlen(o); 7816414Sralph } 7916414Sralph if (LogStat & LOG_PID) { 8016943Sralph sprintf(o, "[%d]", getpid()); 8116414Sralph o += strlen(o); 8216414Sralph } 8316414Sralph time(&now); 8416943Sralph sprintf(o, ": %.15s-- ", ctime(&now) + 4); 8516414Sralph o += strlen(o); 8612742Ssam 8716414Sralph b = buf; 8816414Sralph f = fmt; 8916414Sralph while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) { 9016414Sralph if (c != '%') { 9116414Sralph *b++ = c; 9216414Sralph continue; 9312742Ssam } 9416414Sralph if ((c = *f++) != 'm') { 9516414Sralph *b++ = '%'; 9616414Sralph *b++ = c; 9716414Sralph continue; 9812742Ssam } 9916943Sralph if ((unsigned)olderrno > sys_nerr) 10016943Sralph sprintf(b, "error %d", olderrno); 10112742Ssam else 10216943Sralph strcpy(b, sys_errlist[olderrno]); 10316414Sralph b += strlen(b); 10412742Ssam } 10516414Sralph *b++ = '\n'; 10616414Sralph *b = '\0'; 10716414Sralph sprintf(o, buf, p0, p1, p2, p3, p4); 10816414Sralph c = strlen(outline); 10916414Sralph if (c > MAXLINE) 11016414Sralph c = MAXLINE; 11116414Sralph if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) 11216414Sralph return; 11317918Sralph if (!(LogStat & LOG_CONS) && !(mask(pri) & IMPORTANT)) 11416414Sralph return; 11516414Sralph pid = fork(); 11616414Sralph if (pid == -1) 11716414Sralph return; 11816414Sralph if (pid == 0) { 11916414Sralph LogFile = open(ctty, O_RDWR); 12017918Sralph strcat(o, "\r"); 12117918Sralph write(LogFile, outline, c+1); 12216414Sralph close(LogFile); 12316414Sralph exit(0); 12416414Sralph } 12516943Sralph while ((c = wait((int *)0)) > 0 && c != pid) 12616414Sralph ; 12712742Ssam } 12812742Ssam 12912742Ssam /* 13012742Ssam * OPENLOG -- open system log 13112742Ssam */ 13216414Sralph openlog(ident, logstat, logmask) 13312742Ssam char *ident; 13416414Sralph int logstat, logmask; 13512742Ssam { 13612742Ssam 13716943Sralph LogTag = (ident != NULL) ? ident : "syslog"; 13812742Ssam LogStat = logstat; 13917526Sralph if (logmask != 0) 14016414Sralph LogMask = logmask; 14112742Ssam if (LogFile >= 0) 14212742Ssam return; 14316414Sralph SyslogAddr.sa_family = AF_UNIX; 14416414Sralph strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); 14517918Sralph if (!(LogStat & LOG_ODELAY)) { 14617918Sralph LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); 14717918Sralph fcntl(LogFile, F_SETFD, 1); 14817918Sralph } 14912742Ssam } 15012742Ssam 15112742Ssam /* 15212742Ssam * CLOSELOG -- close the system log 15312742Ssam */ 15412742Ssam closelog() 15512742Ssam { 15612742Ssam 15712742Ssam (void) close(LogFile); 15812742Ssam LogFile = -1; 15912742Ssam } 16016414Sralph 16116414Sralph /* 16216414Sralph * SETLOGMASK -- set the log mask level 16316414Sralph */ 16417526Sralph setlogmask(pmask) 16517526Sralph int pmask; 16616414Sralph { 16717526Sralph int omask; 16816414Sralph 16917526Sralph omask = LogMask; 17017526Sralph if (pmask != 0) 17117526Sralph LogMask = pmask; 17217526Sralph return (omask); 17316414Sralph } 174