]>
git.saurik.com Git - apple/syslog.git/blob - syslogd.tproj/asl_in.c
7a1723e7e01855342512321e065cdf077299cc4f
2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 2004 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 #include <sys/types.h>
27 #include <sys/fcntl.h>
28 #include <sys/socket.h>
38 #define forever for(;;)
43 static FILE *aslfile
= NULL
;
44 static asl_msg_t
*query
= NULL
;
46 extern int asl_log_filter
;
55 static int filter_token
= -1;
57 struct prune_query_entry
60 TAILQ_ENTRY(prune_query_entry
) entries
;
63 static TAILQ_HEAD(pql
, prune_query_entry
) pquery
;
66 _search_next(FILE *log
, char **outstr
)
71 struct prune_query_entry
*p
;
75 if (log
== NULL
) return MATCH_EOF
;
77 str
= get_line_from_file(log
);
78 if (str
== NULL
) return MATCH_EOF
;
80 m
= asl_msg_from_string(str
);
89 for (i
= 0, p
= pquery
.tqh_first
; p
!= NULL
; p
= p
->entries
.tqe_next
, i
++)
91 match
= asl_msg_cmp(p
->query
, m
);
104 * Pruning the main output file (asl.log)
106 * The prune file (_PATH_ASL_PRUNE) is set up by the syslog command-line utiliy.
107 * It contains a set of queries. The main output file is read, and each
108 * message is matched against these queries. If any query matches, we save
109 * that message. Anything that doesn't match is discarded.
113 asl_prune(asl_msg_t
*inq
)
117 struct prune_query_entry
*p
, *n
;
119 int status
, incount
, outcount
;
121 asldebug("syslogd: pruning %s\n", _PATH_ASL_OUT
);
126 p
= (struct prune_query_entry
*)calloc(1, sizeof(struct prune_query_entry
));
127 if (p
== NULL
) return -1;
130 TAILQ_INSERT_TAIL(&pquery
, p
, entries
);
134 qfile
= fopen(_PATH_ASL_PRUNE
, "r");
137 asldebug("syslogd: can't read %s: %s\n", _PATH_ASL_PRUNE
, strerror(errno
));
145 str
= get_line_from_file(qfile
);
146 if (str
== NULL
) break;
148 q
= asl_msg_from_string(str
);
149 asldebug("syslogd: prune line %s\n", str
);
152 if (q
== NULL
) continue;
154 if (q
->type
!= ASL_TYPE_QUERY
)
160 p
= (struct prune_query_entry
*)calloc(1, sizeof(struct prune_query_entry
));
161 if (p
== NULL
) return -1;
164 TAILQ_INSERT_TAIL(&pquery
, p
, entries
);
169 asprintf(&pname
, "%s.%d", _PATH_ASL_OUT
, getpid());
170 if (pname
== NULL
) return -1;
172 pfile
= fopen(pname
, "w");
175 asldebug("syslogd: can't write %s: %s\n", pname
, strerror(errno
));
181 aslfile
= fopen(_PATH_ASL_OUT
, "r");
184 asldebug("syslogd: can't read %s: %s\n", _PATH_ASL_OUT
, strerror(errno
));
186 aslfile
= fopen(_PATH_ASL_OUT
, "a");
197 status
= _search_next(aslfile
, &str
);
200 * Pruning deletes records that match the search.
201 * If the match fails, we keep the record.
203 if (status
== MATCH_FALSE
)
206 fprintf(pfile
, "%s\n", str
);
209 if (str
!= NULL
) free(str
);
211 while (status
!= MATCH_EOF
);
216 unlink(_PATH_ASL_OUT
);
217 rename(pname
, _PATH_ASL_OUT
);
219 unlink(_PATH_ASL_PRUNE
);
220 aslfile
= fopen(_PATH_ASL_OUT
, "a");
223 for (p
= pquery
.tqh_first
; p
!= NULL
; p
= n
)
225 n
= p
->entries
.tqe_next
;
227 if (p
->query
!= NULL
) asl_free(p
->query
);
229 TAILQ_REMOVE(&pquery
, p
, entries
);
233 asldebug("syslogd: prune %d records in, %d records out\n", incount
, outcount
);
239 asl_in_getmsg(int fd
)
246 n
= read(fd
, ls
, 11);
251 asldebug("%s: read error (len): %s\n", MY_ID
, strerror(errno
));
255 aslevent_removefd(fd
);
264 asldebug("%s: expecting message length %d bytes\n", MY_ID
, len
);
266 if (out
== NULL
) return NULL
;
268 n
= read(fd
, out
, len
);
273 asldebug("%s: read error (body): %s\n", MY_ID
, strerror(errno
));
277 aslevent_removefd(fd
);
284 m
= asl_msg_from_string(out
);
290 asl_in_acceptmsg(int fd
)
294 asldebug("%s: accepting message\n", MY_ID
);
295 clientfd
= accept(fd
, NULL
, 0);
298 asldebug("%s: error accepting socket fd %d: %s\n", MY_ID
, fd
, strerror(errno
));
302 if (fcntl(clientfd
, F_SETFL
, O_NONBLOCK
) < 0)
306 asldebug("%s: couldn't set O_NONBLOCK for fd %d: %s\n", MY_ID
, clientfd
, strerror(errno
));
310 aslevent_addfd(clientfd
, asl_in_getmsg
, NULL
, NULL
);
315 aslmod_sendmsg(asl_msg_t
*msg
, const char *outid
)
320 int status
, x
, level
;
322 if (aslfile
== NULL
) return -1;
324 /* set up com.apple.syslog.asl_filter */
325 if (filter_token
== -1)
327 status
= notify_register_check(NOTIFY_SYSTEM_ASL_FILTER
, &filter_token
);
328 if (status
!= NOTIFY_STATUS_OK
)
334 status
= notify_check(filter_token
, &x
);
335 if (status
== NOTIFY_STATUS_OK
) status
= notify_set_state(filter_token
, asl_log_filter
);
336 if (status
!= NOTIFY_STATUS_OK
)
338 notify_cancel(filter_token
);
344 if (filter_token
>= 0)
347 status
= notify_check(filter_token
, &x
);
348 if ((status
== NOTIFY_STATUS_OK
) && (x
== 1))
351 status
= notify_get_state(filter_token
, &x
);
352 if ((status
== NOTIFY_STATUS_OK
) && (x
!= 0)) asl_log_filter
= x
;
356 vlevel
= asl_get(msg
, ASL_KEY_LEVEL
);
358 if (vlevel
!= NULL
) level
= atoi(vlevel
);
359 lmask
= ASL_FILTER_MASK(level
);
360 if ((lmask
& asl_log_filter
) == 0) return 0;
362 mstr
= asl_msg_to_string(msg
, &n
);
365 fprintf(aslfile
, "%s\n", mstr
);
376 struct sockaddr_un sun
;
380 asldebug("%s: init\n", MY_ID
);
381 if (sock
>= 0) return sock
;
383 unlink(_PATH_ASL_IN
);
384 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
387 asldebug("%s: couldn't create socket for %s: %s\n", MY_ID
, _PATH_ASL_IN
, strerror(errno
));
391 asldebug("%s: creating %s for fd %d\n", MY_ID
, _PATH_ASL_IN
, sock
);
393 memset(&sun
, 0, sizeof(sun
));
394 sun
.sun_family
= AF_UNIX
;
395 strcpy(sun
.sun_path
, _PATH_ASL_IN
);
397 len
= sizeof(struct sockaddr_un
);
398 if (bind(sock
, (struct sockaddr
*)&sun
, len
) < 0)
400 asldebug("%s: couldn't bind socket %d for %s: %s\n", MY_ID
, sock
, _PATH_ASL_IN
, strerror(errno
));
406 rbufsize
= 128 * 1024;
407 len
= sizeof(rbufsize
);
409 if (setsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
, &rbufsize
, len
) < 0)
411 asldebug("%s: couldn't set receive buffer size for %s: %s\n", MY_ID
, sock
, _PATH_ASL_IN
, strerror(errno
));
417 if (listen(sock
, SOMAXCONN
) < 0)
419 asldebug("%s: couldn't listen on socket %d for %s: %s\n", MY_ID
, sock
, _PATH_ASL_IN
, strerror(errno
));
422 unlink(_PATH_ASL_IN
);
426 if (fcntl(sock
, F_SETFL
, O_NONBLOCK
) < 0)
428 asldebug("%s: couldn't set O_NONBLOCK for socket %d (%s): %s\n", MY_ID
, sock
, _PATH_ASL_IN
, strerror(errno
));
434 chmod(_PATH_ASL_IN
, 0666);
436 /* Add logger routine for main output file */
437 aslfile
= fopen(_PATH_ASL_OUT
, "a");
440 query
= asl_new(ASL_TYPE_QUERY
);
441 aslevent_addmatch(query
, MY_ID
);
442 aslevent_addoutput(aslmod_sendmsg
, MY_ID
);
445 return aslevent_addfd(sock
, asl_in_acceptmsg
, NULL
, NULL
);
457 if (sock
< 0) return 1;
459 if (filter_token
>= 0) notify_cancel(filter_token
);
465 if (aslfile
!= NULL
) fclose(aslfile
);
466 unlink(_PATH_ASL_IN
);