|
|
1.1 root 1: /*
2: * Copyright (c) 1983, 1988 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #if defined(LIBC_SCCS) && !defined(lint)
21: static char sccsid[] = "@(#)syslog.c 5.28 (Berkeley) 6/27/90";
22: #endif /* LIBC_SCCS and not lint */
23:
24: /*
25: * SYSLOG -- print message on log file
26: *
27: * This routine looks a lot like printf, except that it outputs to the
28: * log file instead of the standard output. Also:
29: * adds a timestamp,
30: * prints the module name in front of the message,
31: * has some other formatting types (or will sometime),
32: * adds a newline on the end of the message.
33: *
34: * The output of this routine is intended to be read by syslogd(8).
35: *
36: * Author: Eric Allman
37: * Modified to use UNIX domain IPC by Ralph Campbell
38: */
39:
40: #include <sys/types.h>
41: #include <sys/socket.h>
42: #include <sys/file.h>
43: #include <sys/signal.h>
44: #include <sys/syslog.h>
45: #include <sys/uio.h>
46: #include <sys/wait.h>
47: #include <netdb.h>
48: #include <string.h>
49: #include <varargs.h>
50: #include <paths.h>
51: #include <stdio.h>
52:
53: #define _PATH_LOGNAME "/dev/log"
54:
55: static int LogFile = -1; /* fd for log */
56: static int connected; /* have done connect */
57: static int LogStat = 0; /* status bits, set by openlog() */
58: static char *LogTag = "syslog"; /* string to tag the entry with */
59: static int LogFacility = LOG_USER; /* default facility code */
60:
61: syslog(pri, fmt, args)
62: int pri, args;
63: char *fmt;
64: {
65: vsyslog(pri, fmt, &args);
66: }
67:
68: vsyslog(pri, fmt, ap)
69: int pri;
70: register char *fmt;
71: va_list ap;
72: {
73: extern int errno;
74: register int cnt;
75: register char *p;
76: time_t now, time();
77: int fd, saved_errno;
78: char tbuf[2048], fmt_cpy[1024], *stdp, *ctime();
79:
80: saved_errno = errno;
81:
82: /* see if we should just throw out this message */
83: if (!LOG_MASK(LOG_PRI(pri)) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)))
84: return;
85: if (LogFile < 0 || !connected)
86: openlog(LogTag, LogStat | LOG_NDELAY, 0);
87:
88: /* set default facility if none specified */
89: if ((pri & LOG_FACMASK) == 0)
90: pri |= LogFacility;
91:
92: /* build the message */
93: (void)time(&now);
94: (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4);
95: for (p = tbuf; *p; ++p);
96: if (LogStat & LOG_PERROR)
97: stdp = p;
98: if (LogTag) {
99: (void)strcpy(p, LogTag);
100: for (; *p; ++p);
101: }
102: if (LogStat & LOG_PID) {
103: (void)sprintf(p, "[%d]", getpid());
104: for (; *p; ++p);
105: }
106: if (LogTag) {
107: *p++ = ':';
108: *p++ = ' ';
109: }
110:
111: /* substitute error message for %m */
112: {
113: register char ch, *t1, *t2;
114: char *strerror();
115:
116: for (t1 = fmt_cpy; ch = *fmt; ++fmt)
117: if (ch == '%' && fmt[1] == 'm') {
118: ++fmt;
119: for (t2 = strerror(saved_errno);
120: *t1 = *t2++; ++t1);
121: }
122: else
123: *t1++ = ch;
124: *t1 = '\0';
125: }
126:
127: (void)vsprintf(p, fmt_cpy, ap);
128:
129: cnt = strlen(tbuf);
130:
131: /* output to stderr if requested */
132: if (LogStat & LOG_PERROR) {
133: struct iovec iov[2];
134: register struct iovec *v = iov;
135:
136: v->iov_base = stdp;
137: v->iov_len = cnt - (stdp - tbuf);
138: ++v;
139: v->iov_base = "\n";
140: v->iov_len = 1;
141: (void)writev(2, iov, 2);
142: }
143:
144: /* output the message to the local logger */
145: if (send(LogFile, tbuf, cnt, 0) >= 0 || !(LogStat&LOG_CONS))
146: return;
147:
148: /*
149: * output the message to the console; don't worry about
150: * blocking, if console blocks everything will.
151: */
152: if ((fd = open(_PATH_CONSOLE, O_WRONLY, 0)) < 0)
153: return;
154: (void)strcat(tbuf, "\r\n");
155: cnt += 2;
156: p = index(tbuf, '>') + 1;
157: (void)write(fd, p, cnt - (p - tbuf));
158: (void)close(fd);
159: }
160:
161: static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
162: /*
163: * OPENLOG -- open system log
164: */
165: openlog(ident, logstat, logfac)
166: char *ident;
167: int logstat, logfac;
168: {
169: if (ident != NULL)
170: LogTag = ident;
171: LogStat = logstat;
172: if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
173: LogFacility = logfac;
174: if (LogFile == -1) {
175: SyslogAddr.sa_family = AF_UNIX;
176: strncpy(SyslogAddr.sa_data, _PATH_LOGNAME,
177: sizeof(SyslogAddr.sa_data));
178: if (LogStat & LOG_NDELAY) {
179: LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
180: fcntl(LogFile, F_SETFD, 1);
181: }
182: }
183: if (LogFile != -1 && !connected &&
184: connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) != -1)
185: connected = 1;
186: }
187:
188: /*
189: * CLOSELOG -- close the system log
190: */
191: closelog()
192: {
193: (void) close(LogFile);
194: LogFile = -1;
195: connected = 0;
196: }
197:
198: static int LogMask = 0xff; /* mask of priorities to be logged */
199: /*
200: * SETLOGMASK -- set the log mask level
201: */
202: setlogmask(pmask)
203: int pmask;
204: {
205: int omask;
206:
207: omask = LogMask;
208: if (pmask != 0)
209: LogMask = pmask;
210: return (omask);
211: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.