]>
git.saurik.com Git - apple/syslog.git/blob - syslogd.tproj/daemon.c
775a0d79f59972eaac508e3d19ecb23358d438d2
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>
26 #include <sys/socket.h>
28 #include <sys/ucred.h>
33 #include <sys/queue.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
40 #define streq(A,B) (strcmp(A,B)==0)
42 static char myname
[MAXHOSTNAMELEN
+ 1] = {0};
43 static int gotname
= 0;
49 unsigned char write
:1;
50 unsigned char except
:1;
57 TAILQ_ENTRY(aslevent
) entries
;
64 TAILQ_ENTRY(asloutput
) entries
;
71 TAILQ_ENTRY(aslmatch
) entries
;
74 TAILQ_HEAD(ae
, aslevent
) Eventq
;
75 TAILQ_HEAD(ao
, asloutput
) Outq
;
76 TAILQ_HEAD(am
, aslmatch
) Matchq
;
89 aslevent_log(asl_msg_t
*msg
, char *outid
)
94 for (i
= Outq
.tqh_first
; i
!= NULL
; i
= i
->entries
.tqe_next
)
96 if ((outid
!= NULL
) && (strcmp(i
->outid
, outid
) == 0))
98 status
= i
->sendmsg(msg
, outid
);
106 aslevent_addmatch(asl_msg_t
*query
, char *outid
)
108 struct aslmatch
*tmp
;
110 if (query
== NULL
) return -1;
111 if (outid
== NULL
) return -1;
113 tmp
= calloc(1, sizeof(struct aslmatch
));
114 if (tmp
== NULL
) return -1;
117 TAILQ_INSERT_TAIL(&Matchq
, tmp
, entries
);
123 aslevent_match(asl_msg_t
*msg
)
127 if (msg
== NULL
) return;
129 for (i
= Matchq
.tqh_first
; i
!= NULL
; i
= i
->entries
.tqe_next
)
131 if (asl_msg_cmp(i
->query
, msg
) != 0)
133 aslevent_log(msg
, i
->outid
);
139 aslevent_removefd(int fd
)
144 for (i
= Eventq
.tqh_first
; i
!= NULL
; i
= i
->entries
.tqe_next
)
148 asldebug("removing %d\n", i
->fd
);
149 TAILQ_REMOVE(&Eventq
, i
, entries
);
151 if (i
->sender
!= NULL
) free(i
->sender
);
166 if (gotname
!= 0) return (const char *)myname
;
168 if (gethostname(myname
, MAXHOSTNAMELEN
) < 0)
170 memset(myname
, 0, sizeof(myname
));
174 if (strcmp(myname
, "localhost")) gotname
= 1;
176 dot
= strchr(myname
, '.');
177 if (dot
!= NULL
) *dot
= '\0';
179 return (const char *)myname
;
183 aslevent_addfd(int fd
, aslreadfn readfn
, aslwritefn writefn
, aslexceptfn exceptfn
)
187 #ifdef LOCAL_PEERCRED
193 struct sockaddr_storage ss
;
194 char *sender
, str
[256];
200 memset(&ss
, 0, sizeof(struct sockaddr_storage
));
202 len
= sizeof(struct sockaddr_storage
);
204 if (getpeername(fd
, (struct sockaddr
*)&ss
, &len
) == 0)
208 /* UNIX Domain socket */
209 snprintf(str
, sizeof(str
), whatsmyhostname());
214 if (inet_ntop(ss
.ss_family
, (struct sockaddr
*)&ss
, str
, 256) == 0) sender
= str
;
218 #ifdef LOCAL_PEERCRED
221 if (getsockopt(fd
, LOCAL_PEERCRED
, 1, &cr
, &len
) == 0)
228 asldebug("fd %d UID %d GID %d Sender %s\n", fd
, u
, g
, (sender
== NULL
) ? "NULL" : sender
);
230 for (e
= Eventq
.tqh_first
; e
!= NULL
; e
= e
->entries
.tqe_next
)
235 e
->writefn
= writefn
;
236 e
->exceptfn
= exceptfn
;
237 if (e
->sender
!= NULL
) free(e
->sender
);
239 if (sender
!= NULL
) e
->sender
= strdup(sender
);
248 e
= calloc(1, sizeof(struct aslevent
));
249 if (e
== NULL
) return -1;
253 e
->writefn
= writefn
;
254 e
->exceptfn
= exceptfn
;
256 if (sender
!= NULL
) e
->sender
= strdup(sender
);
260 TAILQ_INSERT_TAIL(&Eventq
, e
, entries
);
266 aslmsg_verify(struct aslevent
*e
, asl_msg_t
*msg
)
269 char buf
[32], *timestr
;
273 if (msg
== NULL
) return -1;
277 val
= asl_get(msg
, ASL_KEY_TIME
);
278 if (val
!= NULL
) tick
= asl_parse_time(val
);
280 if (tick
== 0) tick
= time(NULL
);
281 memset(>ime
, 0, sizeof(struct tm
));
282 gmtime_r(&tick
, >ime
);
284 /* Canonical form: YYYY.MM.DD hh:mm:ss UTC */
285 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
);
288 asl_set(msg
, ASL_KEY_TIME
, timestr
);
293 if (e
== NULL
) asl_set(msg
, ASL_KEY_HOST
, whatsmyhostname());
294 else if (e
->sender
!= NULL
) asl_set(msg
, ASL_KEY_HOST
, e
->sender
);
297 val
= asl_get(msg
, ASL_KEY_SENDER
);
298 if (val
== NULL
) asl_set(msg
, ASL_KEY_SENDER
, "Unknown");
301 val
= asl_get(msg
, ASL_KEY_PID
);
302 if (val
== NULL
) asl_set(msg
, ASL_KEY_PID
, "0");
305 val
= asl_get(msg
, ASL_KEY_UID
);
308 if (e
== NULL
) asl_set(msg
, ASL_KEY_UID
, "-2");
309 else if (e
->uid
== 99) asl_set(msg
, ASL_KEY_UID
, "-2");
312 snprintf(buf
, sizeof(buf
), "%d", e
->uid
);
313 asl_set(msg
, ASL_KEY_UID
, buf
);
316 else if ((e
!= NULL
) && (e
->uid
!= 99))
318 snprintf(buf
, sizeof(buf
), "%d", e
->uid
);
319 asl_set(msg
, ASL_KEY_UID
, buf
);
323 val
= asl_get(msg
, ASL_KEY_GID
);
326 if (e
== NULL
) asl_set(msg
, ASL_KEY_GID
, "-2");
327 else if (e
->gid
== 99) asl_set(msg
, ASL_KEY_GID
, "-2");
330 snprintf(buf
, sizeof(buf
), "%d", e
->gid
);
331 asl_set(msg
, ASL_KEY_GID
, buf
);
334 else if ((e
!= NULL
) && (e
->gid
!= 99))
336 snprintf(buf
, sizeof(buf
), "%d", e
->gid
);
337 asl_set(msg
, ASL_KEY_GID
, buf
);
341 val
= asl_get(msg
, ASL_KEY_LEVEL
);
342 if (val
== NULL
) asl_set(msg
, ASL_KEY_LEVEL
, "7");
348 aslevent_addoutput(aslsendmsgfn fn
, const char *outid
)
350 struct asloutput
*tmp
;
352 tmp
= calloc(1, sizeof(struct asloutput
));
353 if (tmp
== NULL
) return -1;
358 TAILQ_INSERT_TAIL(&Outq
, tmp
, entries
);
364 aslevent_fdsets(fd_set
*rd
, fd_set
*wr
, fd_set
*ex
)
369 asldebug("--> aslevent_fdsets\n");
374 for (e
= Eventq
.tqh_first
; e
!= NULL
; e
= e
->entries
.tqe_next
)
376 asldebug("adding fd %d\n", e
->fd
);
380 status
= MAX(e
->fd
, status
);
386 status
= MAX(e
->fd
, status
);
392 status
= MAX(e
->fd
, status
);
396 asldebug("<--aslevent_fdsets\n");
401 aslevent_handleevent(fd_set rd
, fd_set wr
, fd_set ex
, char *errstr
)
407 asldebug("--> aslevent_handleevent\n");
408 if (errstr
) errstr
= NULL
;
410 for (e
= Eventq
.tqh_first
; e
!= NULL
; e
= e
->entries
.tqe_next
)
412 if (FD_ISSET(e
->fd
, &rd
) && (e
->readfn
!= NULL
))
414 asldebug("handling read event on %d\n", e
->fd
);
415 msg
= e
->readfn(e
->fd
);
418 asldebug("error reading message\n");
422 if (aslmsg_verify(e
, msg
) < 0)
425 asldebug("recieved invalid message\n");
434 if (FD_ISSET(e
->fd
, &ex
) && e
->exceptfn
)
436 asldebug("handling except event on %d\n", e
->fd
);
437 out
= e
->exceptfn(e
->fd
);
438 if (out
== NULL
) asldebug("error writing message\n");
442 asldebug("<-- aslevent_handleevent\n");
446 asl_log_string(const char *str
)
450 if (str
== NULL
) return 1;
452 msg
= asl_msg_from_string(str
);
453 if (aslmsg_verify(NULL
, msg
) < 0)
470 asprintf(&str
, "[%s syslogd] [%s %u] [%s %u] [%s -- MARK --] [%s 0] [%s 0] [Facility syslog]",
472 ASL_KEY_LEVEL
, ASL_LEVEL_INFO
,
473 ASL_KEY_PID
, getpid(),
474 ASL_KEY_MSG
, ASL_KEY_UID
, ASL_KEY_GID
);
477 if (str
!= NULL
) free(str
);
481 asl_syslog_input_convert(const char *in
, int len
, char *rhost
, int kern
)
483 int pf
, pri
, index
, n
;
484 char *p
, *colon
, *brace
, *tmp
, *tval
, *sval
, *pval
, *mval
;
491 if (in
== NULL
) return NULL
;
492 if (len
<= 0) return NULL
;
494 asldebug("asl_syslog_input_convert: %s\n", in
);
506 while ((index
< len
) && ((*p
== ' ') || (*p
== '\t')))
512 if (index
>= len
) return NULL
;
519 n
= sscanf(p
, "%d", &pf
);
523 if (pf
> 0x7) fval
= asl_syslog_faciliy_num_to_name(pf
& LOG_FACMASK
);
526 while ((index
< len
) && (*p
!= '>'))
539 snprintf(prival
, sizeof(prival
), "%d", pri
);
541 if (((len
- index
) > 15) && (p
[9] == ':') && (p
[12] == ':') && (p
[15] == ' '))
547 tick
= asl_parse_time(tmp
);
548 if (tick
== (time_t)-1)
555 gmtime_r(&tick
, &time
);
556 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
);
565 msg
= (asl_msg_t
*)calloc(1, sizeof(asl_msg_t
));
566 msg
->type
= ASL_TYPE_MSG
;
568 asl_set(msg
, ASL_KEY_SENDER
, "kernel");
570 asl_set(msg
, "Facility", "kern");
573 asl_set(msg
, ASL_KEY_TIME
, tval
);
577 asl_set(msg
, ASL_KEY_MSG
, p
);
579 asl_set(msg
, ASL_KEY_LEVEL
, prival
);
581 asl_set(msg
, ASL_KEY_PID
, "0");
583 asl_set(msg
, ASL_KEY_UID
, "0");
585 asl_set(msg
, ASL_KEY_GID
, "0");
587 asl_set(msg
, ASL_KEY_HOST
, whatsmyhostname());
592 colon
= strchr(p
, ':');
593 brace
= strchr(p
, '[');
597 if ((brace
!= NULL
) && (brace
< colon
))
600 sval
= malloc(n
+ 1);
604 n
= colon
- (brace
+ 1) - 1;
605 pval
= malloc(n
+ 1);
606 memcpy(pval
, (brace
+ 1), n
);
612 sval
= malloc(n
+ 1);
631 mval
= malloc(n
+ 1);
636 if (fval
== NULL
) fval
= asl_syslog_faciliy_num_to_name(LOG_USER
);
638 msg
= (asl_msg_t
*)calloc(1, sizeof(asl_msg_t
));
639 msg
->type
= ASL_TYPE_MSG
;
643 asl_set(msg
, ASL_KEY_TIME
, tval
);
647 if (fval
!= NULL
) asl_set(msg
, "Facility", fval
);
648 else asl_set(msg
, "Facility", "user");
652 asl_set(msg
, ASL_KEY_SENDER
, sval
);
658 asl_set(msg
, ASL_KEY_PID
, pval
);
661 else asl_set(msg
, ASL_KEY_PID
, "-1");
665 asl_set(msg
, ASL_KEY_MSG
, mval
);
669 asl_set(msg
, ASL_KEY_LEVEL
, prival
);
670 asl_set(msg
, ASL_KEY_UID
, "-2");
671 asl_set(msg
, ASL_KEY_GID
, "-2");
673 if (rhost
== NULL
) asl_set(msg
, ASL_KEY_HOST
, whatsmyhostname());
674 else asl_set(msg
, ASL_KEY_HOST
, rhost
);
686 get_line_from_file(FILE *f
)
691 out
= fgetln(f
, &len
);
692 if (out
== NULL
) return NULL
;
693 if (len
== 0) return NULL
;