]> git.saurik.com Git - apple/syslog.git/commitdiff
syslog-132.tar.gz mac-os-x-107 mac-os-x-1071 mac-os-x-1072 mac-os-x-1073 mac-os-x-1074 mac-os-x-1075 v132
authorApple <opensource@apple.com>
Wed, 25 May 2011 01:11:07 +0000 (01:11 +0000)
committerApple <opensource@apple.com>
Wed, 25 May 2011 01:11:07 +0000 (01:11 +0000)
29 files changed:
Makefile [deleted file]
aslcommon/Makefile [deleted file]
aslcommon/asl_ipc.defs [deleted file]
aslcommon/asl_memory.c
aslcommon/asl_mini_memory.c
aslmanager.tproj/Makefile [deleted file]
aslmanager.tproj/aslmanager.c
syslog.xcodeproj/project.pbxproj [new file with mode: 0644]
syslogd.tproj/Makefile [deleted file]
syslogd.tproj/after_install.sh [new file with mode: 0755]
syslogd.tproj/asl.conf.5
syslogd.tproj/asl_action.c
syslogd.tproj/asl_in.c
syslogd.tproj/bb_convert.c
syslogd.tproj/bsd_in.c
syslogd.tproj/bsd_out.c
syslogd.tproj/com.apple.syslogd.plist
syslogd.tproj/daemon.c
syslogd.tproj/daemon.h
syslogd.tproj/dbserver.c
syslogd.tproj/klog_in.c
syslogd.tproj/remote.c
syslogd.tproj/syslog.conf.5
syslogd.tproj/syslogd.8
syslogd.tproj/syslogd.c
syslogd.tproj/udp_in.c
util.tproj/Makefile [deleted file]
util.tproj/syslog.1
util.tproj/syslog.c

diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index ab096dd..0000000
--- a/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-Project = syslog
-
-SubProjects = aslcommon aslmanager.tproj syslogd.tproj util.tproj
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-after_install:
-       $(RMDIR) "$(DSTROOT)"/scratch
diff --git a/aslcommon/Makefile b/aslcommon/Makefile
deleted file mode 100644 (file)
index 9bc1604..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-Project = aslcommon
-ProductType = staticlib
-Install_Dir = /scratch
-
-CFILES = asl_memory.c asl_mini_memory.c
-SERVERDEFS = asl_ipc.defs
-USERDEFS = asl_ipc.defs
-
-#PROJECT_HEADERS = asl_ipc.defs asl_memory.h asl_mini_memory.h asl_ipc.h
-
-Extra_CC_Flags = -Wall -D__MigTypeCheck=1 -I.
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-ifneq ($(SDKROOT),)
-Extra_MIG_Flags = -arch $(firstword $(RC_ARCHS))
-endif
diff --git a/aslcommon/asl_ipc.defs b/aslcommon/asl_ipc.defs
deleted file mode 100644 (file)
index 1fe5bce..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2007-2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <mach/std_types.defs>
-#include <mach/mach_types.defs>
-
-subsystem asl_ipc 1;
-serverprefix _;
-
-import <sys/types.h>;
-
-type ooline_data = ^ array [] of MACH_MSG_TYPE_BYTE
-       ctype : caddr_t;
-
-routine _asl_server_query
-(
-       server : mach_port_t;
-       request : ooline_data, dealloc;
-       startid : uint64_t;
-       count : int;
-       flags : int;
-       out reply : ooline_data, dealloc;
-       out lastid : uint64_t;
-       out status : int;
-       SecToken token : security_token_t
-);
-
-routine _asl_server_query_timeout
-(
-       server : mach_port_t;
-       request : ooline_data, dealloc;
-       startid : uint64_t;
-       count : int;
-       flags : int;
-       WaitTime timeout: natural_t;
-       out reply : ooline_data, dealloc;
-       out lastid : uint64_t;
-       out status : int;
-       SecToken token : security_token_t
-);
-
-routine _asl_server_prune
-(
-       server : mach_port_t;
-       request : ooline_data, dealloc;
-       out status : int;
-       SecToken token : security_token_t
-);
-
-simpleroutine _asl_server_message
-(
-       server : mach_port_t;
-       message : ooline_data, dealloc;
-       ServerAuditToken token : audit_token_t
-);
index 66d8703a2afdd0abcc70b679ae78e947073a4b72..e0a81d1ee29de269579106c4905bd07a264cbba7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 #include <asl_core.h>
-#include <asl_memory.h>
+#include "asl_memory.h"
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -50,7 +50,7 @@ asl_memory_statistics(asl_memory_t *s, aslmsg *msg)
        if (s == NULL) return ASL_STATUS_INVALID_STORE;
        if (msg == NULL) return ASL_STATUS_INVALID_ARG;
 
-       out = (aslmsg)calloc(1, sizeof(asl_msg_t));
+       out = asl_new(ASL_TYPE_MSG);
        if (out == NULL) return ASL_STATUS_NO_MEMORY;
 
        size = sizeof(asl_memory_t);
@@ -379,14 +379,18 @@ asl_memory_record_free(asl_memory_t *s, mem_record_t *r)
  * Creates and caches strings.
  */
 static uint32_t
-asl_memory_message_encode(asl_memory_t *s, asl_msg_t *msg, mem_record_t *r)
+asl_memory_message_encode(asl_memory_t *s, aslmsg msg)
 {
-       uint32_t i;
+       uint32_t x;
        mem_string_t *k, *v;
+       mem_record_t *r;
+       const char *key, *val;
 
        if (s == NULL) return ASL_STATUS_INVALID_STORE;
+       if (s->buffer_record == NULL) return ASL_STATUS_INVALID_STORE;
        if (msg == NULL) return ASL_STATUS_INVALID_MESSAGE;
-       if (r == NULL) return ASL_STATUS_INVALID_ARG;
+
+       r = s->buffer_record;
 
        memset(r, 0, sizeof(mem_record_t));
 
@@ -400,90 +404,93 @@ asl_memory_message_encode(asl_memory_t *s, asl_msg_t *msg, mem_record_t *r)
        r->time = (uint64_t)-1;
        r->nano = (uint32_t)-1;
 
-       for (i = 0; i < msg->count; i++)
+       key = NULL;
+       val = NULL;
+
+       for (x = asl_msg_fetch((asl_msg_t *)msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch((asl_msg_t *)msg, x, &key, &val, NULL))
        {
-               if (msg->key[i] == NULL) continue;
+               if (key == NULL) continue;
 
-               else if (!strcmp(msg->key[i], ASL_KEY_TIME))
+               else if (!strcmp(key, ASL_KEY_TIME))
                {
-                       if (msg->val[i] != NULL) r->time = asl_parse_time(msg->val[i]);
+                       if (val != NULL) r->time = asl_parse_time(val);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_TIME_NSEC))
+               else if (!strcmp(key, ASL_KEY_TIME_NSEC))
                {
-                       if (msg->val[i] != NULL) r->nano = atoi(msg->val[i]);
+                       if (val != NULL) r->nano = atoi(val);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_HOST))
+               else if (!strcmp(key, ASL_KEY_HOST))
                {
-                       if (msg->val[i] != NULL) r->host = asl_memory_string_retain(s, msg->val[i], 1);
+                       if (val != NULL) r->host = asl_memory_string_retain(s, val, 1);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_SENDER))
+               else if (!strcmp(key, ASL_KEY_SENDER))
                {
-                       if (msg->val[i] != NULL) r->sender = asl_memory_string_retain(s, msg->val[i], 1);
+                       if (val != NULL) r->sender = asl_memory_string_retain(s, val, 1);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_PID))
+               else if (!strcmp(key, ASL_KEY_PID))
                {
-                       if (msg->val[i] != NULL) r->pid = atoi(msg->val[i]);
+                       if (val != NULL) r->pid = atoi(val);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_REF_PID))
+               else if (!strcmp(key, ASL_KEY_REF_PID))
                {
-                       if (msg->val[i] != NULL) r->refpid = atoi(msg->val[i]);
+                       if (val != NULL) r->refpid = atoi(val);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_UID))
+               else if (!strcmp(key, ASL_KEY_UID))
                {
-                       if (msg->val[i] != NULL) r->uid = atoi(msg->val[i]);
+                       if (val != NULL) r->uid = atoi(val);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_GID))
+               else if (!strcmp(key, ASL_KEY_GID))
                {
-                       if (msg->val[i] != NULL) r->gid = atoi(msg->val[i]);
+                       if (val != NULL) r->gid = atoi(val);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_LEVEL))
+               else if (!strcmp(key, ASL_KEY_LEVEL))
                {
-                       if (msg->val[i] != NULL) r->level = atoi(msg->val[i]);
+                       if (val != NULL) r->level = atoi(val);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_MSG))
+               else if (!strcmp(key, ASL_KEY_MSG))
                {
-                       if (msg->val[i] != NULL) r->message = asl_memory_string_retain(s, msg->val[i], 1);
+                       if (val != NULL) r->message = asl_memory_string_retain(s, val, 1);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_FACILITY))
+               else if (!strcmp(key, ASL_KEY_FACILITY))
                {
-                       if (msg->val[i] != NULL) r->facility = asl_memory_string_retain(s, msg->val[i], 1);
+                       if (val != NULL) r->facility = asl_memory_string_retain(s, val, 1);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_REF_PROC))
+               else if (!strcmp(key, ASL_KEY_REF_PROC))
                {
-                       if (msg->val[i] != NULL) r->refproc = asl_memory_string_retain(s, msg->val[i], 1);
+                       if (val != NULL) r->refproc = asl_memory_string_retain(s, val, 1);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_SESSION))
+               else if (!strcmp(key, ASL_KEY_SESSION))
                {
-                       if (msg->val[i] != NULL) r->session = asl_memory_string_retain(s, msg->val[i], 1);
+                       if (val != NULL) r->session = asl_memory_string_retain(s, val, 1);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_READ_UID))
+               else if (!strcmp(key, ASL_KEY_READ_UID))
                {
-                       if (((r->flags & ASL_MSG_FLAG_READ_UID_SET) == 0) && (msg->val[i] != NULL))
+                       if (((r->flags & ASL_MSG_FLAG_READ_UID_SET) == 0) && (val != NULL))
                        {
-                               r->ruid = atoi(msg->val[i]);
+                               r->ruid = atoi(val);
                                r->flags |= ASL_MSG_FLAG_READ_UID_SET;
                        }
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_READ_GID))
+               else if (!strcmp(key, ASL_KEY_READ_GID))
                {
-                       if (((r->flags & ASL_MSG_FLAG_READ_GID_SET) == 0) && (msg->val[i] != NULL))
+                       if (((r->flags & ASL_MSG_FLAG_READ_GID_SET) == 0) && (val != NULL))
                        {
-                               r->rgid = atoi(msg->val[i]);
+                               r->rgid = atoi(val);
                                r->flags |= ASL_MSG_FLAG_READ_GID_SET;
                        }
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_MSG_ID))
+               else if (!strcmp(key, ASL_KEY_MSG_ID))
                {
                        /* Ignore */
                        continue;
                }
                else
                {
-                       k = asl_memory_string_retain(s, msg->key[i], 1);
+                       k = asl_memory_string_retain(s, key, 1);
                        if (k == NULL) continue;
 
                        v = NULL;
-                       if (msg->val[i] != NULL) v = asl_memory_string_retain(s, msg->val[i], 1);
+                       if (val != NULL) v = asl_memory_string_retain(s, val, 1);
 
                        if (r->kvcount == 0)
                        {
@@ -518,7 +525,7 @@ asl_memory_save(asl_memory_t *s, aslmsg msg, uint64_t *mid)
        if (s->buffer_record == NULL) return ASL_STATUS_INVALID_STORE;
 
        /* asl_memory_message_encode creates and caches strings */
-       status = asl_memory_message_encode(s, msg, s->buffer_record);
+       status = asl_memory_message_encode(s, msg);
        if (status != ASL_STATUS_OK) return status;
 
        if (*mid != 0)
@@ -550,10 +557,12 @@ asl_memory_save(asl_memory_t *s, aslmsg msg, uint64_t *mid)
  * Decodes a record structure.
  */
 static uint32_t
-asl_memory_message_decode(asl_memory_t *s, mem_record_t *r, asl_msg_t **out)
+asl_memory_message_decode(asl_memory_t *s, mem_record_t *r, aslmsg *out)
 {
-       uint32_t i, n;
-       asl_msg_t *msg;
+       uint32_t i;
+       aslmsg msg;
+       char tmp[64];
+       const char *key, *val;
 
        if (s == NULL) return ASL_STATUS_INVALID_STORE;
        if (r == NULL) return ASL_STATUS_INVALID_ARG;
@@ -561,321 +570,120 @@ asl_memory_message_decode(asl_memory_t *s, mem_record_t *r, asl_msg_t **out)
 
        *out = NULL;
 
-       msg = (asl_msg_t *)calloc(1, sizeof(asl_msg_t));
+       msg = asl_new(ASL_TYPE_MSG);
        if (msg == NULL) return ASL_STATUS_NO_MEMORY;
 
-       msg->type = ASL_TYPE_MSG;
-       /* Level and Message ID are always set */
-       msg->count = 2;
-       if (r->time != (uint64_t)-1) msg->count++;
-       if (r->nano != (uint32_t)-1) msg->count++;
-       if (r->host != NULL) msg->count++;
-       if (r->sender != NULL) msg->count++;
-       if (r->facility != NULL) msg->count++;
-       if (r->refproc != NULL) msg->count++;
-       if (r->session != NULL) msg->count++;
-       if (r->pid != -1) msg->count++;
-       if (r->refpid != 0) msg->count++;
-       if (r->uid != -2) msg->count++;
-       if (r->gid != -2) msg->count++;
-       if (r->message != NULL) msg->count++;
-       if (r->flags & ASL_MSG_FLAG_READ_UID_SET) msg->count++;
-       if (r->flags & ASL_MSG_FLAG_READ_GID_SET) msg->count++;
-
-       msg->count += (r->kvcount / 2);
-
-       msg->key = (char **)calloc(msg->count, sizeof(char *));
-       if (msg->key == NULL)
-       {
-               free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-
-       msg->val = (char **)calloc(msg->count, sizeof(char *));
-       if (msg->val == NULL)
-       {
-               free(msg->key);
-               free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-
-       n = 0;
-
        /* Message ID */
-       msg->key[n] = strdup(ASL_KEY_MSG_ID);
-       if (msg->key[n] == NULL)
-       {
-               asl_free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-
-       asprintf(&(msg->val[n]), "%llu", r->mid);
-       if (msg->val[n] == NULL)
-       {
-               asl_free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-       n++;
+       snprintf(tmp, sizeof(tmp), "%llu", r->mid);
+       asl_set(msg, ASL_KEY_MSG_ID, tmp);
 
        /* Level */
-       msg->key[n] = strdup(ASL_KEY_LEVEL);
-       if (msg->key[n] == NULL)
-       {
-               asl_free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-
-       asprintf(&(msg->val[n]), "%u", r->level);
-       if (msg->val[n] == NULL)
-       {
-               asl_free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-       n++;
+       snprintf(tmp, sizeof(tmp), "%u", r->level);
+       asl_set(msg, ASL_KEY_LEVEL, tmp);
 
        /* Time */
        if (r->time != (uint64_t)-1)
        {
-               msg->key[n] = strdup(ASL_KEY_TIME);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               asprintf(&(msg->val[n]), "%llu", r->time);
-               if (msg->val[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-               n++;
+               snprintf(tmp, sizeof(tmp), "%llu", r->time);
+               asl_set(msg, ASL_KEY_TIME, tmp);
        }
 
        /* Nanoseconds */
        if (r->nano != (uint32_t)-1)
        {
-               msg->key[n] = strdup(ASL_KEY_TIME_NSEC);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               asprintf(&(msg->val[n]), "%lu", r->nano);
-               if (msg->val[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-               n++;
+               snprintf(tmp, sizeof(tmp), "%u", r->nano);
+               asl_set(msg, ASL_KEY_TIME_NSEC, tmp);
        }
 
        /* Host */
        if (r->host != NULL)
        {
-               msg->key[n] = strdup(ASL_KEY_HOST);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               msg->val[n] = strdup(r->host->str);
-               n++;
+               asl_set(msg, ASL_KEY_HOST, r->host->str);
        }
 
        /* Sender */
        if (r->sender != NULL)
        {
-               msg->key[n] = strdup(ASL_KEY_SENDER);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               msg->val[n] = strdup(r->sender->str);
-               n++;
+               asl_set(msg, ASL_KEY_SENDER, r->sender->str);
        }
 
        /* Facility */
        if (r->facility != NULL)
        {
-               msg->key[n] = strdup(ASL_KEY_FACILITY);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               msg->val[n] = strdup(r->facility->str);
-               n++;
+               asl_set(msg, ASL_KEY_FACILITY, r->facility->str);
        }
 
        /* Ref Proc */
        if (r->refproc != NULL)
        {
-               msg->key[n] = strdup(ASL_KEY_REF_PROC);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               msg->val[n] = strdup(r->refproc->str);
-               n++;
+               asl_set(msg, ASL_KEY_REF_PROC, r->refproc->str);
        }
 
        /* Session */
        if (r->session != NULL)
        {
-               msg->key[n] = strdup(ASL_KEY_SESSION);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               msg->val[n] = strdup(r->session->str);
-               n++;
+               asl_set(msg, ASL_KEY_SESSION, r->session->str);
        }
 
        /* PID */
        if (r->pid != -1)
        {
-               msg->key[n] = strdup(ASL_KEY_PID);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               asprintf(&(msg->val[n]), "%d", r->pid);
-               if (msg->val[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-               n++;
+               snprintf(tmp, sizeof(tmp), "%d", r->pid);
+               asl_set(msg, ASL_KEY_PID, tmp);
        }
 
        /* REF PID */
        if (r->refpid != 0)
        {
-               msg->key[n] = strdup(ASL_KEY_REF_PID);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               asprintf(&(msg->val[n]), "%d", r->refpid);
-               if (msg->val[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-               n++;
+               snprintf(tmp, sizeof(tmp), "%d", r->refpid);
+               asl_set(msg, ASL_KEY_REF_PID, tmp);
        }
 
        /* UID */
        if (r->uid != -2)
        {
-               msg->key[n] = strdup(ASL_KEY_UID);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               asprintf(&(msg->val[n]), "%d", r->uid);
-               if (msg->val[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-               n++;
+               snprintf(tmp, sizeof(tmp), "%d", r->uid);
+               asl_set(msg, ASL_KEY_UID, tmp);
        }
 
        /* GID */
        if (r->gid != -2)
        {
-               msg->key[n] = strdup(ASL_KEY_GID);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               asprintf(&(msg->val[n]), "%d", r->gid);
-               if (msg->val[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-               n++;
+               snprintf(tmp, sizeof(tmp), "%d", r->gid);
+               asl_set(msg, ASL_KEY_GID, tmp);
        }
 
        /* Message */
        if (r->message != NULL)
        {
-               msg->key[n] = strdup(ASL_KEY_MSG);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               msg->val[n] = strdup(r->message->str);
-               n++;
+               asl_set(msg, ASL_KEY_MSG, r->message->str);
        }
 
        /* ReadUID */
        if (r->flags & ASL_MSG_FLAG_READ_UID_SET)
        {
-               msg->key[n] = strdup(ASL_KEY_READ_UID);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               asprintf(&(msg->val[n]), "%d", r->ruid);
-               if (msg->val[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-               n++;
+               snprintf(tmp, sizeof(tmp), "%d", r->ruid);
+               asl_set(msg, ASL_KEY_READ_UID, tmp);
        }
 
        /* ReadGID */
        if (r->flags & ASL_MSG_FLAG_READ_GID_SET)
        {
-               msg->key[n] = strdup(ASL_KEY_READ_GID);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               asprintf(&(msg->val[n]), "%d", r->rgid);
-               if (msg->val[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-               n++;
+               snprintf(tmp, sizeof(tmp), "%d", r->rgid);
+               asl_set(msg, ASL_KEY_READ_GID, tmp);
        }
 
        /* Key - Value List */
        for (i = 0; i < r->kvcount; i++)
        {
-               if ((r->kvlist[i] != NULL) && (r->kvlist[i]->str != NULL)) msg->key[n] = strdup(r->kvlist[i]->str);
+               key = NULL;
+               val = NULL;
+
+               if ((r->kvlist[i] != NULL) && (r->kvlist[i]->str != NULL)) key = r->kvlist[i]->str;
                i++;
-               if ((r->kvlist[i] != NULL) && (r->kvlist[i]->str != NULL)) msg->val[n] = strdup(r->kvlist[i]->str);
-               n++;
+               if ((r->kvlist[i] != NULL) && (r->kvlist[i]->str != NULL)) val = r->kvlist[i]->str;
+
+               if (key != NULL) asl_set(msg, key, val);
        }
 
        *out = msg;
@@ -906,11 +714,12 @@ asl_memory_fetch(asl_memory_t *s, uint64_t mid, aslmsg *msg, int32_t ruid, int32
 }
 
 static mem_record_t *
-asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
+asl_memory_query_to_record(asl_memory_t *s, aslmsg q, uint32_t *type)
 {
        mem_record_t *out;
-       uint32_t i, j;
-       mem_string_t *key, *val;
+       uint32_t i, x, op;
+       mem_string_t *mkey, *mval;
+       const char *key, *val;
 
        if (type == NULL) return NULL;
 
@@ -923,14 +732,15 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
        /* NULL query matches anything */
        *type = ASL_QUERY_MATCH_TRUE;
        if (q == NULL) return NULL;
-       if (q->count == 0) return NULL;
+       if (asl_msg_count((asl_msg_t *)q) == 0) return NULL;
 
 
        /* we can only do fast match on equality tests */
        *type = ASL_QUERY_MATCH_SLOW;
-       if (q->op != NULL)
+
+       for (x = asl_msg_fetch((asl_msg_t *)q, 0, NULL, NULL, &op); x != IndexNull; x = asl_msg_fetch((asl_msg_t *)q, x, NULL, NULL, &op))
        {
-               for (i = 0; i < q->count; i++) if (q->op[i] != ASL_QUERY_OP_EQUAL) return NULL;
+               if (op != ASL_QUERY_OP_EQUAL) return NULL;
        }
 
        out = (mem_record_t *)calloc(1, sizeof(mem_record_t));
@@ -940,13 +750,13 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                return NULL;
        }
 
-       for (i = 0; i < q->count; i++)
+       for (x = asl_msg_fetch((asl_msg_t *)q, 0, &key, &val, &op); x != IndexNull; x = asl_msg_fetch((asl_msg_t *)q, x, &key, &val, &op))
        {
-               if (q->key[i] == NULL) continue;
+               if (key == NULL) continue;
 
-               else if (!strcmp(q->key[i], ASL_KEY_MSG_ID))
+               else if (!strcmp(key, ASL_KEY_MSG_ID))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_MSG_ID)
                        {
@@ -956,11 +766,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_MSG_ID;
-                       out->mid = atoll(q->val[i]);
+                       out->mid = atoll(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_TIME))
+               else if (!strcmp(key, ASL_KEY_TIME))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_TIME)
                        {
@@ -970,11 +780,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_TIME;
-                       out->time = asl_parse_time(q->val[i]);
+                       out->time = asl_parse_time(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_TIME_NSEC))
+               else if (!strcmp(key, ASL_KEY_TIME_NSEC))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_NANO)
                        {
@@ -984,11 +794,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_NANO;
-                       out->nano = atoll(q->val[i]);
+                       out->nano = atoll(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_LEVEL))
+               else if (!strcmp(key, ASL_KEY_LEVEL))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_LEVEL)
                        {
@@ -998,11 +808,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_LEVEL;
-                       out->level = atoi(q->val[i]);
+                       out->level = atoi(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_PID))
+               else if (!strcmp(key, ASL_KEY_PID))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_PID)
                        {
@@ -1012,11 +822,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_PID;
-                       out->pid = atoi(q->val[i]);
+                       out->pid = atoi(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_UID))
+               else if (!strcmp(key, ASL_KEY_UID))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_UID)
                        {
@@ -1026,11 +836,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_UID;
-                       out->uid = atoi(q->val[i]);
+                       out->uid = atoi(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_GID))
+               else if (!strcmp(key, ASL_KEY_GID))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_GID)
                        {
@@ -1040,11 +850,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_GID;
-                       out->gid = atoi(q->val[i]);
+                       out->gid = atoi(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_READ_UID))
+               else if (!strcmp(key, ASL_KEY_READ_UID))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_RUID)
                        {
@@ -1054,11 +864,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_RUID;
-                       out->ruid = atoi(q->val[i]);
+                       out->ruid = atoi(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_READ_GID))
+               else if (!strcmp(key, ASL_KEY_READ_GID))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_RGID)
                        {
@@ -1068,11 +878,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_RGID;
-                       out->rgid = atoi(q->val[i]);
+                       out->rgid = atoi(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_REF_PID))
+               else if (!strcmp(key, ASL_KEY_REF_PID))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_REF_PID)
                        {
@@ -1082,11 +892,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_REF_PID;
-                       out->refpid = atoi(q->val[i]);
+                       out->refpid = atoi(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_HOST))
+               else if (!strcmp(key, ASL_KEY_HOST))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_HOST)
                        {
@@ -1096,7 +906,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_HOST;
-                       out->host = asl_memory_string_retain(s, q->val[i], 0);
+                       out->host = asl_memory_string_retain(s, val, 0);
                        if (out->host == NULL)
                        {
                                asl_memory_record_free(s, out);
@@ -1104,9 +914,9 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                                return NULL;
                        }
                }
-               else if (!strcmp(q->key[i], ASL_KEY_SENDER))
+               else if (!strcmp(key, ASL_KEY_SENDER))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_SENDER)
                        {
@@ -1116,7 +926,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_SENDER;
-                       out->sender = asl_memory_string_retain(s, q->val[i], 0);
+                       out->sender = asl_memory_string_retain(s, val, 0);
                        if (out->sender == NULL)
                        {
                                asl_memory_record_free(s, out);
@@ -1124,9 +934,9 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                                return NULL;
                        }
                }
-               else if (!strcmp(q->key[i], ASL_KEY_FACILITY))
+               else if (!strcmp(key, ASL_KEY_FACILITY))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_FACILITY)
                        {
@@ -1136,7 +946,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_FACILITY;
-                       out->facility = asl_memory_string_retain(s, q->val[i], 0);
+                       out->facility = asl_memory_string_retain(s, val, 0);
                        if (out->facility == NULL)
                        {
                                asl_memory_record_free(s, out);
@@ -1144,9 +954,9 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                                return NULL;
                        }
                }
-               else if (!strcmp(q->key[i], ASL_KEY_MSG))
+               else if (!strcmp(key, ASL_KEY_MSG))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_MESSAGE)
                        {
@@ -1156,7 +966,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_MESSAGE;
-                       out->message = asl_memory_string_retain(s, q->val[i], 0);
+                       out->message = asl_memory_string_retain(s, val, 0);
                        if (out->message == NULL)
                        {
                                asl_memory_record_free(s, out);
@@ -1164,9 +974,9 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                                return NULL;
                        }
                }
-               else if (!strcmp(q->key[i], ASL_KEY_REF_PROC))
+               else if (!strcmp(key, ASL_KEY_REF_PROC))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_REF_PROC)
                        {
@@ -1176,7 +986,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_REF_PROC;
-                       out->refproc = asl_memory_string_retain(s, q->val[i], 0);
+                       out->refproc = asl_memory_string_retain(s, val, 0);
                        if (out->refproc == NULL)
                        {
                                asl_memory_record_free(s, out);
@@ -1184,9 +994,9 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                                return NULL;
                        }
                }
-               else if (!strcmp(q->key[i], ASL_KEY_SESSION))
+               else if (!strcmp(key, ASL_KEY_SESSION))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_SESSION)
                        {
@@ -1196,7 +1006,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                        }
 
                        *type |= ASL_QUERY_MATCH_SESSION;
-                       out->session = asl_memory_string_retain(s, q->val[i], 0);
+                       out->session = asl_memory_string_retain(s, val, 0);
                        if (out->session == NULL)
                        {
                                asl_memory_record_free(s, out);
@@ -1206,17 +1016,17 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                }
                else
                {
-                       key = asl_memory_string_retain(s, q->key[i], 0);
-                       if (key == NULL)
+                       mkey = asl_memory_string_retain(s, key, 0);
+                       if (mkey == NULL)
                        {
                                asl_memory_record_free(s, out);
                                *type = ASL_QUERY_MATCH_FALSE;
                                return NULL;
                        }
 
-                       for (j = 0; j < out->kvcount; j += 2)
+                       for (i = 0; i < out->kvcount; i += 2)
                        {
-                               if (out->kvlist[j] == key)
+                               if (out->kvlist[i] == mkey)
                                {
                                        asl_memory_record_free(s, out);
                                        *type = ASL_QUERY_MATCH_SLOW;
@@ -1224,7 +1034,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                                }
                        }
 
-                       val = asl_memory_string_retain(s, q->val[i], 0);
+                       mval = asl_memory_string_retain(s, val, 0);
 
                        if (out->kvcount == 0)
                        {
@@ -1242,8 +1052,8 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type)
                                return NULL;
                        }
 
-                       out->kvlist[out->kvcount++] = key;
-                       out->kvlist[out->kvcount++] = val;
+                       out->kvlist[out->kvcount++] = mkey;
+                       out->kvlist[out->kvcount++] = mval;
                }
        }
 
@@ -1294,9 +1104,9 @@ asl_memory_fast_match(asl_memory_t *s, mem_record_t *r, uint32_t qtype, mem_reco
 }
 
 static uint32_t
-asl_memory_slow_match(asl_memory_t *s, mem_record_t *r, mem_record_t *q, asl_msg_t *rawq)
+asl_memory_slow_match(asl_memory_t *s, mem_record_t *r, aslmsg rawq)
 {
-       asl_msg_t *rawm;
+       aslmsg rawm;
        uint32_t status;
 
        rawm = NULL;
@@ -1304,7 +1114,7 @@ asl_memory_slow_match(asl_memory_t *s, mem_record_t *r, mem_record_t *q, asl_msg
        if (status != ASL_STATUS_OK) return 0;
 
        status = 0;
-       if (asl_msg_cmp(rawq, rawm) != 0) status = 1;
+       if (asl_msg_cmp((asl_msg_t *)rawq, (asl_msg_t *)rawm) != 0) status = 1;
        asl_free(rawm);
        return status;
 }
@@ -1314,7 +1124,7 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t
 {
        uint32_t status, i, where, start, j, do_match, did_match, rescount, *qtype;
        mem_record_t **qp;
-       asl_msg_t *m;
+       aslmsg m;
 
        if (s == NULL) return ASL_STATUS_INVALID_STORE;
        if (res == NULL) return ASL_STATUS_INVALID_ARG;
@@ -1343,7 +1153,7 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t
                do_match = 0;
                for (i = 0; i < query->count; i++)
                {
-                       qp[i] = asl_memory_query_to_record(s, query->msg[i], &(qtype[i]));
+                       qp[i] = asl_memory_query_to_record(s, (aslmsg)query->msg[i], &(qtype[i]));
                        if (qtype[i] == ASL_QUERY_MATCH_ERROR)
                        {
                                for (j = 0; j < i; j++) asl_memory_record_free(s, qp[j]);
@@ -1424,9 +1234,13 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t
                                {
                                        did_match = 1;
                                }
+                               else if (qtype[j] == ASL_QUERY_MATCH_FALSE)
+                               {
+                                       did_match = 0;
+                               }
                                else if (qtype[j] == ASL_QUERY_MATCH_SLOW)
                                {
-                                       did_match = asl_memory_slow_match(s, s->record[where], qp[j], query->msg[j]);
+                                       did_match = asl_memory_slow_match(s, s->record[where], (aslmsg)query->msg[j]);
                                }
                                else
                                {
@@ -1494,7 +1308,7 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t
                                return status;
                        }
 
-                       (*res)->msg[(*res)->curr++] = m;
+                       (*res)->msg[(*res)->curr++] = (asl_msg_t *)m;
                        if ((*res)->curr == rescount) break;
                }
 
index 08ba36e0abd7384f584dd45d09fff42c7247e4a3..8510a0776fdfa419ac49938e7b7542658f8f9a5d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,8 +22,8 @@
  */
 
 #include <asl_core.h>
-#include <asl_mini_memory.h>
-#include <unistd.h>
+#include "asl_mini_memory.h"
+#include <unistd.h>x
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/errno.h>
@@ -31,6 +31,7 @@
 #include <sys/types.h>
 #include <time.h>
 #include <asl_private.h>
+#include <asl_msg.h>
 
 #define DEFAULT_MAX_RECORDS 256
 #define MEM_STRING_HEADER_SIZE 8
@@ -52,7 +53,7 @@ asl_mini_memory_statistics(asl_mini_memory_t *s, aslmsg *msg)
        if (s == NULL) return ASL_STATUS_INVALID_STORE;
        if (msg == NULL) return ASL_STATUS_INVALID_ARG;
 
-       out = (aslmsg)calloc(1, sizeof(asl_msg_t));
+       out = asl_new(ASL_TYPE_MSG);
        if (out == NULL) return ASL_STATUS_NO_MEMORY;
 
        size = sizeof(asl_mini_memory_t);
@@ -380,14 +381,18 @@ asl_mini_memory_record_free(asl_mini_memory_t *s, mini_mem_record_t *r)
  * Creates and caches strings.
  */
 static uint32_t
-asl_mini_memory_message_encode(asl_mini_memory_t *s, asl_msg_t *msg, mini_mem_record_t *r)
+asl_mini_memory_message_encode(asl_mini_memory_t *s, aslmsg msg)
 {
-       uint32_t i;
+       uint32_t x;
        mini_mem_string_t *k, *v;
+       mini_mem_record_t *r;
+       const char *key, *val;
 
        if (s == NULL) return ASL_STATUS_INVALID_STORE;
+       if (s->buffer_record == NULL) return ASL_STATUS_INVALID_STORE;
        if (msg == NULL) return ASL_STATUS_INVALID_MESSAGE;
-       if (r == NULL) return ASL_STATUS_INVALID_ARG;
+
+       r = s->buffer_record;
 
        memset(r, 0, sizeof(mini_mem_record_t));
 
@@ -396,101 +401,104 @@ asl_mini_memory_message_encode(asl_mini_memory_t *s, asl_msg_t *msg, mini_mem_re
        r->pid = -1;
        r->time = (uint64_t)-1;
 
-       for (i = 0; i < msg->count; i++)
+       key = NULL;
+       val = NULL;
+
+       for (x = asl_msg_fetch((asl_msg_t *)msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch((asl_msg_t *)msg, x, &key, &val, NULL))
        {
-               if (msg->key[i] == NULL) continue;
+               if (key == NULL) continue;
 
-               else if (!strcmp(msg->key[i], ASL_KEY_TIME))
+               else if (!strcmp(key, ASL_KEY_TIME))
                {
-                       if (msg->val[i] != NULL) r->time = asl_parse_time(msg->val[i]);
+                       if (val != NULL) r->time = asl_parse_time(val);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_SENDER))
+               else if (!strcmp(key, ASL_KEY_SENDER))
                {
-                       if (msg->val[i] != NULL) r->sender = asl_mini_memory_string_retain(s, msg->val[i], 1);
+                       if (val != NULL) r->sender = asl_mini_memory_string_retain(s, val, 1);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_PID))
+               else if (!strcmp(key, ASL_KEY_PID))
                {
-                       if (msg->val[i] != NULL) r->pid = atoi(msg->val[i]);
+                       if (val != NULL) r->pid = atoi(val);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_LEVEL))
+               else if (!strcmp(key, ASL_KEY_LEVEL))
                {
-                       if (msg->val[i] != NULL) r->level = atoi(msg->val[i]);
+                       if (val != NULL) r->level = atoi(val);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_MSG))
+               else if (!strcmp(key, ASL_KEY_MSG))
                {
-                       if (msg->val[i] != NULL) r->message = asl_mini_memory_string_retain(s, msg->val[i], 1);
+                       if (val != NULL) r->message = asl_mini_memory_string_retain(s, val, 1);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_FACILITY))
+               else if (!strcmp(key, ASL_KEY_FACILITY))
                {
-                       if (msg->val[i] != NULL) r->facility = asl_mini_memory_string_retain(s, msg->val[i], 1);
+                       if (val != NULL) r->facility = asl_mini_memory_string_retain(s, val, 1);
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_MSG_ID))
+               else if (!strcmp(key, ASL_KEY_MSG_ID))
                {
                        /* Ignore */
                        continue;
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_TIME_NSEC))
+               else if (!strcmp(key, ASL_KEY_TIME_NSEC))
                {
                        /* Ignore */
                        continue;
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_HOST))
+               else if (!strcmp(key, ASL_KEY_HOST))
                {
                        /* Ignore */
                        continue;
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_REF_PID))
+               else if (!strcmp(key, ASL_KEY_REF_PID))
                {
                        /* Ignore */
                        continue;
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_REF_PROC))
+               else if (!strcmp(key, ASL_KEY_REF_PROC))
                {
                        /* Ignore */
                        continue;
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_SESSION))
+               else if (!strcmp(key, ASL_KEY_SESSION))
                {
                        /* Ignore */
                        continue;
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_UID))
+               else if (!strcmp(key, ASL_KEY_UID))
                {
                        /* Ignore */
                        continue;
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_GID))
+               else if (!strcmp(key, ASL_KEY_GID))
                {
                        /* Ignore */
                        continue;
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_READ_UID))
+               else if (!strcmp(key, ASL_KEY_READ_UID))
                {
                        /* Ignore */
                        continue;
                }
-               else if (!strcmp(msg->key[i], ASL_KEY_READ_GID))
+               else if (!strcmp(key, ASL_KEY_READ_GID))
                {
                        /* Ignore */
                        continue;
                }
-               else if (!strcmp(msg->key[i], CFLOG_LOCAL_TIME_KEY))
+               else if (!strcmp(key, CFLOG_LOCAL_TIME_KEY))
                {
                        /* Ignore */
                        continue;
                }
-               else if (!strcmp(msg->key[i], CFLOG_THREAD_KEY))
+               else if (!strcmp(key, CFLOG_THREAD_KEY))
                {
                        /* Ignore */
                        continue;
                }
                else
                {
-                       k = asl_mini_memory_string_retain(s, msg->key[i], 1);
+                       k = asl_mini_memory_string_retain(s, key, 1);
                        if (k == NULL) continue;
 
                        v = NULL;
-                       if (msg->val[i] != NULL) v = asl_mini_memory_string_retain(s, msg->val[i], 1);
+                       if (val != NULL) v = asl_mini_memory_string_retain(s, val, 1);
 
                        if (r->kvcount == 0)
                        {
@@ -525,7 +533,7 @@ asl_mini_memory_save(asl_mini_memory_t *s, aslmsg msg, uint64_t *mid)
        if (s->buffer_record == NULL) return ASL_STATUS_INVALID_STORE;
 
        /* asl_mini_memory_message_encode creates and caches strings */
-       status = asl_mini_memory_message_encode(s, msg, s->buffer_record);
+       status = asl_mini_memory_message_encode(s, msg);
        if (status != ASL_STATUS_OK) return status;
 
        s->buffer_record->mid = s->next_id;
@@ -552,10 +560,12 @@ asl_mini_memory_save(asl_mini_memory_t *s, aslmsg msg, uint64_t *mid)
  * Decodes a record structure.
  */
 static uint32_t
-asl_mini_memory_message_decode(asl_mini_memory_t *s, mini_mem_record_t *r, asl_msg_t **out)
+asl_mini_memory_message_decode(asl_mini_memory_t *s, mini_mem_record_t *r, aslmsg *out)
 {
-       uint32_t i, n;
-       asl_msg_t *msg;
+       uint32_t i;
+       aslmsg msg;
+       char tmp[64];
+       const char *key, *val;
 
        if (s == NULL) return ASL_STATUS_INVALID_STORE;
        if (r == NULL) return ASL_STATUS_INVALID_ARG;
@@ -563,157 +573,60 @@ asl_mini_memory_message_decode(asl_mini_memory_t *s, mini_mem_record_t *r, asl_m
 
        *out = NULL;
 
-       msg = (asl_msg_t *)calloc(1, sizeof(asl_msg_t));
+       msg = asl_new(ASL_TYPE_MSG);
        if (msg == NULL) return ASL_STATUS_NO_MEMORY;
 
-       msg->type = ASL_TYPE_MSG;
-       /* Level and Message ID are always set */
-       msg->count = 2;
-
-       if (r->time != (uint64_t)-1) msg->count++;
-       if (r->sender != NULL) msg->count++;
-       if (r->facility != NULL) msg->count++;
-       if (r->pid != -1) msg->count++;
-       if (r->message != NULL) msg->count++;
-
-       msg->count += (r->kvcount / 2);
-
-       msg->key = (char **)calloc(msg->count, sizeof(char *));
-       if (msg->key == NULL)
-       {
-               free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-
-       msg->val = (char **)calloc(msg->count, sizeof(char *));
-       if (msg->val == NULL)
-       {
-               free(msg->key);
-               free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-
-       n = 0;
-
        /* Message ID */
-       msg->key[n] = strdup(ASL_KEY_MSG_ID);
-       if (msg->key[n] == NULL)
-       {
-               asl_free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-
-       asprintf(&(msg->val[n]), "%lu", r->mid);
-       if (msg->val[n] == NULL)
-       {
-               asl_free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-       n++;
+       snprintf(tmp, sizeof(tmp), "%u", r->mid);
+       asl_set(msg, ASL_KEY_MSG_ID, tmp);
 
        /* Level */
-       msg->key[n] = strdup(ASL_KEY_LEVEL);
-       if (msg->key[n] == NULL)
-       {
-               asl_free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-
-       asprintf(&(msg->val[n]), "%u", r->level);
-       if (msg->val[n] == NULL)
-       {
-               asl_free(msg);
-               return ASL_STATUS_NO_MEMORY;
-       }
-       n++;
+       snprintf(tmp, sizeof(tmp), "%u", r->level);
+       asl_set(msg, ASL_KEY_LEVEL, tmp);
 
        /* Time */
        if (r->time != (uint64_t)-1)
        {
-               msg->key[n] = strdup(ASL_KEY_TIME);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               asprintf(&(msg->val[n]), "%llu", r->time);
-               if (msg->val[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-               n++;
+               snprintf(tmp, sizeof(tmp), "%llu", r->time);
+               asl_set(msg, ASL_KEY_TIME, tmp);
        }
 
        /* Sender */
        if (r->sender != NULL)
        {
-               msg->key[n] = strdup(ASL_KEY_SENDER);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               msg->val[n] = strdup(r->sender->str);
-               n++;
+               asl_set(msg, ASL_KEY_SENDER, r->sender->str);
        }
 
        /* Facility */
        if (r->facility != NULL)
        {
-               msg->key[n] = strdup(ASL_KEY_FACILITY);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               msg->val[n] = strdup(r->facility->str);
-               n++;
+               asl_set(msg, ASL_KEY_FACILITY, r->facility->str);
        }
 
        /* PID */
        if (r->pid != -1)
        {
-               msg->key[n] = strdup(ASL_KEY_PID);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               asprintf(&(msg->val[n]), "%d", r->pid);
-               if (msg->val[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-               n++;
+               snprintf(tmp, sizeof(tmp), "%d", r->pid);
+               asl_set(msg, ASL_KEY_PID, tmp);
        }
 
        /* Message */
        if (r->message != NULL)
        {
-               msg->key[n] = strdup(ASL_KEY_MSG);
-               if (msg->key[n] == NULL)
-               {
-                       asl_free(msg);
-                       return ASL_STATUS_NO_MEMORY;
-               }
-
-               msg->val[n] = strdup(r->message->str);
-               n++;
+               asl_set(msg, ASL_KEY_MSG, r->message->str);
        }
 
        /* Key - Value List */
        for (i = 0; i < r->kvcount; i++)
        {
-               if ((r->kvlist[i] != NULL) && (r->kvlist[i]->str != NULL)) msg->key[n] = strdup(r->kvlist[i]->str);
+               key = NULL;
+               val = NULL;
+
+               if ((r->kvlist[i] != NULL) && (r->kvlist[i]->str != NULL)) key = r->kvlist[i]->str;
                i++;
-               if ((r->kvlist[i] != NULL) && (r->kvlist[i]->str != NULL)) msg->val[n] = strdup(r->kvlist[i]->str);
-               n++;
+               if ((r->kvlist[i] != NULL) && (r->kvlist[i]->str != NULL)) val = r->kvlist[i]->str;
+
+               if (key != NULL) asl_set(msg, key, val);
        }
 
        *out = msg;
@@ -741,8 +654,9 @@ static mini_mem_record_t *
 asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *type)
 {
        mini_mem_record_t *out;
-       uint32_t i, j;
-       mini_mem_string_t *key, *val;
+       uint32_t i, x, op;
+       mini_mem_string_t *mkey, *mval;
+       const char *key, *val;
 
        if (type == NULL) return NULL;
 
@@ -755,14 +669,15 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
        /* NULL query matches anything */
        *type = ASL_QUERY_MATCH_TRUE;
        if (q == NULL) return NULL;
-       if (q->count == 0) return NULL;
+       if (asl_msg_count((asl_msg_t *)q) == 0) return NULL;
 
 
        /* we can only do fast match on equality tests */
        *type = ASL_QUERY_MATCH_SLOW;
-       if (q->op != NULL)
+
+       for (x = asl_msg_fetch((asl_msg_t *)q, 0, NULL, NULL, &op); x != IndexNull; x = asl_msg_fetch((asl_msg_t *)q, x, NULL, NULL, &op))
        {
-               for (i = 0; i < q->count; i++) if (q->op[i] != ASL_QUERY_OP_EQUAL) return NULL;
+               if (op != ASL_QUERY_OP_EQUAL) return NULL;
        }
 
        out = (mini_mem_record_t *)calloc(1, sizeof(mini_mem_record_t));
@@ -772,13 +687,13 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                return NULL;
        }
 
-       for (i = 0; i < q->count; i++)
+       for (x = asl_msg_fetch((asl_msg_t *)q, 0, &key, &val, &op); x != IndexNull; x = asl_msg_fetch((asl_msg_t *)q, x, &key, &val, &op))
        {
-               if (q->key[i] == NULL) continue;
+               if (key == NULL) continue;
 
-               else if (!strcmp(q->key[i], ASL_KEY_MSG_ID))
+               else if (!strcmp(key, ASL_KEY_MSG_ID))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_MSG_ID)
                        {
@@ -788,11 +703,11 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                        }
 
                        *type |= ASL_QUERY_MATCH_MSG_ID;
-                       out->mid = atoll(q->val[i]);
+                       out->mid = atoll(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_TIME))
+               else if (!strcmp(key, ASL_KEY_TIME))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_TIME)
                        {
@@ -802,11 +717,11 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                        }
 
                        *type |= ASL_QUERY_MATCH_TIME;
-                       out->time = asl_parse_time(q->val[i]);
+                       out->time = asl_parse_time(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_LEVEL))
+               else if (!strcmp(key, ASL_KEY_LEVEL))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_LEVEL)
                        {
@@ -816,11 +731,11 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                        }
 
                        *type |= ASL_QUERY_MATCH_LEVEL;
-                       out->level = atoi(q->val[i]);
+                       out->level = atoi(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_PID))
+               else if (!strcmp(key, ASL_KEY_PID))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_PID)
                        {
@@ -830,11 +745,11 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                        }
 
                        *type |= ASL_QUERY_MATCH_PID;
-                       out->pid = atoi(q->val[i]);
+                       out->pid = atoi(val);
                }
-               else if (!strcmp(q->key[i], ASL_KEY_SENDER))
+               else if (!strcmp(key, ASL_KEY_SENDER))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_SENDER)
                        {
@@ -844,7 +759,7 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                        }
 
                        *type |= ASL_QUERY_MATCH_SENDER;
-                       out->sender = asl_mini_memory_string_retain(s, q->val[i], 0);
+                       out->sender = asl_mini_memory_string_retain(s, val, 0);
                        if (out->sender == NULL)
                        {
                                asl_mini_memory_record_free(s, out);
@@ -852,9 +767,9 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                                return NULL;
                        }
                }
-               else if (!strcmp(q->key[i], ASL_KEY_FACILITY))
+               else if (!strcmp(key, ASL_KEY_FACILITY))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_FACILITY)
                        {
@@ -864,7 +779,7 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                        }
 
                        *type |= ASL_QUERY_MATCH_FACILITY;
-                       out->facility = asl_mini_memory_string_retain(s, q->val[i], 0);
+                       out->facility = asl_mini_memory_string_retain(s, val, 0);
                        if (out->facility == NULL)
                        {
                                asl_mini_memory_record_free(s, out);
@@ -872,9 +787,9 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                                return NULL;
                        }
                }
-               else if (!strcmp(q->key[i], ASL_KEY_MSG))
+               else if (!strcmp(key, ASL_KEY_MSG))
                {
-                       if (q->val[i] == NULL) continue;
+                       if (val == NULL) continue;
 
                        if (*type & ASL_QUERY_MATCH_MESSAGE)
                        {
@@ -884,7 +799,7 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                        }
 
                        *type |= ASL_QUERY_MATCH_MESSAGE;
-                       out->message = asl_mini_memory_string_retain(s, q->val[i], 0);
+                       out->message = asl_mini_memory_string_retain(s, val, 0);
                        if (out->message == NULL)
                        {
                                asl_mini_memory_record_free(s, out);
@@ -894,17 +809,17 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                }
                else
                {
-                       key = asl_mini_memory_string_retain(s, q->key[i], 0);
-                       if (key == NULL)
+                       mkey = asl_mini_memory_string_retain(s, key, 0);
+                       if (mkey == NULL)
                        {
                                asl_mini_memory_record_free(s, out);
                                *type = ASL_QUERY_MATCH_FALSE;
                                return NULL;
                        }
 
-                       for (j = 0; j < out->kvcount; j += 2)
+                       for (i = 0; i < out->kvcount; i += 2)
                        {
-                               if (out->kvlist[j] == key)
+                               if (out->kvlist[i] == mkey)
                                {
                                        asl_mini_memory_record_free(s, out);
                                        *type = ASL_QUERY_MATCH_SLOW;
@@ -912,7 +827,7 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                                }
                        }
 
-                       val = asl_mini_memory_string_retain(s, q->val[i], 0);
+                       mval = asl_mini_memory_string_retain(s, val, 0);
 
                        if (out->kvcount == 0)
                        {
@@ -930,8 +845,8 @@ asl_mini_memory_query_to_record(asl_mini_memory_t *s, asl_msg_t *q, uint32_t *ty
                                return NULL;
                        }
 
-                       out->kvlist[out->kvcount++] = key;
-                       out->kvlist[out->kvcount++] = val;
+                       out->kvlist[out->kvcount++] = mkey;
+                       out->kvlist[out->kvcount++] = mval;
                }
        }
 
@@ -973,9 +888,9 @@ asl_mini_memory_fast_match(asl_mini_memory_t *s, mini_mem_record_t *r, uint32_t
 }
 
 static uint32_t
-asl_mini_memory_slow_match(asl_mini_memory_t *s, mini_mem_record_t *r, mini_mem_record_t *q, asl_msg_t *rawq)
+asl_mini_memory_slow_match(asl_mini_memory_t *s, mini_mem_record_t *r, mini_mem_record_t *q, aslmsg rawq)
 {
-       asl_msg_t *rawm;
+       aslmsg rawm;
        uint32_t status;
 
        rawm = NULL;
@@ -983,7 +898,7 @@ asl_mini_memory_slow_match(asl_mini_memory_t *s, mini_mem_record_t *r, mini_mem_
        if (status != ASL_STATUS_OK) return 0;
 
        status = 0;
-       if (asl_msg_cmp(rawq, rawm) != 0) status = 1;
+       if (asl_msg_cmp((asl_msg_t *)rawq, (asl_msg_t *)rawm) != 0) status = 1;
        asl_free(rawm);
        return status;
 }
@@ -993,7 +908,7 @@ asl_mini_memory_match(asl_mini_memory_t *s, aslresponse query, aslresponse *res,
 {
        uint32_t status, i, where, start, j, do_match, did_match, rescount, *qtype;
        mini_mem_record_t **qp;
-       asl_msg_t *m;
+       aslmsg m;
 
        if (s == NULL) return ASL_STATUS_INVALID_STORE;
        if (res == NULL) return ASL_STATUS_INVALID_ARG;
@@ -1101,9 +1016,13 @@ asl_mini_memory_match(asl_mini_memory_t *s, aslresponse query, aslresponse *res,
                                {
                                        did_match = 1;
                                }
+                               else if (qtype[j] == ASL_QUERY_MATCH_FALSE)
+                               {
+                                       did_match = 0;
+                               }
                                else if (qtype[j] == ASL_QUERY_MATCH_SLOW)
                                {
-                                       did_match = asl_mini_memory_slow_match(s, s->record[where], qp[j], query->msg[j]);
+                                       did_match = asl_mini_memory_slow_match(s, s->record[where], qp[j], (aslmsg)query->msg[j]);
                                }
                                else
                                {
@@ -1171,7 +1090,7 @@ asl_mini_memory_match(asl_mini_memory_t *s, aslresponse query, aslresponse *res,
                                return status;
                        }
 
-                       (*res)->msg[(*res)->curr++] = m;
+                       (*res)->msg[(*res)->curr++] = (asl_msg_t *)m;
                        if ((*res)->curr == rescount) break;
                }
 
diff --git a/aslmanager.tproj/Makefile b/aslmanager.tproj/Makefile
deleted file mode 100644 (file)
index 9872e69..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-Project = aslmanager
-ProductType = tool
-Install_Dir = /usr/sbin
-
-CFILES = aslmanager.c
-MANPAGES = aslmanager.8
-LAUNCHD_PLISTS = com.apple.aslmanager.plist
-
-Extra_CC_Flags = -Wall -mdynamic-no-pic -DINET6
-Extra_LD_Flags = -dead_strip
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-after_install:
-       codesign -s- $(DSTROOT)/usr/sbin/aslmanager
-       plutil -convert binary1 $(DSTROOT)/System/Library/LaunchDaemons/com.apple.aslmanager.plist
index 747a1b9578c3464ebd44424e1b119a37f503b01c..a524421bf214a9221efd9f1f91e9dc69e8489fe8 100644 (file)
@@ -31,6 +31,7 @@
 #include <time.h>
 #include <sys/time.h>
 #include <sys/stat.h>
+#include <copyfile.h>
 #include <asl.h>
 #include <asl_private.h>
 #include <asl_core.h>
@@ -41,7 +42,6 @@
 #define DEFAULT_MAX_SIZE 150000000
 #define DEFAULT_TTL 7
 
-#define IndexNull (uint32_t)-1
 #define _PATH_ASL_CONF "/etc/asl.conf"
 
 /* global */
@@ -148,7 +148,7 @@ do_copy(const char *infile, const char *outfile, mode_t mode)
        for (i = 0; i < res->count; i++)
        {
                mid = 0;
-               status = asl_file_save(f, res->msg[i], &mid);
+               status = asl_file_save(f, (aslmsg)(res->msg[i]), &mid);
                if (status != ASL_STATUS_OK) break;
        }
 
@@ -156,6 +156,42 @@ do_copy(const char *infile, const char *outfile, mode_t mode)
        return status;
 }
 
+int
+do_dir_archive(const char *indir, const char *outdir)
+{
+       return copyfile(indir, outdir, NULL, COPYFILE_ALL | COPYFILE_RECURSIVE);
+}
+
+int
+remove_directory(const char *path)
+{
+       DIR *dp;
+       struct dirent *dent;
+       char *str;
+       int status;
+
+       dp = opendir(path);
+       if (dp == NULL) return 0;
+
+       while ((dent = readdir(dp)) != NULL)
+       {
+               if ((!strcmp(dent->d_name, ".")) || (!strcmp(dent->d_name, ".."))) continue;
+               asprintf(&str, "%s/%s", path, dent->d_name);
+               if (str != NULL)
+               {
+                       status = unlink(str);
+                       free(str);
+                       str = NULL;
+               }
+       }
+
+       closedir(dp);
+       status = rmdir(path);
+
+       return status;
+}
+
+
 static char **
 _insertString(char *s, char **l, uint32_t x)
 {
@@ -390,6 +426,38 @@ _parse_config_file(const char *name)
        return 0;
 }
 
+size_t
+directory_size(const char *path)
+{
+       DIR *dp;
+       struct dirent *dent;
+       struct stat sb;
+       size_t size;
+       char *str;
+
+       dp = opendir(path);
+       if (dp == NULL) return 0;
+
+       size = 0;
+       while ((dent = readdir(dp)) != NULL)
+       {
+               if ((!strcmp(dent->d_name, ".")) || (!strcmp(dent->d_name, ".."))) continue;
+
+               memset(&sb, 0, sizeof(struct stat));
+               str = NULL;
+               asprintf(&str, "%s/%s", path, dent->d_name);
+
+               if ((str != NULL) && (stat(str, &sb) == 0) && S_ISREG(sb.st_mode))
+               {
+                       size += sb.st_size;
+                       free(str);
+               }
+       }
+
+       closedir(dp);
+       return size;
+}
+
 int
 main(int argc, const char *argv[])
 {
@@ -399,13 +467,15 @@ main(int argc, const char *argv[])
        char today_ymd_string[32], expire_ymd_string[32], *str;
        DIR *dp;
        struct dirent *dent;
-       name_list_t *ymd_list, *bb_list, *e;
+       name_list_t *ymd_list, *bb_list, *aux_list, *bb_aux_list, *e;
        uint32_t status;
        size_t file_size, store_size;
        struct stat sb;
 
        ymd_list = NULL;
        bb_list = NULL;
+       aux_list = NULL;
+       bb_aux_list = NULL;
 
        ttl = DEFAULT_TTL * SECONDS_PER_DAY;
        max_size = DEFAULT_MAX_SIZE;
@@ -448,7 +518,7 @@ main(int argc, const char *argv[])
                if (stat(archive, &sb) == 0)
                {
                        /* must be a directory */
-                       if ((sb.st_mode & S_IFDIR) == 0)
+                       if (!S_ISDIR(sb.st_mode))
                        {
                                fprintf(stderr, "aslmanager error: archive %s is not a directory", archive);
                                return -1;
@@ -502,7 +572,7 @@ main(int argc, const char *argv[])
        dp = opendir(store_dir);
        if (dp == NULL) return -1;
 
-       /* gather a list of YMD files and BB files */
+       /* gather a list of YMD files, AUX dirs, BB.AUX dirs, and BB files */
        while ((dent = readdir(dp)) != NULL)
        {
                memset(&sb, 0, sizeof(struct stat));
@@ -514,6 +584,18 @@ main(int argc, const char *argv[])
                        ymd_list = add_to_list(ymd_list, dent->d_name, file_size);
                        store_size += file_size;
                }
+               else if (!strncmp(dent->d_name, "AUX.", 4) && (dent->d_name[4] >= '0') && (dent->d_name[4] <= '9') && S_ISDIR(sb.st_mode))
+               {
+                       file_size = directory_size(dent->d_name);
+                       aux_list = add_to_list(aux_list, dent->d_name, file_size);
+                       store_size += file_size;
+               }
+               else if (!strncmp(dent->d_name, "BB.AUX.", 7) && (dent->d_name[7] >= '0') && (dent->d_name[7] <= '9') && S_ISDIR(sb.st_mode))
+               {
+                       file_size = directory_size(dent->d_name);
+                       bb_aux_list = add_to_list(bb_aux_list, dent->d_name, file_size);
+                       store_size += file_size;
+               }
                else if (!strncmp(dent->d_name, "BB.", 3) && (dent->d_name[3] >= '0') && (dent->d_name[3] <= '9'))
                {
                        bb_list = add_to_list(bb_list, dent->d_name, file_size);
@@ -536,12 +618,16 @@ main(int argc, const char *argv[])
                printf("Data Store Size = %lu\n", store_size);
                printf("Data Store YMD Files\n");
                for (e = ymd_list; e != NULL; e = e->next) printf("     %s   %lu\n", e->name, e->size);
+               printf("Data Store AUX Directories\n");
+               for (e = aux_list; e != NULL; e = e->next) printf("     %s   %lu\n", e->name, e->size);
+               printf("Data Store BB.AUX Directories\n");
+               for (e = bb_aux_list; e != NULL; e = e->next) printf("  %s   %lu\n", e->name, e->size);
                printf("Data Store BB Files\n");
                for (e = bb_list; e != NULL; e = e->next) printf("      %s   %lu\n", e->name, e->size);
        }
 
        /* Delete/achive expired YMD files */
-       if (debug == 1) printf("Start YMD Scan\n");
+       if (debug == 1) printf("Start YMD File Scan\n");
 
        e = ymd_list;
        while (e != NULL)
@@ -569,7 +655,69 @@ main(int argc, const char *argv[])
                e = e->next;
        }
 
-       if (debug == 1) printf("Finished YMD Scan\n");
+       if (debug == 1) printf("Finished YMD FILE Scan\n");
+
+       /* Delete/achive expired YMD AUX directories */
+       if (debug == 1) printf("Start AUX Directory Scan\n");
+
+       e = aux_list;
+       while (e != NULL)
+       {
+               /* stop when a file name/date is after the expire date */
+               if (strncmp(e->name + 4, expire_ymd_string, expire_ymd_stringlen) > 0) break;
+
+               if (archive != NULL)
+               {
+                       str = NULL;
+                       asprintf(&str, "%s/%s", archive, e->name);
+                       if (str == NULL) return -1;
+
+                       if (debug == 1) printf("  copy %s ---> %s\n", e->name, str);
+                       do_dir_archive(e->name, str);
+                       free(str);
+               }
+
+               if (debug == 1) printf("    Remove %s\n", e->name);
+               remove_directory(e->name);
+
+               store_size -= e->size;
+               e->size = 0;
+
+               e = e->next;
+       }
+
+       if (debug == 1) printf("Finished AUX Directory Scan\n");
+
+       /* Delete/achive expired BB.AUX directories */
+       if (debug == 1) printf("Start BB.AUX Directory Scan\n");
+
+       e = bb_aux_list;
+       while (e != NULL)
+       {
+               /* stop when a file name/date is after the expire date */
+               if (strncmp(e->name + 7, today_ymd_string, today_ymd_stringlen) > 0) break;
+
+               if (archive != NULL)
+               {
+                       str = NULL;
+                       asprintf(&str, "%s/%s", archive, e->name);
+                       if (str == NULL) return -1;
+
+                       if (debug == 1) printf("  copy %s ---> %s\n", e->name, str);
+                       do_dir_archive(e->name, str);
+                       free(str);
+               }
+
+               if (debug == 1) printf("  remove %s\n", e->name);
+               remove_directory(e->name);
+
+               store_size -= e->size;
+               e->size = 0;
+
+               e = e->next;
+       }
+
+       if (debug == 1) printf("Finished BB.AUX Directory Scan\n");
 
        /* Delete/achive expired BB files */
        if (debug == 1) printf("Start BB Scan\n");
@@ -605,7 +753,7 @@ main(int argc, const char *argv[])
 
        /* if data store is over max_size, delete/archive more YMD files */
        if ((debug == 1) && (store_size > max_size)) printf("Additional YMD Scan\n");
-       
+
        e = ymd_list;
        while ((e != NULL) && (store_size > max_size))
        {
diff --git a/syslog.xcodeproj/project.pbxproj b/syslog.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..4ad9a6a
--- /dev/null
@@ -0,0 +1,736 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 45;
+       objects = {
+
+/* Begin PBXAggregateTarget section */
+               5020A3211098EBDE00982ED6 /* All */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = 5020A3311098EC3000982ED6 /* Build configuration list for PBXAggregateTarget "All" */;
+                       buildPhases = (
+                       );
+                       dependencies = (
+                               5020A3241098EBF400982ED6 /* PBXTargetDependency */,
+                               5020A3261098EBF900982ED6 /* PBXTargetDependency */,
+                               5020A3281098EBFC00982ED6 /* PBXTargetDependency */,
+                               503A82141098FB9300B0D08A /* PBXTargetDependency */,
+                       );
+                       name = All;
+                       productName = All;
+               };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+               5020A36B1098EE1D00982ED6 /* libaslcommon.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 505ACB9D108FD16400197086 /* libaslcommon.a */; };
+               5020A37F1098EEC400982ED6 /* libaslcommon.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 505ACB9D108FD16400197086 /* libaslcommon.a */; };
+               5020A3821098EEFD00982ED6 /* System.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5020A3811098EEFD00982ED6 /* System.framework */; };
+               5039176F1091408B0001165E /* aslmanager.c in Sources */ = {isa = PBXBuildFile; fileRef = 5039176C1091408B0001165E /* aslmanager.c */; };
+               503917B81091410E0001165E /* asl_action.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917A61091410E0001165E /* asl_action.c */; };
+               503917B91091410E0001165E /* asl_in.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917A71091410E0001165E /* asl_in.c */; };
+               503917BA1091410E0001165E /* bb_convert.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917A91091410E0001165E /* bb_convert.c */; };
+               503917BB1091410E0001165E /* bsd_in.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917AA1091410E0001165E /* bsd_in.c */; };
+               503917BC1091410E0001165E /* bsd_out.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917AB1091410E0001165E /* bsd_out.c */; };
+               503917BD1091410E0001165E /* daemon.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917AD1091410E0001165E /* daemon.c */; };
+               503917BE1091410E0001165E /* dbserver.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917AF1091410E0001165E /* dbserver.c */; };
+               503917BF1091410E0001165E /* klog_in.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917B01091410E0001165E /* klog_in.c */; };
+               503917C11091410E0001165E /* remote.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917B21091410E0001165E /* remote.c */; };
+               503917C21091410E0001165E /* syslogd.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917B51091410E0001165E /* syslogd.c */; };
+               503917C31091410E0001165E /* udp_in.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917B71091410E0001165E /* udp_in.c */; };
+               503917D2109141530001165E /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = 503917D1109141530001165E /* syslog.c */; };
+               503A81D81098FA3900B0D08A /* asl_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = 505ACBA2108FD18400197086 /* asl_ipc.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; };
+               503A82471099029200B0D08A /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 503A82461099029200B0D08A /* libbsm.dylib */; };
+               503A82741099045F00B0D08A /* aslmanager.8 in Copy Manpage.8 */ = {isa = PBXBuildFile; fileRef = 5039176B1091408B0001165E /* aslmanager.8 */; };
+               503A82761099049900B0D08A /* syslog.1 in Copy Manpage.1 */ = {isa = PBXBuildFile; fileRef = 503917D0109141530001165E /* syslog.1 */; };
+               503A8278109904C000B0D08A /* syslogd.8 in Copy Manpage.8 */ = {isa = PBXBuildFile; fileRef = 503917B41091410E0001165E /* syslogd.8 */; };
+               503A827A109904E400B0D08A /* asl.conf.5 in Copy Manpages.5 */ = {isa = PBXBuildFile; fileRef = 503917A81091410E0001165E /* asl.conf.5 */; };
+               503A827B109904E400B0D08A /* syslog.conf.5 in Copy Manpages.5 */ = {isa = PBXBuildFile; fileRef = 503917B31091410E0001165E /* syslog.conf.5 */; };
+               505ACBA8108FD18400197086 /* asl_ipc.defs in Headers */ = {isa = PBXBuildFile; fileRef = 505ACBA2108FD18400197086 /* asl_ipc.defs */; };
+               505ACBA9108FD18400197086 /* asl_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 505ACBA3108FD18400197086 /* asl_memory.c */; };
+               505ACBAA108FD18400197086 /* asl_memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 505ACBA4108FD18400197086 /* asl_memory.h */; };
+               505ACBAB108FD18400197086 /* asl_mini_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 505ACBA5108FD18400197086 /* asl_mini_memory.c */; };
+               505ACBAC108FD18400197086 /* asl_mini_memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 505ACBA6108FD18400197086 /* asl_mini_memory.h */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+               5020A3231098EBF400982ED6 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 505ACB9C108FD16400197086;
+                       remoteInfo = aslcommon;
+               };
+               5020A3251098EBF900982ED6 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 50391765109140450001165E;
+                       remoteInfo = aslmanager;
+               };
+               5020A3271098EBFC00982ED6 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 503917C71091413E0001165E;
+                       remoteInfo = util;
+               };
+               503A82131098FB9300B0D08A /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 5039177B109140C30001165E;
+                       remoteInfo = syslogd;
+               };
+               FCF3761810D2EED700C0EC8D /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 505ACB9C108FD16400197086;
+                       remoteInfo = aslcommon;
+               };
+               FCF3761A10D2EEDF00C0EC8D /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 505ACB9C108FD16400197086;
+                       remoteInfo = aslcommon;
+               };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+               503A82631099037D00B0D08A /* Copy Manpage.8 */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/share/man/man8/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               503A82741099045F00B0D08A /* aslmanager.8 in Copy Manpage.8 */,
+                       );
+                       name = "Copy Manpage.8";
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               503A8285109904FD00B0D08A /* Copy Manpage.1 */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               503A82761099049900B0D08A /* syslog.1 in Copy Manpage.1 */,
+                       );
+                       name = "Copy Manpage.1";
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               503A8286109904FD00B0D08A /* Copy Manpage.8 */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/share/man/man8/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               503A8278109904C000B0D08A /* syslogd.8 in Copy Manpage.8 */,
+                       );
+                       name = "Copy Manpage.8";
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               503A8287109904FD00B0D08A /* Copy Manpages.5 */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/share/man/man5/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               503A827A109904E400B0D08A /* asl.conf.5 in Copy Manpages.5 */,
+                               503A827B109904E400B0D08A /* syslog.conf.5 in Copy Manpages.5 */,
+                       );
+                       name = "Copy Manpages.5";
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+               2DB4DA0A125FC69A001CDC45 /* after_install.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = after_install.sh; path = syslogd.tproj/after_install.sh; sourceTree = "<group>"; };
+               5020A3811098EEFD00982ED6 /* System.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = System.framework; path = /System/Library/Frameworks/System.framework; sourceTree = "<absolute>"; };
+               50391766109140450001165E /* aslmanager */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = aslmanager; sourceTree = BUILT_PRODUCTS_DIR; };
+               5039176B1091408B0001165E /* aslmanager.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = aslmanager.8; path = aslmanager.tproj/aslmanager.8; sourceTree = "<group>"; };
+               5039176C1091408B0001165E /* aslmanager.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = aslmanager.c; path = aslmanager.tproj/aslmanager.c; sourceTree = "<group>"; };
+               5039176D1091408B0001165E /* com.apple.aslmanager.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.aslmanager.plist; path = aslmanager.tproj/com.apple.aslmanager.plist; sourceTree = "<group>"; };
+               5039177C109140C30001165E /* syslogd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = syslogd; sourceTree = BUILT_PRODUCTS_DIR; };
+               503917A61091410E0001165E /* asl_action.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asl_action.c; path = syslogd.tproj/asl_action.c; sourceTree = "<group>"; };
+               503917A71091410E0001165E /* asl_in.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asl_in.c; path = syslogd.tproj/asl_in.c; sourceTree = "<group>"; };
+               503917A81091410E0001165E /* asl.conf.5 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = asl.conf.5; path = syslogd.tproj/asl.conf.5; sourceTree = "<group>"; };
+               503917A91091410E0001165E /* bb_convert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bb_convert.c; path = syslogd.tproj/bb_convert.c; sourceTree = "<group>"; };
+               503917AA1091410E0001165E /* bsd_in.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bsd_in.c; path = syslogd.tproj/bsd_in.c; sourceTree = "<group>"; };
+               503917AB1091410E0001165E /* bsd_out.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bsd_out.c; path = syslogd.tproj/bsd_out.c; sourceTree = "<group>"; };
+               503917AC1091410E0001165E /* com.apple.syslogd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.syslogd.plist; path = syslogd.tproj/com.apple.syslogd.plist; sourceTree = "<group>"; };
+               503917AD1091410E0001165E /* daemon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = daemon.c; path = syslogd.tproj/daemon.c; sourceTree = "<group>"; };
+               503917AE1091410E0001165E /* daemon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = daemon.h; path = syslogd.tproj/daemon.h; sourceTree = "<group>"; };
+               503917AF1091410E0001165E /* dbserver.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dbserver.c; path = syslogd.tproj/dbserver.c; sourceTree = "<group>"; };
+               503917B01091410E0001165E /* klog_in.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = klog_in.c; path = syslogd.tproj/klog_in.c; sourceTree = "<group>"; };
+               503917B21091410E0001165E /* remote.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = remote.c; path = syslogd.tproj/remote.c; sourceTree = "<group>"; };
+               503917B31091410E0001165E /* syslog.conf.5 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = syslog.conf.5; path = syslogd.tproj/syslog.conf.5; sourceTree = "<group>"; };
+               503917B41091410E0001165E /* syslogd.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = syslogd.8; path = syslogd.tproj/syslogd.8; sourceTree = "<group>"; };
+               503917B51091410E0001165E /* syslogd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = syslogd.c; path = syslogd.tproj/syslogd.c; sourceTree = "<group>"; };
+               503917B61091410E0001165E /* syslogd.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = syslogd.sb; path = syslogd.tproj/syslogd.sb; sourceTree = "<group>"; };
+               503917B71091410E0001165E /* udp_in.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = udp_in.c; path = syslogd.tproj/udp_in.c; sourceTree = "<group>"; };
+               503917C81091413E0001165E /* syslog */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = syslog; sourceTree = BUILT_PRODUCTS_DIR; };
+               503917D0109141530001165E /* syslog.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; name = syslog.1; path = util.tproj/syslog.1; sourceTree = "<group>"; };
+               503917D1109141530001165E /* syslog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = syslog.c; path = util.tproj/syslog.c; sourceTree = "<group>"; };
+               503A82461099029200B0D08A /* libbsm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsm.dylib; path = /usr/lib/libbsm.dylib; sourceTree = "<absolute>"; };
+               505ACB9D108FD16400197086 /* libaslcommon.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libaslcommon.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               505ACBA2108FD18400197086 /* asl_ipc.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; name = asl_ipc.defs; path = /usr/local/include/asl_ipc.defs; sourceTree = SDKROOT; };
+               505ACBA3108FD18400197086 /* asl_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asl_memory.c; sourceTree = "<group>"; };
+               505ACBA4108FD18400197086 /* asl_memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = asl_memory.h; sourceTree = "<group>"; };
+               505ACBA5108FD18400197086 /* asl_mini_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asl_mini_memory.c; sourceTree = "<group>"; };
+               505ACBA6108FD18400197086 /* asl_mini_memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = asl_mini_memory.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               50391764109140450001165E /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               5039177A109140C30001165E /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               5020A37F1098EEC400982ED6 /* libaslcommon.a in Frameworks */,
+                               5020A3821098EEFD00982ED6 /* System.framework in Frameworks */,
+                               503A82471099029200B0D08A /* libbsm.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               503917C61091413E0001165E /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               5020A36B1098EE1D00982ED6 /* libaslcommon.a in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               505ACB9B108FD16400197086 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               08FB7794FE84155DC02AAC07 /* syslog */ = {
+                       isa = PBXGroup;
+                       children = (
+                               505ACBA1108FD18400197086 /* aslcommon */,
+                               503917691091404D0001165E /* aslmanager */,
+                               503917C41091412B0001165E /* util */,
+                               503917711091409F0001165E /* syslogd */,
+                               505ACB9E108FD16400197086 /* Products */,
+                               5020A3811098EEFD00982ED6 /* System.framework */,
+                               503A82461099029200B0D08A /* libbsm.dylib */,
+                       );
+                       name = syslog;
+                       sourceTree = "<group>";
+               };
+               503917691091404D0001165E /* aslmanager */ = {
+                       isa = PBXGroup;
+                       children = (
+                               5039176B1091408B0001165E /* aslmanager.8 */,
+                               5039176C1091408B0001165E /* aslmanager.c */,
+                               5039176D1091408B0001165E /* com.apple.aslmanager.plist */,
+                       );
+                       name = aslmanager;
+                       sourceTree = "<group>";
+               };
+               503917711091409F0001165E /* syslogd */ = {
+                       isa = PBXGroup;
+                       children = (
+                               503917A61091410E0001165E /* asl_action.c */,
+                               2DB4DA0A125FC69A001CDC45 /* after_install.sh */,
+                               503917A71091410E0001165E /* asl_in.c */,
+                               503917A81091410E0001165E /* asl.conf.5 */,
+                               503917A91091410E0001165E /* bb_convert.c */,
+                               503917AA1091410E0001165E /* bsd_in.c */,
+                               503917AB1091410E0001165E /* bsd_out.c */,
+                               503917AC1091410E0001165E /* com.apple.syslogd.plist */,
+                               503917AD1091410E0001165E /* daemon.c */,
+                               503917AE1091410E0001165E /* daemon.h */,
+                               503917AF1091410E0001165E /* dbserver.c */,
+                               503917B01091410E0001165E /* klog_in.c */,
+                               503917B21091410E0001165E /* remote.c */,
+                               503917B31091410E0001165E /* syslog.conf.5 */,
+                               503917B41091410E0001165E /* syslogd.8 */,
+                               503917B51091410E0001165E /* syslogd.c */,
+                               503917B61091410E0001165E /* syslogd.sb */,
+                               503917B71091410E0001165E /* udp_in.c */,
+                       );
+                       name = syslogd;
+                       sourceTree = "<group>";
+               };
+               503917C41091412B0001165E /* util */ = {
+                       isa = PBXGroup;
+                       children = (
+                               503917D0109141530001165E /* syslog.1 */,
+                               503917D1109141530001165E /* syslog.c */,
+                       );
+                       name = util;
+                       sourceTree = "<group>";
+               };
+               505ACB9E108FD16400197086 /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               505ACB9D108FD16400197086 /* libaslcommon.a */,
+                               50391766109140450001165E /* aslmanager */,
+                               5039177C109140C30001165E /* syslogd */,
+                               503917C81091413E0001165E /* syslog */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               505ACBA1108FD18400197086 /* aslcommon */ = {
+                       isa = PBXGroup;
+                       children = (
+                               505ACBA2108FD18400197086 /* asl_ipc.defs */,
+                               505ACBA3108FD18400197086 /* asl_memory.c */,
+                               505ACBA4108FD18400197086 /* asl_memory.h */,
+                               505ACBA5108FD18400197086 /* asl_mini_memory.c */,
+                               505ACBA6108FD18400197086 /* asl_mini_memory.h */,
+                       );
+                       path = aslcommon;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+               505ACB99108FD16400197086 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               505ACBA8108FD18400197086 /* asl_ipc.defs in Headers */,
+                               505ACBAA108FD18400197086 /* asl_memory.h in Headers */,
+                               505ACBAC108FD18400197086 /* asl_mini_memory.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+               50391765109140450001165E /* aslmanager */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 5039176A1091404D0001165E /* Build configuration list for PBXNativeTarget "aslmanager" */;
+                       buildPhases = (
+                               50391763109140450001165E /* Sources */,
+                               50391764109140450001165E /* Frameworks */,
+                               503A82631099037D00B0D08A /* Copy Manpage.8 */,
+                               FCAC6D7410AB34C9008DEAC9 /* ShellScript */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = aslmanager;
+                       productName = aslmanager;
+                       productReference = 50391766109140450001165E /* aslmanager */;
+                       productType = "com.apple.product-type.tool";
+               };
+               5039177B109140C30001165E /* syslogd */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 50391782109140CA0001165E /* Build configuration list for PBXNativeTarget "syslogd" */;
+                       buildPhases = (
+                               50391779109140C30001165E /* Sources */,
+                               5039177A109140C30001165E /* Frameworks */,
+                               503A8286109904FD00B0D08A /* Copy Manpage.8 */,
+                               503A8287109904FD00B0D08A /* Copy Manpages.5 */,
+                               50A9CB7A10A8D16300AA715E /* after install */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               FCF3761B10D2EEDF00C0EC8D /* PBXTargetDependency */,
+                       );
+                       name = syslogd;
+                       productName = syslogd;
+                       productReference = 5039177C109140C30001165E /* syslogd */;
+                       productType = "com.apple.product-type.tool";
+               };
+               503917C71091413E0001165E /* util */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 503917CF1091414A0001165E /* Build configuration list for PBXNativeTarget "util" */;
+                       buildPhases = (
+                               503917C51091413E0001165E /* Sources */,
+                               503917C61091413E0001165E /* Frameworks */,
+                               503A8285109904FD00B0D08A /* Copy Manpage.1 */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               FCF3761910D2EED700C0EC8D /* PBXTargetDependency */,
+                       );
+                       name = util;
+                       productName = util;
+                       productReference = 503917C81091413E0001165E /* syslog */;
+                       productType = "com.apple.product-type.tool";
+               };
+               505ACB9C108FD16400197086 /* aslcommon */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 505ACBA0108FD16500197086 /* Build configuration list for PBXNativeTarget "aslcommon" */;
+                       buildPhases = (
+                               505ACB99108FD16400197086 /* Headers */,
+                               505ACB9A108FD16400197086 /* Sources */,
+                               505ACB9B108FD16400197086 /* Frameworks */,
+                               FCF3762A10D2F47C00C0EC8D /* ShellScript */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = aslcommon;
+                       productName = aslcommon;
+                       productReference = 505ACB9D108FD16400197086 /* libaslcommon.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               08FB7793FE84155DC02AAC07 /* Project object */ = {
+                       isa = PBXProject;
+                       buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "syslog" */;
+                       compatibilityVersion = "Xcode 3.1";
+                       developmentRegion = English;
+                       hasScannedForEncodings = 1;
+                       knownRegions = (
+                               English,
+                               Japanese,
+                               French,
+                               German,
+                       );
+                       mainGroup = 08FB7794FE84155DC02AAC07 /* syslog */;
+                       productRefGroup = 505ACB9E108FD16400197086 /* Products */;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               5020A3211098EBDE00982ED6 /* All */,
+                               505ACB9C108FD16400197086 /* aslcommon */,
+                               50391765109140450001165E /* aslmanager */,
+                               503917C71091413E0001165E /* util */,
+                               5039177B109140C30001165E /* syslogd */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+               50A9CB7A10A8D16300AA715E /* after install */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 8;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "after install";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+                       shellPath = /bin/sh;
+                       shellScript = "exec ${PROJECT_DIR}/syslogd.tproj/after_install.sh";
+               };
+               FCAC6D7410AB34C9008DEAC9 /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 8;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+                       shellPath = /bin/sh;
+                       shellScript = "set -e\n\nDESTDIR=\"$DSTROOT\"/System/Library/LaunchDaemons\ninstall -d -m 0755 -o root -g wheel -d \"$DESTDIR\"\ninstall -m 0644 -o root -g wheel \"$SRCROOT\"/aslmanager.tproj/com.apple.aslmanager.plist \"$DESTDIR\"\nplutil -convert binary1 \"$DESTDIR\"/com.apple.aslmanager.plist";
+                       showEnvVarsInLog = 0;
+               };
+               FCF3762A10D2F47C00C0EC8D /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "set -ex\n\n# Install asl_ipc.h in a location that other targets can find.\n\nfor ARCH in $ARCHS ; do\n\tDESTDIR=\"$BUILT_PRODUCTS_DIR/$ARCH\"\n\tmkdir -p \"$DESTDIR\"\n\tcp \"$DERIVED_SOURCES_DIR/$ARCH\"/asl_ipc{,Server}.h \"$DESTDIR\"\ndone";
+               };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               50391763109140450001165E /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               5039176F1091408B0001165E /* aslmanager.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               50391779109140C30001165E /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               503917B81091410E0001165E /* asl_action.c in Sources */,
+                               503917B91091410E0001165E /* asl_in.c in Sources */,
+                               503917BA1091410E0001165E /* bb_convert.c in Sources */,
+                               503917BB1091410E0001165E /* bsd_in.c in Sources */,
+                               503917BC1091410E0001165E /* bsd_out.c in Sources */,
+                               503917BD1091410E0001165E /* daemon.c in Sources */,
+                               503917BE1091410E0001165E /* dbserver.c in Sources */,
+                               503917BF1091410E0001165E /* klog_in.c in Sources */,
+                               503917C11091410E0001165E /* remote.c in Sources */,
+                               503917C21091410E0001165E /* syslogd.c in Sources */,
+                               503917C31091410E0001165E /* udp_in.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               503917C51091413E0001165E /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               503917D2109141530001165E /* syslog.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               505ACB9A108FD16400197086 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               503A81D81098FA3900B0D08A /* asl_ipc.defs in Sources */,
+                               505ACBA9108FD18400197086 /* asl_memory.c in Sources */,
+                               505ACBAB108FD18400197086 /* asl_mini_memory.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+               5020A3241098EBF400982ED6 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 505ACB9C108FD16400197086 /* aslcommon */;
+                       targetProxy = 5020A3231098EBF400982ED6 /* PBXContainerItemProxy */;
+               };
+               5020A3261098EBF900982ED6 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 50391765109140450001165E /* aslmanager */;
+                       targetProxy = 5020A3251098EBF900982ED6 /* PBXContainerItemProxy */;
+               };
+               5020A3281098EBFC00982ED6 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 503917C71091413E0001165E /* util */;
+                       targetProxy = 5020A3271098EBFC00982ED6 /* PBXContainerItemProxy */;
+               };
+               503A82141098FB9300B0D08A /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 5039177B109140C30001165E /* syslogd */;
+                       targetProxy = 503A82131098FB9300B0D08A /* PBXContainerItemProxy */;
+               };
+               FCF3761910D2EED700C0EC8D /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 505ACB9C108FD16400197086 /* aslcommon */;
+                       targetProxy = FCF3761810D2EED700C0EC8D /* PBXContainerItemProxy */;
+               };
+               FCF3761B10D2EEDF00C0EC8D /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 505ACB9C108FD16400197086 /* aslcommon */;
+                       targetProxy = FCF3761A10D2EEDF00C0EC8D /* PBXContainerItemProxy */;
+               };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+               1DEB928B08733DD80010E9CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_PREFIX_HEADER = "";
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               PREBINDING = NO;
+                               USE_HEADERMAP = NO;
+                               VERSIONING_SYSTEM = "apple-generic";
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+               5020A3221098EBDF00982ED6 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               PRODUCT_NAME = All;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+               50391768109140460001165E /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CODE_SIGN_IDENTITY = "-";
+                               COPY_PHASE_STRIP = YES;
+                               DEAD_CODE_STRIPPING = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               INSTALL_PATH = /usr/sbin;
+                               OTHER_CFLAGS = (
+                                       "-Wall",
+                                       "-DINET6",
+                               );
+                               PREBINDING = NO;
+                               PRODUCT_NAME = aslmanager;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+               5039177E109140C40001165E /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CODE_SIGN_IDENTITY = "-";
+                               COPY_PHASE_STRIP = YES;
+                               DEAD_CODE_STRIPPING = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(BUILT_PRODUCTS_DIR)/$(CURRENT_ARCH)",
+                                       "$(PROJECT_DIR)/aslcommon",
+                                       "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
+                               );
+                               INSTALL_PATH = /usr/sbin;
+                               OTHER_CFLAGS = (
+                                       "-Wall",
+                                       "-DINET6",
+                               );
+                               "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
+                                       "$(OTHER_CFLAGS)",
+                                       "-DCONFIG_IPHONE",
+                                       "-DLOCKDOWN",
+                               );
+                               "OTHER_CFLAGS[sdk=macosx*][arch=*]" = (
+                                       "$(OTHER_CFLAGS)",
+                                       "-DCONFIG_MAC",
+                                       "-DREMOTE_IPV4",
+                               );
+                               PREBINDING = NO;
+                               PRODUCT_NAME = syslogd;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+               503917CA1091413E0001165E /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CODE_SIGN_IDENTITY = "-";
+                               COPY_PHASE_STRIP = YES;
+                               DEAD_CODE_STRIPPING = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(BUILT_PRODUCTS_DIR)/$(CURRENT_ARCH)",
+                                       "$(PROJECT_DIR)/aslcommon",
+                               );
+                               INSTALL_PATH = /usr/bin;
+                               OTHER_CFLAGS = (
+                                       "-Wall",
+                                       "-DINET6",
+                               );
+                               "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
+                                       "$(OTHER_CFLAGS)",
+                                       "-DCONFIG_IPHONE",
+                               );
+                               PREBINDING = NO;
+                               PRODUCT_NAME = syslog;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+               505ACB9F108FD16500197086 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CODE_SIGN_IDENTITY = "-";
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/aslcommon";
+                               INSTALL_PATH = /usr/local/lib;
+                               OTHER_CFLAGS = (
+                                       "-Wall",
+                                       "-D__MigTypeCheck=1",
+                               );
+                               PREBINDING = NO;
+                               PRODUCT_NAME = aslcommon;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "syslog" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               1DEB928B08733DD80010E9CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               5020A3311098EC3000982ED6 /* Build configuration list for PBXAggregateTarget "All" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               5020A3221098EBDF00982ED6 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               5039176A1091404D0001165E /* Build configuration list for PBXNativeTarget "aslmanager" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               50391768109140460001165E /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               50391782109140CA0001165E /* Build configuration list for PBXNativeTarget "syslogd" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               5039177E109140C40001165E /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               503917CF1091414A0001165E /* Build configuration list for PBXNativeTarget "util" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               503917CA1091413E0001165E /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               505ACBA0108FD16500197086 /* Build configuration list for PBXNativeTarget "aslcommon" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               505ACB9F108FD16500197086 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/syslogd.tproj/Makefile b/syslogd.tproj/Makefile
deleted file mode 100644 (file)
index 6f40d64..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-Project = syslogd
-ProductType = tool
-Install_Dir = /usr/sbin
-
-CFILES = asl_action.c asl_in.c bb_convert.c bsd_in.c bsd_out.c daemon.c dbserver.c klog_in.c remote.c syslogd.c udp_in.c
-
-MANPAGES = asl.conf.5 syslogd.8 syslog.conf.5
-#syslogd.sb
-LAUNCHD_PLISTS = com.apple.syslogd.plist
-
-Extra_CC_Flags = -Wall -mdynamic-no-pic \
-       -DINET6 \
-       -I"$(OBJROOT)"/aslcommon \
-       -I../aslcommon \
-       -I"$(SDKROOT)"/System/Library/Frameworks/System.framework/PrivateHeaders
-
-# Determine product configuartion
-PRODUCT = $(shell tconf --product)
-ifeq ($(PRODUCT),MacOSX)
-Extra_CC_Flags += -DCONFIG_MAC -DREMOTE_IPV4
-endif
-ifeq ($(PRODUCT),AppleTV)
-Extra_CC_Flags += -DCONFIG_APPLETV -DREMOTE_IPV4
-endif
-ifeq ($(PRODUCT),iPhone)
-Extra_CC_Flags += -DCONFIG_IPHONE -DLOCKDOWN
-endif
-
-Extra_LD_Flags = -dead_strip -L"$(SYMROOT)" -laslcommon -lbsm
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-after_install:
-       $(INSTALL_DIRECTORY) "$(DSTROOT)"/private/var/log/asl
-       $(INSTALL_DIRECTORY) "$(DSTROOT)"/usr/share/sandbox
-       $(INSTALL_FILE) syslogd.sb "$(DSTROOT)"/usr/share/sandbox
-       codesign -s- $(DSTROOT)/usr/sbin/syslogd
-       plutil -convert binary1 $(DSTROOT)/System/Library/LaunchDaemons/com.apple.syslogd.plist
-       mkfile 8 "$(DSTROOT)"/private/var/log/asl/SweepStore
-       chmod 644 "$(DSTROOT)"/private/var/log/asl/SweepStore
diff --git a/syslogd.tproj/after_install.sh b/syslogd.tproj/after_install.sh
new file mode 100755 (executable)
index 0000000..eb07c3c
--- /dev/null
@@ -0,0 +1,21 @@
+#! /bin/bash
+
+install -d -m 0755 -o root -g wheel "$DSTROOT"/private/var/log/asl
+
+PRODUCT=$(xcodebuild -sdk ${SDKROOT} -version PlatformPath | head -1 | sed 's,^.*/\([^/]*\)\.platform$,\1,')
+if [ ${PRODUCT}x = x ]; then
+    PRODUCT=MacOSX
+fi
+
+if [ ${PRODUCT} = iPhone ]; then
+    install -d -m 0755 -o root -g wheel "$DSTROOT"/usr/share/sandbox
+    install -m 0644 -o root -g wheel "$SRCROOT"/syslogd.tproj/syslogd.sb "$DSTROOT"/usr/share/sandbox
+fi
+
+DESTDIR="$DSTROOT"/System/Library/LaunchDaemons
+install -d -m 0755 -o root -g wheel "$DESTDIR"
+install -m 0644 -o root -g wheel "$SRCROOT"/syslogd.tproj/com.apple.syslogd.plist "$DESTDIR"
+plutil -convert binary1 "$DESTDIR"/com.apple.syslogd.plist
+
+mkfile 8 "$DSTROOT"/private/var/log/asl/SweepStore
+chmod 0644 "$DSTROOT"/private/var/log/asl/SweepStore
index e9ac0225a131f8cdb5448c42759ce16fbeb6a275..1b859c4172d04f44f57e6907ba42c51d7b23d8c3 100644 (file)
@@ -42,7 +42,7 @@ See the ASLMANAGER PARAMETER SETTINGS section below for details on those paramet
 The file may contain parameter settings, used in place of (and which will override) command-line options,
 and may contain query-action rules that trigger specific actions when
 .Nm syslogd
-recieves messages that match the query pattern.
+receives messages that match the query pattern.
 .Pp
 Parameter setting lines in the configuration file begin with an equal sign ("="), 
 and are generally of the form:
@@ -215,15 +215,20 @@ mode specification of the form "0644" (for an octal number) or DDD for a decimal
 .Pp
 Two other optional parameters may also follow the pathname.
 .Pp
-By default,
+If a separate log message data store file is specified as a parameter, then
 .Nm syslogd
 will open the database, save a matching message, and then close the database.
 If a high volume of messages is expected, specifying the "stayopen" option will improve performance.
 .Pp
-Specifying "exclude_asldb" will cause syslogd to save matching messages in the specificed file,
-but exclude them from the main ASL data store.
+Also, if a separate log message data store file is specified as a parameter,
+matching messages will be excluded from all further processing.
+Adding the "continue" option will cause syslogd to save matching messages in the specified store file
+and then continue processing matching messages in accordance with the actions
+specified in /etc/asl.conf and /etc/syslog.conf.
 .Pp
-Note that if the configuration file contains no matching rules for the ASL data store, then
+Note that if the
+.Nm asl.conf
+configuration file contains no matching rules for the main ASL data store, then
 .Nm syslogd
 will save all messages, subject to filtering in accordance with the log cutoff level.
 .Pp
@@ -232,14 +237,14 @@ Causes matching messages to be stored in a log message data store file in a sepa
 The directory path name must follow as the first parameter.
 The named directory must exist.
 .Nm syslogd
-will not ceate the directory path.
+will not create the directory path.
 .Pp
 Messages saved to a store directory are saved in files that are named "yyyy.mm.dd.asl",
 where "yyyy", "mm", and "dd" are the year, month (01 to 12) and day of the month (01 to 31) associated with
 matching messages.
 This has the effect of saving messages in a separate file for each day.
 .Pp
-The "exclude_asldb", "uid=UUU", "gid=GGG", and "mode=MMMM" options available for the "store" action
+The "uid=UUU", "gid=GGG", "mode=MMMM", and "continue" options available for the "store" action
 may also be specified for a store directory.
 The uid, gid, and mode specification will be used when the individual daily store files are created.
 .Pp
index e800e650b3f567a6179c09254e79246892813c93..572f67ba883d2b8fcdf1bbd7d130b8a957d263c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #define ACTION_STORE_DIR 6
 #define ACTION_FORWARD   7
 
-#define IndexNull ((uint32_t)-1)
 #define forever for(;;)
 
-#define ACT_STORE_FLAG_STAY_OPEN     0x00000001
-#define ACT_STORE_FLAG_EXCLUDE_ASLDB 0x00000002
+#define ACT_STORE_FLAG_STAY_OPEN 0x00000001
+#define ACT_STORE_FLAG_CONTINUE  0x00000002
 
 static asl_msg_t *query = NULL;
 static int reset = RESET_NONE;
@@ -92,7 +91,7 @@ static int filter_token = -1;
 
 int asl_action_close();
 static int _parse_config_file(const char *);
-extern void db_save_message(asl_msg_t *m);
+extern void db_save_message(aslmsg m);
 
 static char *
 _next_word(char **s)
@@ -161,8 +160,12 @@ _do_reset(void)
 {
        pthread_mutex_lock(&reset_lock);
 
-       asl_action_close();
-       _parse_config_file(_PATH_ASL_CONF);
+       if (reset == RESET_CONFIG)
+       {
+               asl_action_close();
+               _parse_config_file(_PATH_ASL_CONF);
+       }
+
        reset = RESET_NONE;
 
        pthread_mutex_unlock(&reset_lock);
@@ -257,7 +260,7 @@ _parse_query_action(char *s)
 
        *p = '\0';
 
-       if (s[0] == '*') out->query = asl_new(ASL_TYPE_QUERY);
+       if (s[0] == '*') out->query = asl_msg_new(ASL_TYPE_QUERY);
        else
        {
                s[0] = 'Q';
@@ -267,7 +270,7 @@ _parse_query_action(char *s)
        if (out->query == NULL)
        {
                asldebug("out->query is NULL (ERROR)\n");
-               if (out->options != NULL) free(out->options);
+               free(out->options);
                free(out);
                return -1;
        }
@@ -500,7 +503,7 @@ _parse_line(char *s)
                                 ASL_KEY_UID, ASL_KEY_GID);
 
                asl_log_string(str);
-               if (str != NULL) free(str);
+               free(str);
        }
 
        return status;
@@ -516,8 +519,9 @@ _act_notify(action_rule_t *r)
 }
 
 static void
-_act_broadcast(action_rule_t *r, asl_msg_t *msg)
+_act_broadcast(action_rule_t *r, aslmsg msg)
 {
+#ifndef CONFIG_IPHONE
        FILE *pw;
        const char *val;
 
@@ -537,10 +541,11 @@ _act_broadcast(action_rule_t *r, asl_msg_t *msg)
 
        fprintf(pw, "%s", val);
        pclose(pw);
+#endif
 }
 
 static void
-_act_access_control(action_rule_t *r, asl_msg_t *msg)
+_act_access_control(action_rule_t *r, aslmsg msg)
 {
        int32_t ruid, rgid;
        char *p;
@@ -556,10 +561,10 @@ _act_access_control(action_rule_t *r, asl_msg_t *msg)
                rgid = atoi(p);
        }
 
-       if (ruid != -1) asl_set((aslmsg)msg, ASL_KEY_READ_UID, r->options);
+       if (ruid != -1) asl_set(msg, ASL_KEY_READ_UID, r->options);
        if (p != NULL)
        {
-               if (rgid != -1) asl_set((aslmsg)msg, ASL_KEY_READ_GID, p);
+               if (rgid != -1) asl_set(msg, ASL_KEY_READ_GID, p);
                p--;
                *p = ' ';
        }
@@ -591,6 +596,7 @@ _act_store_dir_setup(struct store_data *sd, time_t tick)
        struct stat sb;
        uint64_t xid;
        int status;
+       mode_t mask;
 
        if (sd == NULL) return ASL_STATUS_INVALID_STORE;
        if (sd->dir == NULL) return ASL_STATUS_INVALID_STORE;
@@ -600,6 +606,33 @@ _act_store_dir_setup(struct store_data *sd, time_t tick)
 
        if (sd->storedata == NULL)
        {
+               memset(&sb, 0, sizeof(struct stat));
+               status = stat(sd->dir, &sb);
+               if (status == 0)
+               {
+                       /* must be a directory */
+                       if (!S_ISDIR(sb.st_mode)) return ASL_STATUS_INVALID_STORE;
+               }
+               else if (errno == ENOENT)
+               {
+                       /* doesn't exist - create it */
+                       mask = umask(0);
+                       status = mkdir(sd->dir, sd->mode);
+                       umask(mask);
+                       
+                       if (status != 0) return ASL_STATUS_WRITE_FAILED;
+                       
+                       if ((sd->uid != 0) || (sd->gid != 0))
+                       {
+                               if (chown(sd->dir, sd->uid, sd->gid) != 0) return ASL_STATUS_WRITE_FAILED;
+                       }
+               }
+               else
+               {
+                       /* Unexpected stat error */
+                       return ASL_STATUS_FAILED;
+               }
+               
                path = NULL;
                asprintf(&path, "%s/%s", sd->dir, FILE_ASL_STORE_DATA);
                if (path == NULL) return ASL_STATUS_NO_MEMORY;
@@ -624,13 +657,7 @@ _act_store_dir_setup(struct store_data *sd, time_t tick)
                                return ASL_STATUS_READ_FAILED;
                        }
                }
-               else if (errno != ENOENT)
-               {
-                       /* Unexpected stat error */
-                       free(path);
-                       return ASL_STATUS_FAILED;
-               }
-               else
+               else if (errno == ENOENT)
                {
                        /* StoreData does not exist: create it */
                        sd->storedata = fopen(path, "w");
@@ -639,6 +666,21 @@ _act_store_dir_setup(struct store_data *sd, time_t tick)
                                free(path);
                                return ASL_STATUS_FAILED;
                        }
+
+                       if ((sd->uid != 0) || (sd->gid != 0))
+                       {
+                               if (chown(path, sd->uid, sd->gid) != 0)
+                               {
+                                       free(path);
+                                       return ASL_STATUS_WRITE_FAILED;
+                               }
+                       }
+               }
+               else
+               {
+                       /* Unexpected stat error */
+                       free(path);
+                       return ASL_STATUS_FAILED;
                }
 
                free(path);
@@ -685,7 +727,7 @@ _act_store_dir_setup(struct store_data *sd, time_t tick)
        sd->p_month = 0;
        sd->p_day = 0;
 
-       if (sd->path != NULL) free(sd->path);
+       free(sd->path);
        sd->path = NULL;
 
        asprintf(&(sd->path), "%s/%d.%02d.%02d.asl", sd->dir, ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday);
@@ -699,14 +741,14 @@ _act_store_dir_setup(struct store_data *sd, time_t tick)
 }
 
 static void
-_act_store(action_rule_t *r, asl_msg_t *msg)
+_act_store(action_rule_t *r, aslmsg msg)
 {
        struct store_data *sd;
        asl_file_t *s;
        uint8_t x;
        uint32_t status;
        uint64_t mid;
-       mode_t tmp_mode;
+       mode_t tmp_mode, mask;
        char *str, *opts, *p;
        const char *val;
        time_t tick;
@@ -728,8 +770,17 @@ _act_store(action_rule_t *r, asl_msg_t *msg)
                if (r->action == ACTION_STORE)
                {
                        sd->path = _next_word(&opts);
-                       if (sd->path == NULL)
+                       if ((sd->path == NULL) || (sd->path[0] != '/'))
                        {
+                               str = NULL;
+                               asprintf(&str, "[%s syslogd] [%s %u] [%s %u] [Facility syslog] [%s Invalid path for \"store\" action: %s]",
+                                                ASL_KEY_SENDER,
+                                                ASL_KEY_LEVEL, ASL_LEVEL_ERR,
+                                                ASL_KEY_PID, getpid(),
+                                                ASL_KEY_MSG, (sd->path == NULL) ? "no path specified" : sd->path);
+
+                               asl_log_string(str);
+                               free(str);
                                free(sd);
                                r->action = ACTION_NONE;
                                return;
@@ -738,15 +789,24 @@ _act_store(action_rule_t *r, asl_msg_t *msg)
                else if (r->action == ACTION_STORE_DIR)
                {
                        sd->dir = _next_word(&opts);
-                       if (sd->dir == NULL)
+                       if ((sd->dir == NULL) || (sd->dir[0] != '/'))
                        {
+                               str = NULL;
+                               asprintf(&str, "[%s syslogd] [%s %u] [%s %u] [Facility syslog] [%s Invalid path for \"store_directory\" action: %s]",
+                                                ASL_KEY_SENDER,
+                                                ASL_KEY_LEVEL, ASL_LEVEL_ERR,
+                                                ASL_KEY_PID, getpid(),
+                                                ASL_KEY_MSG, (sd->dir == NULL) ? "no path specified" : sd->dir);
+
+                               asl_log_string(str);
+                               free(str);
                                free(sd);
                                r->action = ACTION_NONE;
                                return;
                        }
                }
 
-               sd->mode = 0644;
+               sd->mode = 0755;
                sd->next_id = 0;
                sd->uid = 0;
                sd->gid = 0;
@@ -754,8 +814,14 @@ _act_store(action_rule_t *r, asl_msg_t *msg)
 
                while (NULL != (p = _next_word(&opts)))
                {
-                       if (!strcmp(p, "stayopen")) sd->flags |= ACT_STORE_FLAG_STAY_OPEN;
-                       else if (!strcmp(p, "exclude_asldb")) sd->flags |= ACT_STORE_FLAG_EXCLUDE_ASLDB;
+                       if (!strcmp(p, "stayopen"))
+                       {
+                               sd->flags |= ACT_STORE_FLAG_STAY_OPEN;
+                       }
+                       else if (!strcmp(p, "continue"))
+                       {
+                               sd->flags |= ACT_STORE_FLAG_CONTINUE;
+                       }
                        else if (!strncmp(p, "mode=0", 6))
                        {
                                sd->mode = 0;
@@ -763,8 +829,8 @@ _act_store(action_rule_t *r, asl_msg_t *msg)
                                if ((x < '0') || (x > '7'))
                                {
                                        free(p);
-                                       if (sd->path != NULL) free(sd->path);
-                                       if (sd->dir != NULL) free(sd->dir);
+                                       free(sd->path);
+                                       free(sd->dir);
                                        free(sd);
                                        r->action = ACTION_NONE;
                                        return;
@@ -777,8 +843,8 @@ _act_store(action_rule_t *r, asl_msg_t *msg)
                                if ((x < '0') || (x > '7'))
                                {
                                        free(p);
-                                       if (sd->path != NULL) free(sd->path);
-                                       if (sd->dir != NULL) free(sd->dir);
+                                       free(sd->path);
+                                       free(sd->dir);
                                        free(sd);
                                        r->action = ACTION_NONE;
                                        return;
@@ -791,8 +857,8 @@ _act_store(action_rule_t *r, asl_msg_t *msg)
                                if ((x < '0') || (x > '7'))
                                {
                                        free(p);
-                                       if (sd->path != NULL) free(sd->path);
-                                       if (sd->dir != NULL) free(sd->dir);
+                                       free(sd->path);
+                                       free(sd->dir);
                                        free(sd);
                                        r->action = ACTION_NONE;
                                        return;
@@ -838,7 +904,11 @@ _act_store(action_rule_t *r, asl_msg_t *msg)
        if (sd->store == NULL)
        {
                s = NULL;
-               status = asl_file_open_write(sd->path, sd->mode, sd->uid, sd->gid, &s);
+
+               mask = umask(0);
+               status = asl_file_open_write(sd->path, (sd->mode & 0666), sd->uid, sd->gid, &s);
+               umask(mask);
+
                if ((status != ASL_STATUS_OK) || (s == NULL))
                {
                        asldebug("asl_file_open_write %s failed: %s\n", sd->path, asl_core_error(status));
@@ -888,7 +958,7 @@ _act_store(action_rule_t *r, asl_msg_t *msg)
                sd->store = NULL;
        }
 
-       if (sd->flags & ACT_STORE_FLAG_EXCLUDE_ASLDB)
+       if ((sd->flags & ACT_STORE_FLAG_CONTINUE) == 0)
        {
                opts = (char *)asl_get(msg, ASL_KEY_OPTION);
                if (opts == NULL)
@@ -909,13 +979,13 @@ _act_store(action_rule_t *r, asl_msg_t *msg)
 }
 
 static void
-_act_forward(action_rule_t *r, asl_msg_t *msg)
+_act_forward(action_rule_t *r, aslmsg msg)
 {
        /* To do: <rdar://problem/6130747> Add a "forward" action to asl.conf */
 }
 
 static void
-send_to_asl_store(asl_msg_t *msg)
+send_to_asl_store(aslmsg msg)
 {
        const char *vlevel, *val;
        uint64_t v64;
@@ -923,9 +993,6 @@ send_to_asl_store(asl_msg_t *msg)
        int x, log_me;
        action_rule_t *r;
 
-       /* ASLOption "ignore" keeps a message out of the ASL datastore */
-       if (asl_check_option(msg, ASL_OPT_IGNORE) != 0) return;
-
        if (filter_token == -1)
        {
                /* set up com.apple.syslog.asl_filter */
@@ -994,7 +1061,7 @@ send_to_asl_store(asl_msg_t *msg)
 
        for (r = asl_datastore_rule; r != NULL; r = r->next)
        {
-               if (asl_msg_cmp(r->query, msg) == 1)
+               if (asl_msg_cmp(r->query, (asl_msg_t *)msg) == 1)
                {
                        /* if any rule matches, save the message (once!) */
                        db_save_message(msg);
@@ -1004,29 +1071,35 @@ send_to_asl_store(asl_msg_t *msg)
 }
 
 int
-asl_action_sendmsg(asl_msg_t *msg, const char *outid)
+asl_action_sendmsg(aslmsg msg, const char *outid)
 {
        action_rule_t *r;
 
-       if (reset == RESET_CONFIG) _do_reset();
+       if (reset != RESET_NONE) _do_reset();
 
        if (msg == NULL) return -1;
 
        for (r = asl_action_rule; r != NULL; r = r->next)
        {
-               if (asl_msg_cmp(r->query, msg) == 1)
+               if (asl_msg_cmp(r->query, (asl_msg_t *)msg) == 1)
                {
+                       if ((r->action == ACTION_STORE) || (r->action == ACTION_STORE_DIR))
+                       {
+                               _act_store(r, msg);
+                               if (asl_check_option(msg, ASL_OPT_IGNORE) != 0) return -1;
+                       }
+
                        if (r->action == ACTION_NONE) continue;
-                       else if (r->action == ACTION_IGNORE) return 0;
+                       else if (r->action == ACTION_IGNORE) return -1;
                        else if (r->action == ACTION_ACCESS) _act_access_control(r, msg);
                        else if (r->action == ACTION_NOTIFY) _act_notify(r);
-                       else if (r->action == ACTION_STORE) _act_store(r, msg);
-                       else if (r->action == ACTION_STORE_DIR) _act_store(r, msg);
                        else if (r->action == ACTION_BROADCAST) _act_broadcast(r, msg);
                        else if (r->action == ACTION_FORWARD) _act_forward(r, msg);
                }
        }
 
+       if (asl_check_option(msg, ASL_OPT_IGNORE) != 0) return -1;
+
        send_to_asl_store(msg);
 
        return 0;
@@ -1057,7 +1130,7 @@ asl_action_init(void)
 {
        asldebug("%s: init\n", MY_ID);
 
-       query = asl_new(ASL_TYPE_QUERY);
+       query = asl_msg_new(ASL_TYPE_QUERY);
        aslevent_addmatch(query, MY_ID);
        aslevent_addoutput(asl_action_sendmsg, MY_ID);
 
@@ -1087,14 +1160,14 @@ asl_action_close(void)
                        sd = (struct store_data *)r->data;
                        if (sd->store != NULL) asl_file_close(sd->store);
                        if (sd->storedata != NULL) fclose(sd->storedata);
-                       if (sd->path != NULL) free(sd->path);
-                       if (sd->dir != NULL) free(sd->dir);
+                       free(sd->path);
+                       free(sd->dir);
                        sd->store = NULL;
                        free(sd);
                }
 
-               if (r->query != NULL) asl_free(r->query);
-               if (r->options != NULL) free(r->options);
+               if (r->query != NULL) asl_msg_release(r->query);
+               free(r->options);
 
                free(r);
        }
@@ -1106,8 +1179,8 @@ asl_action_close(void)
        {
                n = r->next;
 
-               if (r->query != NULL) asl_free(r->query);
-               if (r->options != NULL) free(r->options);
+               if (r->query != NULL) asl_msg_release(r->query);
+               free(r->options);
 
                free(r);
        }
index 1bd0883ff1c72847927a71903e4f8a8295e366f3..9229f55e111acebd291a268600d596c919714854 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 
 static int sock = -1;
 
-asl_msg_t *
+aslmsg
 asl_in_getmsg(int fd)
 {
        char *out;
-       asl_msg_t *m;
+       aslmsg msg;
        uint32_t len, n;
        char tmp[16];
        int status;
@@ -110,24 +110,24 @@ asl_in_getmsg(int fd)
        gid = -2;
 
        status = getpeereid(fd, &uid, &gid);
-       m = asl_msg_from_string(out);
-       if (m == NULL)
+       msg = (aslmsg)asl_msg_from_string(out);
+       if (msg == NULL)
        {
                free(out);
                return NULL;
        }
 
        snprintf(tmp, sizeof(tmp), "%d", uid);
-       asl_set(m, ASL_KEY_UID, tmp);
+       asl_set(msg, ASL_KEY_UID, tmp);
 
        snprintf(tmp, sizeof(tmp), "%d", gid);
-       asl_set(m, ASL_KEY_GID, tmp);
+       asl_set(msg, ASL_KEY_GID, tmp);
 
        free(out);
-       return m;
+       return msg;
 }
 
-asl_msg_t *
+aslmsg
 asl_in_new_connection(int fd)
 {
        int clientfd;
@@ -226,19 +226,20 @@ asl_in_init(void)
        return aslevent_addfd(SOURCE_ASL_SOCKET, sock, ADDFD_FLAGS_LOCAL, asl_in_new_connection, NULL, NULL);
 }
 
-int
-asl_in_reset(void)
-{
-       return 0;
-}
-
 int
 asl_in_close(void)
 {
        if (sock < 0) return 1;
 
+       aslevent_removefd(sock);
        close(sock);
-       unlink(_PATH_ASL_IN);
+       sock = -1;
 
        return 0;
 }
+
+int
+asl_in_reset(void)
+{
+       return 0;
+}
index f247dc94ea3cedf89d0ecefde7353d7b922f83ce..b0df48fd893e9828a9a1982d0427a29658ceee35 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -118,7 +118,7 @@ do_ASLExpireTime_search(asl_store_t *s, asl_search_result_t **out)
        uint32_t status;
        uint64_t mid;
 
-       qm[0] = asl_new(ASL_TYPE_QUERY);
+       qm[0] = asl_msg_new(ASL_TYPE_QUERY);
        if (qm[0] == NULL) return ASL_STATUS_NO_MEMORY;
 
        q.count = 1;
@@ -126,9 +126,9 @@ do_ASLExpireTime_search(asl_store_t *s, asl_search_result_t **out)
        q.msg = qm;
        query = &q;
 
-       if (asl_set_query(qm[0], ASL_KEY_EXPIRE_TIME, NULL, ASL_QUERY_OP_TRUE) != 0)
+       if (asl_msg_set_key_val_op(qm[0], ASL_KEY_EXPIRE_TIME, NULL, ASL_QUERY_OP_TRUE) != 0)
        {
-               asl_free(qm[0]);
+               asl_msg_release(qm[0]);
                return ASL_STATUS_NO_MEMORY;
        }
 
@@ -136,7 +136,7 @@ do_ASLExpireTime_search(asl_store_t *s, asl_search_result_t **out)
        mid = 0;
        status = asl_store_match(s, query, out, &mid, 0, 0, 1);
 
-       asl_free(qm[0]);
+       asl_msg_release(qm[0]);
        return status;
 }
 
@@ -144,7 +144,7 @@ do_ASLExpireTime_search(asl_store_t *s, asl_search_result_t **out)
 static uint32_t
 do_ASLExpireTime_filter(const char *name)
 {
-       asl_msg_t *msg;
+       aslmsg msg;
        asl_file_t *in, *out;
        uint32_t status;
        uint64_t mid;
@@ -227,8 +227,8 @@ sort_compare(const void *a, const void *b)
        const char *va, *vb;
        uint64_t na, nb;
 
-       va = asl_get(*(asl_msg_t **)a, ASL_KEY_MSG_ID);
-       vb = asl_get(*(asl_msg_t **)b, ASL_KEY_MSG_ID);
+       va = asl_get(*(aslmsg *)a, ASL_KEY_MSG_ID);
+       vb = asl_get(*(aslmsg *)b, ASL_KEY_MSG_ID);
 
        if (va == NULL) return -1;
        if (vb == NULL) return 1;
@@ -243,7 +243,7 @@ sort_compare(const void *a, const void *b)
 
 /* save a message to an appropriately named BB file */
 static uint32_t 
-save_bb_msg(asl_msg_t *msg)
+save_bb_msg(aslmsg msg)
 {
        const char *val;
        uid_t u, ruid;
@@ -442,7 +442,7 @@ bb_convert(const char *name)
        if (i != 0) return ASL_STATUS_INVALID_STORE;
 
        /* must be a regular file */
-       if ((sb.st_mode & S_IFREG) == 0) return ASL_STATUS_INVALID_STORE;
+       if (!S_ISREG(sb.st_mode)) return ASL_STATUS_INVALID_STORE;
 
        /* check is the store has already been converted */
        if (sb.st_size > sizeof(uint64_t)) return ASL_STATUS_OK;
@@ -483,12 +483,12 @@ bb_convert(const char *name)
        if ((expire_time_records == NULL) || (expire_time_records->count == 0)) return finish_conversion();
 
        /* sort by ASLMessageID */
-       qsort(expire_time_records->msg, expire_time_records->count, sizeof(asl_msg_t *), sort_compare);
+       qsort(expire_time_records->msg, expire_time_records->count, sizeof(aslmsg), sort_compare);
 
        /* save the ASLExpireTime messages into a new set of BB files */
        for (i = 0; i < expire_time_records->count; i++)
        {
-               status = save_bb_msg(expire_time_records->msg[i]);
+               status = save_bb_msg((aslmsg)expire_time_records->msg[i]);
                if (status != ASL_STATUS_OK)
                {
                        if (cache_file != NULL) asl_file_close(cache_file);
index eafca64b52eefe409b21472abf5818a3239409c9..fa10fd46c68de7a5f7bf3a44a284b02e5fda863a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -40,7 +40,7 @@
 
 static int sock = -1;
 
-asl_msg_t *
+aslmsg
 bsd_in_acceptmsg(int fd)
 {
        uint32_t len;
@@ -55,7 +55,7 @@ bsd_in_acceptmsg(int fd)
 
        line[n] = '\0';
 
-       return asl_input_parse(line, n, NULL, 0);
+       return asl_input_parse(line, n, NULL, SOURCE_BSD_SOCKET);
 }
 
 int
@@ -132,17 +132,19 @@ bsd_in_init(void)
 }
 
 int
-bsd_in_reset(void)
+bsd_in_close(void)
 {
+       if (sock < 0) return 1;
+
+       aslevent_removefd(sock);
+       close(sock);
+       sock = -1;
+
        return 0;
 }
 
 int
-bsd_in_close(void)
+bsd_in_reset(void)
 {
-       if (sock < 0) return 1;
-
-       close(sock);
-       unlink(_PATH_SYSLOG_IN);
        return 0;
 }
index 10bbb75c18a372141c0daa88b5e7b8a24fe741f8..015283cdc45a125d8b1c3e50cfb4581ea6de54ec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -66,6 +66,7 @@ struct config_rule
        int type;
        struct sockaddr *addr;
        char **facility;
+       uint32_t *fac_prefix_len;
        int *pri;
        uint32_t last_hash;
        uint32_t last_count;
@@ -302,7 +303,7 @@ _clean_facility_name(char *s)
 static int
 _parse_line(char *s)
 {
-       char **semi, **comma;
+       char **semi, **comma, *star;
        int i, j, n, lasts, lastc, pri;
        struct config_rule *out;
 
@@ -349,20 +350,27 @@ _parse_line(char *s)
                        if (out->count == 0)
                        {
                                out->facility = (char **)calloc(1, sizeof(char *));
+                               out->fac_prefix_len = (uint32_t *)calloc(1, sizeof(uint32_t));
                                out->pri = (int *)calloc(1, sizeof(int));
                        }
                        else
                        {
                                out->facility = (char **)reallocf(out->facility, (out->count + 1) * sizeof(char *));
+                               out->fac_prefix_len = (uint32_t *)reallocf(out->fac_prefix_len, (out->count + 1) * sizeof(uint32_t));
                                out->pri = (int *)reallocf(out->pri, (out->count + 1) * sizeof(int));
                        }
 
                        if (out->facility == NULL) return -1;
+                       if (out->fac_prefix_len == NULL) return -1;
                        if (out->pri == NULL) return -1;
 
                        out->facility[out->count] = _clean_facility_name(comma[j]);
                        if (out->facility[out->count] == NULL) return -1;
 
+                       out->fac_prefix_len[out->count] = 0;
+                       star = strchr(out->facility[out->count], '*');
+                       if (star != NULL) out->fac_prefix_len[out->count] = (uint32_t)(star - out->facility[out->count]);
+
                        out->pri[out->count] = pri;
                        out->count++;
                }
@@ -377,64 +385,6 @@ _parse_line(char *s)
        return 0;
 }
 
-static char *
-bsd_log_string(const char *msg)
-{
-       uint32_t i, len, outlen;
-       char *out, *q;
-       uint8_t c;
-
-       if (msg == NULL) return NULL;
-
-       len = strlen(msg);
-       while ((len > 0) && (msg[len - 1] == '\n')) len--;
-
-       if (len == 0) return NULL;
-
-       outlen = len + 1;
-       for (i = 0; i < len; i++)
-       {
-               c = msg[i];
-               if (isascii(c) && iscntrl(c) && (c != '\t')) outlen++;
-       }
-
-       out = malloc(outlen);
-       if (out == NULL) return NULL;
-
-       q = out;
-
-       for (i = 0; i < len; i++)
-       {
-               c = msg[i];
-
-               if (isascii(c) && iscntrl(c))
-               {
-                       if (c == '\n')
-                       {
-                               *q++ = '\\';
-                               *q++ = 'n';
-                       }
-                       else if (c == '\t')
-                       {
-                               *q++ = c;
-                       }
-                       else
-                       {
-                               *q++ = '^';
-                               *q++ = c ^ 0100;
-                       }
-               }
-               else
-               {
-                       *q++ = c;
-               }
-       }
-
-       *q = '\0';
-
-       return out;
-}
-
 static int
 _syslog_send_repeat_msg(struct config_rule *r)
 {
@@ -447,7 +397,6 @@ _syslog_send_repeat_msg(struct config_rule *r)
        if (r->last_count == 0) return 0;
 
        tick = time(NULL);
-
        memset(vt, 0, sizeof(vt));
        ctime_r(&tick, vt);
        vt[19] = '\0';
@@ -486,20 +435,20 @@ _syslog_send_repeat_msg(struct config_rule *r)
 }
 
 static int
-_syslog_send(asl_msg_t *msg, struct config_rule *r, char **out, char **fwd, time_t now)
+_syslog_send(aslmsg msg, struct config_rule *r, char **out, char **fwd, time_t now)
 {
-       char vt[16], tstr[32], *so, *sf, *outmsg;
-       const char *vtime, *vhost, *vident, *vpid, *vmsg, *vlevel, *vfacility, *vrefproc, *vrefpid;
-       size_t outlen, n;
-       time_t tick;
+       char *sf, *outmsg;
+       const char *vlevel, *vfacility;
+       size_t outlen;
        int pf, fc, status, is_dup, do_write;
-       FILE *pw;
-       uint32_t msg_hash;
+       uint32_t msg_hash, n;
 
        if (out == NULL) return -1;
        if (fwd == NULL) return -1;
        if (r == NULL) return -1;
 
+       _syslog_dst_open(r);
+
        if (r->type == DST_TYPE_NOTE)
        {
                notify_post(r->dst+1);
@@ -512,123 +461,8 @@ _syslog_send(asl_msg_t *msg, struct config_rule *r, char **out, char **fwd, time
        /* Build output string if it hasn't been built by a previous rule-match */
        if (*out == NULL)
        {
-               tick = now;
-               vtime = asl_get(msg, ASL_KEY_TIME);
-               if (vtime != NULL)
-               {
-                       /* aslmsg_verify converts time to seconds, but use current time if something went sour */
-                       tick = atol(vtime);
-                       if (tick == 0) tick = now;
-               }
-
-               memset(tstr, 0, sizeof(tstr));
-               ctime_r(&tick, tstr);
-               memcpy(vt, tstr+4, 15);
-               vt[15] = '\0';
-
-               vhost = asl_get(msg, ASL_KEY_HOST);
-               if (vhost == NULL) vhost = "localhost";
-
-               vident = asl_get(msg, ASL_KEY_SENDER);
-               if ((vident != NULL) && (!strcmp(vident, "Unknown"))) vident = NULL;
-
-               vpid = asl_get(msg, ASL_KEY_PID);
-               if ((vpid != NULL) && (!strcmp(vpid, "-1"))) vpid = NULL;
-
-               if ((vpid != NULL) && (vident == NULL)) vident = "Unknown";
-
-               vrefproc = asl_get(msg, ASL_KEY_REF_PROC);
-               vrefpid = asl_get(msg, ASL_KEY_REF_PID);
-
-               vmsg = asl_get(msg, ASL_KEY_MSG);
-               if (vmsg != NULL) outmsg = bsd_log_string(vmsg);
-
-               n = 0;
-               /* Time + " " */
-               n += (strlen(vt) + 1);
-
-               /* Host + " " */
-               if (vhost != NULL) n += (strlen(vhost) + 1);
-
-               /* Sender */
-               if (vident != NULL) n += strlen(vident);
-
-               /* "[" PID "]" */
-               if (vpid != NULL) n += (strlen(vpid) + 2);
-
-               /* " (" */
-               if ((vrefproc != NULL) || (vrefpid != NULL)) n += 2;
-
-               /* RefProc */
-               if (vrefproc != NULL) n += strlen(vrefproc);
-
-               /* "[" RefPID "]" */
-               if (vrefpid != NULL) n += (strlen(vrefpid) + 2);
-
-               /* ")" */
-               if ((vrefproc != NULL) || (vrefpid != NULL)) n += 1;
-
-               /* ": " */
-               n += 2;
-
-               /* Message */
-               if (outmsg != NULL) n += strlen(outmsg);
-
-               if (n == 0) return -1;
-
-               /* "\n" + nul */
-               n += 2;
-
-               so = calloc(1, n);
-               if (so == NULL) return -1;
-
-               strcat(so, vt);
-               strcat(so, " ");
-
-               if (vhost != NULL)
-               {
-                       strcat(so, vhost);
-                       strcat(so, " ");
-               }
-
-               if (vident != NULL)
-               {
-                       strcat(so, vident);
-                       if (vpid != NULL)
-                       {
-                               strcat(so, "[");
-                               strcat(so, vpid);
-                               strcat(so, "]");
-                       }
-               }
-
-               if ((vrefproc != NULL) || (vrefpid != NULL))
-               {
-                       strcat(so, " (");
-
-                       if (vrefproc != NULL) strcat(so, vrefproc);
-
-                       if (vrefpid != NULL)
-                       {
-                               strcat(so, "[");
-                               strcat(so, vrefpid);
-                               strcat(so, "]");
-                       }
-
-                       strcat(so, ")");
-               }
-
-               strcat(so, ": ");
-
-               if (outmsg != NULL)
-               {
-                       strcat(so, outmsg);
-                       free(outmsg);
-               }
-
-               strcat(so, "\n");
-
-               *out = so;
+               *out = asl_format_message((asl_msg_t *)msg, ASL_MSG_FMT_BSD, ASL_TIME_FMT_LCL, ASL_ENCODE_SAFE, &n);
+               if (*out == NULL) return -1;
        }
 
        /* check if message is a duplicate of the last message, and inside the dup time window */
@@ -662,8 +496,6 @@ _syslog_send(asl_msg_t *msg, struct config_rule *r, char **out, char **fwd, time
        if (r->type == DST_TYPE_SOCK) outlen = strlen(*fwd);
        else outlen = strlen(*out);
 
-       _syslog_dst_open(r);
-
        if ((r->type == DST_TYPE_FILE) || (r->type == DST_TYPE_CONS))
        {
                /*
@@ -714,7 +546,8 @@ _syslog_send(asl_msg_t *msg, struct config_rule *r, char **out, char **fwd, time
        }
        else if (r->type == DST_TYPE_WALL)
        {
-               pw = popen(_PATH_WALL, "w");
+#ifndef CONFIG_IPHONE
+               FILE *pw = popen(_PATH_WALL, "w");
                if (pw < 0)
                {
                        asldebug("%s: error sending wall message: %s\n", MY_ID, strerror(errno));
@@ -723,6 +556,7 @@ _syslog_send(asl_msg_t *msg, struct config_rule *r, char **out, char **fwd, time
 
                fprintf(pw, "%s", *out);
                pclose(pw);
+#endif
        }
 
        if (is_dup == 1)
@@ -731,7 +565,7 @@ _syslog_send(asl_msg_t *msg, struct config_rule *r, char **out, char **fwd, time
        }
        else
        {
-               if (r->last_msg != NULL) free(r->last_msg);
+               free(r->last_msg);
                r->last_msg = NULL;
 
                if (*out != NULL) r->last_msg = strdup(*out + 16);
@@ -745,7 +579,7 @@ _syslog_send(asl_msg_t *msg, struct config_rule *r, char **out, char **fwd, time
 }
 
 static int
-_syslog_rule_match(asl_msg_t *msg, struct config_rule *r)
+_syslog_rule_match(aslmsg msg, struct config_rule *r)
 {
        uint32_t i, test, f, pri;
        const char *val;
@@ -764,11 +598,19 @@ _syslog_rule_match(asl_msg_t *msg, struct config_rule *r)
                if ((test == 0) && (r->pri[i] == -2)) continue;
 
                f = 0;
-               if (strcmp(r->facility[i], "*") == 0) f = 1;
-               else
+               val = asl_get(msg, ASL_KEY_FACILITY);
+
+               if (strcmp(r->facility[i], "*") == 0)
                {
-                       val = asl_get(msg, ASL_KEY_FACILITY);
-                       if ((val != NULL) && (strcasecmp(r->facility[i], val) == 0)) f = 1;
+                       f = 1;
+               }
+               else if ((r->fac_prefix_len[i] > 0) && (strncasecmp(r->facility[i], val, r->fac_prefix_len[i]) == 0))
+               {
+                       f = 1;
+               }
+               else if ((val != NULL) && (strcasecmp(r->facility[i], val) == 0))
+               {
+                       f = 1;
                }
 
                if (f == 0) continue;
@@ -793,7 +635,7 @@ _syslog_rule_match(asl_msg_t *msg, struct config_rule *r)
 }
 
 int
-bsd_out_sendmsg(asl_msg_t *msg, const char *outid)
+bsd_out_sendmsg(aslmsg msg, const char *outid)
 {
        struct config_rule *r;
        char *out, *fwd;
@@ -825,8 +667,8 @@ bsd_out_sendmsg(asl_msg_t *msg, const char *outid)
                }
        }
 
-       if (out != NULL) free(out);
-       if (fwd != NULL) free(fwd);
+       free(out);
+       free(fwd);
 
        return 0;
 }
@@ -912,7 +754,7 @@ bsd_out_init(void)
 
        TAILQ_INIT(&bsd_out_rule);
 
-       query = asl_new(ASL_TYPE_QUERY);
+       query = asl_msg_new(ASL_TYPE_QUERY);
        aslevent_addmatch(query, MY_ID);
        aslevent_addoutput(bsd_out_sendmsg, MY_ID);
 
@@ -938,19 +780,21 @@ bsd_out_close(void)
        {
                n = r->entries.tqe_next;
 
-               if (r->dst != NULL) free(r->dst);
-               if (r->fd > 0) close(r->fd);
-               if (r->addr != NULL) free(r->addr);
-               if (r->last_msg != NULL) free(r->last_msg);
+        free(r->dst);
+               free(r->addr);
+               free(r->last_msg);
+               free(r->fac_prefix_len);
+               free(r->pri);
+
+               if (r->fd >= 0) close(r->fd);
+
                if (r->facility != NULL)
                {
                        for (i = 0; i < r->count; i++) 
-                       {
-                               if (r->facility[i] != NULL) free(r->facility[i]);
-                       }
+                free(r->facility[i]);
+
                        free(r->facility);
                }
-               if (r->pri != NULL) free(r->pri);
 
                TAILQ_REMOVE(&bsd_out_rule, r, entries);
                free(r);
@@ -970,6 +814,11 @@ bsd_out_network_reset(void)
                {
                        close(r->fd);
                        r->fd = -1;
+                       if (r->addr != NULL)
+                       {
+                               free(r->addr);
+                               r->addr = NULL;
+                       }
                }
        }
 
index 7ddd7f6076a768375ec864aab981dbd43f8c8dbb..6f935b0a72aa912434a4aba9e1a96cd6a9d09c38 100644 (file)
@@ -2,16 +2,23 @@
 <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
-    <key>Label</key>
-    <string>com.apple.syslogd</string>
-    <key>OnDemand</key>
-    <false/>
+       <key>Label</key>
+       <string>com.apple.syslogd</string>
+       <key>OnDemand</key>
+       <false/>
+       <key>JetsamProperties</key>
+       <dict>
+               <key>JetsamPriority</key>
+               <integer>-49</integer>
+               <key>JetsamMemoryLimit</key>
+               <integer>300</integer>
+       </dict>
        <key>HopefullyExitsLast</key>
        <true/>
        <key>EnableTransactions</key>
        <true/>
        <key>ProgramArguments</key>
-    <array>
+       <array>
 <!--
        Un-comment the following lines to run syslogd with a sandbox profile.
        Sandbox profiles restrict processes from performing unauthorized
                <string>/usr/share/sandbox/syslogd.sb</string>
 -->
                <string>/usr/sbin/syslogd</string>
-    </array>
+       </array>
+       <key>EnvironmentVariables</key>
+       <dict>
+               <key>ASL_DISABLE</key>
+               <string>1</string>
+       </dict>
        <key>MachServices</key>
        <dict>
                <key>com.apple.system.logger</key>
index ca428fcc0e8a387273c5e21610f7349cbf09fd76..2d09885280772856f64e3d1263bb4d6236fafc65 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -46,7 +46,6 @@
 
 #define streq(A,B) (strcmp(A,B)==0)
 #define forever for(;;)
-#define IndexNull ((uint32_t)-1)
 
 #define ASL_MSG_TYPE_MASK 0x0000000f
 #define ASL_TYPE_ERROR 2
@@ -62,7 +61,7 @@
 #define VERIFY_STATUS_INVALID_MESSAGE 1
 #define VERIFY_STATUS_EXCEEDED_QUOTA 2
 
-extern void disaster_message(asl_msg_t *m);
+extern void disaster_message(aslmsg m);
 static char myname[MAXHOSTNAMELEN + 1] = {0};
 
 static OSSpinLock count_lock = 0;
@@ -232,7 +231,7 @@ freeList(char **l)
  */
  
 static uint32_t
-quota_check(pid_t pid, time_t now, asl_msg_t *msg)
+quota_check(pid_t pid, time_t now, aslmsg msg)
 {
        int i, x, maxx, max;
        char *str;
@@ -305,6 +304,7 @@ quota_check(pid_t pid, time_t now, asl_msg_t *msg)
        }
 
        /* can't find the pid and no slots were available - reuse slot with highest remaining quota */
+       asldebug("Quotas: reused slot %d pid %d quota %d for new pid %d\n", maxx, (int)quota_table_pid[maxx], quota_table_quota[maxx], (int)pid);
        quota_table_pid[maxx] = pid;
        quota_table_quota[maxx] = global.mps_limit;
 
@@ -313,7 +313,7 @@ quota_check(pid_t pid, time_t now, asl_msg_t *msg)
 }
 
 int
-asl_check_option(asl_msg_t *msg, const char *opt)
+asl_check_option(aslmsg msg, const char *opt)
 {
        const char *p;
        uint32_t len;
@@ -355,7 +355,7 @@ aslevent_init(void)
 }
 
 int
-aslevent_log(asl_msg_t *msg, char *outid)
+aslevent_log(aslmsg msg, char *outid)
 {
        struct asloutput *i;
        int status = -1;
@@ -365,6 +365,7 @@ aslevent_log(asl_msg_t *msg, char *outid)
                if ((outid != NULL) && (strcmp(i->outid, outid) == 0))
                {
                        status = i->sendmsg(msg, outid);
+                       if (status < 0) break;
                }
        }
 
@@ -390,17 +391,19 @@ aslevent_addmatch(asl_msg_t *query, char *outid)
 }
 
 void
-asl_message_match_and_log(asl_msg_t *msg)
+asl_message_match_and_log(aslmsg msg)
 {
        struct aslmatch *i;
+       int status = -1;
 
        if (msg == NULL) return;
 
        for (i = Matchq.tqh_first; i != NULL; i = i->entries.tqe_next)
        {
-               if (asl_msg_cmp(i->query, msg) != 0)
+               if (asl_msg_cmp(i->query, (asl_msg_t *)msg) != 0)
                {
-                       aslevent_log(msg, i->outid);
+                       status = aslevent_log(msg, i->outid);
+                       if (status < 0) break;
                }
        }
 }
@@ -427,6 +430,53 @@ aslevent_removefd(int fd)
        return -1;
 }
 
+static const char *_source_name(int n)
+{
+       switch (n)
+       {
+               case SOURCE_INTERNAL: return "internal";
+               case SOURCE_ASL_SOCKET: return "ASL socket";
+               case SOURCE_BSD_SOCKET: return "BSD socket";
+               case SOURCE_UDP_SOCKET: return "UDP socket";
+               case SOURCE_KERN: return "kernel";
+               case SOURCE_ASL_MESSAGE: return "ASL message";
+               case SOURCE_LAUNCHD: return "launchd";
+               case SOURCE_SESSION: return "session";
+               default: return "unknown";
+       }
+
+       return "unknown";
+}
+
+void
+aslevent_check()
+{
+       struct aslevent *e, *next;
+       fd_set test;
+       struct timeval zero = {0};
+       int max;
+
+       e = Eventq.tqh_first;
+
+       while (e != NULL)
+       {
+               next = e->entries.tqe_next;
+               if (e->fd >= 0)
+               {
+                       FD_ZERO(&test);
+                       FD_SET(e->fd, &test);
+                       max = e->fd + 1;
+
+                       if (select(max, &test, NULL, NULL, &zero) < 0)
+                       {
+                               asldebug("aslevent_check: fd %d source %d (%s) errno %d\n", e->fd, e->source, _source_name(e->source), e->fd);
+                       }
+               }
+
+               e = next;
+       }
+}
+
 const char *
 whatsmyhostname()
 {
@@ -594,9 +644,9 @@ aslevent_addfd(int source, int fd, uint32_t flags, aslreadfn readfn, aslwritefn
  */
 
 static uint32_t
-aslmsg_verify(uint32_t source, struct aslevent *e, asl_msg_t *msg, int32_t *kern_post_level)
+aslmsg_verify(uint32_t source, struct aslevent *e, aslmsg msg, int32_t *kern_post_level)
 {
-       const char *val, *fac;
+       const char *val, *fac, *ruval, *rgval;
        char buf[64];
        time_t tick, now;
        uid_t uid;
@@ -643,8 +693,11 @@ aslmsg_verify(uint32_t source, struct aslevent *e, asl_msg_t *msg, int32_t *kern
                if (val != NULL) pid = (pid_t)atoi(val);
        }
 
-       /* if quotas are enabled and pid > 1 (not kernel or launchd) check quota */
-       if ((global.mps_limit > 0) && (pid > 1))
+       /*
+        * if quotas are enabled and pid > 1 (not kernel or launchd)
+        * and no processes are watching, then check quota
+        */
+       if ((global.mps_limit > 0) && (pid > 1) && (global.watchers_active == 0))
        {
                status = quota_check(pid, now, msg);
                if (status != VERIFY_STATUS_OK) return status;
@@ -806,17 +859,24 @@ aslmsg_verify(uint32_t source, struct aslevent *e, asl_msg_t *msg, int32_t *kern
 
        /*
         * kernel messages are only readable by root and admin group.
+        * all other messages are admin-only readable unless they already
+        * have specific read access controls set.
         */
        if (source == SOURCE_KERN)
        {
                asl_set(msg, ASL_KEY_READ_UID, "0");
                asl_set(msg, ASL_KEY_READ_GID, "80");
        }
+       else
+       {
+               ruval = asl_get(msg, ASL_KEY_READ_UID);
+               rgval = asl_get(msg, ASL_KEY_READ_GID);
 
-       /*
-        * Access Control: only UID 0 may use facility com.apple.system (or anything with that prefix).
-        * N.B. kernel can use any facility name.
-        */
+               if ((ruval == NULL) && (rgval == NULL))
+               {
+                       asl_set(msg, ASL_KEY_READ_GID, "80");
+               }
+       }
 
        /* Set DB Expire Time for com.apple.system.utmpx and lastlog */
        if ((!strcmp(fac, "com.apple.system.utmpx")) || (!strcmp(fac, "com.apple.system.lastlog")))
@@ -921,7 +981,7 @@ aslevent_cleanup()
 }
 
 void
-list_append_msg(asl_search_result_t *list, asl_msg_t *msg)
+list_append_msg(asl_search_result_t *list, aslmsg msg)
 {
        if (list == NULL) return;
        if (msg == NULL) return;
@@ -951,12 +1011,12 @@ list_append_msg(asl_search_result_t *list, asl_msg_t *msg)
                list->curr += LIST_SIZE_DELTA;
        }
 
-       list->msg[list->count] = msg;
+       list->msg[list->count] = (asl_msg_t *)msg;
        list->count++;
 }
 
 void
-work_enqueue(asl_msg_t *m)
+work_enqueue(aslmsg m)
 {
        pthread_mutex_lock(global.work_queue_lock);
        list_append_msg(global.work_queue, m);
@@ -965,16 +1025,13 @@ work_enqueue(asl_msg_t *m)
 }
 
 void
-asl_enqueue_message(uint32_t source, struct aslevent *e, asl_msg_t *msg)
+asl_enqueue_message(uint32_t source, struct aslevent *e, aslmsg msg)
 {
        int32_t kplevel;
        uint32_t status;
 
        if (msg == NULL) return;
 
-       /* set retain count to 1 */
-       msg->type |= 0x10;
-
        kplevel = -1;
        status = aslmsg_verify(source, e, msg, &kplevel);
        if (status == VERIFY_STATUS_OK)
@@ -984,17 +1041,20 @@ asl_enqueue_message(uint32_t source, struct aslevent *e, asl_msg_t *msg)
        }
        else
        {
-               asl_msg_release(msg);
+               asl_free(msg);
        }
 }
 
-asl_msg_t **
-asl_work_dequeue(uint32_t *count)
+aslmsg *
+work_dequeue(uint32_t *count)
 {
-       asl_msg_t **work;
+       aslmsg *work;
 
        pthread_mutex_lock(global.work_queue_lock);
-       pthread_cond_wait(&global.work_queue_cond, global.work_queue_lock);
+       if (global.work_queue->count == 0)
+       {
+               pthread_cond_wait(&global.work_queue_cond, global.work_queue_lock);
+       }
 
        work = NULL;
        *count = 0;
@@ -1005,7 +1065,7 @@ asl_work_dequeue(uint32_t *count)
                return NULL;
        }
 
-       work = global.work_queue->msg;
+       work = (aslmsg *)(global.work_queue->msg);
        *count = global.work_queue->count;
 
        global.work_queue->count = 0;
@@ -1021,7 +1081,7 @@ aslevent_handleevent(fd_set *rd, fd_set *wr, fd_set *ex)
 {
        struct aslevent *e;
        char *out = NULL;
-       asl_msg_t *msg;
+       aslmsg msg;
        int32_t cleanup;
 
 //     asldebug("--> aslevent_handleevent\n");
@@ -1061,11 +1121,11 @@ aslevent_handleevent(fd_set *rd, fd_set *wr, fd_set *ex)
 int
 asl_log_string(const char *str)
 {
-       asl_msg_t *msg;
+       aslmsg msg;
 
        if (str == NULL) return 1;
 
-       msg = asl_msg_from_string(str);
+       msg = (aslmsg)asl_msg_from_string(str);
        if (msg == NULL) return 1;
 
        asl_enqueue_message(SOURCE_INTERNAL, NULL, msg);
@@ -1121,14 +1181,14 @@ asl_mark(void)
        if (str != NULL) free(str);
 }
 
-asl_msg_t *
-asl_syslog_input_convert(const char *in, int len, char *rhost, int kern)
+aslmsg 
+asl_syslog_input_convert(const char *in, int len, char *rhost, uint32_t source)
 {
        int pf, pri, index, n;
-       char *p, *colon, *brace, *tmp, *tval, *sval, *pval, *mval;
+       char *p, *colon, *brace, *space, *tmp, *tval, *hval, *sval, *pval, *mval;
        char prival[8];
        const char *fval;
-       asl_msg_t *msg;
+       aslmsg msg;
        struct tm time;
        time_t tick;
 
@@ -1137,6 +1197,7 @@ asl_syslog_input_convert(const char *in, int len, char *rhost, int kern)
 
        pri = LOG_DEBUG;
        tval = NULL;
+       hval = NULL;
        sval = NULL;
        pval = NULL;
        mval = NULL;
@@ -1145,6 +1206,7 @@ asl_syslog_input_convert(const char *in, int len, char *rhost, int kern)
        index = 0;
        p = (char *)in;
 
+       /* skip leading whitespace */
        while ((index < len) && ((*p == ' ') || (*p == '\t')))
        {
                p++;
@@ -1153,6 +1215,7 @@ asl_syslog_input_convert(const char *in, int len, char *rhost, int kern)
 
        if (index >= len) return NULL;
 
+       /* parse "<NN>" priority (level and facility) */
        if (*p == '<')
        {
                p++;
@@ -1180,6 +1243,7 @@ asl_syslog_input_convert(const char *in, int len, char *rhost, int kern)
 
        snprintf(prival, sizeof(prival), "%d", pri);
 
+       /* check if a timestamp is included */
        if (((len - index) > 15) && (p[9] == ':') && (p[12] == ':') && (p[15] == ' '))
        {
                tmp = malloc(16);
@@ -1204,26 +1268,42 @@ asl_syslog_input_convert(const char *in, int len, char *rhost, int kern)
                index += 16;
        }
 
-       if (kern != 0)
+       /* stop here for kernel messages */
+       if (source == SOURCE_KERN)
        {
-               msg = (asl_msg_t *)calloc(1, sizeof(asl_msg_t));
+               msg = asl_new(ASL_TYPE_MSG);
                if (msg == NULL) return NULL;
 
-
                asl_set(msg, ASL_KEY_MSG, p);
-
                asl_set(msg, ASL_KEY_LEVEL, prival);
-
                asl_set(msg, ASL_KEY_PID, "0");
-
                asl_set(msg, ASL_KEY_HOST, whatsmyhostname());
 
                return msg;
        }
 
+       /* if message is from a network socket, hostname follows */
+       if (source == SOURCE_UDP_SOCKET)
+       {
+               space = strchr(p, ' ');
+               if (space != NULL)
+               {
+                       n = space - p;
+                       hval = malloc(n + 1);
+                       if (hval == NULL) return NULL;
+
+                       memcpy(hval, p, n);
+                       hval[n] = '\0';
+
+                       p = space + 1;
+                       index += (n + 1);
+               }
+       }
+
        colon = strchr(p, ':');
        brace = strchr(p, '[');
 
+       /* check for "sender:" or sender[pid]:"  */
        if (colon != NULL)
        {
                if ((brace != NULL) && (brace < colon))
@@ -1275,7 +1355,7 @@ asl_syslog_input_convert(const char *in, int len, char *rhost, int kern)
 
        if (fval == NULL) fval = asl_syslog_faciliy_num_to_name(LOG_USER);
 
-       msg = (asl_msg_t *)calloc(1, sizeof(asl_msg_t));
+       msg = asl_new(ASL_TYPE_MSG);
        if (msg == NULL) return NULL;
 
        if (tval != NULL)
@@ -1298,7 +1378,10 @@ asl_syslog_input_convert(const char *in, int len, char *rhost, int kern)
                asl_set(msg, ASL_KEY_PID, pval);
                free(pval);
        }
-       else asl_set(msg, ASL_KEY_PID, "-1");
+       else
+       {
+               asl_set(msg, ASL_KEY_PID, "-1");
+       }
 
        if (mval != NULL)
        {
@@ -1311,21 +1394,18 @@ asl_syslog_input_convert(const char *in, int len, char *rhost, int kern)
        asl_set(msg, ASL_KEY_GID, "-2");
 
        if (rhost == NULL) asl_set(msg, ASL_KEY_HOST, whatsmyhostname());
+       else if (hval != NULL)  asl_set(msg, ASL_KEY_HOST, hval);
        else asl_set(msg, ASL_KEY_HOST, rhost);
 
-       if (msg->count == 0)
-       {
-               asl_msg_release(msg);
-               return NULL;
-       }
+       if (hval != NULL) free(hval);
 
        return msg;
 }
 
-asl_msg_t *
-asl_input_parse(const char *in, int len, char *rhost, int kern)
+aslmsg 
+asl_input_parse(const char *in, int len, char *rhost, uint32_t source)
 {
-       asl_msg_t *m;
+       aslmsg msg;
        int status, x, legacy;
 
        asldebug("asl_input_parse: %s\n", (in == NULL) ? "NULL" : in);
@@ -1333,7 +1413,7 @@ asl_input_parse(const char *in, int len, char *rhost, int kern)
        if (in == NULL) return NULL;
 
        legacy = 1;
-       m = NULL;
+       msg = NULL;
 
        /* calculate length if not provided */
        if (len == 0) len = strlen(in);
@@ -1349,14 +1429,14 @@ asl_input_parse(const char *in, int len, char *rhost, int kern)
                if ((status == 1) && (in[10] == ' ') && (in[11] == '[')) legacy = 0;
        }
 
-       if (legacy == 1) return asl_syslog_input_convert(in, len, rhost, kern);
+       if (legacy == 1) return asl_syslog_input_convert(in, len, rhost, source);
 
-       m = asl_msg_from_string(in + 11);
-       if (m == NULL) return NULL;
+       msg = (aslmsg)asl_msg_from_string(in + 11);
+       if (msg == NULL) return NULL;
 
-       if (rhost != NULL) asl_set(m, ASL_KEY_HOST, rhost);
+       if (rhost != NULL) asl_set(msg, ASL_KEY_HOST, rhost);
 
-       return m;
+       return msg;
 }
 
 char *
@@ -1378,45 +1458,10 @@ get_line_from_file(FILE *f)
        return s;
 }
 
-uint32_t
-asl_msg_type(asl_msg_t *m)
-{
-       if (m == NULL) return ASL_TYPE_ERROR;
-       return (m->type & ASL_MSG_TYPE_MASK);
-}
-
-void
-asl_msg_release(asl_msg_t *m)
-{
-       int32_t newval;
-
-       if (m == NULL) return;
-
-       newval = OSAtomicAdd32(-0x10, (int32_t*)&m->type) >> 4;
-       assert(newval >= 0);
-
-       if (newval > 0) return;
-
-       asl_free(m);
-}
-
-asl_msg_t *
-asl_msg_retain(asl_msg_t *m)
-{
-       int32_t newval;
-
-       if (m == NULL) return NULL;
-
-       newval = OSAtomicAdd32(0x10, (int32_t*)&m->type) >> 4;
-       assert(newval > 0);
-
-       return m;
-}
-
 void
 launchd_callback(struct timeval *when, pid_t from_pid, pid_t about_pid, uid_t sender_uid, gid_t sender_gid, int priority, const char *from_name, const char *about_name, const char *session_name, const char *msg)
 {
-       asl_msg_t *m;
+       aslmsg m;
        char str[256];
        time_t now;
 
index f4fce9eaf3700f33c2b2ef09e1df9f7cfb3c1504..1c41ec8f5faf4d01c49b21d7c5af0f4c0d857996 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <sys/queue.h>
 #include <time.h>
 #include <asl.h>
+#include <asl_msg.h>
 #include <asl_private.h>
 #include <asl_store.h>
-#include <asl_memory.h>
-#include <asl_mini_memory.h>
+#include "asl_memory.h"
+#include "asl_mini_memory.h"
 #include <notify.h>
 #include <launch.h>
 #include <libkern/OSAtomic.h>
 #define ASL_DB_NOTIFICATION "com.apple.system.logger.message"
 #define SELF_DB_NOTIFICATION "self.logger.message"
 
-#define ASL_KEY_READ_UID "ReadUID"
-#define ASL_KEY_READ_GID "ReadGID"
-#define ASL_KEY_EXPIRE_TIME "ASLExpireTime"
-#define ASL_KEY_TIME_NSEC "TimeNanoSec"
-#define ASL_KEY_REF_PID "RefPID"
-#define ASL_KEY_REF_PROC "RefProc"
-#define ASL_KEY_SESSION "Session"
-#define ASL_KEY_OPTION "ASLOption"
-
 #define ASL_OPT_IGNORE "ignore"
 #define ASL_OPT_STORE "store"
 
@@ -96,6 +88,8 @@ struct global_s
        launch_data_t launch_dict;
        uint32_t store_flags;
        time_t start_time;
+       int lockdown_session_fd;
+       int watchers_active;
        int kfd;
        int reset;
        uint64_t bsd_flush_time;
@@ -126,10 +120,10 @@ struct global_s
 
 extern struct global_s global;
 
-typedef asl_msg_t *(*aslreadfn)(int);
+typedef aslmsg (*aslreadfn)(int);
 typedef char *(*aslwritefn)(const char *, int);
 typedef char *(*aslexceptfn)(int);
-typedef int (*aslsendmsgfn)(asl_msg_t *msg, const char *outid);
+typedef int (*aslsendmsgfn)(aslmsg msg, const char *outid);
 
 struct aslevent
 {
@@ -169,6 +163,7 @@ int aslevent_fdsets(fd_set *, fd_set *, fd_set *);
 void aslevent_handleevent(fd_set *, fd_set *, fd_set *);
 void asl_mark(void);
 void asl_archive(void);
+void aslevent_check(void);
 
 void asl_client_count_increment();
 void asl_client_count_decrement();
@@ -178,7 +173,6 @@ char *get_line_from_file(FILE *f);
 int asldebug(const char *, ...);
 int asl_log_string(const char *str);
 
-char *asl_msg_to_string(asl_msg_t *msg, uint32_t *len);
 asl_msg_t *asl_msg_from_string(const char *buf);
 int asl_msg_cmp(asl_msg_t *a, asl_msg_t *b);
 time_t asl_parse_time(const char *str);
@@ -187,25 +181,21 @@ int aslevent_addfd(int source, int fd, uint32_t flags, aslreadfn readfn, aslwrit
 int aslevent_removefd(int fd);
 int aslevent_addmatch(asl_msg_t *query, char *outid);
 
-int asl_check_option(asl_msg_t *msg, const char *opt);
+int asl_check_option(aslmsg msg, const char *opt);
 
 int aslevent_addoutput(aslsendmsgfn, const char *outid);
 
-void asl_enqueue_message(uint32_t source, struct aslevent *e, asl_msg_t *msg);
-asl_msg_t **asl_work_dequeue(uint32_t *count);
-void asl_message_match_and_log(asl_msg_t *msg);
+void asl_enqueue_message(uint32_t source, struct aslevent *e, aslmsg msg);
+aslmsg *work_dequeue(uint32_t *count);
+void asl_message_match_and_log(aslmsg msg);
+void send_to_direct_watchers(asl_msg_t *msg);
 
 int asl_syslog_faciliy_name_to_num(const char *fac);
 const char *asl_syslog_faciliy_num_to_name(int num);
-asl_msg_t *asl_input_parse(const char *in, int len, char *rhost, int flag);
+aslmsg asl_input_parse(const char *in, int len, char *rhost, uint32_t source);
 
 void db_ping_store(void);
 
-/* message refcount utilities */
-uint32_t asl_msg_type(asl_msg_t *m);
-asl_msg_t *asl_msg_retain(asl_msg_t *m);
-void asl_msg_release(asl_msg_t *m);
-
 /* notify SPI */
 uint32_t notify_register_plain(const char *name, int *out_token);
 
index 09f90eef8f10760c0d313e85b071426357cd8b52..c8d37ac76aea2087c93d87d886c1762376542786 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <bsm/libbsm.h>
 #include <errno.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>
 #include <sys/event.h>
 #include <servers/bootstrap.h>
 #include <pthread.h>
 #include <notify.h>
 #include <sys/time.h>
 #include <asl.h>
-#include <asl_ipc.h>
-#include <asl_ipc_server.h>
+#include "asl_ipc.h"
+#include "asl_ipcServer.h"
 #include <asl_core.h>
+#include <asl_store.h>
 #include "daemon.h"
 
 #define forever for(;;)
@@ -69,6 +71,11 @@ extern uint32_t bb_convert(const char *name);
 static task_name_t *client_tasks = NULL;
 static uint32_t client_tasks_count = 0;
 
+static int *direct_watch = NULL;
+/* N.B. ports are in network byte order */
+static uint16_t *direct_watch_port = NULL;
+static uint32_t direct_watch_count = 0;
+
 typedef union
 {
        mach_msg_header_t head;
@@ -105,7 +112,7 @@ db_asl_open()
                if (stat(PATH_ASL_STORE, &sb) == 0)
                {
                        /* must be a directory */
-                       if ((sb.st_mode & S_IFDIR) == 0)
+                       if (!S_ISDIR(sb.st_mode))
                        {
                                asldebug("error: %s is not a directory", PATH_ASL_STORE);
                                return;
@@ -178,7 +185,7 @@ db_asl_open()
 void
 output_worker()
 {
-       asl_msg_t **work;
+       aslmsg *work;
        uint32_t i, count;
        mach_msg_empty_send_t *empty;
        kern_return_t kstatus;
@@ -191,7 +198,7 @@ output_worker()
                count = 0;
 
                /* blocks until work is available */
-               work = asl_work_dequeue(&count);
+               work = work_dequeue(&count);
 
                if (work == NULL)
                {
@@ -207,7 +214,7 @@ output_worker()
                for (i = 0; i < count; i++)
                {
                        asl_message_match_and_log(work[i]);
-                       asl_msg_release(work[i]);
+                       asl_free(work[i]);
                }
 
                free(work);
@@ -224,7 +231,113 @@ output_worker()
                empty->header.msgh_size = sizeof(mach_msg_empty_send_t);
                empty->header.msgh_id = SEND_NOTIFICATION;
 
-               kstatus = mach_msg(&(empty->header), MACH_SEND_MSG | MACH_SEND_TIMEOUT, empty->header.msgh_size, 0, MACH_PORT_NULL, 2, MACH_PORT_NULL);
+               kstatus = mach_msg(&(empty->header), MACH_SEND_MSG | MACH_SEND_TIMEOUT, empty->header.msgh_size, 0, MACH_PORT_NULL, 100, MACH_PORT_NULL);
+       }
+}
+
+void
+send_to_direct_watchers(asl_msg_t *msg)
+{
+       uint32_t i, j, nlen, outlen, cleanup, total_sent;
+       ssize_t sent;
+       char *out;
+
+#ifdef LOCKDOWN
+       if (global.lockdown_session_fd >= 0)
+       {
+               /* PurpleConsole eats newlines */
+               out = asl_format_message(msg, ASL_MSG_FMT_STD, ASL_TIME_FMT_LCL, ASL_ENCODE_SAFE, &outlen);
+               if ((write(global.lockdown_session_fd, "\n", 1) < 0) || 
+                       (write(global.lockdown_session_fd, out, outlen) < 0) ||
+                       (write(global.lockdown_session_fd, "\n", 1) < 0))
+               {
+                       close(global.lockdown_session_fd);
+                       global.lockdown_session_fd = -1;
+                       global.watchers_active = direct_watch_count + ((global.lockdown_session_fd < 0) ? 0 : 1);
+               }
+
+               free(out);
+       }
+#endif
+
+       if (direct_watch_count == 0) return;
+
+       cleanup = 0;
+       out = asl_msg_to_string(msg, &outlen);
+
+       if (out == NULL) return;
+
+       nlen = htonl(outlen);
+       for (i = 0; i < direct_watch_count; i++)
+       {
+               sent = send(direct_watch[i], &nlen, sizeof(nlen), 0);
+               if (sent < sizeof(nlen))
+               {
+                       /* bail out if we can't send 4 bytes */
+                       close(direct_watch[i]);
+                       direct_watch[i] = -1;
+                       cleanup = 1;
+               }
+               else
+               {
+                       total_sent = 0;
+                       while (total_sent < outlen)
+                       {
+                               sent = send(direct_watch[i], out + total_sent, outlen - total_sent, 0);
+                               if (sent < 0)
+                               {
+                                       close(direct_watch[i]);
+                                       direct_watch[i] = -1;
+                                       cleanup = 1;
+                                       break;
+                               }
+
+                               total_sent += sent;
+                       }
+               }
+       }
+
+       free(out);
+
+       if (cleanup == 0) return;
+
+       j = 0;
+       for (i = 0; i < direct_watch_count; i++)
+       {
+               if (direct_watch[i] >= 0)
+               {
+                       if (j != i)
+                       {
+                               direct_watch[j] = direct_watch[i];
+                               direct_watch_port[j] = direct_watch_port[i];
+                               j++;
+                       }
+               }
+       }
+
+       direct_watch_count = j;
+       if (direct_watch_count == 0)
+       {
+               free(direct_watch);
+               direct_watch = NULL;
+
+               free(direct_watch_port);
+               direct_watch_port = NULL;
+       }
+       else
+       {
+               direct_watch = reallocf(direct_watch, direct_watch_count * sizeof(int));
+               direct_watch_port = reallocf(direct_watch_port, direct_watch_count * sizeof(uint16_t));
+               if ((direct_watch == NULL) || (direct_watch_port == NULL))
+               {
+                       free(direct_watch);
+                       direct_watch = NULL;
+
+                       free(direct_watch_port);
+                       direct_watch_port = NULL;
+
+                       direct_watch_count = 0;
+               }
        }
 }
 
@@ -232,11 +345,13 @@ output_worker()
  * Called from asl_action.c to save messgaes to the ASL data store
  */
 void
-db_save_message(asl_msg_t *msg)
+db_save_message(aslmsg msg)
 {
        uint64_t msgid;
        uint32_t status;
 
+       send_to_direct_watchers((asl_msg_t *)msg);
+
        pthread_mutex_lock(&db_lock);
 
        db_asl_open();
@@ -316,19 +431,15 @@ db_save_message(asl_msg_t *msg)
                }
        }
 
-
        pthread_mutex_unlock(&db_lock);
-
 }
 
 void
-disaster_message(asl_msg_t *msg)
+disaster_message(aslmsg msg)
 {
        uint64_t msgid;
        uint32_t status;
 
-       global.disaster_occurred = 1;
-
        msgid = 0;
 
        if ((global.dbtype & DB_TYPE_MINI) == 0)
@@ -395,14 +506,28 @@ register_session(task_name_t task_name, pid_t pid)
        uint32_t i;
 
        if (task_name == MACH_PORT_NULL) return;
-       if (global.dead_session_port == MACH_PORT_NULL) return;
 
-       for (i = 0; i < client_tasks_count; i++) if (task_name == client_tasks[i]) return;
+       if (global.dead_session_port == MACH_PORT_NULL)
+       {
+               mach_port_deallocate(mach_task_self(), task_name);
+               return;
+       }
+
+       for (i = 0; i < client_tasks_count; i++) if (task_name == client_tasks[i])
+       {
+               mach_port_deallocate(mach_task_self(), task_name);
+               return;
+       }
 
        if (client_tasks_count == 0) client_tasks = (task_name_t *)calloc(1, sizeof(task_name_t));
        else client_tasks = (task_name_t *)reallocf(client_tasks, (client_tasks_count + 1) * sizeof(task_name_t));
 
-       if (client_tasks == NULL) return;
+       if (client_tasks == NULL)
+       {
+               mach_port_deallocate(mach_task_self(), task_name);
+               return;
+       }
+
        client_tasks[client_tasks_count] = task_name;
        client_tasks_count++;
 
@@ -438,10 +563,128 @@ cancel_session(task_name_t task_name)
        }
 
        asldebug("cancel_session: %u\n", (unsigned int)task_name);
-       mach_port_destroy(mach_task_self(), task_name);
+
+       /* we hold a send right or dead name right for the task name port */
+       mach_port_deallocate(mach_task_self(), task_name);
        asl_client_count_decrement();
 }
 
+static uint32_t
+register_direct_watch(uint16_t port)
+{
+       uint32_t i;
+       int sock, flags;
+       struct sockaddr_in address;
+
+       if (port == 0) return ASL_STATUS_FAILED;
+
+       sock = socket(AF_INET, SOCK_STREAM, 0);
+       if (sock < 0) return ASL_STATUS_FAILED;
+
+       address.sin_family = AF_INET;
+       /* port must be sent in network byte order */
+       address.sin_port = port;
+       address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+       if (connect(sock, (struct sockaddr*)&address, sizeof(address)) != 0) return ASL_STATUS_FAILED;
+
+       i = 1;
+       setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof(i));
+
+       i = 1;
+       setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i));
+
+       /* make socket non-blocking */
+       flags = fcntl(sock, F_GETFL, 0);
+       if (flags == -1) flags = 0;
+       fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+
+       if (direct_watch_count == 0)
+       {
+               direct_watch = (int *)calloc(1, sizeof(int));
+               direct_watch_port = (uint16_t *)calloc(1, sizeof(uint16_t));
+       }
+       else
+       {
+               direct_watch = (int *)reallocf(direct_watch, (direct_watch_count + 1) * sizeof(int));
+               direct_watch_port = (uint16_t *)reallocf(direct_watch_port, (direct_watch_count + 1) * sizeof(uint16_t));
+       }
+
+       if ((direct_watch == NULL) || (direct_watch_port == NULL))
+       {
+               close(sock);
+
+               free(direct_watch);
+               direct_watch = NULL;
+
+               free(direct_watch_port);
+               direct_watch_port = NULL;
+
+               direct_watch_count = 0;
+               global.watchers_active = 0;
+               if (global.lockdown_session_fd >= 0) global.watchers_active = 1;
+
+               return ASL_STATUS_FAILED;
+       }
+
+       direct_watch[direct_watch_count] = sock;
+       direct_watch_port[direct_watch_count] = port;
+       direct_watch_count++;
+       global.watchers_active = direct_watch_count + ((global.lockdown_session_fd < 0) ? 0 : 1);
+
+       return ASL_STATUS_OK;
+}
+
+static void
+cancel_direct_watch(uint16_t port)
+{
+       uint32_t i;
+
+       for (i = 0; (i < direct_watch_count) && (port != direct_watch_port[i]); i++);
+
+       if (i >= direct_watch_count) return;
+
+       if (direct_watch_count == 1)
+       {
+               free(direct_watch);
+               direct_watch = NULL;
+
+               free(direct_watch_port);
+               direct_watch_port = NULL;
+
+               direct_watch_count = 0;
+               global.watchers_active = 0;
+               if (global.lockdown_session_fd >= 0) global.watchers_active = 1;
+       }
+       else
+       {
+               for (i++; i < direct_watch_count; i++)
+               {
+                       direct_watch[i-1] = direct_watch[i];
+                       direct_watch_port[i-1] = direct_watch_port[i];
+               }
+
+               direct_watch_count--;
+               global.watchers_active = direct_watch_count + ((global.lockdown_session_fd < 0) ? 0 : 1);
+
+               direct_watch = (int *)reallocf(direct_watch, direct_watch_count * sizeof(int));
+               direct_watch_port = (uint16_t *)reallocf(direct_watch_port, direct_watch_count * sizeof(uint16_t));
+
+               if ((direct_watch == NULL) || (direct_watch_port == NULL))
+               {
+                       free(direct_watch);
+                       direct_watch = NULL;
+
+                       free(direct_watch_port);
+                       direct_watch_port = NULL;
+
+                       direct_watch_count = 0;
+                       global.watchers_active = 0;
+                       if (global.lockdown_session_fd >= 0) global.watchers_active = 1;
+               }
+       }
+}
+
 /*
  * Receives messages on the "com.apple.system.logger" mach port.
  * Services database search requests.
@@ -522,6 +765,9 @@ database_server()
                {
                        deadname = (mach_dead_name_notification_t *)request;
                        cancel_session(deadname->not_port);
+
+                       /* dead name notification includes a dead name right - release it here */
+                       mach_port_deallocate(mach_task_self(), deadname->not_port);
                        free(request);
                        continue;
                }
@@ -530,7 +776,8 @@ database_server()
                kstatus = mach_msg(&(reply->head), sbits, reply->head.msgh_size, 0, MACH_PORT_NULL, 10, MACH_PORT_NULL);
                if (kstatus == MACH_SEND_INVALID_DEST)
                {
-                       mach_port_destroy(mach_task_self(), request->head.msgh_remote_port);
+                       /* release send right for the port */
+                       mach_port_deallocate(mach_task_self(), request->head.msgh_remote_port);
                }
 
                free(request);
@@ -560,8 +807,16 @@ __asl_server_query
        kern_return_t kstatus;
 
        *status = ASL_STATUS_OK;
+
+       if ((request != NULL) && (request[requestCnt - 1] != '\0'))
+       {
+               *status = ASL_STATUS_INVALID_ARG;
+               vm_deallocate(mach_task_self(), (vm_address_t)request, requestCnt);
+               return KERN_SUCCESS;
+       }
+
        query = asl_list_from_string(request);
-       vm_deallocate(mach_task_self(), (vm_address_t)request, requestCnt);
+       if (request != NULL) vm_deallocate(mach_task_self(), (vm_address_t)request, requestCnt);
        res = NULL;
 
        *status = db_query(query, &res, startid, count, flags, lastid, token->val[0], token->val[1]);
@@ -642,7 +897,7 @@ __asl_server_message
        audit_token_t token
 )
 {
-       asl_msg_t *m;
+       aslmsg msg;
        char tmp[64];
        uid_t uid;
        gid_t gid;
@@ -650,11 +905,24 @@ __asl_server_message
        kern_return_t kstatus;
        mach_port_name_t client;
 
+       if (message == NULL)
+       {
+               return KERN_SUCCESS;
+       }
+
+       if (message[messageCnt - 1] != '\0')
+       {
+               vm_deallocate(mach_task_self(), (vm_address_t)message, messageCnt);
+               return KERN_SUCCESS;
+       }
+
        asldebug("__asl_server_message: %s\n", (message == NULL) ? "NULL" : message);
 
-       m = asl_msg_from_string(message);
+       msg = (aslmsg)asl_msg_from_string(message);
        vm_deallocate(mach_task_self(), (vm_address_t)message, messageCnt);
 
+       if (msg == NULL) return KERN_SUCCESS;
+
        uid = (uid_t)-1;
        gid = (gid_t)-1;
        pid = (gid_t)-1;
@@ -664,19 +932,160 @@ __asl_server_message
        kstatus = task_name_for_pid(mach_task_self(), pid, &client);
        if (kstatus == KERN_SUCCESS) register_session(client, pid);
 
-       if (m == NULL) return KERN_SUCCESS;
-
        snprintf(tmp, sizeof(tmp), "%d", uid);
-       asl_set(m, ASL_KEY_UID, tmp);
+       asl_set(msg, ASL_KEY_UID, tmp);
 
        snprintf(tmp, sizeof(tmp), "%d", gid);
-       asl_set(m, ASL_KEY_GID, tmp);
+       asl_set(msg, ASL_KEY_GID, tmp);
 
        snprintf(tmp, sizeof(tmp), "%d", pid);
-       asl_set(m, ASL_KEY_PID, tmp);
+       asl_set(msg, ASL_KEY_PID, tmp);
 
        /* verify and enqueue for processing */
-       asl_enqueue_message(SOURCE_ASL_MESSAGE, NULL, m);
+       asl_enqueue_message(SOURCE_ASL_MESSAGE, NULL, msg);
+
+       return KERN_SUCCESS;
+}
+
+kern_return_t
+__asl_server_create_aux_link
+(
+       mach_port_t server,
+       caddr_t message,
+       mach_msg_type_number_t messageCnt,
+       mach_port_t *fileport,
+       caddr_t *newurl,
+       mach_msg_type_number_t *newurlCnt,
+       int *status,
+       audit_token_t token
+)
+{
+       aslmsg msg;
+       char tmp[64];
+       uid_t uid;
+       gid_t gid;
+       pid_t pid;
+       kern_return_t kstatus;
+       mach_port_name_t client;
+       char *url, *vmbuffer;
+       int fd;
+
+       *status = ASL_STATUS_OK;
+
+       if (message == NULL)
+       {
+               *status = ASL_STATUS_INVALID_ARG;
+               return KERN_SUCCESS;
+       }
+
+       if (message[messageCnt - 1] != '\0')
+       {
+               *status = ASL_STATUS_INVALID_ARG;
+               vm_deallocate(mach_task_self(), (vm_address_t)message, messageCnt);
+               return KERN_SUCCESS;
+       }
+
+       asldebug("__asl_server_create_aux_link: %s\n", (message == NULL) ? "NULL" : message);
+
+       if ((global.dbtype & DB_TYPE_FILE) == 0)
+       {
+               *status = ASL_STATUS_INVALID_STORE;
+               return KERN_SUCCESS;
+       }
+
+       *fileport = MACH_PORT_NULL;
+
+       msg = (aslmsg)asl_msg_from_string(message);
+       vm_deallocate(mach_task_self(), (vm_address_t)message, messageCnt);
+
+       if (msg == NULL) return KERN_SUCCESS;
+
+       uid = (uid_t)-1;
+       gid = (gid_t)-1;
+       pid = (gid_t)-1;
+       audit_token_to_au32(token, NULL, &uid, &gid, NULL, NULL, &pid, NULL, NULL);
+
+       client = MACH_PORT_NULL;
+       kstatus = task_name_for_pid(mach_task_self(), pid, &client);
+       if (kstatus == KERN_SUCCESS) register_session(client, pid);
+
+       snprintf(tmp, sizeof(tmp), "%d", uid);
+       asl_set(msg, ASL_KEY_UID, tmp);
+
+       snprintf(tmp, sizeof(tmp), "%d", gid);
+       asl_set(msg, ASL_KEY_GID, tmp);
+
+       snprintf(tmp, sizeof(tmp), "%d", pid);
+       asl_set(msg, ASL_KEY_PID, tmp);
+
+       /* create a file for the client */
+       *status = asl_store_open_aux(global.file_db, msg, &fd, &url);
+       asl_free(msg);
+       if (*status != ASL_STATUS_OK) return KERN_SUCCESS;
+       if (url == NULL)
+       {
+               if (fd >= 0) close(fd);
+               *status = ASL_STATUS_FAILED;
+               return KERN_SUCCESS;
+       }
+
+       if (fileport_makeport(fd, (fileport_t *)fileport) < 0)
+       {
+               close(fd);
+               free(url);
+               *status = ASL_STATUS_FAILED;
+               return KERN_SUCCESS;
+       }
+
+       close(fd);
+
+       *newurlCnt = strlen(url) + 1;
+
+       kstatus = vm_allocate(mach_task_self(), (vm_address_t *)&vmbuffer, *newurlCnt, TRUE);
+       if (kstatus != KERN_SUCCESS)
+       {
+               free(url);
+               return kstatus;
+       }
+
+       memmove(vmbuffer, url, *newurlCnt);
+       free(url);
+       
+       *newurl = vmbuffer;     
+       
+       return KERN_SUCCESS;
+}
+
+kern_return_t
+__asl_server_register_direct_watch
+(
+       mach_port_t server,
+       int port,
+       audit_token_t token
+)
+{
+       uint16_t p16 = port;
+
+       asldebug("__asl_server_register_direct_watch: %hu\n", ntohs(p16));
+
+       register_direct_watch(p16);
+
+       return KERN_SUCCESS;
+}
+
+kern_return_t
+__asl_server_cancel_direct_watch
+(
+       mach_port_t server,
+       int port,
+       audit_token_t token
+)
+{
+       uint16_t p16 = port;
+
+       asldebug("__asl_server_cancel_direct_watch: %hu\n", ntohs(p16));
+
+       cancel_direct_watch(p16);
 
        return KERN_SUCCESS;
 }
index cb734f6651ef2bb59d5f1550cc075d7ad40339cb..664293625d09ddb5003f8abc48977263d1de983e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -42,7 +42,7 @@
 static int kx = 0;
 static char kline[MAXLINE + 1];
 
-asl_msg_t *
+aslmsg
 klog_in_acceptmsg(int fd)
 {
        int n;
@@ -62,7 +62,7 @@ klog_in_acceptmsg(int fd)
        kline[kx] = '\0';
        kx = 0;
 
-       return asl_input_parse(kline, n, NULL, 1);
+       return asl_input_parse(kline, n, NULL, SOURCE_KERN);
 }
 
 int
@@ -89,19 +89,20 @@ klog_in_init(void)
        return aslevent_addfd(SOURCE_KERN, global.kfd, ADDFD_FLAGS_LOCAL, klog_in_acceptmsg, NULL, NULL);
 }
 
-int
-klog_in_reset(void)
-{
-       return 0;
-}
-
 int
 klog_in_close(void)
 {
        if (global.kfd < 0) return 1;
 
+       aslevent_removefd(global.kfd);
        close(global.kfd);
        global.kfd = -1;
 
        return 0;
 }
+
+int
+klog_in_reset(void)
+{
+       return 0;
+}
index 4273abbf18964c7d700de75b08b3df83808f666b..ad563a55ac65213018e657affa3de2426cc56ed0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -39,7 +39,7 @@
 #include <pthread.h>
 #include <notify.h>
 #include <asl_core.h>
-#include <asl_memory.h>
+#include "asl_memory.h"
 #include "daemon.h"
 
 #define forever for(;;)
 #define PRINT_STD 0
 #define PRINT_RAW 1
 
+#define WATCH_OFF 0
+#define WATCH_LOCKDOWN_START 1
+#define WATCH_RUN 2
+
+#define SESSION_FLAGS_LOCKDOWN 0x00000001
+
 #define MAXSOCK 1
 
 static int rfd4 = -1;
@@ -72,6 +78,12 @@ extern uint32_t db_query(aslresponse query, aslresponse *res, uint64_t startid,
 
 #define SESSION_WRITE(f,x) if (write(f, x, strlen(x)) < 0) goto exit_session
 
+typedef struct
+{
+       int sock;
+       uint32_t flags;
+} session_args_t;
+
 uint32_t
 remote_db_size(uint32_t sel)
 {
@@ -90,10 +102,10 @@ remote_db_set_size(uint32_t sel, uint32_t size)
        return 0;
 }
 
-asl_msg_t *
+aslmsg 
 remote_db_stats(uint32_t sel)
 {
-       asl_msg_t *m;
+       aslmsg m;
        m = NULL;
 
        if (sel == DB_TYPE_FILE) asl_store_statistics(global.file_db, &m);
@@ -105,11 +117,11 @@ remote_db_stats(uint32_t sel)
 void
 session(void *x)
 {
-       int i, *sp, s, wfd, status, pfmt, watch, wtoken, nfd, do_prompt, filter;
+       int i, s, wfd, status, pfmt, watch, wtoken, nfd, do_prompt, filter;
        aslresponse res;
        asl_search_result_t ql;
        uint32_t outlen;
-       asl_msg_t *stats;
+       aslmsg stats;
        asl_msg_t *query;
        asl_msg_t *qlq[1];
        char str[1024], *p, *qs, *out;
@@ -117,15 +129,17 @@ session(void *x)
        fd_set readfds;
        uint64_t low_id, high_id;
        notify_state_t nstate;
-       uint32_t dbselect;
+       uint32_t dbselect, flags;
+       session_args_t *sp;
 
        if (x == NULL) pthread_exit(NULL);
 
-       sp = (int *)x;
-       s = *sp;
+       sp = (session_args_t *)x;
+       s = sp->sock;
+       flags = sp->flags;
        free(x);
 
-       watch = 0;
+       watch = WATCH_OFF;
        wfd = -1;
        wtoken = -1;
 
@@ -256,7 +270,7 @@ session(void *x)
                        else if (!strcmp(str, "stats"))
                        {
                                stats = remote_db_stats(dbselect);
-                               out = asl_format_message(stats, ASL_MSG_FMT_RAW, ASL_TIME_FMT_SEC, ASL_ENCODE_NONE, &outlen);
+                               out = asl_format_message((asl_msg_t *)stats, ASL_MSG_FMT_RAW, ASL_TIME_FMT_SEC, ASL_ENCODE_NONE, &outlen);
                                write(s, out, outlen);
                                free(out);
                                asl_free(stats);
@@ -483,9 +497,9 @@ session(void *x)
                        }
                        else if (!strcmp(str, "stop"))
                        {
-                               if (watch == 1)
+                               if (watch != WATCH_OFF)
                                {
-                                       watch = 0;
+                                       watch = WATCH_OFF;
                                        notify_cancel(wtoken);
                                        wfd = -1;
                                        wtoken = -1;
@@ -517,22 +531,29 @@ session(void *x)
                        }
                        else if (!strcmp(str, "watch"))
                        {
-                               if (watch == 1)
+                               if (watch != WATCH_OFF)
                                {
                                        snprintf(str, sizeof(str) - 1, "already watching!\n");
                                        SESSION_WRITE(s, str);
                                        continue;
                                }
 
-                               status = notify_register_file_descriptor(ASL_DB_NOTIFICATION, &wfd, 0, &wtoken);
-                               if (status != 0)
+                               if (flags & SESSION_FLAGS_LOCKDOWN)
                                {
-                                       snprintf(str, sizeof(str) - 1, "notify_register_file_descriptor failed: %d\n", status);
-                                       SESSION_WRITE(s, str);
-                                       continue;
+                                       watch = WATCH_LOCKDOWN_START;
                                }
+                               else
+                               {
+                                       status = notify_register_file_descriptor(ASL_DB_NOTIFICATION, &wfd, 0, &wtoken);
+                                       if (status != 0)
+                                       {
+                                               snprintf(str, sizeof(str) - 1, "notify_register_file_descriptor failed: %d\n", status);
+                                               SESSION_WRITE(s, str);
+                                               continue;
+                                       }
 
-                               watch = 1;
+                                       watch = WATCH_RUN;
+                               }
 
                                snprintf(str, sizeof(str) - 1, "OK\n");
                                SESSION_WRITE(s, str);
@@ -584,6 +605,25 @@ session(void *x)
                        }
                }
 
+               /*
+                * If this session is PurpleConsole watching for log messages,
+                * we pass through this part of the loop once initially to pick up
+                * existing messages already in memory.  After that, dbserver will
+                * send new messages in send_to_direct_watchers().  We wait until
+                * the initial messages are sent to PurpleConsole before setting 
+                * global.lockdown_session_fd to allow this query to complete before
+                * dbserver starts sending.  To prevent a race between this query and
+                * when the first message is sent by send_to_direct_watchers, we hold
+                * the work queue lock between the time of the query and the time that
+                * lockdown_session_fd is set.
+                */
+               if ((flags & SESSION_FLAGS_LOCKDOWN) && (watch == WATCH_RUN)) continue;
+
+               if (watch == WATCH_LOCKDOWN_START)
+               {
+                       pthread_mutex_lock(global.work_queue_lock);
+               }
+
                if (query != NULL)
                {
                        ql.count = 1;
@@ -591,17 +631,17 @@ session(void *x)
                        ql.msg = qlq;
                }
 
-               if (watch == 0) low_id = 0;
+               if (watch == WATCH_OFF) low_id = 0;
 
                memset(&res, 0, sizeof(aslresponse));
                high_id = 0;
                status = db_query(&ql, (aslresponse *)&res, low_id, 0, 0, &high_id, 0, 0);
 
-               if ((watch == 1) && (high_id >= low_id)) low_id = high_id + 1;
+               if ((watch == WATCH_RUN) && (high_id >= low_id)) low_id = high_id + 1;
 
                if (res == NULL)
                {
-                       if (watch == 0)
+                       if (watch == WATCH_OFF)
                        {
                                snprintf(str, sizeof(str) - 1, "-nil-\n");
                                SESSION_WRITE(s, str);
@@ -613,7 +653,7 @@ session(void *x)
                }
                else if (pfmt == PRINT_RAW)
                {
-                       if (watch == 1)
+                       if (watch == WATCH_RUN)
                        {
                                snprintf(str, sizeof(str) - 1, "\n");
                                SESSION_WRITE(s, str);
@@ -629,7 +669,7 @@ session(void *x)
                }
                else
                {
-                       if (watch == 1)
+                       if (watch == WATCH_RUN)
                        {
                                snprintf(str, sizeof(str) - 1, "\n");
                                SESSION_WRITE(s, str);
@@ -644,29 +684,41 @@ session(void *x)
                }
 
                aslresponse_free(res);
+
+               if (watch == WATCH_LOCKDOWN_START)
+               {
+                       global.lockdown_session_fd = s;
+                       global.watchers_active++;
+                       watch = WATCH_RUN;
+
+                       pthread_mutex_unlock(global.work_queue_lock);
+               }
        }
 
 exit_session:
 
        if (s >= 0)
        {
+               if (s == global.lockdown_session_fd) global.lockdown_session_fd = -1;
+               if (global.watchers_active > 0) global.watchers_active--;
                close(s);
                s = -1;
        }
 
-       if (watch == 1) notify_cancel(wtoken);
-       if (query != NULL) asl_free(query);
+       if (watch != WATCH_OFF) notify_cancel(wtoken);
+       if (query != NULL) asl_msg_release(query);
        pthread_exit(NULL);
 }
 
-asl_msg_t *
+aslmsg 
 remote_acceptmsg(int fd, int tcp)
 {
        socklen_t fromlen;
-       int s, status, flags, *sp;
+       int s, status, flags, v;
        pthread_attr_t attr;
        pthread_t t;
        struct sockaddr_storage from;
+       session_args_t *sp;
 
        fromlen = sizeof(struct sockaddr_un);
        if (tcp == 1) fromlen = sizeof(struct sockaddr_storage);
@@ -690,13 +742,16 @@ remote_acceptmsg(int fd, int tcp)
                return NULL;
        }
 
+       v = 1;
+       setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &v, sizeof(v));
+
        if (tcp == 1)
        {
                flags = 1;
                setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(int));
        }
 
-       sp = malloc(sizeof(int));
+       sp = (session_args_t *)calloc(1, sizeof(session_args_t));
        if (sp == NULL)
        {
                asldebug("%s: malloc: %s\n", MY_ID, strerror(errno));
@@ -704,7 +759,11 @@ remote_acceptmsg(int fd, int tcp)
                return NULL;
        }
 
-       *sp = s;
+       sp->sock = s;
+       if ((tcp == 0) && (global.lockdown_session_fd < 0))
+       {
+               sp->flags |= SESSION_FLAGS_LOCKDOWN;
+       }
 
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
@@ -714,13 +773,13 @@ remote_acceptmsg(int fd, int tcp)
        return NULL;
 }
 
-asl_msg_t *
+aslmsg 
 remote_acceptmsg_local(int fd)
 {
        return remote_acceptmsg(fd, 0);
 }
 
-asl_msg_t *
+aslmsg 
 remote_acceptmsg_tcp(int fd)
 {
        return remote_acceptmsg(fd, 1);
@@ -880,13 +939,28 @@ remote_init(void)
 int
 remote_close(void)
 {
-       if (rfdl >= 0) close(rfdl);
+       if (rfdl >= 0)
+       {
+               aslevent_removefd(rfdl);
+               close(rfdl);
+       }
+
        rfdl = -1;
 
-       if (rfd4 >= 0) close(rfd4);
+       if (rfd4 >= 0) 
+       {
+               aslevent_removefd(rfd4);
+               close(rfd4);
+       }
+
        rfd4 = -1;
 
-       if (rfd6 >= 0) close(rfd6);
+       if (rfd6 >= 0)
+       {
+               aslevent_removefd(rfd6);
+               close(rfd6);
+       }
+
        rfd6 = -1;
 
        return 0;
index f11d3cd448fc010b1f6b0e058e06407e90152582..303d91770b51e44c9861e6b404f3ade0485801f4 100644 (file)
@@ -88,7 +88,7 @@ and
 .Xr syslog 3
 library routines.
 .Pp
-Apple System Log messages, sent using the
+Apple System Log (ASL) messages, sent using the
 .Xr asl 3
 library routines permit the facility name to be an arbitrary string,
 although users of the system are encouraged to use a 
@@ -98,6 +98,17 @@ naming convention, for example
 Since these facility names may contain dot characters, the names may be enclosed in
 either singe quote or double quote characters.
 .Pp
+If 
+.Em facility
+is terminated by an asterisk (``*''),
+then facility names are matched using the prefix characters preceeding the asterisk.
+For example,
+.Pp
+.Dq 'com.apple.abc.*'
+.Pp
+matches any facility with the prefix ``com.apple.abc.''.
+These wildcard facility names typically must be enclosed in single or double quotes characters.
+.Pp
 The
 .Em level
 describes the severity of the message, and is a keyword from the
index c2df7b856664380e669eb9c9c8a22680e15eb3aa..c0b614928bd79cf32c25e48c92b36156952bbc7a 100644 (file)
@@ -243,7 +243,7 @@ module receives log messages on the UDP socket associated with the Internet sysl
 .Pp
 This module is normally enabled, but is inactive.
 The actual UDP sockets are managed by
-.Nm launched ,
+.Nm launchd ,
 and configured in the
 .Nm syslogd
 configuration file /System/Library/LaunchDaemons/com.apple.syslogd.plist.
@@ -255,6 +255,17 @@ UDP service, so no sockets are provided to the
 .Dq udp_in 
 module.
 If no sockets are provided, the module remains inactive.
+A socket may be specified by adding the following entry to the
+.Dq Sockets
+dictionary in the com.apple.syslogd.plist file.
+.Pp
+.Dl            <key>NetworkListener</key>
+.Dl            <dict>
+.Dl                    <key>SockServiceName</key>
+.Dl                    <string>syslog</string>
+.Dl                    <key>SockType</key>
+.Dl                    <string>dgram</string>
+.Dl            </dict>
 .Pp
 The module may be specifically disabled using the
 .Fl udp_in Li 0 
@@ -310,6 +321,9 @@ kernel log device
 data store directory
 .It Pa /var/log/asl.archive
 default archive directory
+.It Pa /System/Library/LaunchDaemons/com.apple.syslogd.plist
+launchd configuration file for
+.Nm syslogd
 .El
 .Sh SEE ALSO
 .Xr syslog 1 ,
index 6d1baf897bca3d125679ba302206de0aa4679bf1..43844f68507e83e0b563b9d45c44c5ee3f5c0da9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <servers/bootstrap.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/stat.h>
 #include <sys/fcntl.h>
+#include <sys/errno.h>
 #include <sys/queue.h>
 #include <sys/time.h>
+#include <sys/un.h>
 #include <pthread.h>
 #include <dirent.h>
 #include <dlfcn.h>
 #include <libgen.h>
 #include <notify.h>
+#include <utmpx.h>
 #include "daemon.h"
 
 #define SERVICE_NAME "com.apple.system.logger"
@@ -338,10 +343,21 @@ load_modules(const char *mp)
 }
 
 static void
-writepid(void)
+writepid(int *first)
 {
+       struct stat sb;
        FILE *fp;
 
+       if (first != NULL)
+       {
+               *first = 1;
+               memset(&sb, 0, sizeof(struct stat));
+               if (stat(_PATH_PIDFILE, &sb) == 0)
+               {
+                       if (S_ISREG(sb.st_mode)) *first = 0;
+               }
+       }
+
        fp = fopen(_PATH_PIDFILE, "w");
        if (fp != NULL)
        {
@@ -596,7 +612,8 @@ config_debug(int enable, const char *path)
 
        global.debug = enable;
        if (global.debug_file != NULL) free(global.debug_file);
-       global.debug_file = strdup(path);
+       global.debug_file = NULL;
+       if (path != NULL) global.debug_file = strdup(path);
 
        OSSpinLockUnlock(&global.lock);
 }
@@ -632,6 +649,71 @@ config_data_store(int type, uint32_t file_max, uint32_t memory_max, uint32_t min
        pthread_mutex_unlock(global.db_lock);
 }
 
+void
+write_boot_log(int first)
+{
+    int mib[2] = {CTL_KERN, KERN_BOOTTIME};
+       size_t len;
+       aslmsg msg;
+       char buf[256];
+    struct utmpx utx;
+
+       if (first == 0)
+       {
+               /* syslogd restart */
+               msg = asl_new(ASL_TYPE_MSG);
+               if (msg == NULL) return;
+
+               asl_set(msg, ASL_KEY_SENDER, "syslogd");
+               asl_set(msg, ASL_KEY_FACILITY, "daemon");
+               asl_set(msg, ASL_KEY_LEVEL, "Notice");
+               asl_set(msg, ASL_KEY_UID, "0");
+               asl_set(msg, ASL_KEY_GID, "0");
+               snprintf(buf, sizeof(buf), "%u", getpid());
+               asl_set(msg, ASL_KEY_PID, buf);
+               asl_set(msg, ASL_KEY_MSG, "--- syslogd restarted ---");
+               asl_enqueue_message(SOURCE_INTERNAL, NULL, msg);
+               return;
+       }
+
+    bzero(&utx, sizeof(utx));
+    utx.ut_type = BOOT_TIME;
+    utx.ut_pid = 1;
+
+       /* get the boot time */
+    len = sizeof(struct timeval);
+    if (sysctl(mib, 2, &utx.ut_tv, &len, NULL, 0) < 0)
+       {
+               gettimeofday(&utx.ut_tv, NULL);
+       }
+
+    pututxline(&utx);
+
+       msg = asl_new(ASL_TYPE_MSG);
+       if (msg == NULL) return;
+
+       asl_set(msg, ASL_KEY_SENDER, "bootlog");
+       asl_set(msg, ASL_KEY_FACILITY, "com.apple.system.utmpx");
+       asl_set(msg, ASL_KEY_LEVEL, "Notice");
+       asl_set(msg, ASL_KEY_UID, "0");
+       asl_set(msg, ASL_KEY_GID, "0");
+       asl_set(msg, ASL_KEY_PID, "0");
+       snprintf(buf, sizeof(buf), "BOOT_TIME %lu %u", (unsigned long)utx.ut_tv.tv_sec, (unsigned int)utx.ut_tv.tv_usec);
+       asl_set(msg, ASL_KEY_MSG, buf);
+       asl_set(msg, "ut_id", "0x00 0x00 0x00 0x00");
+       asl_set(msg, "ut_pid", "1");
+       asl_set(msg, "ut_type", "2");
+       snprintf(buf, sizeof(buf), "%lu", (unsigned long)utx.ut_tv.tv_sec);
+       asl_set(msg, ASL_KEY_TIME, buf);
+       asl_set(msg, "ut_tv.tv_sec", buf);
+       snprintf(buf, sizeof(buf), "%u", (unsigned int)utx.ut_tv.tv_usec);
+       asl_set(msg, "ut_tv.tv_usec", buf);
+       snprintf(buf, sizeof(buf), "%u%s", (unsigned int)utx.ut_tv.tv_usec, (utx.ut_tv.tv_usec == 0) ? "" : "000");
+       asl_set(msg, ASL_KEY_TIME_NSEC, buf);
+
+       asl_enqueue_message(SOURCE_INTERNAL, NULL, msg);
+}
+
 int
 main(int argc, const char *argv[])
 {
@@ -645,6 +727,10 @@ main(int argc, const char *argv[])
        int network_change_token;
        char tstr[32];
        time_t now;
+       int first_syslogs_start = 1;
+
+       /* Set I/O policy */
+       setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_PASSIVE);
 
        memset(&global, 0, sizeof(struct global_s));
 
@@ -667,6 +753,7 @@ main(int argc, const char *argv[])
        global.fs_ttl = DEFAULT_FS_TTL_SEC;
        global.mps_limit = DEFAULT_MPS_LIMIT;
        global.kfd = -1;
+       global.lockdown_session_fd = -1;
 
 #ifdef CONFIG_MAC
        global.dbtype = DB_TYPE_FILE;
@@ -674,12 +761,6 @@ main(int argc, const char *argv[])
        global.asl_store_ping_time = 150;
 #endif
 
-#ifdef CONFIG_APPLETV
-       global.dbtype = DB_TYPE_FILE;
-       global.db_file_max = 10240000;
-       global.asl_store_ping_time = 150;
-#endif
-
 #ifdef CONFIG_IPHONE
        global.dbtype = DB_TYPE_MINI;
        activate_remote = 1;
@@ -844,7 +925,7 @@ main(int argc, const char *argv[])
                        closeall();
                }
 
-               writepid();
+               writepid(&first_syslogs_start);
        }
 
        init_config();
@@ -882,6 +963,11 @@ main(int argc, const char *argv[])
        FD_ZERO(&wr);
        FD_ZERO(&ex);
 
+       /*
+        * Log UTMPX boot time record
+        */
+       write_boot_log(first_syslogs_start);
+
        /*
         * drain /dev/klog first
         */
@@ -909,9 +995,17 @@ main(int argc, const char *argv[])
 
        forever
        {
+               /* aslevent_fdsets clears the fdsets, then sets any non-zero fds from the aslevent list */
                max = aslevent_fdsets(&rd, &wr, &ex) + 1;
 
                status = select(max, &rd, &wr, &ex, runloop_timer);
+               if ((status < 0) && (errno == EBADF))
+               {
+                       /* Catastrophic error! */
+                       aslevent_check();
+                       abort();
+               }
+
                if ((global.kfd >= 0) && FD_ISSET(global.kfd, &rd))
                {
                        /*  drain /dev/klog */
@@ -925,14 +1019,14 @@ main(int argc, const char *argv[])
                        }
                }
 
-               if (global.reset != RESET_NONE)
+               if (status > 0) aslevent_handleevent(&rd, &wr, &ex);
+
+               if ((global.reset != RESET_NONE) || (status < 0))
                {
                        send_reset();
                        global.reset = RESET_NONE;
                }
 
-               if (status != 0) aslevent_handleevent(&rd, &wr, &ex);
-
                timed_events(&runloop_timer);
        }
 }
index 85b865e97dc074870ba1e45c3172247b84a9a3fc..4fd10e219d31c33caa26700811cfe5d0df0ae142 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -52,7 +52,7 @@ static char uline[MAXLINE + 1];
 #define FMT_LEGACY 0
 #define FMT_ASL 1
 
-asl_msg_t *
+aslmsg 
 udp_in_acceptmsg(int fd)
 {
        socklen_t fromlen;
@@ -91,7 +91,7 @@ udp_in_acceptmsg(int fd)
        p = strrchr(uline, '\n');
        if (p != NULL) *p = '\0';
 
-       return asl_input_parse(uline, len, r, 0);
+       return asl_input_parse(uline, len, r, SOURCE_UDP_SOCKET);
 }
 
 int
@@ -165,12 +165,6 @@ udp_in_init(void)
        return 0;
 }
 
-int
-udp_in_reset(void)
-{
-       return 0;
-}
-
 int
 udp_in_close(void)
 {
@@ -180,7 +174,12 @@ udp_in_close(void)
 
        for (i = 0; i < nsock; i++)
        {
-               if (ufd[i] != -1) close(ufd[i]);
+               if (ufd[i] != -1)
+               {
+                       aslevent_removefd(ufd[i]);
+                       close(ufd[i]);
+               }
+
                ufd[i] = -1;
        }
 
@@ -188,3 +187,9 @@ udp_in_close(void)
 
        return 0;
 }
+
+int
+udp_in_reset(void)
+{
+       return 0;
+}
diff --git a/util.tproj/Makefile b/util.tproj/Makefile
deleted file mode 100644 (file)
index 895a116..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-Project = syslog
-ProductType = tool
-Install_Dir = /usr/bin
-
-CFILES = syslog.c
-MANPAGES = syslog.1
-
-Extra_CC_Flags = -Wall -mdynamic-no-pic \
-       -DINET6 \
-        -I"$(OBJROOT)"/aslcommon
-Extra_LD_Flags = -dead_strip -L"$(SYMROOT)" -laslcommon
-
-# Determine product configuartion
-PRODUCT = $(shell tconf --product)
-ifeq ($(PRODUCT),iPhone)
-Extra_CC_Flags += -DCONFIG_IPHONE
-endif
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-after_install:
-       codesign -s- $(DSTROOT)/usr/bin/syslog
index 4fca72a9e2a5ea97cb2d670a7b5f7a228a55287f..88868001420a36e322cab33d6694bd60a3712822 100644 (file)
@@ -49,6 +49,7 @@ key val
 .Nm
 .Op Fl f Ar file ...
 .Op Fl d Ar dir ...
+.Op Fl B
 .Op Fl w Op Ar n
 .Op Fl F Ar format
 .Op Fl T Ar format
@@ -223,6 +224,17 @@ and
 options.
 .Pp
 The
+.Fl B
+option causes
+.Nm
+to start processing messages beginning at the time of the last system startup.
+If used in conjunction with
+.Fl w ,
+all messages since the last system startup are displayed, or matched against an expression, before
+.Nm
+waits for new messages.
+.Pp
+The
 .Fl w
 option causes
 .Nm
@@ -238,7 +250,25 @@ For example:
 .Pp
 .Dl syslog -w 20
 .Pp
-This usage is similar to watching a log file using, e.g.
+Use the value
+.Dq all
+to view all messages in the data store before watching for new messages.
+The value
+.Dq boot
+will display messages since the last system startup before watching for new messages.
+Specifying
+.Dq -w boot
+is equivalent to using
+.Fl w
+and
+.Fl B
+together.
+.Pp
+Using
+.Nm
+with the
+.Fl w
+option is similar to watching a log file using, e.g.
 .Pp
 .Dl tail -f /var/log/system.log
 .Pp
index 383be598162d9fdc8c6f165be1faeb9776d7790d..11d2613fc7d80f99f4e8db3aea3fa3c44dfd5985 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -39,8 +39,9 @@
 #include <netdb.h>
 #include <notify.h>
 #include <asl.h>
+#include <asl_msg.h>
 #include <asl_private.h>
-#include <asl_ipc.h>
+#include "asl_ipc.h"
 #include <asl_core.h>
 #include <asl_store.h>
 #include <asl_file.h>
@@ -92,6 +93,7 @@
 #define FORMAT_LEGACY  0x00000200
 #define FORMAT_STD             0x00000400
 #define FORMAT_XML             0x00000800
+#define COMPRESS_DUPS   0x00010000
 
 #define EXPORT                 0x00000100
 
 #define ASL_FILTER_MASK_PAC      0x07
 
 #define FETCH_BATCH    1024
+#define MAX_RANDOM 8192
 
-#define DB_SELECT_STORE   0
-#define DB_SELECT_FILES   1
-#define DB_SELECT_SYSLOGD 2
-#define DB_SELECT_LEGACY  3
+#define DB_SELECT_ASL     0
+#define DB_SELECT_STORE   1
+#define DB_SELECT_FILES   2
+#define DB_SELECT_SYSLOGD 3
+#define DB_SELECT_LEGACY  4
+
+/* STD and BSD format messages start with 'DAY MMM DD HH:MM:SS ' timestamp */
+#define STD_BSD_DATE_LEN 20
+
+/* Max message size for direct watch */
+#define MAX_DIRECT_SIZE 16384
+
+/* Buffer for direct watch data */
+#define DIRECT_BUF_SIZE 1024
 
 static asl_file_list_t *db_files = NULL;
 static asl_store_t *store = NULL;
 static asl_file_t *legacy = NULL;
 static asl_file_t *export = NULL;
-
-static uint32_t dbselect = DB_SELECT_STORE;
+static const char *sort_key = NULL;
+static const char *sort_key_2 = NULL;
+static int sort_numeric = 0;
+static char *last_printmsg_str = NULL;
+static int last_printmsg_count = 0;
+
+#ifdef CONFIG_IPHONE
+static uint32_t dbselect = DB_SELECT_SYSLOGD;
+#else
+static uint32_t dbselect = DB_SELECT_ASL;
+#endif
 
 /* notify SPI */
 uint32_t notify_register_plain(const char *name, int *out_token);
 
-extern char *asl_msg_to_string(aslmsg msg, uint32_t *len);
 extern asl_msg_t *asl_msg_from_string(const char *buf);
 extern char *asl_list_to_string(asl_search_result_t *list, uint32_t *outlen);
 extern asl_search_result_t *asl_list_from_string(const char *buf);
@@ -155,25 +176,30 @@ usage()
        fprintf(stderr, "   d = Debug\n");
        fprintf(stderr, "   a minus sign preceeding a single letter means \"up to\" that level\n");
        fprintf(stderr, "\n");
-       fprintf(stderr, "%s [-f file...] [-d path...] [-x file] [-w [N]] [-F format] [-u] [-k key [[op] val]]... [-o -k key [[op] val]] ...]...\n", myname);
-       fprintf(stderr, "   -f    read named file[s], rather than standard log message store.\n");
-       fprintf(stderr, "   -d    read all file in named directory path, rather than standard log message store.\n");
-       fprintf(stderr, "   -x    export to named ASL format file, rather than printing\n");
-       fprintf(stderr, "   -w    watch data store (^C to quit)\n");
-       fprintf(stderr, "         prints the last N matching lines (default 10) before waiting\n");
-       fprintf(stderr, "         \"-w 0\" prints all matching lines before waiting\n");
-       fprintf(stderr, "   -F    output format may be \"std\", \"raw\", \"bsd\", or \"xml\"\n");
-       fprintf(stderr, "         format may also be a string containing variables of the form\n");
-       fprintf(stderr, "         $Key or $(Key) - use the latter for non-whitespace delimited variables\n");
-       fprintf(stderr, "   -T    timestamp format may be \"sec\" (seconds), \"utc\" (UTC), or \"local\" (local timezone)\n");
-       fprintf(stderr, "   -E    text encoding may be \"vis\", \"safe\", or \"none\"\n");
-       fprintf(stderr, "   -u    print timestamps using UTC (equivalent to \"-T utc\")\n");
-       fprintf(stderr, "   -k    key/value match\n");
-       fprintf(stderr, "         if no operator or value is given, checks for the existance of the key\n");
-       fprintf(stderr, "         if no operator is given, default is \"%s\"\n", OP_EQ);
-       fprintf(stderr, "   -C    alias for \"-k Facility com.apple.console\"\n");
-       fprintf(stderr, "   -o    begins a new query\n");
-       fprintf(stderr, "         queries are \'OR\'ed together\n");
+       fprintf(stderr, "%s [-f file...] [-d path...] [-x file] [-w [N]] [-F format] [-nocompress] [-u] [-sort key1 [key2]] [-nsort key1 [key2]] [-k key [[op] val]]... [-o -k key [[op] val]] ...]...\n", myname);
+       fprintf(stderr, "   -f     read named file[s], rather than standard log message store.\n");
+       fprintf(stderr, "   -d     read all file in named directory path, rather than standard log message store.\n");
+       fprintf(stderr, "   -x     export to named ASL format file, rather than printing\n");
+       fprintf(stderr, "   -w     watch data store (^C to quit)\n");
+       fprintf(stderr, "          prints the last N matching lines (default 10) before waiting\n");
+       fprintf(stderr, "          \"-w all\" prints all matching lines before waiting\n");
+       fprintf(stderr, "          \"-w boot\" prints all matching lines since last system boot before waiting\n");
+       fprintf(stderr, "   -F     output format may be \"std\", \"raw\", \"bsd\", or \"xml\"\n");
+       fprintf(stderr, "          format may also be a string containing variables of the form\n");
+       fprintf(stderr, "          $Key or $(Key) - use the latter for non-whitespace delimited variables\n");
+       fprintf(stderr, "   -T     timestamp format may be \"sec\" (seconds), \"utc\" (UTC), or \"local\" (local timezone)\n");
+       fprintf(stderr, "   -E     text encoding may be \"vis\", \"safe\", or \"none\"\n");
+       fprintf(stderr, "   -nodc  no duplicate message compression\n");
+       fprintf(stderr, "   -u     print timestamps using UTC (equivalent to \"-T utc\")\n");
+       fprintf(stderr, "   -sort  sort messages using value for specified key1 (secondary sort by key2 if provided)\n");
+       fprintf(stderr, "   -nsort numeric sort messages using value for specified key1 (secondary sort by key2 if provided)\n");
+       fprintf(stderr, "   -k     key/value match\n");
+       fprintf(stderr, "          if no operator or value is given, checks for the existance of the key\n");
+       fprintf(stderr, "          if no operator is given, default is \"%s\"\n", OP_EQ);
+       fprintf(stderr, "   -B     only process log messages since last system boot\n");
+       fprintf(stderr, "   -C     alias for \"-k Facility com.apple.console\"\n");
+       fprintf(stderr, "   -o     begins a new query\n");
+       fprintf(stderr, "          queries are \'OR\'ed together\n");
        fprintf(stderr, "operators are zero or more modifiers followed by a comparison\n");
        fprintf(stderr, "   %s   equal\n", OP_EQ);
        fprintf(stderr, "   %s   not equal\n", OP_NE);
@@ -534,17 +560,19 @@ int
 rcontrol_set(pid_t pid, uid_t uid, int filter)
 {
        int status;
-       const char *name;
+       const char *name, *rcname;
+
+       rcname = rcontrol_name(pid, uid);
 
        if (pid < 0)
        {
                name = "Master";
                if (pid == RC_SYSLOGD) name = "ASL Data Store";
-               status = rcontrol_set_string(rcontrol_name(pid, uid), filter);
+               status = rcontrol_set_string(rcname, filter);
 
                if (status == NOTIFY_STATUS_OK)
                {
-                       printf("Set %s syslog filter mask: %s\n", name, asl_filter_string(filter));
+                       if (pid == RC_MASTER) status = notify_post(NOTIFY_SYSTEM_MASTER);
                        return 0;
                }
 
@@ -552,11 +580,10 @@ rcontrol_set(pid_t pid, uid_t uid, int filter)
                return -1;
        }
 
-       status = rcontrol_set_string(rcontrol_name(pid, uid), filter);
+       status = rcontrol_set_string(rcname, filter);
        if (status == NOTIFY_STATUS_OK)
        {
-               if (pid == RC_SYSLOGD) status = notify_post(NOTIFY_SYSTEM_ASL_FILTER);
-               printf("Set process %d syslog filter mask set: %s\n", pid, asl_filter_string(filter));
+               status = notify_post(rcname);
                return 0;
        }
 
@@ -572,7 +599,6 @@ rsend(aslmsg msg, char *rhost)
        char *timestr;
        const char *val;
        time_t tick;
-       struct tm gtime;
        int s;
        struct sockaddr_in dst;
        struct hostent *h;
@@ -597,15 +623,10 @@ rsend(aslmsg msg, char *rhost)
        val = asl_get(msg, ASL_KEY_LEVEL);
        if (val != NULL) level = atoi(val);
 
-       memset(&gtime, 0, sizeof(struct tm));
-       timestr = NULL;
 
        tick = time(NULL);
-       gmtime_r(&tick, &gtime);
-
-       /* Canonical form: YYYY.MM.DD hh:mm:ss UTC */
-       asprintf(&timestr, "%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);
-
+       timestr = NULL;
+       asprintf(&timestr, "%lu", tick);
        if (timestr != NULL)
        {
                asl_set(msg, ASL_KEY_TIME, timestr);
@@ -615,7 +636,7 @@ rsend(aslmsg msg, char *rhost)
        if (gethostname(myname, MAXHOSTNAMELEN) == 0) asl_set(msg, ASL_KEY_HOST, myname);
 
        len = 0;
-       str = asl_msg_to_string(msg, &len);
+       str = asl_msg_to_string((asl_msg_t *)msg, &len);
        if (str == NULL) return -1;
 
        asprintf(&out, "%10u %s\n", len+1, str);
@@ -938,7 +959,7 @@ print_xml_trailer(FILE *f)
 }
 
 static void
-printmsg(FILE *f, asl_msg_t *msg, char *fmt, int pflags)
+printmsg(FILE *f, aslmsg msg, char *fmt, int pflags)
 {
        char *str;
        const char *mf, *tf;
@@ -975,8 +996,41 @@ printmsg(FILE *f, asl_msg_t *msg, char *fmt, int pflags)
        if (pflags & TIME_LCL) tf = ASL_TIME_FMT_LCL;
 
        len = 0;
-       str = asl_format_message(msg, mf, tf, encode, &len);
-       if (str != NULL)
+       str = asl_format_message((asl_msg_t *)msg, mf, tf, encode, &len);
+       if (str == NULL) return;
+
+       if (pflags & COMPRESS_DUPS)
+       {
+               if (last_printmsg_str != NULL) 
+               {
+                       if (!strcmp(str + STD_BSD_DATE_LEN, last_printmsg_str + STD_BSD_DATE_LEN))
+                       {
+                               last_printmsg_count++;
+                               free(str);
+                       }
+                       else
+                       {
+                               if (last_printmsg_count > 0)
+                               {
+                                       fprintf(f, "--- last message repeated %d time%s ---\n", last_printmsg_count, (last_printmsg_count == 1) ? "" : "s");
+                               }
+
+                               free(last_printmsg_str);
+                               last_printmsg_str = str;
+                               last_printmsg_count = 0;
+
+                               fprintf(f, "%s", str);
+                       }
+               }
+               else
+               {
+                       last_printmsg_str = str;
+                       last_printmsg_count = 0;
+
+                       fprintf(f, "%s", str);
+               }
+       }
+       else
        {
                fprintf(f, "%s", str);
                free(str);
@@ -1078,6 +1132,192 @@ syslogd_query(asl_search_result_t *q, uint64_t start, int count, int dir, uint64
        return l;
 }
 
+void
+filter_and_print(aslmsg msg, asl_search_result_t *ql, FILE *f, char *pfmt, int pflags)
+{
+       int i, do_match, did_match;
+
+       if (msg == NULL) return;
+
+       do_match = 1;
+       if (ql == NULL) do_match = 0;
+       else if (ql->count == 0) do_match = 0;
+
+       did_match = 1;
+
+       if (do_match != 0)
+       {
+               did_match = 0;
+
+               for (i = 0; (i < ql->count) && (did_match == 0); i++)
+               {
+                       did_match = asl_msg_cmp(ql->msg[i], (asl_msg_t *)msg);
+               }
+       }
+
+       if (did_match != 0) printmsg(f, msg, pfmt, pflags);
+}
+
+void
+syslogd_direct_watch(FILE *f, char *pfmt, int pflags, asl_search_result_t *ql)
+{
+       struct sockaddr_in address;
+       int i, bytes, n, inlen, sock, stream, status;
+       uint16_t port;
+       socklen_t addresslength;
+       char *str, buf[DIRECT_BUF_SIZE];
+       aslmsg msg;
+
+       if (asl_server_port == MACH_PORT_NULL)
+       {
+               status = bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &asl_server_port);
+               if (status != KERN_SUCCESS)
+               {
+                       fprintf(stderr, "query failed: can't contact syslogd\n");
+                       exit(1);
+               }
+       }
+
+reset:
+
+       addresslength = sizeof(address);
+       sock = socket(AF_INET, SOCK_STREAM, 0);
+       port = (arc4random() % (IPPORT_HILASTAUTO - IPPORT_HIFIRSTAUTO)) + IPPORT_HIFIRSTAUTO;
+
+       address.sin_addr.s_addr = 0;
+       address.sin_family = AF_INET;
+       address.sin_port = htons(port);
+
+       status = bind(sock, (struct sockaddr *)&address, sizeof(address));
+
+       for (i = 0; (i < MAX_RANDOM) && (status < 0); i++)
+       {
+               port = (arc4random() % (IPPORT_HILASTAUTO - IPPORT_HIFIRSTAUTO)) + IPPORT_HIFIRSTAUTO;
+               address.sin_port = htons(port);
+
+               status = bind(sock, (struct sockaddr *)&address, sizeof(address));
+       }
+
+       if (status < 0)
+       {
+               fprintf(stderr, "query failed: can't find a port to connect to syslogd\n");
+               exit(1);
+       }
+
+       bytes = 0;
+
+       if (listen(sock, 1) == -1)
+       {
+               perror("listen");
+               exit(1);
+       }
+
+       i = htons(port);
+       _asl_server_register_direct_watch(asl_server_port, i);
+
+       stream = accept(sock, (struct sockaddr*)&address, &addresslength);
+       if (stream == -1)
+       {
+               perror("accept");
+               exit(1);
+       }
+
+       forever
+       {
+               inlen = 0;
+               bytes = recvfrom(stream, &n, sizeof(n), 0, NULL, NULL);
+               if (bytes == 0) break;
+               else inlen = ntohl(n);
+
+               if (inlen == 0) continue;
+               if (inlen > MAX_DIRECT_SIZE)
+               {
+                       fprintf(f, "\n*** received invalid message data [%d] from syslogd - resetting connection ***\n\n", inlen);
+                       close(stream);
+                       close(sock);
+                       goto reset;
+               }
+
+               str = NULL;
+               if (inlen <= DIRECT_BUF_SIZE)
+               {
+                       str = buf;
+               }
+               else
+               {
+                       str = calloc(1, inlen + 1);
+                       if (str == NULL)
+                       {
+                               fprintf(stderr, "\ncan't allocate memory - exiting\n");
+                               close(stream);
+                               close(sock);
+                               exit(1);
+                       }
+               }
+
+               n = 0;
+               while (n < inlen)
+               {
+                       bytes = recvfrom(stream, str + n, inlen - n, 0, NULL, NULL);
+                       if (bytes == 0) break;
+                       else n += bytes;
+               }
+
+               msg = (aslmsg)asl_msg_from_string(str);
+               if (str != buf) free(str);
+               filter_and_print(msg, ql, f, pfmt, pflags);
+               asl_free(msg);
+       }
+
+       close(stream);
+       close(sock);
+
+       address.sin_addr.s_addr = 0;
+}
+
+int
+sort_compare_key(const void *a, const void *b, const char *key)
+{
+       aslmsg *ma, *mb;
+       const char *va, *vb;
+       uint64_t na, nb;
+
+       if (key == NULL) return 0;
+
+       ma = (aslmsg *)a;
+       mb = (aslmsg *)b;
+
+       va = asl_get(*ma, key);
+       vb = asl_get(*mb, key);
+
+       if (va == NULL) return -1;
+       if (vb == NULL) return 1;
+
+       if (sort_numeric == 1)
+       {
+               na = atoll(va);
+               nb = atoll(vb);
+               if (na < nb) return -1;
+               if (na > nb) return 1;
+               return 0;
+       }
+
+       return strcmp(va, vb);
+}
+
+int
+sort_compare(const void *a, const void *b)
+{
+       int cmp;
+
+       if (sort_key == NULL) return 0;
+
+       cmp = sort_compare_key(a, b, sort_key);
+       if ((cmp == 0) && (sort_key_2 != NULL)) cmp = sort_compare_key(a, b, sort_key_2);
+
+       return cmp;
+}
+
 void
 search_once(FILE *f, char *pfmt, int pflags, asl_search_result_t *ql, uint64_t qmin, uint64_t *cmax, uint32_t count, uint32_t batch, int dir, uint32_t tail)
 {
@@ -1092,13 +1332,15 @@ search_once(FILE *f, char *pfmt, int pflags, asl_search_result_t *ql, uint64_t q
 
        while (more == 1)
        {
-               if (dbselect == DB_SELECT_STORE) res = store_query(ql, qmin, batch, dir, cmax);
+               if (batch == 0) more = 0;
+
+               if ((dbselect == DB_SELECT_ASL) || (dbselect == DB_SELECT_STORE)) res = store_query(ql, qmin, batch, dir, cmax);
                else if (dbselect == DB_SELECT_FILES) res = file_query(ql, qmin, batch, dir, cmax);
                else if (dbselect == DB_SELECT_SYSLOGD) res = syslogd_query(ql, qmin, batch, dir, cmax);
                else if (dbselect == DB_SELECT_LEGACY) res = legacy_query(ql, qmin, batch, dir, cmax);
 
-               if ((dir >= 0) && (*cmax > qmin)) qmin = *cmax;
-               else if ((dir < 0) && (*cmax < qmin)) qmin = *cmax;
+               if ((dir >= 0) && (*cmax > qmin)) qmin = *cmax + 1;
+               else if ((dir < 0) && (*cmax < qmin)) qmin = *cmax - 1;
 
                if (res == NULL)
                {
@@ -1118,15 +1360,28 @@ search_once(FILE *f, char *pfmt, int pflags, asl_search_result_t *ql, uint64_t q
                                if (i < 0) i = 0;
                        }
 
+                       if (sort_key != NULL)
+                       {
+                               qsort(res->msg, res->count, sizeof(asl_msg_t *), sort_compare);
+                       }
+
                        if ((f != NULL) || (export != NULL))
                        {
-                               for (; i < res->count; i++) printmsg(f, res->msg[i], pfmt, pflags);
+                               for (; i < res->count; i++) printmsg(f, (aslmsg)(res->msg[i]), pfmt, pflags);
                        }
 
                        aslresponse_free((aslresponse)res);
                }
        }
 
+       if ((pflags & COMPRESS_DUPS) && (last_printmsg_count > 0))
+       {
+               fprintf(f, "--- last message repeated %d time%s ---\n", last_printmsg_count, (last_printmsg_count == 1) ? "" : "s");
+               free(last_printmsg_str);
+               last_printmsg_str = NULL;
+               last_printmsg_count = 0;
+       }
+
        if (pflags & FORMAT_XML) print_xml_trailer(f);
 }
 
@@ -1289,8 +1544,8 @@ add_op(asl_msg_t *q, char *key, char *op, char *val, uint32_t flags)
        }
 
        o |= flags;
-       if (qval != NULL) asl_set_query(q, key, qval, o);
-       else asl_set_query(q, key, val, o);
+       if (qval != NULL) asl_msg_set_key_val_op(q, key, qval, o);
+       else asl_msg_set_key_val_op(q, key, val, o);
 
        return 0;
 }
@@ -1309,7 +1564,7 @@ add_db_file(const char *name)
        }
 
        /* shouldn't happen */
-       if (name == NULL) return DB_SELECT_STORE;
+       if (name == NULL) return DB_SELECT_ASL;
 
        s = NULL;
        status = asl_file_open_read(name, &s);
@@ -1351,6 +1606,17 @@ add_db_dir(const char *name)
        asl_file_t *s;
        char *path;
 
+       /* 
+        * Try opening as a data store
+        */
+       status = asl_store_open_read(name, &store);
+       if (status == 0)
+       {
+               if (name == NULL) return DB_SELECT_ASL;
+               if (!strcmp(name, PATH_ASL_STORE)) return DB_SELECT_ASL;
+               return DB_SELECT_STORE;
+       }
+
        /*
         * Open all readable files
         */
@@ -1390,7 +1656,7 @@ int
 main(int argc, char *argv[])
 {
        FILE *outfile;
-       int i, j, n, watch, status, pflags, tflags, iamroot, user_tflag;
+       int i, j, n, watch, status, pflags, tflags, iamroot, user_tflag, export_preserve_id, saw_dash_d, since_boot;
        int notify_file, notify_token;
        asl_search_result_t *qlist;
        asl_msg_t *cq;
@@ -1406,11 +1672,14 @@ main(int argc, char *argv[])
        flags = 0;
        tail_count = 0;
        batch = FETCH_BATCH;
-       pflags = FORMAT_STD;
+       pflags = FORMAT_STD | COMPRESS_DUPS;
        tflags = TIME_LCL;
-       encode = ASL_ENCODE_ASL;
+       encode = ASL_ENCODE_SAFE;
        cq = NULL;
        exportname = NULL;
+       export_preserve_id = 0;
+       saw_dash_d = 0;
+       since_boot = 0;
 
        i = asl_store_location();
        if (i == ASL_STORE_LOCATION_MEMORY) dbselect = DB_SELECT_SYSLOGD;
@@ -1459,6 +1728,7 @@ main(int argc, char *argv[])
                                        if (!strcmp(argv[j], "-"))
                                        {
                                                dbselect = DB_SELECT_SYSLOGD;
+                                               i++;
                                                break;
                                        }
                                        else if (argv[j][0] == '-')
@@ -1468,23 +1738,28 @@ main(int argc, char *argv[])
                                        else
                                        {
                                                dbselect = add_db_file(argv[j]);
+                                               i++;
                                        }
                                }
                        }
                }
-               if (!strcmp(argv[i], "-d"))
+               else if (!strcmp(argv[i], "-d"))
                {
-                       if ((i + 1) < argc)
+                       saw_dash_d = i + 1;
+
+                       if (saw_dash_d < argc)
                        {
-                               for (j = i + 1; j < argc; j++)
+                               for (j = saw_dash_d; j < argc; j++)
                                {
                                        if (!strcmp(argv[j], "store"))
                                        {
                                                dbselect = add_db_dir(PATH_ASL_STORE);
+                                               i++;
                                        }
                                        else if (!strcmp(argv[j], "archive"))
                                        {
                                                dbselect = add_db_dir(PATH_ASL_ARCHIVE);
+                                               i++;
                                        }
                                        else if (argv[j][0] == '-')
                                        {
@@ -1493,9 +1768,23 @@ main(int argc, char *argv[])
                                        else
                                        {
                                                dbselect = add_db_dir(argv[j]);
+                                               i++;
                                        }
                                }
                        }
+                       else
+                       {
+                               fprintf(stderr, "missing directory name following -d flag\n");
+                               return -1;
+                       }
+               }
+               else if (!strcmp(argv[i], "-b"))
+               {
+                       batch = atoi(argv[++i]);
+               }
+               else if (!strcmp(argv[i], "-B"))
+               {
+                       since_boot = 1;
                }
                else if (!strcmp(argv[i], "-w"))
                {
@@ -1504,15 +1793,67 @@ main(int argc, char *argv[])
                        if (((i + 1) < argc) && (argv[i + 1][0] != '-'))
                        {
                                i++;
-                               tail_count = atoi(argv[i]);
+                               if (!strcmp(argv[i], "all"))
+                               {
+                                       tail_count = (uint32_t)-1;
+                               }
+                               else if (!strcmp(argv[i], "boot"))
+                               {
+                                       since_boot = 1;
+                               }
+                               else
+                               {
+                                       tail_count = atoi(argv[i]);
+                               }
                        }
                }
+               else if (!strcmp(argv[i], "-sort"))
+               {
+                       if (((i + 1) < argc) && (argv[i + 1][0] != '-'))
+                       {
+                               i++;
+                               sort_key = argv[i];
+
+                               if (((i + 1) < argc) && (argv[i + 1][0] != '-'))
+                               {
+                                       i++;
+                                       sort_key_2 = argv[i];
+                               }
+                       }
+                       else
+                       {
+                               sort_key = ASL_KEY_MSG_ID;
+                       }
+
+                       batch = 0;
+               }
+               else if (!strcmp(argv[i], "-nsort"))
+               {
+                       if (((i + 1) < argc) && (argv[i + 1][0] != '-'))
+                       {
+                               i++;
+                               sort_key = argv[i];
+
+                               if (((i + 1) < argc) && (argv[i + 1][0] != '-'))
+                               {
+                                       i++;
+                                       sort_key_2 = argv[i];
+                               }
+                       }
+                       else
+                       {
+                               sort_key = ASL_KEY_MSG_ID;
+                       }
+
+                       sort_numeric = 1;
+                       batch = 0;
+               }
                else if (!strcmp(argv[i], "-u"))
                {
                        tflags = TIME_UTC;
                        user_tflag = 1;
                }
-               else if (!strcmp(argv[i], "-x"))
+               else if ((!strcmp(argv[i], "-x")) || (!strcmp(argv[i], "-X")))
                {
                        if ((i + 1) >= argc)
                        {
@@ -1521,6 +1862,8 @@ main(int argc, char *argv[])
                                exit(1);
                        }
 
+                       if (!strcmp(argv[i], "-x")) export_preserve_id = 1;
+
                        exportname = argv[++i];
                }
                else if (!strcmp(argv[i], "-E"))
@@ -1557,11 +1900,11 @@ main(int argc, char *argv[])
                        }
                        else if (!strcmp(argv[i], "std"))
                        {
-                               pflags = FORMAT_STD;
+                               pflags = FORMAT_STD | COMPRESS_DUPS;
                        }
                        else if (!strcmp(argv[i], "bsd"))
                        {
-                               pflags = FORMAT_LEGACY;
+                               pflags = FORMAT_LEGACY | COMPRESS_DUPS;
                        }
                        else if (!strcmp(argv[i], "xml"))
                        {
@@ -1591,6 +1934,10 @@ main(int argc, char *argv[])
                        else if (!strcmp(argv[i], "lcl")) tflags = TIME_LCL;
                        else  tflags = TIME_LCL;
                }
+               else if (!strcmp(argv[i], "-nodc"))
+               {
+                       pflags = pflags & ~COMPRESS_DUPS;
+               }
                else if (!strcmp(argv[i], "-o"))
                {
                        flags = 0;
@@ -1606,7 +1953,7 @@ main(int argc, char *argv[])
 
                        if (qlist->msg == NULL) exit(1);
 
-                       cq = asl_new(ASL_TYPE_QUERY);
+                       cq = asl_msg_new(ASL_TYPE_QUERY);
                        qlist->msg[qlist->count] = cq;
                        qlist->count++;
                }
@@ -1621,7 +1968,7 @@ main(int argc, char *argv[])
                                qlist->msg = (asl_msg_t **)calloc(1, sizeof(asl_msg_t *));
                                if (qlist->msg == NULL) exit(1);
 
-                               cq = asl_new(ASL_TYPE_QUERY);
+                               cq = asl_msg_new(ASL_TYPE_QUERY);
                                qlist->msg[qlist->count] = cq;
                                qlist->count++;
                        }
@@ -1665,7 +2012,7 @@ main(int argc, char *argv[])
                                qlist->msg = (asl_msg_t **)calloc(1, sizeof(asl_msg_t *));
                                if (qlist->msg == NULL) exit(1);
 
-                               cq = asl_new(ASL_TYPE_QUERY);
+                               cq = asl_msg_new(ASL_TYPE_QUERY);
                                qlist->msg[qlist->count] = cq;
                                qlist->count++;
                        }
@@ -1681,6 +2028,14 @@ main(int argc, char *argv[])
                                aslresponse_free(qlist);
                                exit(1);
                        }
+
+                       i += (n - 1);
+               }
+               else
+               {
+                       fprintf(stderr, "syslog: unknown option \"%s\"\n", argv[i]);
+                       fprintf(stderr, "run \"syslog -help\" for usage\n");
+                       exit(1);
                }
        }
 
@@ -1689,6 +2044,33 @@ main(int argc, char *argv[])
 
        outfile = stdout;
 
+       /*
+        * Catch and report some cases where watch (-w) doesn't work
+        */
+       if (watch == 1)
+       {
+               if (sort_key != NULL)
+               {
+                       fprintf(stderr, "Warning: -w flag has no effect with -sort flag\n");
+                       watch = 0;
+               }
+
+               if (dbselect == DB_SELECT_FILES)
+               {
+                       if (saw_dash_d == 0)
+                       {
+                               fprintf(stderr, "Warning: -w flag not supported for a set of one or more files\n");
+                       }
+                       else
+                       {
+                               fprintf(stderr, "Warning: directory \"%s\" is not an ASL data store\n", argv[saw_dash_d]);
+                               fprintf(stderr, "         -w flag not supported for a set of one or more files\n");
+                       }
+
+                       watch = 0;
+               }
+       }
+
        if (exportname != NULL)
        {
                if (watch == 1)
@@ -1709,7 +2091,8 @@ main(int argc, char *argv[])
                 * allow the string cache to be unlimited to maximize string dup compression
                 * preserve message IDs
                 */
-               export->flags = ASL_FILE_FLAG_UNLIMITED_CACHE | ASL_FILE_FLAG_PRESERVE_MSG_ID;
+               export->flags = ASL_FILE_FLAG_UNLIMITED_CACHE;
+               if (export_preserve_id != 0) export->flags |= ASL_FILE_FLAG_PRESERVE_MSG_ID;
 
                outfile = NULL;
                pflags = EXPORT;
@@ -1720,31 +2103,77 @@ main(int argc, char *argv[])
        notify_file = -1;
        notify_token = -1;
 
-       if (watch == 1)
+       /* set starting point */
+       if (since_boot == 1)
        {
-               if ((dbselect == DB_SELECT_STORE) || (dbselect == DB_SELECT_SYSLOGD))
+               /* search back for last "BOOT_TIME (ut_type == 2) record */
+               asl_search_result_t *bt;
+               aslmsg bq;
+
+               bt = (asl_search_result_t *)calloc(1, sizeof(asl_search_result_t));
+               if (bt == NULL)
                {
-                       status = notify_register_file_descriptor("com.apple.system.logger.message", &notify_file, 0, &notify_token);
-                       if (status != NOTIFY_STATUS_OK) notify_token = -1;
+                       fprintf(stderr, "\ncan't allocate memory - exiting\n");
+                       exit(1);
+               }
+
+               bt->msg = (asl_msg_t **)calloc(1, sizeof(asl_msg_t *));
+               if (bt->msg == NULL)
+               {
+                       fprintf(stderr, "\ncan't allocate memory - exiting\n");
+                       exit(1);
                }
-       }
 
-       if ((qlist->count == 0) && (watch == 1))
+               bq = asl_new(ASL_TYPE_QUERY);
+               if (bq == NULL)
+               {
+                       fprintf(stderr, "\ncan't allocate memory - exiting\n");
+                       exit(1);
+               }
+
+               asl_set_query(bq, "ut_type", "2", ASL_QUERY_OP_EQUAL);
+               bt->count = 1;
+               bt->msg[0] = (asl_msg_t *)bq;
+       
+               /* XXX */
+               search_once(NULL, NULL, 0, bt, -1, &qmin, 1, 1, -1, 0);
+               asl_free(bq);
+               free(bt->msg);
+               free(bt);
+       
+               if (qmin > 0) qmin--;
+               tail_count = 0;
+       }
+       else if (watch == 1)
        {
+               /* go back tail_count records from last record */
                qmin = -1;
-               search_once(NULL, NULL, 0, NULL, qmin, &cmax, 1, 1, -1, 0);
-               qmin = (cmax + 1) - tail_count;
+               search_once(NULL, NULL, 0, qlist, qmin, &cmax, 1, 1, -1, 0);
+
+               if (cmax >= tail_count) qmin = cmax - tail_count;
+               else qmin = 0;
+
                tail_count = 0;
        }
 
+       if ((watch == 1) && (dbselect == DB_SELECT_ASL))
+       {
+               status = notify_register_file_descriptor("com.apple.system.logger.message", &notify_file, 0, &notify_token);
+               if (status != NOTIFY_STATUS_OK) notify_token = -1;
+       }
+
        /* output should be line buffered */
        if (outfile != NULL) setlinebuf(outfile);
 
-       search_once(outfile, pfmt, pflags, qlist, qmin, &cmax, 0, batch, 1, tail_count);
+       search_once(outfile, pfmt, pflags, qlist, qmin + 1, &cmax, 0, 0, 1, tail_count);
 
        if (watch == 1)
        {
-               if (notify_token == -1)
+               if (dbselect == DB_SELECT_SYSLOGD)
+               {
+                       syslogd_direct_watch(outfile, pfmt, pflags, qlist);
+               }
+               else if (notify_token == -1)
                {
                        forever
                        {