]> git.saurik.com Git - apple/syslog.git/blobdiff - libsystem_asl.tproj/src/asl.c
syslog-377.0.1.tar.gz
[apple/syslog.git] / libsystem_asl.tproj / src / asl.c
index 745a788d6b9a0e47da167cb1e2f239f3d0a6c578..8e255b4c79c297ca01de59f3e619a979beebefb6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2015 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -52,6 +52,8 @@
 #include <dispatch/dispatch.h>
 #include <libkern/OSAtomic.h>
 #include <os/activity.h>
+#include <os/log.h>
+#include <os/log_private.h>
 #include <asl_ipc.h>
 #include <asl_client.h>
 #include <asl_core.h>
 
 #define FETCH_BATCH    256
 
-#define LEVEL_MASK   0x0000000f
-#define EVAL_MASK    0x000000f0
-#define EVAL_IGNORE  0x00000000
-#define EVAL_ASLFILE 0x00000010
-#define EVAL_SEND    0x00000020
-#define EVAL_TUNNEL  0x00000040
-#define EVAL_FILE    0x00000080
-#define EVAL_QUOTA   0x00000100
+#define EVAL_DEFAULT_ACTION (EVAL_SEND_ASL | EVAL_SEND_TRACE)
+#define EVAL_ASL (EVAL_SEND_ASL | EVAL_TEXT_FILE | EVAL_ASL_FILE)
 
 /*
  * Clients get a max of 36000 messages per hour.
 #define NOQUOTA_ENV "ASL_QUOTA_DISABLED"
 #define QUOTA_DISABLED_MSG "*** MESSAGE QUOTA DISABLED FOR THIS PROCESS ***"
 #define QUOTA_MSG "*** LOG MESSAGE QUOTA EXCEEDED - SOME MESSAGES FROM THIS PROCESS HAVE BEEN DISCARDED ***"
-#define QUOTA_LEVEL 2
-#define QUOTA_LEVEL_STR "2"
+#define QUOTA_LEVEL ASL_LEVEL_CRIT
+#define QUOTA_LEVEL_STR ASL_STRING_CRIT
+
+/*
+ * Limit the size of messages sent to syslogd.
+ */
+#define SIZE_LIMIT_MSG "*** ASL MESSAGE SIZE (%u bytes) EXCEEDED MAXIMIMUM SIZE (%u bytes) ***"
+
+static const os_log_type_t shim_asl_to_log_type[8] = {
+       OS_LOG_TYPE_DEFAULT,    // ASL_LEVEL_EMERG
+       OS_LOG_TYPE_DEFAULT,    // ASL_LEVEL_ALERT
+       OS_LOG_TYPE_DEFAULT,    // ASL_LEVEL_CRIT
+       OS_LOG_TYPE_DEFAULT,    // ASL_LEVEL_ERR
+       OS_LOG_TYPE_DEFAULT,    // ASL_LEVEL_WARNING
+       OS_LOG_TYPE_DEFAULT,    // ASL_LEVEL_NOTICE
+       OS_LOG_TYPE_INFO,       // ASL_LEVEL_INFO
+       OS_LOG_TYPE_DEBUG       // ASL_LEVEL_DEBUG
+};
 
 /* forward */
 static ASL_STATUS _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *mstring);
+static ASL_STATUS _asl_send_message_text(asl_client_t *asl, asl_msg_t *sendmsg, asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *mstring, bool shimmed);
 __private_extern__ asl_client_t *_asl_open_default();
 
 /* notify SPI */
@@ -96,6 +109,11 @@ uint32_t notify_register_plain(const char *name, int *out_token);
 /* fork handling in asl_fd.c */
 extern void _asl_redirect_fork_child(void);
 
+#if TARGET_OS_OSX
+extern void _asl_mt_shim_fork_child(void);
+extern void _asl_mt_shim_send_message(asl_msg_t *msg);
+#endif
+
 typedef struct
 {
        int fd;
@@ -114,6 +132,7 @@ typedef struct
        time_t last_send;
        time_t last_oq_msg;
        uint32_t quota;
+       dispatch_once_t port_lookup_once;
        mach_port_t server_port;
        char *sender;
        pthread_mutex_t lock;
@@ -122,7 +141,7 @@ typedef struct
        asl_client_t *asl;
 } _asl_global_t;
 
-__private_extern__ _asl_global_t _asl_global = {0, -1, -1, -1, 0LL, 0LL, 0LL, 0LL, 0, MACH_PORT_NULL, NULL, PTHREAD_MUTEX_INITIALIZER, 0, NULL, NULL};
+__private_extern__ _asl_global_t _asl_global = {0, -1, -1, -1, 0LL, 0LL, 0LL, 0LL, 0, 0, MACH_PORT_NULL, NULL, PTHREAD_MUTEX_INITIALIZER, 0, NULL, NULL};
 
 static const char *level_to_number_string[] = {"0", "1", "2", "3", "4", "5", "6", "7"};
 
@@ -145,11 +164,15 @@ _asl_fork_child()
        _asl_global.last_send = 0;
        _asl_global.last_oq_msg = 0;
 
+       _asl_global.port_lookup_once = 0;
        _asl_global.server_port = MACH_PORT_NULL;
 
        pthread_mutex_init(&(_asl_global.lock), NULL);
 
        _asl_redirect_fork_child();
+#if TARGET_OS_OSX
+       _asl_mt_shim_fork_child();
+#endif
 }
 
 /*
@@ -239,9 +262,22 @@ _asl_notify_close()
 #endif
 
 static void
-_asl_global_init(int reset)
+_asl_global_init()
 {
-       _asl_global.server_port = asl_core_get_service_port(reset);
+       dispatch_once(&_asl_global.port_lookup_once, ^{
+               char *str = getenv("ASL_DISABLE");
+               if ((str == NULL) || strcmp(str, "1"))
+               {
+                       bootstrap_look_up2(bootstrap_port, ASL_SERVICE_NAME, &_asl_global.server_port, 0, BOOTSTRAP_PRIVILEGED_SERVER);
+               }
+       });
+}
+
+mach_port_t
+asl_core_get_service_port(__unused int reset)
+{
+       _asl_global_init();
+       return _asl_global.server_port;
 }
 
 #pragma mark -
@@ -253,7 +289,7 @@ asl_open(const char *ident, const char *facility, uint32_t opts)
        asl_client_t *asl = asl_client_open(ident, facility, opts);
        if (asl == NULL) return NULL;
 
-       _asl_global_init(0);
+       _asl_global_init();
        if (!(opts & ASL_OPT_NO_REMOTE)) _asl_notify_open(1);
 
        return (asl_object_t)asl;
@@ -428,13 +464,14 @@ asl_set_filter(asl_object_t client, int f)
 
 /*
  * Evaluate client / message / level to determine what to do with a message.
- * Checks filters, tunneling, and log files.  Returns EVAL_IGNORE if the message
- * can be ignored.  Otherwise it returns the bits below, ORed with the level.
+ * Checks filters, tunneling, and log files.
+ * Returns the bits below, ORed with the message level.
  *
- * EVAL_ASLFILE - will write to an asl file (see asl_open_from_file)
- * EVAL_SEND - will send to syslogd
- * EVAL_TUNNEL - will send to syslogd with tunneling enabled
- * EVAL_FILE - will write to file
+ * EVAL_SEND_ASL       - send this message to syslogd
+ * EVAL_SEND_TRACE     - log this message with Activity Tracing
+ * EVAL_ASL_FILE       - write to a standalone ASL file (see asl_open_from_file)
+ * EVAL_TEXT_FILE      - write this message to a text file / stderr
+ * EVAL_TUNNEL         - tunneling enabled when sending to syslogd
  */
 uint32_t
 _asl_evaluate_send(asl_object_t client, asl_object_t m, int slevel)
@@ -445,37 +482,41 @@ _asl_evaluate_send(asl_object_t client, asl_object_t m, int slevel)
        int check;
        uint64_t v64;
        const char *val;
+       uint32_t eval;
 
        level = ASL_LEVEL_DEBUG;
        if (slevel >= 0) level = slevel;
-       
+
        val = NULL;
        if ((asl_msg_lookup(msg, ASL_KEY_LEVEL, &val, NULL) == 0) && (val != NULL)) level = atoi(val);
-       
+
        if (level < ASL_LEVEL_EMERG) level = ASL_LEVEL_EMERG;
        else if (level > ASL_LEVEL_DEBUG) level = ASL_LEVEL_DEBUG;
 
        if ((client != NULL) && (asl_get_type(client) != ASL_TYPE_CLIENT))
        {
                /* sending to something other than a client */
-               return (level | EVAL_SEND);
+               return EVAL_ACTIVE | EVAL_SEND_ASL | level;
        }
 
        asl = (asl_client_t *)client;
+       if ((asl != NULL) && (asl->aslfile != NULL)) return (EVAL_ASL_FILE | level);
+
+       if (asl == NULL) asl = _asl_open_default();
        if (asl == NULL)
        {
-               asl = _asl_open_default();
-               if (asl == NULL) return EVAL_IGNORE;
+               eval = EVAL_ACTIVE | EVAL_DEFAULT_ACTION | level;
+               eval &= ~EVAL_SEND_ASL;
+               return eval;
        }
 
-       if (asl->aslfile != NULL) return (level | EVAL_ASLFILE);
-
-       lmask = ASL_FILTER_MASK(level);
+       eval = (asl_client_get_control(asl) & EVAL_ACTION_MASK) | level;
 
        filter = asl->filter & 0xff;
        tunnel = (asl->filter & ASL_FILTER_MASK_TUNNEL) >> 8;
+       if (tunnel != 0) eval |= EVAL_TUNNEL;
 
-       if (!(asl->options & ASL_OPT_NO_REMOTE))
+       if ((asl->options & ASL_OPT_NO_REMOTE) == 0)
        {
                pthread_mutex_lock(&_asl_global.lock);
 
@@ -502,39 +543,158 @@ _asl_evaluate_send(asl_object_t client, asl_object_t m, int slevel)
                        }
                }
 
-               pthread_mutex_unlock(&_asl_global.lock);
-               /* master filter overrides local filter */
-               if (_asl_global.master_filter != 0)
+               if (_asl_global.master_filter & EVAL_ACTIVE)
                {
-                       filter = _asl_global.master_filter;
-                       tunnel = 1;
+                       /* clear bits and set according to master */
+                       eval &= ~(EVAL_SEND_ASL | EVAL_SEND_TRACE);
+                       eval |= (_asl_global.master_filter & (EVAL_SEND_ASL | EVAL_SEND_TRACE));
+                       eval |= EVAL_TUNNEL;
+
+                       if ((_asl_global.master_filter & EVAL_LEVEL_MASK) != 0) filter = _asl_global.proc_filter & EVAL_LEVEL_MASK;
                }
 
-               /* process-specific filter overrides local and master */
-               if (_asl_global.proc_filter != 0)
+               if (_asl_global.proc_filter & EVAL_ACTIVE)
                {
-                       filter = _asl_global.proc_filter;
-                       tunnel = 1;
+                       /* clear bits and set according to proc */
+                       eval &= ~(EVAL_SEND_ASL | EVAL_SEND_TRACE | EVAL_TEXT_FILE);
+                       eval |= (_asl_global.proc_filter & (EVAL_SEND_ASL | EVAL_SEND_TRACE | EVAL_TEXT_FILE));
+                       eval |= EVAL_TUNNEL;
+
+                       if ((_asl_global.proc_filter & EVAL_LEVEL_MASK) != 0) filter = _asl_global.proc_filter & EVAL_LEVEL_MASK;
                }
+
+               pthread_mutex_unlock(&_asl_global.lock);
        }
 
-       if ((filter != 0) && ((filter & lmask) != 0))
-       {
-               level |= EVAL_SEND;
-               if (tunnel != 0) level |= EVAL_TUNNEL;
-               if (asl->out_count > 0) level |= EVAL_FILE;
+       lmask = ASL_FILTER_MASK(level);
+       if ((filter != 0) && ((filter & lmask) == 0)) eval &= ~EVAL_SEND_ASL;
+       if (asl->out_count > 0) eval |= EVAL_TEXT_FILE;
 
-               return level;
+       /* don't send MessageTracer messages to Activity Tracing */
+       val = NULL;
+       if ((asl_msg_lookup(msg, ASL_KEY_MESSAGETRACER, &val, NULL) == 0) && (val != NULL))
+       {
+               eval &= ~EVAL_SEND_TRACE;
+               eval |= EVAL_MT_SHIM;
        }
 
-       if ((asl->options & ASL_OPT_SYSLOG_LEGACY) && (filter != 0) && ((filter & lmask) == 0))
+       /* don't send PowerManagement messages to Activity Tracing */
+       val = NULL;
+       if ((asl_msg_lookup(msg, ASL_KEY_POWERMANAGEMENT, &val, NULL) == 0) && (val != NULL)) eval &= ~EVAL_SEND_TRACE;
+
+       /* don't send control messages to Activity Tracing */
+       val = NULL;
+       if ((asl_msg_lookup(msg, ASL_KEY_OPTION, &val, NULL) == 0) && (val != NULL)) eval &= ~EVAL_SEND_TRACE;
+
+       /* don't send CFLog messages to Activity Tracing */
+       val = NULL;
+       if ((asl_msg_lookup(msg, ASL_KEY_CFLOG_LOCAL_TIME, &val, NULL) == 0) && (val != NULL)) eval &= ~EVAL_SEND_TRACE;
+
+       val = NULL;
+       if (((asl_msg_lookup(msg, ASL_KEY_FACILITY, &val, NULL) == 0) && (val != NULL)) ||
+               ((asl_msg_lookup(asl->kvdict, ASL_KEY_FACILITY, &val, NULL) == 0) && (val != NULL)))
        {
-               return EVAL_IGNORE;
+               /* don't send lastlog/utmp messages to Activity Tracing */
+               if (!strcmp(val, FACILITY_LASTLOG) || !strcmp(val, FACILITY_UTMPX)) eval &= ~EVAL_SEND_TRACE;
+
+               /* don't send LOG_INSTALL messages to Activity Tracing */
+               if (!strcmp(val, asl_syslog_faciliy_num_to_name(LOG_INSTALL))) eval &= ~EVAL_SEND_TRACE;
        }
 
-       if (asl->out_count > 0) return (level | EVAL_FILE);
+       return eval;
+}
+
+/*
+ * _asl_lib_vlog_text
+ * Internal routine used by asl_vlog.
+ * msg:  an asl messsage
+ * eval: log level and send flags for the message
+ * format: A formating string
+ * ap: va_list for the format
+ * returns 0 for success, non-zero for failure
+ */
 
-       return EVAL_IGNORE;
+__private_extern__ ASL_STATUS
+_asl_lib_vlog_text(asl_object_t obj, uint32_t eval, asl_object_t msg, const char *format, va_list ap)
+{
+    int saved_errno = errno;
+    int status;
+    char *str, *fmt, estr[NL_TEXTMAX];
+    uint32_t i, len, elen, expand;
+
+    if (format == NULL) return ASL_STATUS_INVALID_ARG;
+
+    /* insert strerror for %m */
+    len = 0;
+    elen = 0;
+
+    expand = 0;
+    for (i = 0; format[i] != '\0'; i++)
+    {
+        if (format[i] == '%')
+        {
+            if (format[i+1] == '\0') len++;
+            else if (format[i+1] == 'm')
+            {
+                expand = 1;
+                strerror_r(saved_errno, estr, sizeof(estr));
+                elen = strlen(estr);
+                len += elen;
+                i++;
+            }
+            else
+            {
+                len += 2;
+                i++;
+            }
+        }
+        else len++;
+    }
+
+    fmt = (char *)format;
+
+    if (expand != 0)
+    {
+        fmt = malloc(len + 1);
+        if (fmt == NULL) return ASL_STATUS_NO_MEMORY;
+
+        len = 0;
+
+        for (i = 0; format[i] != '\0'; i++)
+        {
+            if (format[i] == '%')
+            {
+                if (format[i+1] == '\0')
+                {
+                }
+                else if ((format[i+1] == 'm') && (elen != 0))
+                {
+                    memcpy(fmt+len, estr, elen);
+                    len += elen;
+                    i++;
+                }
+                else
+                {
+                    fmt[len++] = format[i++];
+                    fmt[len++] = format[i];
+                }
+            }
+            else fmt[len++] = format[i];
+        }
+        
+        fmt[len] = '\0';
+    }
+    
+    str = NULL;
+    vasprintf(&str, fmt, ap);
+    if (expand != 0) free(fmt);
+    
+    if (str == NULL) return ASL_STATUS_NO_MEMORY;
+    
+    status = _asl_send_message_text(NULL, NULL, obj, eval, (asl_msg_t *)msg, str, true);
+    free(str);
+    
+    return status;
 }
 
 /*
@@ -546,7 +706,7 @@ _asl_evaluate_send(asl_object_t client, asl_object_t m, int slevel)
  * ap: va_list for the format
  * returns 0 for success, non-zero for failure
  */
-static ASL_STATUS
+__private_extern__ ASL_STATUS
 _asl_lib_vlog(asl_object_t obj, uint32_t eval, asl_object_t msg, const char *format, va_list ap)
 {
        int saved_errno = errno;
@@ -588,11 +748,7 @@ _asl_lib_vlog(asl_object_t obj, uint32_t eval, asl_object_t msg, const char *for
        if (expand != 0)
        {
                fmt = malloc(len + 1);
-               if (fmt == NULL)
-               {
-                       if (estr != NULL) free(estr);
-                       return ASL_STATUS_NO_MEMORY;
-               }
+               if (fmt == NULL) return ASL_STATUS_NO_MEMORY;
 
                len = 0;
 
@@ -645,16 +801,37 @@ _asl_lib_vlog(asl_object_t obj, uint32_t eval, asl_object_t msg, const char *for
 int
 asl_vlog(asl_object_t client, asl_object_t msg, int level, const char *format, va_list ap)
 {
+       ASL_STATUS status = ASL_STATUS_OK;
        uint32_t eval = _asl_evaluate_send(client, msg, level);
-       if (eval == EVAL_IGNORE) return 0;
+       void *addr = __builtin_return_address(0);
+
+       if ((eval & EVAL_SEND_TRACE) && os_log_shim_enabled(addr))
+       {
+               va_list ap_copy;
+               if (level < ASL_LEVEL_EMERG) level = ASL_LEVEL_EMERG;
+               if (level > ASL_LEVEL_DEBUG) level = ASL_LEVEL_DEBUG;
+               os_log_type_t type = shim_asl_to_log_type[level];
+
+               va_copy(ap_copy, ap);
+               os_log_with_args(OS_LOG_DEFAULT, type, format, ap_copy, addr);
+               va_end(ap_copy);
+
+               if (eval & EVAL_TEXT_FILE)
+               {
+                       status = _asl_lib_vlog_text(client, eval, msg, format, ap);
+               }
+       }
+       else if (eval & EVAL_ASL)
+       {
+               status = _asl_lib_vlog(client, eval, msg, format, ap);
+       }
 
-       ASL_STATUS status = _asl_lib_vlog(client, eval, msg, format, ap);
        return (status == ASL_STATUS_OK) ? 0 : -1;
 }
 
 /*
  * _asl_lib_log
- * SPI used by ASL_PREFILTER_LOG. Converts format arguments to a va_list and
+ * SPI used by legacy (non-shim) ASL_PREFILTER_LOG. Converts format arguments to a va_list and
  * forwards the call to _asl_lib_vlog.
  * msg:  an asl message
  * eval: log level and send flags for the message
@@ -665,13 +842,16 @@ asl_vlog(asl_object_t client, asl_object_t msg, int level, const char *format, v
 int
 _asl_lib_log(asl_object_t client, uint32_t eval, asl_object_t msg, const char *format, ...)
 {
-       int status;
-       if (eval == EVAL_IGNORE) return 0;
+       int status = 0;
 
-       va_list ap;
-       va_start(ap, format);
-       status = _asl_lib_vlog(client, eval, msg, format, ap);
-       va_end(ap);
+       if (eval & EVAL_ASL)
+       {
+               va_list ap;
+
+               va_start(ap, format);
+               status = _asl_lib_vlog(client, eval, msg, format, ap);
+               va_end(ap);
+       }
 
        return status;
 }
@@ -688,14 +868,36 @@ _asl_lib_log(asl_object_t client, uint32_t eval, asl_object_t msg, const char *f
 int
 asl_log(asl_object_t client, asl_object_t msg, int level, const char *format, ...)
 {
-       ASL_STATUS status;
+       ASL_STATUS status = ASL_STATUS_OK;
        uint32_t eval = _asl_evaluate_send(client, msg, level);
-       if (eval == EVAL_IGNORE) return 0;
+       void *addr = __builtin_return_address(0);
 
-       va_list ap;
-       va_start(ap, format);
-       status = _asl_lib_vlog(client, eval, msg, format, ap);
-       va_end(ap);
+       if ((eval & EVAL_SEND_TRACE) && os_log_shim_enabled(addr))
+       {
+               va_list ap;
+               if (level < ASL_LEVEL_EMERG) level = ASL_LEVEL_EMERG;
+               if (level > ASL_LEVEL_DEBUG) level = ASL_LEVEL_DEBUG;
+               os_log_type_t type = shim_asl_to_log_type[level];
+
+               va_start(ap, format);
+               os_log_with_args(OS_LOG_DEFAULT, type, format, ap, addr);
+               va_end(ap);
+
+               if (eval & EVAL_TEXT_FILE)
+               {
+                       va_list ap;
+                       va_start(ap, format);
+                       status = _asl_lib_vlog_text(client, eval, msg, format, ap);
+                       va_end(ap);
+               }
+       }
+       else if (eval & EVAL_ASL)
+       {
+               va_list ap;
+               va_start(ap, format);
+               status = _asl_lib_vlog(client, eval, msg, format, ap);
+               va_end(ap);
+       }
 
        return (status == ASL_STATUS_OK) ? 0 : -1;
 }
@@ -711,14 +913,36 @@ asl_log(asl_object_t client, asl_object_t msg, int level, const char *format, ..
 int
 asl_log_message(int level, const char *format, ...)
 {
-       int status;
+       ASL_STATUS status = ASL_STATUS_OK;
        uint32_t eval = _asl_evaluate_send(NULL, NULL, level);
-       if (eval == EVAL_IGNORE) return 0;
+       void *addr = __builtin_return_address(0);
 
-       va_list ap;
-       va_start(ap, format);
-       status = _asl_lib_vlog(NULL, eval, NULL, format, ap);
-       va_end(ap);
+       if ((eval & EVAL_SEND_TRACE) && os_log_shim_enabled(addr))
+       {
+               va_list ap;
+               if (level < ASL_LEVEL_EMERG) level = ASL_LEVEL_EMERG;
+               if (level > ASL_LEVEL_DEBUG) level = ASL_LEVEL_DEBUG;
+               os_log_type_t type = shim_asl_to_log_type[level];
+
+               va_start(ap, format);
+               os_log_with_args(OS_LOG_DEFAULT, type, format, ap, addr);
+               va_end(ap);
+
+               if (eval & EVAL_TEXT_FILE)
+               {
+                       va_list ap;
+                       va_start(ap, format);
+                       status = _asl_lib_vlog_text(NULL, eval, NULL, format, ap);
+                       va_end(ap);
+               }
+       }
+       else if (eval & EVAL_ASL)
+       {
+               va_list ap;
+               va_start(ap, format);
+               status = _asl_lib_vlog(NULL, eval, NULL, format, ap);
+               va_end(ap);
+       }
 
        return (status == ASL_STATUS_OK) ? 0 : -1;
 }
@@ -746,7 +970,7 @@ asl_get_filter(asl_object_t client, int *local, int *master, int *remote, int *a
 
        asl = (asl_client_t *)client;
        if (asl == NULL) asl = asl_default;
-       if (asl != NULL) l = asl->filter & 0xff;
+       if (asl != NULL) l = asl->filter & EVAL_LEVEL_MASK;
 
        if ((asl_default != NULL) && (!(asl_default->options & ASL_OPT_NO_REMOTE)))
        {
@@ -792,19 +1016,46 @@ asl_get_filter(asl_object_t client, int *local, int *master, int *remote, int *a
        return 0;
 }
 
+/* SPI for SHIM control */
+uint32_t
+asl_set_local_control(asl_object_t client, uint32_t filter)
+{
+       asl_client_t *asl = (asl_client_t *)client;
+       if (asl == NULL)
+       {
+               asl = _asl_open_default();
+               if (asl == NULL) return UINT32_MAX;
+       }
+       else if (asl_get_type(client) != ASL_TYPE_CLIENT) return UINT32_MAX;
+
+       return asl_client_set_control(asl, filter);
+}
+
+uint32_t
+asl_get_local_control(asl_object_t client)
+{
+       asl_client_t *asl = (asl_client_t *)client;
+       if (asl == NULL)
+       {
+               asl = _asl_open_default();
+               if (asl == NULL) return UINT32_MAX;
+       }
+       else if (asl_get_type(client) != ASL_TYPE_CLIENT) return UINT32_MAX;
+
+       return asl_client_get_control(asl);
+}
+
 /*
- * Sets Host, PID, UID, GID, and OSActivityID values in a new message.
+ * Sets PID and OSActivityID values in a new message.
  * Also sets Level, Time, TimeNanoSec, Sender, Facility and Message if provided.
  */
 asl_msg_t *
 asl_base_msg(asl_client_t *asl, uint32_t level, const struct timeval *tv, const char *sstr, const char *fstr, const char *mstr)
 {
        char aux_val[64];
-       char aux_host[_POSIX_HOST_NAME_MAX];
        asl_msg_t *aux;
        int status;
-       unsigned int osacount = 1;
-       os_activity_t osaid = 0;
+       os_activity_id_t osaid;
 
        aux = asl_msg_new(ASL_TYPE_MSG);
        if (aux == NULL) return NULL;
@@ -815,7 +1066,7 @@ asl_base_msg(asl_client_t *asl, uint32_t level, const struct timeval *tv, const
        /* Time and TimeNanoSec */
        if (tv != NULL)
        {
-               snprintf(aux_val, sizeof(aux_val), "%lu", tv->tv_sec);
+               snprintf(aux_val, sizeof(aux_val), "%llu", (unsigned long long) tv->tv_sec);
                asl_msg_set_key_val(aux, ASL_KEY_TIME, aux_val);
 
                snprintf(aux_val, sizeof(aux_val), "%d", tv->tv_usec * 1000);
@@ -825,31 +1076,20 @@ asl_base_msg(asl_client_t *asl, uint32_t level, const struct timeval *tv, const
        /* Message */
        if (mstr != NULL) asl_msg_set_key_val(aux, ASL_KEY_MSG, mstr);
 
-       /* Host */
-       memset(&aux_host, 0, _POSIX_HOST_NAME_MAX);
-       if (gethostname(aux_host, _POSIX_HOST_NAME_MAX) == 0) asl_msg_set_key_val(aux, ASL_KEY_HOST, aux_host);
-
        /* PID */
        snprintf(aux_val, sizeof(aux_val), "%u", getpid());
        asl_msg_set_key_val(aux, ASL_KEY_PID, aux_val);
 
-       /* UID */
-       snprintf(aux_val, sizeof(aux_val), "%d", getuid());
-       asl_msg_set_key_val(aux, ASL_KEY_UID, aux_val);
-
-       /* GID */
-       snprintf(aux_val, sizeof(aux_val), "%d", getgid());
-       asl_msg_set_key_val(aux, ASL_KEY_GID, aux_val);
-
        /* OSActivityID */
-       if (os_activity_get_active(&osaid, &osacount) == 1)
+       osaid = os_activity_get_identifier(OS_ACTIVITY_CURRENT, NULL);
+       if (osaid)
        {
-               snprintf(aux_val, sizeof(aux_val), "0x%016llx", (uint64_t)osaid);
+               snprintf(aux_val, sizeof(aux_val), "0x%016llx", osaid);
                asl_msg_set_key_val(aux, ASL_KEY_OS_ACTIVITY_ID, aux_val);
        }
 
        /* Sender */
-       if (sstr == NULL)
+       if ((sstr == NULL) && (asl != NULL))
        {
                /* See if the client has a value for ASL_KEY_SENDER */
                status = asl_msg_lookup((asl_msg_t *)asl->kvdict, ASL_KEY_SENDER, &sstr, NULL);
@@ -883,7 +1123,7 @@ asl_base_msg(asl_client_t *asl, uint32_t level, const struct timeval *tv, const
        if (sstr != NULL) asl_msg_set_key_val(aux, ASL_KEY_SENDER, sstr);
 
        /* Facility */
-       if (fstr == NULL)
+       if ((fstr == NULL) && (asl != NULL))
        {
                status = asl_msg_lookup((asl_msg_t *)asl->kvdict, ASL_KEY_FACILITY, &fstr, NULL);
                if (status != 0) fstr = NULL;
@@ -944,10 +1184,119 @@ asl_prepared_message(asl_client_t *asl, asl_msg_t *msg)
 }
 #endif
 
+static void
+_asl_set_option(asl_msg_t *msg, const char *opt)
+{
+       const char *val = NULL;
+       uint32_t status;
+
+       if (msg == NULL) return;
+       if (opt == NULL) return;
+
+       status = asl_msg_lookup(msg, ASL_KEY_OPTION, &val, NULL);
+       if ((status != 0) || (val == NULL))
+       {
+               asl_msg_set_key_val(msg, ASL_KEY_OPTION, opt);
+       }
+       else
+       {
+               char *option = NULL;
+               asprintf(&option, "%s %s", opt, val);
+               asl_msg_set_key_val(msg, ASL_KEY_OPTION, option);
+               free(option);
+       }
+}
+
+static ASL_STATUS
+_asl_send_message_text(asl_client_t *asl, asl_msg_t *sendmsg, asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *mstr, bool shimmed)
+{
+    int status;
+    uint32_t level, lmask;
+    asl_msg_t *release_sendmsg = NULL;
+
+    if (asl == NULL) {
+        if (obj == NULL) {
+            asl = _asl_open_default();
+            if (asl == NULL) return ASL_STATUS_FAILED;
+         } else {
+            uint32_t objtype = asl_get_type(obj);
+            if (objtype == ASL_TYPE_CLIENT) asl = (asl_client_t *)obj;
+        }
+    }
+
+    level = eval & EVAL_LEVEL_MASK;
+    if (level > 7) level = 7;
+    lmask = ASL_FILTER_MASK(level);
+
+    if (sendmsg == NULL) {
+        struct timeval tval = {0, 0};
+        const char *sstr, *fstr;
+
+        status = gettimeofday(&tval, NULL);
+        if (status != 0) {
+            time_t tick = time(NULL);
+            tval.tv_sec = tick;
+            tval.tv_usec = 0;
+        }
+
+        sstr = NULL;
+        status = asl_msg_lookup(msg, ASL_KEY_SENDER, &sstr, NULL);
+        if (status != 0) {
+            sstr = NULL;
+        }
+
+        fstr = NULL;
+        status = asl_msg_lookup(msg, ASL_KEY_FACILITY, &fstr, NULL);
+        if (status != 0) {
+            fstr = NULL;
+        }
+        sendmsg = asl_base_msg(asl, level, &tval, sstr, fstr, mstr);
+        if (sendmsg == NULL) {
+            return ASL_STATUS_FAILED;
+        }
+
+        release_sendmsg = sendmsg = asl_msg_merge(sendmsg, msg);
+    }
+
+    /* write to file descriptors */
+    for (uint32_t i = 0; i < asl->out_count; i++) {
+        if (shimmed) {
+            if ((asl->out_list[i].fd != STDOUT_FILENO) && (asl->out_list[i].fd != STDERR_FILENO)) {
+                continue; // new logging only support stdout/stderr
+            }
+        }
+
+        if ((asl->out_list[i].fd >= 0) && (asl->out_list[i].filter != 0) && ((asl->out_list[i].filter & lmask) != 0)) {
+            char *str;
+
+            uint32_t len = 0;
+            str = asl_format_message(sendmsg, asl->out_list[i].mfmt, asl->out_list[i].tfmt, asl->out_list[i].encoding, &len);
+            if (str == NULL) continue;
+
+            status = write(asl->out_list[i].fd, str, len - 1);
+            if (status < 0)
+            {
+                /* soft error for fd 2 (stderr) */
+                if (asl->out_list[i].fd == 2) status = 0;
+                asl->out_list[i].fd = -1;
+            } else {
+                status = 0;
+            }
+            
+            free(str);
+        }
+    }
+    if (release_sendmsg) {
+        asl_msg_release(release_sendmsg);
+    }
+
+    return status;
+}
+
 static ASL_STATUS
 _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *mstr)
 {
-       uint32_t i, len, level, lmask, outstatus, objtype;
+       uint32_t len, level, lmask, outstatus, objtype;
        const char *sstr, *fstr;
        struct timeval tval = {0, 0};
        int status;
@@ -957,8 +1306,9 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
        asl_msg_t *qd_msg = NULL;
        asl_client_t *asl = NULL;
        static dispatch_once_t noquota_once;
+       __block int log_quota_msg = 0;
 
-       if (eval == EVAL_IGNORE) return ASL_STATUS_OK;
+       if ((eval & EVAL_ASL) == 0) return ASL_STATUS_OK;
 
        if (obj == NULL)
        {
@@ -971,12 +1321,10 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
        {
                objtype = asl_get_type(obj);
                if (objtype == ASL_TYPE_CLIENT) asl = (asl_client_t *)obj;
-               else asl = _asl_open_default();
        }
 
-       level = eval & LEVEL_MASK;
+       level = eval & EVAL_LEVEL_MASK;
        if (level > 7) level = 7;
-       eval &= EVAL_MASK;
        lmask = ASL_FILTER_MASK(level);
 
        if ((objtype == ASL_TYPE_CLIENT) && (asl->aslfile != NULL)) use_global_lock = 1;
@@ -1001,22 +1349,7 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
        if (sendmsg == NULL) return ASL_STATUS_FAILED;
 
        /* Set "ASLOption store" if tunneling */
-       if (eval & EVAL_TUNNEL)
-       {
-               const char *val = NULL;
-               status = asl_msg_lookup(msg, ASL_KEY_OPTION, &val, NULL);
-               if ((status != 0) || (val == NULL))
-               {
-                       asl_msg_set_key_val(sendmsg, ASL_KEY_OPTION, ASL_OPT_STORE);
-               }
-               else
-               {
-                       char *option = NULL;
-                       asprintf(&option, "%s %s", ASL_OPT_STORE, val);
-                       asl_msg_set_key_val(sendmsg, ASL_KEY_OPTION, option);
-                       free(option);
-               }
-       }
+       if (eval & EVAL_TUNNEL) _asl_set_option(sendmsg, ASL_OPT_STORE);
 
        outstatus = -1;
 
@@ -1052,7 +1385,7 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
                return outstatus;
        }
 
-       _asl_global_init(0);
+       _asl_global_init();
        outstatus = 0;
 
        /*
@@ -1062,28 +1395,44 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
         * - Environment variable ASL_QUOTA_DISABLED == 1
         * - /etc/asl/.noquota existed at the time that the process started
         *
-        * Note that we just check /etc/asl/.noquota once, since it would be
+        * We just check /etc/asl/.noquota once, since it would be
         * expensive to stat() for every log message.
+        *
+        * We only check the Environment variable once, since getenv() is
+        * not thread safe.  If someone is changing the environment,
+        * this can crash.
         */
-       
+
        dispatch_once(&noquota_once, ^{
                struct stat sb;
                memset(&sb, 0, sizeof(struct stat));
-               if (stat(NOQUOTA_FILE_PATH, &sb) == 0) _asl_global.quota = UINT32_MAX;
-       });
-       
-       if (_asl_global.quota != UINT32_MAX)
-       {
-               const char *qtest = getenv(NOQUOTA_ENV);
-               if ((qtest != NULL) && (!strcmp(qtest, "1")))
+
+               int save_errno = errno;
+
+               if (stat(NOQUOTA_FILE_PATH, &sb) == 0)
                {
                        _asl_global.quota = UINT32_MAX;
-
-                       qd_msg = asl_base_msg(asl, QUOTA_LEVEL, &tval, sstr, fstr, QUOTA_DISABLED_MSG);
-                       asl_msg_set_key_val(qd_msg, ASL_KEY_OPTION, ASL_OPT_STORE);
                }
+               else
+               {
+                       const char *qtest = getenv(NOQUOTA_ENV);
+                       if ((qtest != NULL) && (!strcmp(qtest, "1")))
+                       {
+                               _asl_global.quota = UINT32_MAX;
+                               log_quota_msg = 1;
+                       }
+               }
+
+               /* reset errno since we want stat() to fail silently */
+               errno = save_errno;
+       });
+
+       if (log_quota_msg != 0)
+       {
+               qd_msg = asl_base_msg(asl, QUOTA_LEVEL, &tval, sstr, fstr, QUOTA_DISABLED_MSG);
+               asl_msg_set_key_val(qd_msg, ASL_KEY_OPTION, ASL_OPT_STORE);
        }
-       
+
        if (((eval & EVAL_TUNNEL) == 0) && (_asl_global.quota != UINT32_MAX))
        {
                time_t last_send = _asl_global.last_send;
@@ -1115,7 +1464,7 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
                        }
                        else
                        {
-                               eval &= ~EVAL_SEND;
+                               eval &= ~EVAL_SEND_ASL;
                        }
                }
                else
@@ -1124,7 +1473,14 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
                }
        }
 
-       if ((_asl_global.server_port != MACH_PORT_NULL) && (eval & EVAL_SEND))
+#if TARGET_OS_OSX
+       if (eval & EVAL_MT_SHIM)
+       {
+               _asl_mt_shim_send_message(sendmsg);
+       }
+#endif
+
+       if ((_asl_global.server_port != MACH_PORT_NULL) && (eval & EVAL_SEND_ASL))
        {
                asl_string_t *send_str;
                const char *str;
@@ -1142,13 +1498,45 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
                        len = asl_string_length(send_str);
                        vmsize = asl_string_allocated_size(send_str);
                        str = asl_string_release_return_bytes(send_str);
-                       if (len != 0) kstatus = _asl_server_message(_asl_global.server_port, (caddr_t)str, len);
-                       if ((str != NULL) && (vmsize != 0)) vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize);
+                       if (len != 0)
+                       {
+                               kstatus = _asl_server_message(_asl_global.server_port, (caddr_t)str, len);
+                               if (kstatus != KERN_SUCCESS)
+                               {
+                                       vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize);
+                               }
+                       }
+                       else if (vmsize != 0)
+                       {
+                               vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize);
+                       }
                        asl_msg_release(qd_msg);
                }
-       
+
                send_str = asl_msg_to_string_raw(ASL_STRING_MIG, sendmsg, "raw");
                len = asl_string_length(send_str);
+
+               if (len > LIBASL_MAX_MSG_SIZE)
+               {
+                       char tmp[256];
+
+                       snprintf(tmp, sizeof(tmp), SIZE_LIMIT_MSG, len, LIBASL_MAX_MSG_SIZE);
+                       asl_msg_t *limitmsg = asl_base_msg(asl, ASL_LEVEL_CRIT, &tval, sstr, fstr, tmp);
+
+                       asl_string_release(send_str);
+                       len = 0;
+
+                       if (limitmsg != NULL)
+                       {
+                               /* Set "ASLOption store" if tunneling */
+                               if (eval & EVAL_TUNNEL) _asl_set_option(limitmsg, ASL_OPT_STORE);
+
+                               send_str = asl_msg_to_string_raw(ASL_STRING_MIG, limitmsg, "raw");
+                               len = asl_string_length(send_str);
+                               asl_msg_release(limitmsg);
+                       }
+               }
+
                vmsize = asl_string_allocated_size(send_str);
                str = asl_string_release_return_bytes(send_str);
 
@@ -1158,14 +1546,8 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
                        kstatus = _asl_server_message(_asl_global.server_port, (caddr_t)str, len);
                        if (kstatus != KERN_SUCCESS)
                        {
-                               /* retry once if the call failed */
-                               _asl_global_init(1);
-                               kstatus = _asl_server_message(_asl_global.server_port, (caddr_t)str, len);
-                               if (kstatus != KERN_SUCCESS)
-                               {
-                                       vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize);
-                                       outstatus = -1;
-                               }
+                               vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize);
+                               outstatus = -1;
                        }
                }
                else if (vmsize >0) vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize);
@@ -1173,28 +1555,7 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
 
        if ((sendmsg != NULL) && (asl->out_count > 0))
        {
-               /* write to file descriptors */
-               for (i = 0; i < asl->out_count; i++)
-               {
-                       if ((asl->out_list[i].fd >= 0) && (asl->out_list[i].filter != 0) && ((asl->out_list[i].filter & lmask) != 0))
-                       {
-                               char *str;
-
-                               len = 0;
-                               str = asl_format_message(sendmsg, asl->out_list[i].mfmt, asl->out_list[i].tfmt, asl->out_list[i].encoding, &len);
-                               if (str == NULL) continue;
-
-                               status = write(asl->out_list[i].fd, str, len - 1);
-                               if (status < 0)
-                               {
-                                       /* soft error for fd 2 (stderr) */
-                                       if (asl->out_list[i].fd != 2) outstatus = -1;
-                                       asl->out_list[i].fd = -1;
-                               }
-
-                               free(str);
-                       }
-               }
+               status = _asl_send_message_text(asl, sendmsg, obj, eval, msg, mstr, false);
        }
 
        asl_msg_release(sendmsg);
@@ -1204,6 +1565,19 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
        return outstatus;
 }
 
+static void
+os_log_with_args_wrapper(void *addr, int level, const char *format, ...)
+{
+       va_list ap;
+       if (level < ASL_LEVEL_EMERG) level = ASL_LEVEL_EMERG;
+       if (level > ASL_LEVEL_DEBUG) level = ASL_LEVEL_DEBUG;
+       os_log_type_t type = shim_asl_to_log_type[level];
+
+       va_start(ap, format);
+       os_log_with_args(OS_LOG_DEFAULT, type, format, ap, addr);
+       va_end(ap);
+}
+
 /*
  * asl_send: send a message 
  * This routine may be used instead of asl_log() or asl_vlog() if asl_set()
@@ -1213,11 +1587,36 @@ _asl_send_message(asl_object_t obj, uint32_t eval, asl_msg_t *msg, const char *m
  * returns 0 for success, non-zero for failure
  */
 __private_extern__ ASL_STATUS
-asl_client_internal_send(asl_object_t obj, asl_object_t msg)
+asl_client_internal_send(asl_object_t obj, asl_object_t msg, void *addr)
 {
        int status = ASL_STATUS_OK;
        uint32_t eval = _asl_evaluate_send(obj, msg, -1);
-       if (eval != 0) status = _asl_send_message(obj, eval, (asl_msg_t *)msg, NULL);
+
+       const char *message = asl_msg_get_val_for_key((asl_msg_t *)msg, ASL_KEY_MSG);
+
+       if ((eval & EVAL_SEND_TRACE) && message && message[0] && os_log_shim_enabled(addr))
+       {
+               int level = ASL_LEVEL_DEBUG;
+               const char *lval = asl_msg_get_val_for_key((asl_msg_t *)msg, ASL_KEY_LEVEL);
+               if (lval != NULL) level = atoi(lval);
+
+               /*
+                * If the return address and the format string are from different
+                * binaries, os_log_with_args will not record the return address.
+                * Work around this by passing a dynamic format string.
+                */
+               char dynamic_format[] = "%s";
+               os_log_with_args_wrapper(addr, level, dynamic_format, message);
+
+               if (eval & EVAL_TEXT_FILE)
+               {
+                       status = _asl_send_message_text(NULL, NULL, obj, eval, (asl_msg_t *)msg, NULL, true);
+               }
+       }
+       else if (eval & EVAL_ASL)
+       {
+               status = _asl_send_message(obj, eval, (asl_msg_t *)msg, NULL);
+       }
 
        return status;
 }
@@ -1359,7 +1758,7 @@ _asl_auxiliary(asl_msg_t *msg, const char *title, const char *uti, const char *u
                return ASL_STATUS_OK;
        }
 
-       _asl_global_init(0);
+       _asl_global_init();
        if (_asl_global.server_port == MACH_PORT_NULL) return ASL_STATUS_FAILED;
 
        send_str = asl_msg_to_string_raw(ASL_STRING_MIG, aux, "raw");
@@ -1381,15 +1780,9 @@ _asl_auxiliary(asl_msg_t *msg, const char *title, const char *uti, const char *u
        kstatus = _asl_server_create_aux_link(_asl_global.server_port, (caddr_t)str, len, &fileport, &newurl, &newurllen, &status);
        if (kstatus != KERN_SUCCESS)
        {
-               /* retry once if the call failed */
-               _asl_global_init(1);
-               kstatus = _asl_server_create_aux_link(_asl_global.server_port, (caddr_t)str, len, &fileport, &newurl, &newurllen, &status);
-               if (kstatus != KERN_SUCCESS)
-               {
-                       vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize);
-                       asl_msg_release(aux);
-                       return ASL_STATUS_FAILED;
-               }
+               vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize);
+               asl_msg_release(aux);
+               return ASL_STATUS_FAILED;
        }
 
        if (status != 0)
@@ -1542,7 +1935,7 @@ _asl_server_control_query(void)
        asl_msg_t *m = NULL;
        static const char ctlstr[] = "1\nQ [= ASLOption control]\n";
 
-       _asl_global_init(0);
+       _asl_global_init();
        if (_asl_global.server_port == MACH_PORT_NULL) return NULL;
 
        len = strlen(ctlstr) + 1;
@@ -1552,19 +1945,14 @@ _asl_server_control_query(void)
        res = NULL;
        reslen = 0;
 
-       kstatus = vm_allocate(mach_task_self(), (vm_address_t *)&vmstr, len, TRUE);
+       kstatus = vm_allocate(mach_task_self(), (vm_address_t *)&vmstr, len, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_ASL));
        if (kstatus != KERN_SUCCESS) return NULL;
 
        memmove(vmstr, ctlstr, len);
 
        status = 0;
        kstatus = _asl_server_query_2(_asl_global.server_port, vmstr, len, qmin, FETCH_BATCH, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status);
-       if (kstatus != KERN_SUCCESS)
-       {
-               /* retry once if the call failed */
-               _asl_global_init(1);
-               kstatus = _asl_server_query_2(_asl_global.server_port, vmstr, len, qmin, FETCH_BATCH, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status);
-       }
+       if (kstatus != KERN_SUCCESS) return NULL;
 
        list = asl_msg_list_from_string(res);
        vm_deallocate(mach_task_self(), (vm_address_t)res, reslen);
@@ -1586,7 +1974,7 @@ asl_store_location()
        uint32_t reslen, status;
        uint64_t cmax;
 
-       _asl_global_init(0);
+       _asl_global_init();
        if (_asl_global.server_port == MACH_PORT_NULL) return ASL_STORE_LOCATION_FILE;
 
        res = NULL;
@@ -1595,17 +1983,11 @@ asl_store_location()
        status = ASL_STATUS_OK;
 
        kstatus = _asl_server_query_2(_asl_global.server_port, NULL, 0, 0, -1, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status);
-       if (kstatus != KERN_SUCCESS)
-       {
-               /* retry once if the call failed */
-               _asl_global_init(1);
-               kstatus = _asl_server_query_2(_asl_global.server_port, NULL, 0, 0, -1, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status);
-       }
+       if (kstatus != KERN_SUCCESS) return ASL_STORE_LOCATION_FILE;
 
        /* res should never be returned, but just to be certain we don't leak VM ... */
        if (res != NULL) vm_deallocate(mach_task_self(), (vm_address_t)res, reslen);
 
-       if (kstatus != KERN_SUCCESS) return ASL_STORE_LOCATION_FILE;
        if (status == ASL_STATUS_OK) return ASL_STORE_LOCATION_MEMORY;
        return ASL_STORE_LOCATION_FILE;
 }
@@ -1655,7 +2037,7 @@ asl_open_path(const char *path, uint32_t opts)
                        if (opts & ASL_OPT_CREATE_STORE)
                        {
                                if (asl_store_open_write(path, &sout) != ASL_STATUS_OK) return NULL;
-                               return (asl_object_t)fout;
+                               return (asl_object_t)sout;
                        }
                        else
                        {