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: #if defined(LIBC_SCCS) && !defined(lint) 8: static char sccsid[] = "@(#)syslog.c 5.9 (Berkeley) 5/7/86"; 9: #endif LIBC_SCCS and 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 <sys/signal.h> 32: #include <sys/syslog.h> 33: #include <netdb.h> 34: #include <strings.h> 35: 36: #define MAXLINE 1024 /* max message size */ 37: #define NULL 0 /* manifest */ 38: 39: #define PRIMASK(p) (1 << ((p) & LOG_PRIMASK)) 40: #define PRIFAC(p) (((p) & LOG_FACMASK) >> 3) 41: #define IMPORTANT LOG_ERR 42: 43: static char logname[] = "/dev/log"; 44: static char ctty[] = "/dev/console"; 45: 46: static int LogFile = -1; /* fd for log */ 47: static int LogStat = 0; /* status bits, set by openlog() */ 48: static char *LogTag = "syslog"; /* string to tag the entry with */ 49: static int LogMask = 0xff; /* mask of priorities to be logged */ 50: static int LogFacility = LOG_USER; /* default facility code */ 51: 52: static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 53: 54: extern int errno, sys_nerr; 55: extern char *sys_errlist[]; 56: 57: syslog(pri, fmt, p0, p1, p2, p3, p4) 58: int pri; 59: char *fmt; 60: { 61: char buf[MAXLINE + 1], outline[MAXLINE + 1]; 62: register char *b, *f, *o; 63: register int c; 64: long now; 65: int pid, olderrno = errno; 66: 67: /* see if we should just throw out this message */ 68: if (pri <= 0 || PRIFAC(pri) >= LOG_NFACILITIES || (PRIMASK(pri) & LogMask) == 0) 69: return; 70: if (LogFile < 0) 71: openlog(LogTag, LogStat | LOG_NDELAY, 0); 72: 73: /* set default facility if none specified */ 74: if ((pri & LOG_FACMASK) == 0) 75: pri |= LogFacility; 76: 77: /* build the message */ 78: o = outline; 79: sprintf(o, "<%d>", pri); 80: o += strlen(o); 81: time(&now); 82: sprintf(o, "%.15s ", ctime(&now) + 4); 83: o += strlen(o); 84: if (LogTag) { 85: strcpy(o, LogTag); 86: o += strlen(o); 87: } 88: if (LogStat & LOG_PID) { 89: sprintf(o, "[%d]", getpid()); 90: o += strlen(o); 91: } 92: if (LogTag) { 93: strcpy(o, ": "); 94: o += 2; 95: } 96: 97: b = buf; 98: f = fmt; 99: while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) { 100: if (c != '%') { 101: *b++ = c; 102: continue; 103: } 104: if ((c = *f++) != 'm') { 105: *b++ = '%'; 106: *b++ = c; 107: continue; 108: } 109: if ((unsigned)olderrno > sys_nerr) 110: sprintf(b, "error %d", olderrno); 111: else 112: strcpy(b, sys_errlist[olderrno]); 113: b += strlen(b); 114: } 115: *b++ = '\n'; 116: *b = '\0'; 117: sprintf(o, buf, p0, p1, p2, p3, p4); 118: c = strlen(outline); 119: if (c > MAXLINE) 120: c = MAXLINE; 121: 122: /* output the message to the local logger */ 123: if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) 124: return; 125: if (!(LogStat & LOG_CONS)) 126: return; 127: 128: /* output the message to the console */ 129: pid = vfork(); 130: if (pid == -1) 131: return; 132: if (pid == 0) { 133: int fd; 134: 135: signal(SIGALRM, SIG_DFL); 136: sigsetmask(sigblock(0) & ~sigmask(SIGALRM)); 137: alarm(5); 138: fd = open(ctty, O_WRONLY); 139: alarm(0); 140: strcat(o, "\r"); 141: o = index(outline, '>') + 1; 142: write(fd, o, c + 1 - (o - outline)); 143: close(fd); 144: _exit(0); 145: } 146: if (!(LogStat & LOG_NOWAIT)) 147: while ((c = wait((int *)0)) > 0 && c != pid) 148: ; 149: } 150: 151: /* 152: * OPENLOG -- open system log 153: */ 154: 155: openlog(ident, logstat, logfac) 156: char *ident; 157: int logstat, logfac; 158: { 159: if (ident != NULL) 160: LogTag = ident; 161: LogStat = logstat; 162: if (logfac != 0) 163: LogFacility = logfac & LOG_FACMASK; 164: if (LogFile >= 0) 165: return; 166: SyslogAddr.sa_family = AF_UNIX; 167: strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); 168: if (LogStat & LOG_NDELAY) { 169: LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); 170: fcntl(LogFile, F_SETFD, 1); 171: } 172: } 173: 174: /* 175: * CLOSELOG -- close the system log 176: */ 177: 178: closelog() 179: { 180: 181: (void) close(LogFile); 182: LogFile = -1; 183: } 184: 185: /* 186: * SETLOGMASK -- set the log mask level 187: */ 188: setlogmask(pmask) 189: int pmask; 190: { 191: int omask; 192: 193: omask = LogMask; 194: if (pmask != 0) 195: LogMask = pmask; 196: return (omask); 197: }