112742Ssam #ifndef lint 2*18020Sralph static char sccsid[] = "@(#)syslog.c 4.7 (Berkeley) 02/20/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 3117918Sralph #define mask(p) (1 << (p)) 3217918Sralph #define IMPORTANT (mask(KERN_EMERG)|mask(KERN_ALERT)|mask(KERN_ERR)|mask(KERN_FAIL)\ 3317918Sralph |mask(KERN_RECOV)|mask(KERN_INFO)|mask(LOG_EMERG)|mask(LOG_ALERT)\ 3417918Sralph |mask(LOG_CRIT)|mask(LOG_ERR)|mask(LOG_FAIL)) 3517918Sralph 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 */ 42*18020Sralph /* mask of priorities to be logged */ 43*18020Sralph static int LogMask = ~(mask(KERN_EMERG)|mask(KERN_ALERT)|mask(KERN_ERR)| 44*18020Sralph mask(KERN_FAIL)|mask(KERN_RECOV)|mask(KERN_INFO)); 4512742Ssam 4616414Sralph static struct sockaddr SyslogAddr; 4716414Sralph 4812742Ssam extern int errno, sys_nerr; 4912742Ssam extern char *sys_errlist[]; 5012742Ssam 5112742Ssam syslog(pri, fmt, p0, p1, p2, p3, p4) 5212742Ssam int pri; 5312742Ssam char *fmt; 5412742Ssam { 5516414Sralph char buf[MAXLINE + 1], outline[MAXLINE + 1]; 5616414Sralph register char *b, *f, *o; 5716414Sralph register int c; 5816414Sralph long now; 5916943Sralph int pid, olderrno = errno; 6012742Ssam 6112742Ssam /* see if we should just throw out this message */ 6217918Sralph if (pri <= 0 || pri >= 32 || (mask(pri) & LogMask) == 0) 6312742Ssam return; 6416414Sralph if (LogFile < 0) 6517918Sralph openlog(LogTag, LogStat & ~LOG_ODELAY, 0); 6616414Sralph o = outline; 6716943Sralph sprintf(o, "<%d>", pri); 6816943Sralph o += strlen(o); 6916414Sralph if (LogTag) { 7016414Sralph strcpy(o, LogTag); 7116414Sralph o += strlen(o); 7216414Sralph } 7316414Sralph if (LogStat & LOG_PID) { 7416943Sralph sprintf(o, "[%d]", getpid()); 7516414Sralph o += strlen(o); 7616414Sralph } 7716414Sralph time(&now); 7816943Sralph sprintf(o, ": %.15s-- ", ctime(&now) + 4); 7916414Sralph o += strlen(o); 8012742Ssam 8116414Sralph b = buf; 8216414Sralph f = fmt; 8316414Sralph while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) { 8416414Sralph if (c != '%') { 8516414Sralph *b++ = c; 8616414Sralph continue; 8712742Ssam } 8816414Sralph if ((c = *f++) != 'm') { 8916414Sralph *b++ = '%'; 9016414Sralph *b++ = c; 9116414Sralph continue; 9212742Ssam } 9316943Sralph if ((unsigned)olderrno > sys_nerr) 9416943Sralph sprintf(b, "error %d", olderrno); 9512742Ssam else 9616943Sralph strcpy(b, sys_errlist[olderrno]); 9716414Sralph b += strlen(b); 9812742Ssam } 9916414Sralph *b++ = '\n'; 10016414Sralph *b = '\0'; 10116414Sralph sprintf(o, buf, p0, p1, p2, p3, p4); 10216414Sralph c = strlen(outline); 10316414Sralph if (c > MAXLINE) 10416414Sralph c = MAXLINE; 10516414Sralph if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) 10616414Sralph return; 10717918Sralph if (!(LogStat & LOG_CONS) && !(mask(pri) & IMPORTANT)) 10816414Sralph return; 10916414Sralph pid = fork(); 11016414Sralph if (pid == -1) 11116414Sralph return; 11216414Sralph if (pid == 0) { 11316414Sralph LogFile = open(ctty, O_RDWR); 11417918Sralph strcat(o, "\r"); 11517918Sralph write(LogFile, outline, c+1); 11616414Sralph close(LogFile); 11716414Sralph exit(0); 11816414Sralph } 11916943Sralph while ((c = wait((int *)0)) > 0 && c != pid) 12016414Sralph ; 12112742Ssam } 12212742Ssam 12312742Ssam /* 12412742Ssam * OPENLOG -- open system log 12512742Ssam */ 12616414Sralph openlog(ident, logstat, logmask) 12712742Ssam char *ident; 12816414Sralph int logstat, logmask; 12912742Ssam { 13012742Ssam 13116943Sralph LogTag = (ident != NULL) ? ident : "syslog"; 13212742Ssam LogStat = logstat; 13317526Sralph if (logmask != 0) 13416414Sralph LogMask = logmask; 13512742Ssam if (LogFile >= 0) 13612742Ssam return; 13716414Sralph SyslogAddr.sa_family = AF_UNIX; 13816414Sralph strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); 13917918Sralph if (!(LogStat & LOG_ODELAY)) { 14017918Sralph LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); 14117918Sralph fcntl(LogFile, F_SETFD, 1); 14217918Sralph } 14312742Ssam } 14412742Ssam 14512742Ssam /* 14612742Ssam * CLOSELOG -- close the system log 14712742Ssam */ 14812742Ssam closelog() 14912742Ssam { 15012742Ssam 15112742Ssam (void) close(LogFile); 15212742Ssam LogFile = -1; 15312742Ssam } 15416414Sralph 15516414Sralph /* 15616414Sralph * SETLOGMASK -- set the log mask level 15716414Sralph */ 15817526Sralph setlogmask(pmask) 15917526Sralph int pmask; 16016414Sralph { 16117526Sralph int omask; 16216414Sralph 16317526Sralph omask = LogMask; 16417526Sralph if (pmask != 0) 16517526Sralph LogMask = pmask; 16617526Sralph return (omask); 16716414Sralph } 168