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