1 #ifndef lint 2 static char SccsId[] = "@(#)syslog.c 4.1 (Berkeley) 05/27/83"; 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, it prints the module name in front of lines, 11 * and has some other formatting types (or will sometime). 12 * Also, it adds a newline on the end of messages. 13 * 14 * The output of this routine is intended to be read by 15 * /etc/syslog, which will add timestamps. 16 */ 17 #include <sys/types.h> 18 #include <sys/socket.h> 19 #include <netinet/in.h> 20 21 #include <syslog.h> 22 #include <netdb.h> 23 24 #define MAXLINE 1024 /* max message size */ 25 #define BUFSLOP 20 /* space to allow for "extra stuff" */ 26 #define NULL 0 /* manifest */ 27 28 int LogFile = -1; /* fd for log */ 29 int LogStat = 0; /* status bits, set by initlog */ 30 char *LogTag = NULL; /* string to tag the entry with */ 31 int LogMask = LOG_DEBUG; /* lowest priority to be logged */ 32 33 struct sockaddr_in SyslogAddr; 34 static char *SyslogHost = LOG_HOST; 35 36 extern int errno, sys_nerr; 37 extern char *sys_errlist[]; 38 39 syslog(pri, fmt, p0, p1, p2, p3, p4) 40 int pri; 41 char *fmt; 42 { 43 char buf[MAXLINE+BUFSLOP], outline[MAXLINE + 1]; 44 register char *b, *f; 45 46 if (LogFile < 0) 47 openlog(0, 0); 48 /* see if we should just throw out this message */ 49 if (pri > LogMask) 50 return; 51 for (b = buf, f = fmt; f && *f; b = buf) { 52 register char c; 53 54 if (pri > 0 && (LogStat & LOG_COOLIT) == 0) { 55 sprintf(b, "<%d>", pri); 56 b += strlen(b); 57 } 58 if (LogStat & LOG_PID) { 59 sprintf(b, "%d ", getpid()); 60 b += strlen(b); 61 } 62 if (LogTag) { 63 sprintf(b, "%s: ", LogTag); 64 b += strlen(b); 65 } 66 while ((c = *f++) != '\0' && c != '\n' && b < buf + MAXLINE) { 67 if (c != '%') { 68 *b++ = c; 69 continue; 70 } 71 c = *f++; 72 if (c != 'm') { 73 *b++ = '%', *b++ = c, *b++ = '\0'; 74 continue; 75 } 76 if ((unsigned)errno > sys_nerr) 77 sprintf(b, "error %d", errno); 78 else 79 strcat(b, sys_errlist[errno]); 80 b += strlen(b); 81 } 82 if (c == '\0') 83 f--; 84 *b++ = '\n', *b = '\0'; 85 sprintf(outline, buf, p0, p1, p2, p3, p4); 86 errno = 0; 87 if (LogStat & LOG_DGRAM) 88 (void) sendto(LogFile, outline, strlen(outline), 0, 89 &SyslogAddr, sizeof SyslogAddr); 90 else 91 (void) write(LogFile, outline, strlen(outline)); 92 if (errno) 93 perror("syslog: sendto"); 94 } 95 } 96 97 /* 98 * OPENLOG -- open system log 99 */ 100 openlog(ident, logstat) 101 char *ident; 102 int logstat; 103 { 104 struct servent *sp; 105 struct hostent *hp; 106 107 LogTag = ident; 108 LogStat = logstat; 109 if (LogFile >= 0) 110 return; 111 sp = getservbyname("syslog", "udp"); 112 hp = gethostbyname(SyslogHost); 113 if (sp == NULL || hp == NULL) 114 goto bad; 115 LogFile = socket(AF_INET, SOCK_DGRAM, 0); 116 if (LogFile < 0) { 117 perror("syslog: socket"); 118 goto bad; 119 } 120 bzero(&SyslogAddr, sizeof SyslogAddr); 121 SyslogAddr.sin_family = hp->h_addrtype; 122 bcopy(hp->h_addr, (char *)&SyslogAddr.sin_addr, hp->h_length); 123 SyslogAddr.sin_port = sp->s_port; 124 LogStat |= LOG_DGRAM; 125 return; 126 bad: 127 LogStat |= LOG_COOLIT; 128 LogStat &= ~LOG_DGRAM; 129 LogMask = LOG_CRIT; 130 LogFile = open("/dev/console", 1); 131 if (LogFile < 0) { 132 perror("syslog: /dev/console"); 133 LogFile = 2; 134 } 135 } 136 137 /* 138 * CLOSELOG -- close the system log 139 */ 140 closelog() 141 { 142 143 (void) close(LogFile); 144 LogFile = -1; 145 } 146