1 #ifndef lint 2 static char sccsid[] = "@(#)syslog.c 4.6 (Berkeley) 02/04/85"; 3 #endif 4 5 /* 6 * SYSLOG -- print message on log file 7 * 8 * This routine looks a lot like printf, except that it 9 * outputs to the log file instead of the standard output. 10 * Also: 11 * adds a timestamp, 12 * prints the module name in front of the message, 13 * has some other formatting types (or will sometime), 14 * adds a newline on the end of the message. 15 * 16 * The output of this routine is intended to be read by /etc/syslogd. 17 * 18 * Author: Eric Allman 19 * Modified to use UNIX domain IPC by Ralph Campbell 20 */ 21 22 #include <sys/types.h> 23 #include <sys/socket.h> 24 #include <sys/file.h> 25 #include <syslog.h> 26 #include <netdb.h> 27 28 #define MAXLINE 1024 /* max message size */ 29 #define NULL 0 /* manifest */ 30 31 #define mask(p) (1 << (p)) 32 #define IMPORTANT (mask(KERN_EMERG)|mask(KERN_ALERT)|mask(KERN_ERR)|mask(KERN_FAIL)\ 33 |mask(KERN_RECOV)|mask(KERN_INFO)|mask(LOG_EMERG)|mask(LOG_ALERT)\ 34 |mask(LOG_CRIT)|mask(LOG_ERR)|mask(LOG_FAIL)) 35 36 static char logname[] = "/dev/log"; 37 static char ctty[] = "/dev/console"; 38 39 static int LogFile = -1; /* fd for log */ 40 static int LogStat = 0; /* status bits, set by openlog() */ 41 static char *LogTag = NULL; /* string to tag the entry with */ 42 static int LogMask = 0xffffffff; /* mask of priorities to be logged */ 43 44 static struct sockaddr SyslogAddr; 45 46 extern int errno, sys_nerr; 47 extern char *sys_errlist[]; 48 49 syslog(pri, fmt, p0, p1, p2, p3, p4) 50 int pri; 51 char *fmt; 52 { 53 char buf[MAXLINE + 1], outline[MAXLINE + 1]; 54 register char *b, *f, *o; 55 register int c; 56 long now; 57 int pid, olderrno = errno; 58 59 /* see if we should just throw out this message */ 60 if (pri <= 0 || pri >= 32 || (mask(pri) & LogMask) == 0) 61 return; 62 if (LogFile < 0) 63 openlog(LogTag, LogStat & ~LOG_ODELAY, 0); 64 o = outline; 65 sprintf(o, "<%d>", pri); 66 o += strlen(o); 67 if (LogTag) { 68 strcpy(o, LogTag); 69 o += strlen(o); 70 } 71 if (LogStat & LOG_PID) { 72 sprintf(o, "[%d]", getpid()); 73 o += strlen(o); 74 } 75 time(&now); 76 sprintf(o, ": %.15s-- ", ctime(&now) + 4); 77 o += strlen(o); 78 79 b = buf; 80 f = fmt; 81 while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) { 82 if (c != '%') { 83 *b++ = c; 84 continue; 85 } 86 if ((c = *f++) != 'm') { 87 *b++ = '%'; 88 *b++ = c; 89 continue; 90 } 91 if ((unsigned)olderrno > sys_nerr) 92 sprintf(b, "error %d", olderrno); 93 else 94 strcpy(b, sys_errlist[olderrno]); 95 b += strlen(b); 96 } 97 *b++ = '\n'; 98 *b = '\0'; 99 sprintf(o, buf, p0, p1, p2, p3, p4); 100 c = strlen(outline); 101 if (c > MAXLINE) 102 c = MAXLINE; 103 if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) 104 return; 105 if (!(LogStat & LOG_CONS) && !(mask(pri) & IMPORTANT)) 106 return; 107 pid = fork(); 108 if (pid == -1) 109 return; 110 if (pid == 0) { 111 LogFile = open(ctty, O_RDWR); 112 strcat(o, "\r"); 113 write(LogFile, outline, c+1); 114 close(LogFile); 115 exit(0); 116 } 117 while ((c = wait((int *)0)) > 0 && c != pid) 118 ; 119 } 120 121 /* 122 * OPENLOG -- open system log 123 */ 124 openlog(ident, logstat, logmask) 125 char *ident; 126 int logstat, logmask; 127 { 128 129 LogTag = (ident != NULL) ? ident : "syslog"; 130 LogStat = logstat; 131 if (logmask != 0) 132 LogMask = logmask; 133 if (LogFile >= 0) 134 return; 135 SyslogAddr.sa_family = AF_UNIX; 136 strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); 137 if (!(LogStat & LOG_ODELAY)) { 138 LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); 139 fcntl(LogFile, F_SETFD, 1); 140 } 141 } 142 143 /* 144 * CLOSELOG -- close the system log 145 */ 146 closelog() 147 { 148 149 (void) close(LogFile); 150 LogFile = -1; 151 } 152 153 /* 154 * SETLOGMASK -- set the log mask level 155 */ 156 setlogmask(pmask) 157 int pmask; 158 { 159 int omask; 160 161 omask = LogMask; 162 if (pmask != 0) 163 LogMask = pmask; 164 return (omask); 165 } 166