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*24846Seric static char sccsid[] = "@(#)syslog.c 5.2 (Berkeley) 09/17/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> 3112742Ssam #include <syslog.h> 3212742Ssam #include <netdb.h> 3312742Ssam 3416414Sralph #define MAXLINE 1024 /* max message size */ 3516414Sralph #define NULL 0 /* manifest */ 3612742Ssam 37*24846Seric #define PRIMASK(p) (1 << ((p) & LOG_PRIMASK)) 38*24846Seric #define PRIFAC(p) (((p) & LOG_FACMASK) >> 3) 39*24846Seric #define IMPORTANT LOG_ERR 4017918Sralph 4116414Sralph static char logname[] = "/dev/log"; 4216414Sralph static char ctty[] = "/dev/console"; 4312742Ssam 4416414Sralph static int LogFile = -1; /* fd for log */ 4516414Sralph static int LogStat = 0; /* status bits, set by openlog() */ 46*24846Seric static char *LogTag = "syslog"; /* string to tag the entry with */ 47*24846Seric static int LogMask = 0xff; /* mask of priorities to be logged */ 48*24846Seric static int LogFacility = LOG_USER; /* default facility code */ 4912742Ssam 50*24846Seric static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 5116414Sralph 5212742Ssam extern int errno, sys_nerr; 5312742Ssam extern char *sys_errlist[]; 5412742Ssam 5512742Ssam syslog(pri, fmt, p0, p1, p2, p3, p4) 5612742Ssam int pri; 5712742Ssam char *fmt; 5812742Ssam { 5916414Sralph char buf[MAXLINE + 1], outline[MAXLINE + 1]; 6016414Sralph register char *b, *f, *o; 6116414Sralph register int c; 6216414Sralph long now; 6316943Sralph int pid, olderrno = errno; 6412742Ssam 6512742Ssam /* see if we should just throw out this message */ 66*24846Seric if (pri <= 0 || PRIFAC(pri) >= LOG_NFACILITIES || (PRIMASK(pri) & LogMask) == 0) 6712742Ssam return; 6816414Sralph if (LogFile < 0) 6917918Sralph openlog(LogTag, LogStat & ~LOG_ODELAY, 0); 70*24846Seric 71*24846Seric /* set default facility if none specified */ 72*24846Seric if ((pri & LOG_FACMASK) == 0) 73*24846Seric pri |= LogFacility; 74*24846Seric 75*24846Seric /* build the message */ 7616414Sralph o = outline; 7716943Sralph sprintf(o, "<%d>", pri); 7816943Sralph o += strlen(o); 79*24846Seric time(&now); 80*24846Seric sprintf(o, "%.15s ", ctime(&now) + 4); 81*24846Seric o += strlen(o); 8216414Sralph if (LogTag) { 8316414Sralph strcpy(o, LogTag); 8416414Sralph o += strlen(o); 8516414Sralph } 8616414Sralph if (LogStat & LOG_PID) { 8716943Sralph sprintf(o, "[%d]", getpid()); 8816414Sralph o += strlen(o); 8916414Sralph } 90*24846Seric if (LogTag) { 91*24846Seric strcpy(o, ": "); 92*24846Seric o += 2; 93*24846Seric } 9412742Ssam 9516414Sralph b = buf; 9616414Sralph f = fmt; 9716414Sralph while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) { 9816414Sralph if (c != '%') { 9916414Sralph *b++ = c; 10016414Sralph continue; 10112742Ssam } 10216414Sralph if ((c = *f++) != 'm') { 10316414Sralph *b++ = '%'; 10416414Sralph *b++ = c; 10516414Sralph continue; 10612742Ssam } 10716943Sralph if ((unsigned)olderrno > sys_nerr) 10816943Sralph sprintf(b, "error %d", olderrno); 10912742Ssam else 11016943Sralph strcpy(b, sys_errlist[olderrno]); 11116414Sralph b += strlen(b); 11212742Ssam } 11316414Sralph *b++ = '\n'; 11416414Sralph *b = '\0'; 11516414Sralph sprintf(o, buf, p0, p1, p2, p3, p4); 11616414Sralph c = strlen(outline); 11716414Sralph if (c > MAXLINE) 11816414Sralph c = MAXLINE; 119*24846Seric 120*24846Seric /* output the message to the local logger */ 12116414Sralph if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) 12216414Sralph return; 123*24846Seric if (!(LogStat & LOG_CONS) && (pri & LOG_PRIMASK) <= LOG_ERR) 12416414Sralph return; 125*24846Seric 126*24846Seric /* output the message to the console */ 12716414Sralph pid = fork(); 12816414Sralph if (pid == -1) 12916414Sralph return; 13016414Sralph if (pid == 0) { 131*24846Seric LogFile = open(ctty, O_WRONLY); 13217918Sralph strcat(o, "\r"); 13317918Sralph write(LogFile, outline, c+1); 13416414Sralph close(LogFile); 13516414Sralph exit(0); 13616414Sralph } 13716943Sralph while ((c = wait((int *)0)) > 0 && c != pid) 13816414Sralph ; 13912742Ssam } 14012742Ssam 14112742Ssam /* 14212742Ssam * OPENLOG -- open system log 14312742Ssam */ 144*24846Seric 145*24846Seric openlog(ident, logstat, logfac) 14612742Ssam char *ident; 147*24846Seric int logstat, logfac; 14812742Ssam { 149*24846Seric if (ident != NULL) 150*24846Seric LogTag = ident; 15112742Ssam LogStat = logstat; 152*24846Seric if (logfac != 0) 153*24846Seric LogFacility = logfac & LOG_FACMASK; 15412742Ssam if (LogFile >= 0) 15512742Ssam return; 15616414Sralph SyslogAddr.sa_family = AF_UNIX; 15716414Sralph strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); 15817918Sralph if (!(LogStat & LOG_ODELAY)) { 15917918Sralph LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); 16017918Sralph fcntl(LogFile, F_SETFD, 1); 16117918Sralph } 16212742Ssam } 16312742Ssam 16412742Ssam /* 16512742Ssam * CLOSELOG -- close the system log 16612742Ssam */ 16712742Ssam closelog() 16812742Ssam { 16912742Ssam 17012742Ssam (void) close(LogFile); 17112742Ssam LogFile = -1; 17212742Ssam } 17316414Sralph 17416414Sralph /* 17516414Sralph * SETLOGMASK -- set the log mask level 17616414Sralph */ 17717526Sralph setlogmask(pmask) 17817526Sralph int pmask; 17916414Sralph { 18017526Sralph int omask; 18116414Sralph 18217526Sralph omask = LogMask; 18317526Sralph if (pmask != 0) 18417526Sralph LogMask = pmask; 18517526Sralph return (omask); 18616414Sralph } 187