1 /* 2 * Copyright (c) 1983, 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)syslog.c 5.30 (Berkeley) 09/30/90"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/types.h> 13 #include <sys/socket.h> 14 #include <sys/file.h> 15 #include <sys/syslog.h> 16 #include <sys/uio.h> 17 #include <sys/errno.h> 18 #include <netdb.h> 19 #include <string.h> 20 #include <varargs.h> 21 #include <paths.h> 22 #include <stdio.h> 23 24 static int LogFile = -1; /* fd for log */ 25 static int connected; /* have done connect */ 26 static int LogStat = 0; /* status bits, set by openlog() */ 27 static char *LogTag = "syslog"; /* string to tag the entry with */ 28 static int LogFacility = LOG_USER; /* default facility code */ 29 30 /* 31 * syslog, vsyslog -- 32 * print message on log file; output is intended for syslogd(8). 33 */ 34 syslog(pri, fmt, args) 35 int pri, args; 36 char *fmt; 37 { 38 return(vsyslog(pri, fmt, &args)); 39 } 40 41 vsyslog(pri, fmt, ap) 42 int pri; 43 register char *fmt; 44 va_list ap; 45 { 46 register int cnt; 47 register char *p; 48 time_t now, time(); 49 int fd, saved_errno; 50 char tbuf[2048], fmt_cpy[1024], *stdp, *ctime(); 51 52 /* check for invalid bits or no priority set */ 53 if (!LOG_PRI(pri) || (pri &~ (LOG_PRIMASK|LOG_FACMASK))) { 54 errno = EINVAL; 55 return(-1); 56 } 57 58 saved_errno = errno; 59 60 /* set default facility if none specified */ 61 if ((pri & LOG_FACMASK) == 0) 62 pri |= LogFacility; 63 64 /* build the message */ 65 (void)time(&now); 66 (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4); 67 for (p = tbuf; *p; ++p); 68 if (LogStat & LOG_PERROR) 69 stdp = p; 70 if (LogTag) { 71 (void)strcpy(p, LogTag); 72 for (; *p; ++p); 73 } 74 if (LogStat & LOG_PID) { 75 (void)sprintf(p, "[%d]", getpid()); 76 for (; *p; ++p); 77 } 78 if (LogTag) { 79 *p++ = ':'; 80 *p++ = ' '; 81 } 82 83 /* substitute error message for %m */ 84 { 85 register char ch, *t1, *t2; 86 char *strerror(); 87 88 for (t1 = fmt_cpy; ch = *fmt; ++fmt) 89 if (ch == '%' && fmt[1] == 'm') { 90 ++fmt; 91 for (t2 = strerror(saved_errno); 92 *t1 = *t2++; ++t1); 93 } 94 else 95 *t1++ = ch; 96 *t1 = '\0'; 97 } 98 99 (void)vsprintf(p, fmt_cpy, ap); 100 101 cnt = strlen(tbuf); 102 103 /* output to stderr if requested */ 104 if (LogStat & LOG_PERROR) { 105 struct iovec iov[2]; 106 register struct iovec *v = iov; 107 108 v->iov_base = stdp; 109 v->iov_len = cnt - (stdp - tbuf); 110 ++v; 111 v->iov_base = "\n"; 112 v->iov_len = 1; 113 (void)writev(2, iov, 2); 114 } 115 116 /* get connected, output the message to the local logger */ 117 if ((connected || !openlog(LogTag, LogStat | LOG_NDELAY, 0)) && 118 send(LogFile, tbuf, cnt, 0) >= 0) 119 return(0); 120 121 /* see if should attempt the console */ 122 if (!(LogStat&LOG_CONS)) 123 return(-1); 124 125 /* 126 * Output the message to the console; don't worry about blocking, 127 * if console blocks everything will. Make sure the error reported 128 * is the one from the syslogd failure. 129 */ 130 saved_errno = errno; 131 if ((fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { 132 (void)strcat(tbuf, "\r\n"); 133 cnt += 2; 134 p = index(tbuf, '>') + 1; 135 (void)write(fd, p, cnt - (p - tbuf)); 136 (void)close(fd); 137 } else 138 errno = saved_errno; 139 return(-1); 140 } 141 142 static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 143 144 openlog(ident, logstat, logfac) 145 char *ident; 146 int logstat, logfac; 147 { 148 int saved_errno; 149 150 if (ident != NULL) 151 LogTag = ident; 152 LogStat = logstat; 153 if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) 154 LogFacility = logfac; 155 156 if (LogFile == -1) { 157 SyslogAddr.sa_family = AF_UNIX; 158 (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, 159 sizeof(SyslogAddr.sa_data)); 160 if (LogStat & LOG_NDELAY) { 161 if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) 162 return(-1); 163 (void)fcntl(LogFile, F_SETFD, 1); 164 } 165 } 166 if (LogFile != -1 && !connected) 167 if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { 168 saved_errno = errno; 169 (void)close(LogFile); 170 errno = saved_errno; 171 LogFile = -1; 172 return(-1); 173 } else 174 connected = 1; 175 return(0); 176 } 177 178 closelog() 179 { 180 int rval; 181 182 rval = close(LogFile); 183 LogFile = -1; 184 connected = 0; 185 return(rval); 186 } 187 188 static int LogMask = 0xff; /* mask of priorities to be logged */ 189 190 /* setlogmask -- set the log mask level */ 191 setlogmask(pmask) 192 int pmask; 193 { 194 int omask; 195 196 omask = LogMask; 197 if (pmask != 0) 198 LogMask = pmask; 199 return (omask); 200 } 201