112742Ssam #ifndef lint 2*17918Sralph static char sccsid[] = "@(#)syslog.c 4.6 (Berkeley) 02/04/85"; 312742Ssam #endif 412742Ssam 512742Ssam /* 612742Ssam * SYSLOG -- print message on log file 712742Ssam * 812742Ssam * This routine looks a lot like printf, except that it 912742Ssam * outputs to the log file instead of the standard output. 1016414Sralph * Also: 1116414Sralph * adds a timestamp, 1216414Sralph * prints the module name in front of the message, 1316414Sralph * has some other formatting types (or will sometime), 1416414Sralph * adds a newline on the end of the message. 1512742Ssam * 1616414Sralph * The output of this routine is intended to be read by /etc/syslogd. 1716943Sralph * 1816943Sralph * Author: Eric Allman 1916943Sralph * Modified to use UNIX domain IPC by Ralph Campbell 2012742Ssam */ 2116414Sralph 2212742Ssam #include <sys/types.h> 2312742Ssam #include <sys/socket.h> 2416414Sralph #include <sys/file.h> 2512742Ssam #include <syslog.h> 2612742Ssam #include <netdb.h> 2712742Ssam 2816414Sralph #define MAXLINE 1024 /* max message size */ 2916414Sralph #define NULL 0 /* manifest */ 3012742Ssam 31*17918Sralph #define mask(p) (1 << (p)) 32*17918Sralph #define IMPORTANT (mask(KERN_EMERG)|mask(KERN_ALERT)|mask(KERN_ERR)|mask(KERN_FAIL)\ 33*17918Sralph |mask(KERN_RECOV)|mask(KERN_INFO)|mask(LOG_EMERG)|mask(LOG_ALERT)\ 34*17918Sralph |mask(LOG_CRIT)|mask(LOG_ERR)|mask(LOG_FAIL)) 35*17918Sralph 3616414Sralph static char logname[] = "/dev/log"; 3716414Sralph static char ctty[] = "/dev/console"; 3812742Ssam 3916414Sralph static int LogFile = -1; /* fd for log */ 4016414Sralph static int LogStat = 0; /* status bits, set by openlog() */ 4116414Sralph static char *LogTag = NULL; /* string to tag the entry with */ 4217526Sralph static int LogMask = 0xffffffff; /* mask of priorities to be logged */ 4312742Ssam 4416414Sralph static struct sockaddr SyslogAddr; 4516414Sralph 4612742Ssam extern int errno, sys_nerr; 4712742Ssam extern char *sys_errlist[]; 4812742Ssam 4912742Ssam syslog(pri, fmt, p0, p1, p2, p3, p4) 5012742Ssam int pri; 5112742Ssam char *fmt; 5212742Ssam { 5316414Sralph char buf[MAXLINE + 1], outline[MAXLINE + 1]; 5416414Sralph register char *b, *f, *o; 5516414Sralph register int c; 5616414Sralph long now; 5716943Sralph int pid, olderrno = errno; 5812742Ssam 5912742Ssam /* see if we should just throw out this message */ 60*17918Sralph if (pri <= 0 || pri >= 32 || (mask(pri) & LogMask) == 0) 6112742Ssam return; 6216414Sralph if (LogFile < 0) 63*17918Sralph openlog(LogTag, LogStat & ~LOG_ODELAY, 0); 6416414Sralph o = outline; 6516943Sralph sprintf(o, "<%d>", pri); 6616943Sralph o += strlen(o); 6716414Sralph if (LogTag) { 6816414Sralph strcpy(o, LogTag); 6916414Sralph o += strlen(o); 7016414Sralph } 7116414Sralph if (LogStat & LOG_PID) { 7216943Sralph sprintf(o, "[%d]", getpid()); 7316414Sralph o += strlen(o); 7416414Sralph } 7516414Sralph time(&now); 7616943Sralph sprintf(o, ": %.15s-- ", ctime(&now) + 4); 7716414Sralph o += strlen(o); 7812742Ssam 7916414Sralph b = buf; 8016414Sralph f = fmt; 8116414Sralph while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) { 8216414Sralph if (c != '%') { 8316414Sralph *b++ = c; 8416414Sralph continue; 8512742Ssam } 8616414Sralph if ((c = *f++) != 'm') { 8716414Sralph *b++ = '%'; 8816414Sralph *b++ = c; 8916414Sralph continue; 9012742Ssam } 9116943Sralph if ((unsigned)olderrno > sys_nerr) 9216943Sralph sprintf(b, "error %d", olderrno); 9312742Ssam else 9416943Sralph strcpy(b, sys_errlist[olderrno]); 9516414Sralph b += strlen(b); 9612742Ssam } 9716414Sralph *b++ = '\n'; 9816414Sralph *b = '\0'; 9916414Sralph sprintf(o, buf, p0, p1, p2, p3, p4); 10016414Sralph c = strlen(outline); 10116414Sralph if (c > MAXLINE) 10216414Sralph c = MAXLINE; 10316414Sralph if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) 10416414Sralph return; 105*17918Sralph if (!(LogStat & LOG_CONS) && !(mask(pri) & IMPORTANT)) 10616414Sralph return; 10716414Sralph pid = fork(); 10816414Sralph if (pid == -1) 10916414Sralph return; 11016414Sralph if (pid == 0) { 11116414Sralph LogFile = open(ctty, O_RDWR); 112*17918Sralph strcat(o, "\r"); 113*17918Sralph write(LogFile, outline, c+1); 11416414Sralph close(LogFile); 11516414Sralph exit(0); 11616414Sralph } 11716943Sralph while ((c = wait((int *)0)) > 0 && c != pid) 11816414Sralph ; 11912742Ssam } 12012742Ssam 12112742Ssam /* 12212742Ssam * OPENLOG -- open system log 12312742Ssam */ 12416414Sralph openlog(ident, logstat, logmask) 12512742Ssam char *ident; 12616414Sralph int logstat, logmask; 12712742Ssam { 12812742Ssam 12916943Sralph LogTag = (ident != NULL) ? ident : "syslog"; 13012742Ssam LogStat = logstat; 13117526Sralph if (logmask != 0) 13216414Sralph LogMask = logmask; 13312742Ssam if (LogFile >= 0) 13412742Ssam return; 13516414Sralph SyslogAddr.sa_family = AF_UNIX; 13616414Sralph strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); 137*17918Sralph if (!(LogStat & LOG_ODELAY)) { 138*17918Sralph LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); 139*17918Sralph fcntl(LogFile, F_SETFD, 1); 140*17918Sralph } 14112742Ssam } 14212742Ssam 14312742Ssam /* 14412742Ssam * CLOSELOG -- close the system log 14512742Ssam */ 14612742Ssam closelog() 14712742Ssam { 14812742Ssam 14912742Ssam (void) close(LogFile); 15012742Ssam LogFile = -1; 15112742Ssam } 15216414Sralph 15316414Sralph /* 15416414Sralph * SETLOGMASK -- set the log mask level 15516414Sralph */ 15617526Sralph setlogmask(pmask) 15717526Sralph int pmask; 15816414Sralph { 15917526Sralph int omask; 16016414Sralph 16117526Sralph omask = LogMask; 16217526Sralph if (pmask != 0) 16317526Sralph LogMask = pmask; 16417526Sralph return (omask); 16516414Sralph } 166