112742Ssam #ifndef lint 2*16943Sralph static char sccsid[] = "@(#)syslog.c 4.4 (Berkeley) 08/16/84"; 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. 17*16943Sralph * 18*16943Sralph * Author: Eric Allman 19*16943Sralph * 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 3116414Sralph static char logname[] = "/dev/log"; 3216414Sralph static char ctty[] = "/dev/console"; 3312742Ssam 3416414Sralph static int LogFile = -1; /* fd for log */ 3516414Sralph static int LogStat = 0; /* status bits, set by openlog() */ 3616414Sralph static char *LogTag = NULL; /* string to tag the entry with */ 3716414Sralph static int LogMask = LOG_DEBUG; /* lowest priority to be logged */ 3812742Ssam 3916414Sralph static struct sockaddr SyslogAddr; 4016414Sralph 4112742Ssam extern int errno, sys_nerr; 4212742Ssam extern char *sys_errlist[]; 4312742Ssam 4412742Ssam syslog(pri, fmt, p0, p1, p2, p3, p4) 4512742Ssam int pri; 4612742Ssam char *fmt; 4712742Ssam { 4816414Sralph char buf[MAXLINE + 1], outline[MAXLINE + 1]; 4916414Sralph register char *b, *f, *o; 5016414Sralph register int c; 5116414Sralph long now; 52*16943Sralph int pid, olderrno = errno; 5312742Ssam 5412742Ssam /* see if we should just throw out this message */ 55*16943Sralph if (pri < LOG_ALERT || pri > LogMask) 5612742Ssam return; 5716414Sralph if (LogFile < 0) 5816414Sralph openlog(NULL, 0, 0); 5916414Sralph o = outline; 60*16943Sralph sprintf(o, "<%d>", pri); 61*16943Sralph o += strlen(o); 6216414Sralph if (LogTag) { 6316414Sralph strcpy(o, LogTag); 6416414Sralph o += strlen(o); 6516414Sralph } 6616414Sralph if (LogStat & LOG_PID) { 67*16943Sralph sprintf(o, "[%d]", getpid()); 6816414Sralph o += strlen(o); 6916414Sralph } 7016414Sralph time(&now); 71*16943Sralph sprintf(o, ": %.15s-- ", ctime(&now) + 4); 7216414Sralph o += strlen(o); 7312742Ssam 7416414Sralph b = buf; 7516414Sralph f = fmt; 7616414Sralph while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) { 7716414Sralph if (c != '%') { 7816414Sralph *b++ = c; 7916414Sralph continue; 8012742Ssam } 8116414Sralph if ((c = *f++) != 'm') { 8216414Sralph *b++ = '%'; 8316414Sralph *b++ = c; 8416414Sralph continue; 8512742Ssam } 86*16943Sralph if ((unsigned)olderrno > sys_nerr) 87*16943Sralph sprintf(b, "error %d", olderrno); 8812742Ssam else 89*16943Sralph strcpy(b, sys_errlist[olderrno]); 9016414Sralph b += strlen(b); 9112742Ssam } 9216414Sralph *b++ = '\n'; 9316414Sralph *b = '\0'; 9416414Sralph sprintf(o, buf, p0, p1, p2, p3, p4); 9516414Sralph c = strlen(outline); 9616414Sralph if (c > MAXLINE) 9716414Sralph c = MAXLINE; 9816414Sralph if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) 9916414Sralph return; 10016414Sralph if (pri > LOG_CRIT) 10116414Sralph return; 10216414Sralph pid = fork(); 10316414Sralph if (pid == -1) 10416414Sralph return; 10516414Sralph if (pid == 0) { 10616414Sralph LogFile = open(ctty, O_RDWR); 10716414Sralph write(LogFile, outline, c); 10816414Sralph close(LogFile); 10916414Sralph exit(0); 11016414Sralph } 111*16943Sralph while ((c = wait((int *)0)) > 0 && c != pid) 11216414Sralph ; 11312742Ssam } 11412742Ssam 11512742Ssam /* 11612742Ssam * OPENLOG -- open system log 11712742Ssam */ 11816414Sralph openlog(ident, logstat, logmask) 11912742Ssam char *ident; 12016414Sralph int logstat, logmask; 12112742Ssam { 12212742Ssam 123*16943Sralph LogTag = (ident != NULL) ? ident : "syslog"; 12412742Ssam LogStat = logstat; 12516414Sralph if (logmask > 0 && logmask <= LOG_DEBUG) 12616414Sralph LogMask = logmask; 12712742Ssam if (LogFile >= 0) 12812742Ssam return; 12916414Sralph SyslogAddr.sa_family = AF_UNIX; 13016414Sralph strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); 13116414Sralph LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); 13216440Sralph fcntl(LogFile, F_SETFD, 1); 13312742Ssam } 13412742Ssam 13512742Ssam /* 13612742Ssam * CLOSELOG -- close the system log 13712742Ssam */ 13812742Ssam closelog() 13912742Ssam { 14012742Ssam 14112742Ssam (void) close(LogFile); 14212742Ssam LogFile = -1; 14312742Ssam } 14416414Sralph 14516414Sralph /* 14616414Sralph * SETLOGMASK -- set the log mask level 14716414Sralph */ 14816414Sralph setlogmask(pri) 14916414Sralph int pri; 15016414Sralph { 15116414Sralph int opri; 15216414Sralph 15316414Sralph opri = LogMask; 154*16943Sralph if (pri > 0 && pri <= LOG_DEBUG) 155*16943Sralph LogMask = pri; 15616414Sralph return (opri); 15716414Sralph } 158