|
|
1.1 root 1: # include <syslog.h>
2: # include <sys/types.h>
3: # include <sys/stat.h>
4: # include <sgtty.h>
5: # ifdef LOG_IPC
6: # include <sys/socket.h>
7: #ifdef LOG_OLDIPC
8: # include <net/in.h>
9: #else LOG_OLDIPC
10: # include <netinet/in.h>
11: # include <netdb.h>
12: #endif LOG_OLDIPC
13: # endif LOG_IPC
14:
15: static char SccsId[] = "@(#)syslog.c 4.1 7/25/83";
16:
17:
18: /*
19: ** SYSLOG -- print message on log file
20: **
21: ** This routine looks a lot like printf, except that it
22: ** outputs to the log file instead of the standard output.
23: ** Also, it prints the module name in front of lines,
24: ** and has some other formatting types (or will sometime).
25: ** Also, it adds a newline on the end of messages.
26: **
27: ** The output of this routine is intended to be read by
28: ** /etc/syslog, which will add timestamps.
29: **
30: ** Parameters:
31: ** pri -- the message priority.
32: ** fmt -- the format string.
33: ** p0 -- the first of many parameters.
34: **
35: ** Returns:
36: ** none
37: **
38: ** Side Effects:
39: ** output to log.
40: */
41:
42: # define MAXLINE 1000 /* maximum line length */
43: # define BUFSLOP 20 /* space to allow for "extra stuff" */
44: # define NULL 0 /* manifest */
45:
46: int LogFile = -1; /* fd for log */
47: int LogStat = 0; /* status bits, set by initlog */
48: char *LogTag = NULL; /* string to tag the entry with */
49: int LogMask = LOG_DEBUG; /* lowest priority to be logged */
50:
51: # ifdef LOG_IPC
52: #ifndef LOG_OLDIPC
53: struct sockaddr_in SyslogAddr;
54: #else LOG_OLDIPC
55: struct sockaddr_in SyslogAddr = { AF_INET, LOG_PORT };
56: struct sockproto SyslogProto = { PF_INET, IPPROTO_UDP };
57: #endif LOG_OLDIPC
58: static char *SyslogHost = LOG_HOST;
59: # endif LOG_IPC
60:
61: syslog(pri, fmt, p0, p1, p2, p3, p4)
62: int pri;
63: char *fmt;
64: {
65: char buf[MAXLINE+BUFSLOP];
66: register char *b;
67: char *f;
68: int prec;
69: int len;
70: register char c;
71: register char *p;
72: int i;
73: extern int errno;
74: extern int sys_nerr;
75: extern char *sys_errlist[];
76: extern char *logcvt();
77: char outline[MAXLINE + 1];
78:
79: /* if we have no log, open it */
80: if (LogFile < 0)
81: openlog(0, 0);
82:
83: /* see if we should just throw out this message */
84: if (pri > LogMask)
85: return;
86:
87: f = fmt;
88:
89: while (*f != '\0')
90: {
91: /* beginning of line */
92: b = buf;
93:
94: /* insert priority code */
95: if (pri > 0 && (LogStat & LOG_COOLIT) == 0)
96: {
97: *b++ = '<';
98: *b++ = pri + '0';
99: *b++ = '>';
100: }
101:
102: /* output current process ID */
103: if ((LogStat & LOG_PID) != 0)
104: {
105: sprintf(b, "%d ", getpid());
106: b += strlen(b);
107: }
108:
109: /* and module name */
110: if (LogTag != 0)
111: {
112: for (p = LogTag; *p != '\0'; )
113: *b++ = *p++;
114: *b++ = ':';
115: *b++ = ' ';
116: }
117: while ((c = *f++) != '\0' && c != '\n')
118: {
119: /* output character directly if not interpolated */
120: if (c != '%')
121: {
122: *b++ = c;
123: continue;
124: }
125: c = *f++;
126: switch (c)
127: {
128: case 'm': /* output error code */
129: if (errno < 0 || errno > sys_nerr)
130: sprintf(b, "error %d", errno);
131: else
132: sprintf(b, "%s", sys_errlist[errno]);
133: break;
134:
135: default:
136: *b++ = '%';
137: *b++ = c;
138: *b = '\0';
139: break;
140: }
141: b += strlen(b);
142: if (b >= &buf[MAXLINE])
143: break;
144: }
145: if (c == '\0')
146: f--;
147:
148: /* add trailing newline */
149: *b++ = '\n';
150: *b = '\0';
151:
152: /* output string */
153: sprintf(outline, buf, p0, p1, p2, p3, p4);
154: # ifdef LOG_IPC
155: if (LogStat & LOG_DGRAM)
156: {
157: register int r;
158:
159: #ifndef LOG_OLDIPC
160: r = sendto(LogFile, outline, strlen(outline), 0,
161: &SyslogAddr, sizeof SyslogAddr);
162: #else LOG_OLDIPC
163: r = send(LogFile, &SyslogAddr, outline, strlen(outline));
164: #endif LOG_OLDIPC
165: # ifdef EBUG
166: if (r < 0)
167: perror("syslog: send");
168: # endif EBUG
169: }
170: else
171: # endif LOG_IPC
172: write(LogFile, outline, strlen(outline));
173: }
174: }
175: /*
176: ** OPENLOG -- open system log
177: **
178: ** This happens automatically with reasonable defaults if you
179: ** do nothing.
180: **
181: ** Parameters:
182: ** ident -- the name to be printed as a header for
183: ** all messages.
184: ** logstat -- a status word, interpreted as follows:
185: ** LOG_PID -- log the pid with each message.
186: **
187: ** Returns:
188: ** 0 -- success.
189: ** -1 -- failure; logging on /dev/console instead.
190: **
191: ** Side Effects:
192: ** Several global variables get set.
193: */
194:
195: openlog(ident, logstat)
196: char *ident;
197: int logstat;
198: {
199: register int i;
200: register int fd;
201: struct stat st;
202: #ifndef LOG_OLDIPC
203: # ifdef LOG_IPC
204: struct servent *sp;
205: struct hostent *hp;
206: # endif LOG_IPC
207: #endif LOG_OLDIPC
208:
209: LogTag = ident;
210: LogStat = logstat;
211:
212: if (LogFile >= 0)
213: return;
214: # ifdef LOG_IPC
215: #ifndef LOG_OLDIPC
216: sp = getservbyname("syslog", "udp");
217: hp = gethostbyname(SyslogHost);
218: if (sp != NULL && hp != NULL)
219: {
220: bzero(&SyslogAddr, sizeof SyslogAddr);
221: SyslogAddr.sin_family = AF_INET;
222: LogFile = socket(AF_INET, SOCK_DGRAM, 0, 0);
223: if (LogFile >= 0 && bind(LogFile, &SyslogAddr, sizeof SyslogAddr, 0) < 0)
224: {
225: close(LogFile);
226: LogFile = -1;
227: }
228: # ifdef EBUG
229: if (LogFile < 0)
230: perror("syslog: socket");
231: # endif EBUG
232: SyslogAddr.sin_port = sp->s_port;
233: bcopy(hp->h_addr, (char *) &SyslogAddr.sin_addr, hp->h_length);
234: LogStat |= LOG_DGRAM;
235: }
236: #else LOG_OLDIPC
237: SyslogAddr.sin_addr.s_addr = rhost(&SyslogHost);
238: LogFile = socket(SOCK_DGRAM, &SyslogProto, 0, 0);
239: # ifdef EBUG
240: if (LogFile < 0)
241: perror("syslog: socket");
242: # endif EBUG
243: LogStat |= LOG_DGRAM;
244: #endif LOG_OLDIPC
245: # else LOG_IPC
246: LogFile = open("/dev/log", 1);
247: # endif LOG_IPC
248: if (LogFile < 0)
249: {
250: nolog:
251: LogStat |= LOG_COOLIT;
252: LogStat &= ~LOG_DGRAM;
253: LogMask = LOG_CRIT;
254: # ifdef EBUG
255: LogFile = -1;
256: # else EBUG
257: LogFile = open("/dev/console", 1);
258: # endif EBUG
259: if (LogFile < 0)
260: {
261: perror("Cannot open /dev/console");
262: LogFile = 2;
263: }
264: }
265: # ifndef LOG_IPC
266: if (fstat(LogFile, &st) < 0)
267: goto nolog;
268: switch (st.st_mode & S_IFMT)
269: {
270: case S_IFREG:
271: case S_IFDIR:
272: (void) close(LogFile);
273: goto nolog;
274: }
275:
276: # ifdef FIOCLEX
277: /* have it close automatically on exec */
278: ioctl(LogFile, FIOCLEX, NULL);
279: # endif FIOCLEX
280: # endif LOG_IPC
281: }
282: /*
283: ** CLOSELOG -- close the system log
284: **
285: ** Parameters:
286: ** none.
287: **
288: ** Returns:
289: ** none.
290: **
291: ** Side Effects:
292: ** The system log is closed.
293: */
294:
295: closelog()
296: {
297: (void) close(LogFile);
298: LogFile = -1;
299: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.