|
|
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
6: * provided that the above copyright notice and this paragraph are
7: * duplicated in all such forms and that any documentation,
8: * advertising materials, and other materials related to such
9: * distribution and use acknowledge that the software was developed
10: * by the University of California, Berkeley. The name of the
11: * University may not be used to endorse or promote products derived
12: * from this software without specific prior written permission.
13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16: */
17:
18: #if defined(LIBC_SCCS) && !defined(lint)
19: static char sccsid[] = "@(#)syslog.c 5.16 (Berkeley) 6/27/88";
20: #endif /* LIBC_SCCS and not lint */
21:
22: /*
23: * SYSLOG -- print message on log file
24: *
25: * This routine looks a lot like printf, except that it
26: * outputs to the log file instead of the standard output.
27: * Also:
28: * adds a timestamp,
29: * prints the module name in front of the message,
30: * has some other formatting types (or will sometime),
31: * adds a newline on the end of the message.
32: *
33: * The output of this routine is intended to be read by /etc/syslogd.
34: *
35: * Author: Eric Allman
36: * Modified to use UNIX domain IPC by Ralph Campbell
37: */
38:
39: #include <sys/types.h>
40: #include <sys/socket.h>
41: #include <sys/file.h>
42: #include <sys/signal.h>
43: #include <sys/syslog.h>
44: #include <netdb.h>
45: #include <strings.h>
46:
47: #define MAXLINE 1024 /* max message size */
48: #define NULL 0 /* manifest */
49:
50: #define IMPORTANT LOG_ERR
51:
52: static char logname[] = "/dev/log";
53: static char ctty[] = "/dev/console";
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 LogMask = 0xff; /* mask of priorities to be logged */
60: static int LogFacility = LOG_USER; /* default facility code */
61:
62: static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
63:
64: extern int errno, sys_nerr;
65: extern char *sys_errlist[];
66:
67: syslog(pri, fmt, p0, p1, p2, p3, p4)
68: int pri;
69: char *fmt;
70: {
71: char buf[MAXLINE + 1], outline[MAXLINE + 1];
72: register char *b, *f, *o;
73: register int c;
74: long now;
75: int pid, olderrno = errno;
76:
77: /* see if we should just throw out this message */
78: if ((unsigned) LOG_FAC(pri) >= LOG_NFACILITIES ||
79: LOG_MASK(LOG_PRI(pri)) == 0 ||
80: (pri &~ (LOG_PRIMASK|LOG_FACMASK)) != 0)
81: return;
82: if (LogFile < 0 || !connected)
83: openlog(LogTag, LogStat | LOG_NDELAY, 0);
84:
85: /* set default facility if none specified */
86: if ((pri & LOG_FACMASK) == 0)
87: pri |= LogFacility;
88:
89: /* build the message */
90: o = outline;
91: (void)sprintf(o, "<%d>", pri);
92: o += strlen(o);
93: time(&now);
94: (void)sprintf(o, "%.15s ", ctime(&now) + 4);
95: o += strlen(o);
96: if (LogTag) {
97: strcpy(o, LogTag);
98: o += strlen(o);
99: }
100: if (LogStat & LOG_PID) {
101: (void)sprintf(o, "[%d]", getpid());
102: o += strlen(o);
103: }
104: if (LogTag) {
105: strcpy(o, ": ");
106: o += 2;
107: }
108:
109: b = buf;
110: f = fmt;
111: while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
112: if (c != '%') {
113: *b++ = c;
114: continue;
115: }
116: if ((c = *f++) != 'm') {
117: *b++ = '%';
118: *b++ = c;
119: continue;
120: }
121: if ((unsigned)olderrno > sys_nerr)
122: (void)sprintf(b, "error %d", olderrno);
123: else
124: strcpy(b, sys_errlist[olderrno]);
125: b += strlen(b);
126: }
127: *b++ = '\n';
128: *b = '\0';
129: (void)sprintf(o, buf, p0, p1, p2, p3, p4);
130: c = strlen(outline);
131: if (c > MAXLINE)
132: c = MAXLINE;
133:
134: /* output the message to the local logger */
135: if (send(LogFile, outline, c, 0) >= 0)
136: return;
137: if (!(LogStat & LOG_CONS))
138: return;
139:
140: /* output the message to the console */
141: pid = vfork();
142: if (pid == -1)
143: return;
144: if (pid == 0) {
145: int fd;
146:
147: signal(SIGALRM, SIG_DFL);
148: sigsetmask(sigblock(0L) & ~sigmask(SIGALRM));
149: alarm(5);
150: fd = open(ctty, O_WRONLY);
151: alarm(0);
152: strcat(o, "\r");
153: o = index(outline, '>') + 1;
154: write(fd, o, c + 1 - (o - outline));
155: close(fd);
156: _exit(0);
157: }
158: if (!(LogStat & LOG_NOWAIT))
159: while ((c = wait((int *)0)) > 0 && c != pid)
160: ;
161: }
162:
163: /*
164: * OPENLOG -- open system log
165: */
166:
167: openlog(ident, logstat, logfac)
168: char *ident;
169: int logstat, logfac;
170: {
171: if (ident != NULL)
172: LogTag = ident;
173: LogStat = logstat;
174: if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
175: LogFacility = logfac;
176: if (LogFile == -1) {
177: SyslogAddr.sa_family = AF_UNIX;
178: strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
179: if (LogStat & LOG_NDELAY) {
180: LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
181: fcntl(LogFile, F_SETFD, 1);
182: }
183: }
184: if (LogFile != -1 && !connected &&
185: connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) != -1)
186: connected = 1;
187: }
188:
189: /*
190: * CLOSELOG -- close the system log
191: */
192:
193: closelog()
194: {
195:
196: (void) close(LogFile);
197: LogFile = -1;
198: connected = 0;
199: }
200:
201: /*
202: * SETLOGMASK -- set the log mask level
203: */
204: setlogmask(pmask)
205: int pmask;
206: {
207: int omask;
208:
209: omask = LogMask;
210: if (pmask != 0)
211: LogMask = pmask;
212: return (omask);
213: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.