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