1 #ifndef lint 2 static char sccsid[] = "@(#)syslog.c 4.7 (Berkeley) 02/20/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 /* mask of priorities to be logged */ 43 static int LogMask = ~(mask(KERN_EMERG)|mask(KERN_ALERT)|mask(KERN_ERR)| 44 mask(KERN_FAIL)|mask(KERN_RECOV)|mask(KERN_INFO)); 45 46 static struct sockaddr SyslogAddr; 47 48 extern int errno, sys_nerr; 49 extern char *sys_errlist[]; 50 51 syslog(pri, fmt, p0, p1, p2, p3, p4) 52 int pri; 53 char *fmt; 54 { 55 char buf[MAXLINE + 1], outline[MAXLINE + 1]; 56 register char *b, *f, *o; 57 register int c; 58 long now; 59 int pid, olderrno = errno; 60 61 /* see if we should just throw out this message */ 62 if (pri <= 0 || pri >= 32 || (mask(pri) & LogMask) == 0) 63 return; 64 if (LogFile < 0) 65 openlog(LogTag, LogStat & ~LOG_ODELAY, 0); 66 o = outline; 67 sprintf(o, "<%d>", pri); 68 o += strlen(o); 69 if (LogTag) { 70 strcpy(o, LogTag); 71 o += strlen(o); 72 } 73 if (LogStat & LOG_PID) { 74 sprintf(o, "[%d]", getpid()); 75 o += strlen(o); 76 } 77 time(&now); 78 sprintf(o, ": %.15s-- ", ctime(&now) + 4); 79 o += strlen(o); 80 81 b = buf; 82 f = fmt; 83 while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) { 84 if (c != '%') { 85 *b++ = c; 86 continue; 87 } 88 if ((c = *f++) != 'm') { 89 *b++ = '%'; 90 *b++ = c; 91 continue; 92 } 93 if ((unsigned)olderrno > sys_nerr) 94 sprintf(b, "error %d", olderrno); 95 else 96 strcpy(b, sys_errlist[olderrno]); 97 b += strlen(b); 98 } 99 *b++ = '\n'; 100 *b = '\0'; 101 sprintf(o, buf, p0, p1, p2, p3, p4); 102 c = strlen(outline); 103 if (c > MAXLINE) 104 c = MAXLINE; 105 if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) 106 return; 107 if (!(LogStat & LOG_CONS) && !(mask(pri) & IMPORTANT)) 108 return; 109 pid = fork(); 110 if (pid == -1) 111 return; 112 if (pid == 0) { 113 LogFile = open(ctty, O_RDWR); 114 strcat(o, "\r"); 115 write(LogFile, outline, c+1); 116 close(LogFile); 117 exit(0); 118 } 119 while ((c = wait((int *)0)) > 0 && c != pid) 120 ; 121 } 122 123 /* 124 * OPENLOG -- open system log 125 */ 126 openlog(ident, logstat, logmask) 127 char *ident; 128 int logstat, logmask; 129 { 130 131 LogTag = (ident != NULL) ? ident : "syslog"; 132 LogStat = logstat; 133 if (logmask != 0) 134 LogMask = logmask; 135 if (LogFile >= 0) 136 return; 137 SyslogAddr.sa_family = AF_UNIX; 138 strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); 139 if (!(LogStat & LOG_ODELAY)) { 140 LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); 141 fcntl(LogFile, F_SETFD, 1); 142 } 143 } 144 145 /* 146 * CLOSELOG -- close the system log 147 */ 148 closelog() 149 { 150 151 (void) close(LogFile); 152 LogFile = -1; 153 } 154 155 /* 156 * SETLOGMASK -- set the log mask level 157 */ 158 setlogmask(pmask) 159 int pmask; 160 { 161 int omask; 162 163 omask = LogMask; 164 if (pmask != 0) 165 LogMask = pmask; 166 return (omask); 167 } 168