]>
git.saurik.com Git - apple/syslog.git/blob - syslogd.tproj/daemon.c
f519a1774f2e58dbb5061e702ed49c2b0340fe63
2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <sys/types.h>
25 #include <sys/socket.h>
27 #include <sys/ucred.h>
32 #include <sys/queue.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
39 #define streq(A,B) (strcmp(A,B)==0)
41 static char myname
[MAXHOSTNAMELEN
+ 1] = {0};
42 static int gotname
= 0;
48 unsigned char write
:1;
49 unsigned char except
:1;
56 TAILQ_ENTRY(aslevent
) entries
;
63 TAILQ_ENTRY(asloutput
) entries
;
70 TAILQ_ENTRY(aslmatch
) entries
;
73 TAILQ_HEAD(ae
, aslevent
) Eventq
;
74 TAILQ_HEAD(ao
, asloutput
) Outq
;
75 TAILQ_HEAD(am
, aslmatch
) Matchq
;
88 aslevent_log(asl_msg_t
*msg
, char *outid
)
93 for (i
= Outq
.tqh_first
; i
!= NULL
; i
= i
->entries
.tqe_next
)
95 if ((outid
!= NULL
) && (strcmp(i
->outid
, outid
) == 0))
97 status
= i
->sendmsg(msg
, outid
);
105 aslevent_addmatch(asl_msg_t
*query
, char *outid
)
107 struct aslmatch
*tmp
;
109 if (query
== NULL
) return -1;
110 if (outid
== NULL
) return -1;
112 tmp
= calloc(1, sizeof(struct aslmatch
));
113 if (tmp
== NULL
) return -1;
116 TAILQ_INSERT_TAIL(&Matchq
, tmp
, entries
);
122 aslevent_match(asl_msg_t
*msg
)
126 if (msg
== NULL
) return;
128 for (i
= Matchq
.tqh_first
; i
!= NULL
; i
= i
->entries
.tqe_next
)
130 if (asl_msg_cmp(i
->query
, msg
) != 0)
132 aslevent_log(msg
, i
->outid
);
138 aslevent_removefd(int fd
)
143 for (i
= Eventq
.tqh_first
; i
!= NULL
; i
= i
->entries
.tqe_next
)
147 asldebug("removing %d\n", i
->fd
);
148 TAILQ_REMOVE(&Eventq
, i
, entries
);
150 if (i
->sender
!= NULL
) free(i
->sender
);
165 if (gotname
!= 0) return (const char *)myname
;
167 if (gethostname(myname
, MAXHOSTNAMELEN
) < 0)
169 memset(myname
, 0, sizeof(myname
));
173 if (strcmp(myname
, "localhost")) gotname
= 1;
175 dot
= strchr(myname
, '.');
176 if (dot
!= NULL
) *dot
= '\0';
178 return (const char *)myname
;
182 aslevent_addfd(int fd
, aslreadfn readfn
, aslwritefn writefn
, aslexceptfn exceptfn
)
186 #ifdef LOCAL_PEERCRED
192 struct sockaddr_storage ss
;
193 char *sender
, str
[256];
199 memset(&ss
, 0, sizeof(struct sockaddr_storage
));
201 len
= sizeof(struct sockaddr_storage
);
203 if (getpeername(fd
, (struct sockaddr
*)&ss
, &len
) == 0)
207 /* UNIX Domain socket */
208 snprintf(str
, sizeof(str
), whatsmyhostname());
213 if (inet_ntop(ss
.ss_family
, (struct sockaddr
*)&ss
, str
, 256) == 0) sender
= str
;
217 #ifdef LOCAL_PEERCRED
220 if (getsockopt(fd
, LOCAL_PEERCRED
, 1, &cr
, &len
) == 0)
227 asldebug("fd %d UID %d GID %d Sender %s\n", fd
, u
, g
, (sender
== NULL
) ? "NULL" : sender
);
229 for (e
= Eventq
.tqh_first
; e
!= NULL
; e
= e
->entries
.tqe_next
)
234 e
->writefn
= writefn
;
235 e
->exceptfn
= exceptfn
;
236 if (e
->sender
!= NULL
) free(e
->sender
);
238 if (sender
!= NULL
) e
->sender
= strdup(sender
);
247 e
= calloc(1, sizeof(struct aslevent
));
248 if (e
== NULL
) return -1;
252 e
->writefn
= writefn
;
253 e
->exceptfn
= exceptfn
;
255 if (sender
!= NULL
) e
->sender
= strdup(sender
);
259 TAILQ_INSERT_TAIL(&Eventq
, e
, entries
);
265 aslmsg_verify(struct aslevent
*e
, asl_msg_t
*msg
)
268 char buf
[32], *timestr
;
272 if (msg
== NULL
) return -1;
276 val
= asl_get(msg
, ASL_KEY_TIME
);
277 if (val
!= NULL
) tick
= asl_parse_time(val
);
279 if (tick
== 0) tick
= time(NULL
);
280 memset(>ime
, 0, sizeof(struct tm
));
281 gmtime_r(&tick
, >ime
);
283 /* Canonical form: YYYY.MM.DD hh:mm:ss UTC */
284 asprintf(×tr
, "%d.%02d.%02d %02d:%02d:%02d UTC", gtime
.tm_year
+ 1900, gtime
.tm_mon
+ 1, gtime
.tm_mday
, gtime
.tm_hour
, gtime
.tm_min
, gtime
.tm_sec
);
287 asl_set(msg
, ASL_KEY_TIME
, timestr
);
292 if (e
== NULL
) asl_set(msg
, ASL_KEY_HOST
, whatsmyhostname());
293 else if (e
->sender
!= NULL
) asl_set(msg
, ASL_KEY_HOST
, e
->sender
);
296 val
= asl_get(msg
, ASL_KEY_SENDER
);
297 if (val
== NULL
) asl_set(msg
, ASL_KEY_SENDER
, "Unknown");
300 val
= asl_get(msg
, ASL_KEY_PID
);
301 if (val
== NULL
) asl_set(msg
, ASL_KEY_PID
, "0");
304 val
= asl_get(msg
, ASL_KEY_UID
);
307 if (e
== NULL
) asl_set(msg
, ASL_KEY_UID
, "-2");
308 else if (e
->uid
== 99) asl_set(msg
, ASL_KEY_UID
, "-2");
311 snprintf(buf
, sizeof(buf
), "%d", e
->uid
);
312 asl_set(msg
, ASL_KEY_UID
, buf
);
315 else if ((e
!= NULL
) && (e
->uid
!= 99))
317 snprintf(buf
, sizeof(buf
), "%d", e
->uid
);
318 asl_set(msg
, ASL_KEY_UID
, buf
);
322 val
= asl_get(msg
, ASL_KEY_GID
);
325 if (e
== NULL
) asl_set(msg
, ASL_KEY_GID
, "-2");
326 else if (e
->gid
== 99) asl_set(msg
, ASL_KEY_GID
, "-2");
329 snprintf(buf
, sizeof(buf
), "%d", e
->gid
);
330 asl_set(msg
, ASL_KEY_GID
, buf
);
333 else if ((e
!= NULL
) && (e
->gid
!= 99))
335 snprintf(buf
, sizeof(buf
), "%d", e
->gid
);
336 asl_set(msg
, ASL_KEY_GID
, buf
);
340 val
= asl_get(msg
, ASL_KEY_LEVEL
);
341 if (val
== NULL
) asl_set(msg
, ASL_KEY_LEVEL
, "7");
347 aslevent_addoutput(aslsendmsgfn fn
, const char *outid
)
349 struct asloutput
*tmp
;
351 tmp
= calloc(1, sizeof(struct asloutput
));
352 if (tmp
== NULL
) return -1;
357 TAILQ_INSERT_TAIL(&Outq
, tmp
, entries
);
363 aslevent_fdsets(fd_set
*rd
, fd_set
*wr
, fd_set
*ex
)
368 asldebug("--> aslevent_fdsets\n");
373 for (e
= Eventq
.tqh_first
; e
!= NULL
; e
= e
->entries
.tqe_next
)
375 asldebug("adding fd %d\n", e
->fd
);
379 status
= MAX(e
->fd
, status
);
385 status
= MAX(e
->fd
, status
);
391 status
= MAX(e
->fd
, status
);
395 asldebug("<--aslevent_fdsets\n");
400 aslevent_handleevent(fd_set rd
, fd_set wr
, fd_set ex
, char *errstr
)
406 asldebug("--> aslevent_handleevent\n");
407 if (errstr
) errstr
= NULL
;
409 for (e
= Eventq
.tqh_first
; e
!= NULL
; e
= e
->entries
.tqe_next
)
411 if (FD_ISSET(e
->fd
, &rd
) && (e
->readfn
!= NULL
))
413 asldebug("handling read event on %d\n", e
->fd
);
414 msg
= e
->readfn(e
->fd
);
417 asldebug("error reading message\n");
421 if (aslmsg_verify(e
, msg
) < 0)
424 asldebug("recieved invalid message\n");
433 if (FD_ISSET(e
->fd
, &ex
) && e
->exceptfn
)
435 asldebug("handling except event on %d\n", e
->fd
);
436 out
= e
->exceptfn(e
->fd
);
437 if (out
== NULL
) asldebug("error writing message\n");
441 asldebug("<-- aslevent_handleevent\n");
445 asl_log_string(const char *str
)
449 if (str
== NULL
) return 1;
451 msg
= asl_msg_from_string(str
);
452 if (aslmsg_verify(NULL
, msg
) < 0)
469 asprintf(&str
, "[%s syslogd] [%s %u] [%s %u] [%s -- MARK --] [%s 0] [%s 0] [Facility syslog]",
471 ASL_KEY_LEVEL
, ASL_LEVEL_INFO
,
472 ASL_KEY_PID
, getpid(),
473 ASL_KEY_MSG
, ASL_KEY_UID
, ASL_KEY_GID
);
476 if (str
!= NULL
) free(str
);
480 asl_syslog_input_convert(const char *in
, int len
, char *rhost
, int kern
)
482 int pf
, pri
, index
, n
;
483 char *p
, *colon
, *brace
, *tmp
, *tval
, *sval
, *pval
, *mval
;
490 if (in
== NULL
) return NULL
;
491 if (len
<= 0) return NULL
;
493 asldebug("asl_syslog_input_convert: %s\n", in
);
505 while ((index
< len
) && ((*p
== ' ') || (*p
== '\t')))
511 if (index
>= len
) return NULL
;
518 n
= sscanf(p
, "%d", &pf
);
522 if (pf
> 0x7) fval
= asl_syslog_faciliy_num_to_name(pf
& LOG_FACMASK
);
525 while ((index
< len
) && (*p
!= '>'))
538 snprintf(prival
, sizeof(prival
), "%d", pri
);
540 if (((len
- index
) > 15) && (p
[9] == ':') && (p
[12] == ':') && (p
[15] == ' '))
546 tick
= asl_parse_time(tmp
);
547 if (tick
== (time_t)-1)
554 gmtime_r(&tick
, &time
);
555 asprintf(&tval
, "%d.%02d.%02d %02d:%02d:%02d UTC", time
.tm_year
+ 1900, time
.tm_mon
+ 1, time
.tm_mday
, time
.tm_hour
, time
.tm_min
, time
.tm_sec
);
564 msg
= (asl_msg_t
*)calloc(1, sizeof(asl_msg_t
));
565 msg
->type
= ASL_TYPE_MSG
;
567 asl_set(msg
, ASL_KEY_SENDER
, "kernel");
569 asl_set(msg
, "Facility", "kern");
572 asl_set(msg
, ASL_KEY_TIME
, tval
);
576 asl_set(msg
, ASL_KEY_MSG
, p
);
578 asl_set(msg
, ASL_KEY_LEVEL
, prival
);
580 asl_set(msg
, ASL_KEY_PID
, "0");
582 asl_set(msg
, ASL_KEY_UID
, "0");
584 asl_set(msg
, ASL_KEY_GID
, "0");
586 asl_set(msg
, ASL_KEY_HOST
, whatsmyhostname());
591 colon
= strchr(p
, ':');
592 brace
= strchr(p
, '[');
596 if ((brace
!= NULL
) && (brace
< colon
))
599 sval
= malloc(n
+ 1);
603 n
= colon
- (brace
+ 1) - 1;
604 pval
= malloc(n
+ 1);
605 memcpy(pval
, (brace
+ 1), n
);
611 sval
= malloc(n
+ 1);
630 mval
= malloc(n
+ 1);
635 if (fval
== NULL
) fval
= asl_syslog_faciliy_num_to_name(LOG_USER
);
637 msg
= (asl_msg_t
*)calloc(1, sizeof(asl_msg_t
));
638 msg
->type
= ASL_TYPE_MSG
;
642 asl_set(msg
, ASL_KEY_TIME
, tval
);
646 if (fval
!= NULL
) asl_set(msg
, "Facility", fval
);
647 else asl_set(msg
, "Facility", "user");
651 asl_set(msg
, ASL_KEY_SENDER
, sval
);
657 asl_set(msg
, ASL_KEY_PID
, pval
);
660 else asl_set(msg
, ASL_KEY_PID
, "-1");
664 asl_set(msg
, ASL_KEY_MSG
, mval
);
668 asl_set(msg
, ASL_KEY_LEVEL
, prival
);
669 asl_set(msg
, ASL_KEY_UID
, "-2");
670 asl_set(msg
, ASL_KEY_GID
, "-2");
672 if (rhost
== NULL
) asl_set(msg
, ASL_KEY_HOST
, whatsmyhostname());
673 else asl_set(msg
, ASL_KEY_HOST
, rhost
);
685 get_line_from_file(FILE *f
)
690 out
= fgetln(f
, &len
);
691 if (out
== NULL
) return NULL
;
692 if (len
== 0) return NULL
;