]> git.saurik.com Git - apple/syslog.git/blobdiff - syslogd.tproj/syslogd.c
syslog-356.50.1.tar.gz
[apple/syslog.git] / syslogd.tproj / syslogd.c
index 0d79fd88ece39b199f9de871d7737ce89c4c87f6..2d45dc5839118d943a4385695ccfa8934f05b0c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
 
+#include <TargetConditionals.h>
+
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-#include <signal.h>
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 #include <mach/mach_time.h>
 #include <notify.h>
 #include <notify_keys.h>
 #include <utmpx.h>
-#include <vproc_priv.h>
+#include <asl_private.h>
+
+#if !TARGET_OS_IPHONE
+#include <quarantine.h>
+#endif
 #include "daemon.h"
 
 #define SERVICE_NAME "com.apple.system.logger"
 
 #define NOTIFY_DELAY 1
 
-#define streq(A,B) (strcmp(A,B)==0)
-#define forever for(;;)
-
-extern int __notify_78945668_info__;
 extern int _malloc_no_asl_log;
 
+#if TARGET_IPHONE_SIMULATOR
+const char *_path_pidfile;
+const char *_path_syslogd_log;
+#endif
+
 /* global */
 struct global_s global;
 
+#if !TARGET_IPHONE_SIMULATOR
 /* Input Modules */
 int klog_in_init(void);
 int klog_in_reset(void);
 int klog_in_close(void);
 static int activate_klog_in = 1;
+#endif
 
 int bsd_in_init(void);
 int bsd_in_reset(void);
 int bsd_in_close(void);
 static int activate_bsd_in = 1;
 
+#if !TARGET_IPHONE_SIMULATOR
 int udp_in_init(void);
 int udp_in_reset(void);
 int udp_in_close(void);
@@ -89,25 +99,31 @@ int bsd_out_init(void);
 int bsd_out_reset(void);
 int bsd_out_close(void);
 static int activate_bsd_out = 1;
+#endif
 
 int asl_action_init(void);
 int asl_action_reset(void);
 int asl_action_close(void);
 static int activate_asl_action = 1;
 
+#if !TARGET_IPHONE_SIMULATOR
 /* Interactive Module */
 int remote_init(void);
 int remote_reset(void);
 int remote_close(void);
 static int remote_enabled = 0;
+#endif
 
 extern void database_server();
 
 static void
 init_modules()
 {
-       module_t *m_klog_in, *m_bsd_in, *m_bsd_out, *m_udp_in;
-       module_t *m_asl, *m_remote;
+#if !TARGET_IPHONE_SIMULATOR
+       module_t *m_klog_in, *m_bsd_out, *m_udp_in, *m_remote;
+#endif
+       module_t *m_asl, *m_bsd_in;
+       int m = 0;
 
        /* ASL module (configured by /etc/asl.conf) */
        m_asl = (module_t *)calloc(1, sizeof(module_t));
@@ -125,6 +141,7 @@ init_modules()
 
        if (m_asl->enabled) m_asl->init();
 
+#if !TARGET_IPHONE_SIMULATOR
        /* BSD output module (configured by /etc/syslog.conf) */
        m_bsd_out = (module_t *)calloc(1, sizeof(module_t));
        if (m_bsd_out == NULL)
@@ -160,6 +177,7 @@ init_modules()
        m_klog_in->close = klog_in_close;
 
        if (m_klog_in->enabled) m_klog_in->init();
+#endif
 
        /* BSD (UNIX domain socket) input module */
        m_bsd_in = (module_t *)calloc(1, sizeof(module_t));
@@ -177,6 +195,7 @@ init_modules()
 
        if (m_bsd_in->enabled) m_bsd_in->init();
 
+#if !TARGET_IPHONE_SIMULATOR
        /* network (syslog protocol) input module */
        m_udp_in = (module_t *)calloc(1, sizeof(module_t));
        if (m_udp_in == NULL)
@@ -208,9 +227,14 @@ init_modules()
        m_remote->close = remote_close;
 
        if (m_remote->enabled) m_remote->init();
+#endif /* TARGET_IPHONE_SIMULATOR */
 
        /* save modules in global.module array */
+#if TARGET_IPHONE_SIMULATOR
+       global.module_count = 2;
+#else
        global.module_count = 6;
+#endif
        global.module = (module_t **)calloc(global.module_count, sizeof(module_t *));
        if (global.module == NULL)
        {
@@ -218,12 +242,14 @@ init_modules()
                exit(1);
        }
 
-       global.module[0] = m_asl;
-       global.module[1] = m_bsd_out;
-       global.module[2] = m_klog_in;
-       global.module[3] = m_bsd_in;
-       global.module[4] = m_udp_in;
-       global.module[5] = m_remote;
+       global.module[m++] = m_asl;
+       global.module[m++] = m_bsd_in;
+#if !TARGET_IPHONE_SIMULATOR
+       global.module[m++] = m_bsd_out;
+       global.module[m++] = m_klog_in;
+       global.module[m++] = m_udp_in;
+       global.module[m++] = m_remote;
+#endif
 }
 
 static void
@@ -231,9 +257,6 @@ writepid(int *first)
 {
        struct stat sb;
        FILE *fp;
-       pid_t pid = getpid();
-
-       asldebug("\nsyslogd %d start\n", pid);
 
        if (first != NULL)
        {
@@ -248,7 +271,7 @@ writepid(int *first)
        fp = fopen(_PATH_PIDFILE, "w");
        if (fp != NULL)
        {
-               fprintf(fp, "%d\n", pid);
+               fprintf(fp, "%d\n", global.pid);
                fclose(fp);
        }
 }
@@ -265,21 +288,21 @@ launch_config()
 
        if (global.launch_dict == NULL)
        {
-               asldebug("%d launchd checkin failed\n", getpid());
+               asldebug("%d launchd checkin failed\n", global.pid);
                exit(1);
        }
 
        tmp = launch_data_dict_lookup(global.launch_dict, LAUNCH_JOBKEY_MACHSERVICES);
        if (tmp == NULL)
        {
-               asldebug("%d launchd lookup of LAUNCH_JOBKEY_MACHSERVICES failed\n", getpid());
+               asldebug("%d launchd lookup of LAUNCH_JOBKEY_MACHSERVICES failed\n", global.pid);
                exit(1);
        }
 
        pdict = launch_data_dict_lookup(tmp, SERVICE_NAME);
        if (pdict == NULL)
        {
-               asldebug("%d launchd lookup of SERVICE_NAME failed\n", getpid());
+               asldebug("%d launchd lookup of SERVICE_NAME failed\n", global.pid);
                exit(1);
        }
 
@@ -329,7 +352,7 @@ config_debug(int enable, const char *path)
 }
 
 void
-config_data_store(int type, uint32_t file_max, uint32_t memory_max, uint32_t mini_max)
+config_data_store(int type, uint32_t file_max, uint32_t memory_max, uint32_t str_memory_max)
 {
        pthread_mutex_lock(global.db_lock);
 
@@ -345,16 +368,10 @@ config_data_store(int type, uint32_t file_max, uint32_t memory_max, uint32_t min
                global.memory_db = NULL;
        }
 
-       if (global.dbtype & DB_TYPE_MINI)
-       {
-               asl_mini_memory_close(global.mini_db);
-               global.mini_db = NULL;
-       }
-
        global.dbtype = type;
        global.db_file_max = file_max;
        global.db_memory_max = memory_max;
-       global.db_mini_max = mini_max;
+       global.db_memory_str_max = str_memory_max;
 
        pthread_mutex_unlock(global.db_lock);
 }
@@ -362,80 +379,120 @@ config_data_store(int type, uint32_t file_max, uint32_t memory_max, uint32_t min
 void
 write_boot_log(int first)
 {
-    int mib[2] = {CTL_KERN, KERN_BOOTTIME};
+       int mib[2] = {CTL_KERN, KERN_BOOTTIME};
        size_t len;
-       aslmsg msg;
+       asl_msg_t *msg;
        char buf[256];
-    struct utmpx utx;
+       struct utmpx utx;
 
        if (first == 0)
        {
                /* syslogd restart */
-               msg = asl_new(ASL_TYPE_MSG);
+               msg = asl_msg_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 ---");
-               dispatch_async(global.work_queue, ^{ process_message(msg, SOURCE_INTERNAL); });
+               asl_msg_set_key_val(msg, ASL_KEY_SENDER, "syslogd");
+               asl_msg_set_key_val(msg, ASL_KEY_FACILITY, "daemon");
+               asl_msg_set_key_val(msg, ASL_KEY_LEVEL, "Notice");
+               asl_msg_set_key_val(msg, ASL_KEY_UID, "0");
+               asl_msg_set_key_val(msg, ASL_KEY_GID, "0");
+               snprintf(buf, sizeof(buf), "%u", global.pid);
+               asl_msg_set_key_val(msg, ASL_KEY_PID, buf);
+               asl_msg_set_key_val(msg, ASL_KEY_MSG, "--- syslogd restarted ---");
+               process_message(msg, SOURCE_INTERNAL);
                return;
        }
 
-    bzero(&utx, sizeof(utx));
-    utx.ut_type = BOOT_TIME;
-    utx.ut_pid = 1;
+       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)
+       len = sizeof(struct timeval);
+       if (sysctl(mib, 2, &utx.ut_tv, &len, NULL, 0) < 0)
        {
                gettimeofday(&utx.ut_tv, NULL);
        }
 
-    pututxline(&utx);
+       pututxline(&utx);
 
-       msg = asl_new(ASL_TYPE_MSG);
+       msg = asl_msg_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");
+       asl_msg_set_key_val(msg, ASL_KEY_SENDER, "bootlog");
+       asl_msg_set_key_val(msg, ASL_KEY_FACILITY, "com.apple.system.utmpx");
+       asl_msg_set_key_val(msg, ASL_KEY_LEVEL, "Notice");
+       asl_msg_set_key_val(msg, ASL_KEY_UID, "0");
+       asl_msg_set_key_val(msg, ASL_KEY_GID, "0");
+       asl_msg_set_key_val(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");
+       asl_msg_set_key_val(msg, ASL_KEY_MSG, buf);
+       asl_msg_set_key_val(msg, "ut_id", "0x00 0x00 0x00 0x00");
+       asl_msg_set_key_val(msg, "ut_pid", "1");
+       asl_msg_set_key_val(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);
+       asl_msg_set_key_val(msg, ASL_KEY_TIME, buf);
+       asl_msg_set_key_val(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);
+       asl_msg_set_key_val(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_msg_set_key_val(msg, ASL_KEY_TIME_NSEC, buf);
 
-       dispatch_async(global.work_queue, ^{ process_message(msg, SOURCE_INTERNAL); });
+       process_message(msg, SOURCE_INTERNAL);
 }
 
 int
 main(int argc, const char *argv[])
 {
        int32_t i;
-       int network_change_token, asl_db_token;
-       char tstr[32];
+       uint64_t master_val;
+#if !TARGET_IPHONE_SIMULATOR
+       int network_change_token;
+#endif
+       int quota_file_token, asl_db_token, master_token;
+       char tstr[32], *notify_key;
        time_t now;
        int first_syslogd_start = 1;
 
+#if TARGET_IPHONE_SIMULATOR
+       const char *sim_log_dir = getenv("SIMULATOR_LOG_ROOT");
+       const char *sim_resource_dir = getenv("SIMULATOR_SHARED_RESOURCES_DIRECTORY");
+       char *p;
+
+       /* assert is evil */
+       assert(sim_log_dir && sim_resource_dir);
+
+       asprintf((char **)&_path_syslogd_log, "%s/syslogd.log", sim_log_dir);
+       asprintf((char **)&_path_pidfile, "%s/var/run/syslog.pid", sim_resource_dir);
+
+       if (_path_syslogd_log == NULL) _path_syslogd_log = "/tmp/syslogd.log";
+       else mkpath_np(sim_log_dir, 0755);
+
+       if (_path_pidfile == NULL)
+       {
+               _path_pidfile = "/tmp/syslog.pid";
+       }
+       else
+       {
+               p = strrchr(_path_pidfile, '/');
+               *p = '\0';
+               mkpath_np(_path_pidfile, 0755);
+               *p = '/';
+       }
+#endif
+
        /* Set I/O policy */
        setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_PASSIVE);
 
+#if !TARGET_OS_IPHONE
+       /* Set Quarantine */
+       qtn_proc_t qp = qtn_proc_alloc();
+       qtn_proc_set_identifier(qp, "com.apple.syslogd");
+       qtn_proc_set_flags(qp, QTN_FLAG_SANDBOX | QTN_FLAG_HARD);
+       qtn_proc_apply_to_self(qp);
+       qtn_proc_free(qp);
+#endif
+
        memset(&global, 0, sizeof(struct global_s));
 
        global.db_lock = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));
@@ -447,11 +504,9 @@ main(int argc, const char *argv[])
        global.work_queue = dispatch_queue_create("Work Queue", NULL);
        dispatch_suspend(global.work_queue);
 
-       global.lockdown_session_fd = -1;
-
        init_globals();
 
-#ifdef CONFIG_IPHONE
+#if TARGET_OS_EMBEDDED
        remote_enabled = 1;
        activate_bsd_out = 0;
 #endif
@@ -479,8 +534,13 @@ main(int argc, const char *argv[])
                                }
                                else if (streq(argv[i], "iphone"))
                                {
-                                       global.dbtype = DB_TYPE_MINI;
+#if TARGET_IPHONE_SIMULATOR
+                                       global.dbtype = DB_TYPE_FILE;
+                                       global.db_file_max = 25600000;
+#else
+                                       global.dbtype = DB_TYPE_MEMORY;
                                        remote_enabled = 1;
+#endif
                                }
                        }
                }
@@ -492,11 +552,6 @@ main(int argc, const char *argv[])
                {
                        global.debug = 1;
                        if (((i+1) < argc) && (argv[i+1][0] != '-')) global.debug_file = strdup(argv[++i]);
-                       memset(tstr, 0, sizeof(tstr));
-                       now = time(NULL);
-                       ctime_r(&now, tstr);
-                       tstr[19] = '\0';
-                       asldebug("%s syslogd[%d]: Start\n", tstr, getpid());
                }
                else if (streq(argv[i], "-db"))
                {
@@ -513,11 +568,6 @@ main(int argc, const char *argv[])
                                        global.dbtype |= DB_TYPE_MEMORY;
                                        if (((i + 1) < argc) && (argv[i+1][0] != '-')) global.db_memory_max = atol(argv[++i]);
                                }
-                               else if (streq(argv[i], "mini"))
-                               {
-                                       global.dbtype |= DB_TYPE_MINI;
-                                       if (((i + 1) < argc) && (argv[i+1][0] != '-')) global.db_mini_max = atol(argv[++i]);
-                               }
                        }
                }
                else if (streq(argv[i], "-m"))
@@ -536,6 +586,7 @@ main(int argc, const char *argv[])
                {
                        if ((i + 1) < argc) global.bsd_max_dup_time = atoll(argv[++i]);
                }
+#if !TARGET_IPHONE_SIMULATOR
                else if (streq(argv[i], "-klog_in"))
                {
                        if ((i + 1) < argc) activate_klog_in = atoi(argv[++i]);
@@ -548,6 +599,12 @@ main(int argc, const char *argv[])
                {
                        if ((i + 1) < argc) activate_udp_in = atoi(argv[++i]);
                }
+#endif
+               else if (streq(argv[i], "-launchd_in"))
+               {
+                       if ((i + 1) < argc) global.launchd_enabled = atoi(argv[++i]);
+               }
+#if !TARGET_IPHONE_SIMULATOR
                else if (streq(argv[i], "-bsd_out"))
                {
                        if ((i + 1) < argc) activate_bsd_out = atoi(argv[++i]);
@@ -556,6 +613,7 @@ main(int argc, const char *argv[])
                {
                        if ((i + 1) < argc) remote_enabled = atoi(argv[++i]);
                }
+#endif
        }
 
        if (global.dbtype == 0)
@@ -566,6 +624,12 @@ main(int argc, const char *argv[])
 
        signal(SIGHUP, SIG_IGN);
 
+       memset(tstr, 0, sizeof(tstr));
+       now = time(NULL);
+       ctime_r(&now, tstr);
+       tstr[19] = '\0';
+       asldebug("\n%s syslogd PID %d starting\n", tstr, global.pid);
+
        writepid(&first_syslogd_start);
 
        /*
@@ -573,18 +637,56 @@ main(int argc, const char *argv[])
         */
        write_boot_log(first_syslogd_start);
 
+       /* default NOTIFY_SYSTEM_MASTER settings */
+       master_val = 0x0;
+       notify_register_plain(NOTIFY_SYSTEM_MASTER, &master_token);
+       notify_set_state(master_token, master_val);
+
        asldebug("reading launch plist\n");
        launch_config();
 
        asldebug("initializing modules\n");
        init_modules();
-       dispatch_resume(global.work_queue);
+
+#if !TARGET_IPHONE_SIMULATOR
+       asldebug("setting up network change notification handler\n");
 
        /* network change notification resets UDP and BSD modules */
-    notify_register_dispatch(kNotifySCNetworkChange, &network_change_token, global.work_queue, ^(int x){
-        if (activate_udp_in != 0) udp_in_reset();
-        if (activate_bsd_out != 0) bsd_out_reset();
-    });
+       notify_register_dispatch(kNotifySCNetworkChange, &network_change_token, global.work_queue, ^(int x){
+               if (activate_udp_in != 0) udp_in_reset();
+               if (activate_bsd_out != 0) bsd_out_reset();
+       });
+#endif
+
+       asldebug("setting up quota notification handler\n");
+
+       notify_key = NULL;
+       asprintf(&notify_key, "%s%s", NOTIFY_PATH_SERVICE, NOQUOTA_FILE_PATH);
+       if (notify_key != NULL)
+       {
+               int status;
+
+               status = notify_register_dispatch(notify_key, &quota_file_token, dispatch_get_main_queue(), ^(int t){
+                       struct stat sb;
+                       memset(&sb, 0, sizeof(sb));
+                       if (stat(NOQUOTA_FILE_PATH, &sb) == 0)
+                       {
+                               char *str = NULL;
+                               asprintf(&str, "[Sender syslogd] [Level 2] [PID %u] [Facility syslog] [Message *** MESSAGE QUOTAS DISABLED FOR ALL PROCESSES ***]", global.pid);
+                               internal_log_message(str);
+                               free(str);
+                       }
+                       else
+                       {
+                               char *str = NULL;
+                               asprintf(&str, "[Sender syslogd] [Level 2] [PID %u] [Facility syslog] [Message *** MESSAGE QUOTAS ENABLED ***]", global.pid);
+                               internal_log_message(str);
+                               free(str);
+                       }
+               });
+
+               free(notify_key);
+       }
 
        /* SIGHUP resets all modules */
        global.sig_hup_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, (uintptr_t)SIGHUP, 0, dispatch_get_main_queue());
@@ -606,26 +708,17 @@ main(int argc, const char *argv[])
        notify_register_plain(kNotifyASLDBUpdate, &asl_db_token);
 
        /* timer for MARK facility */
-    if (global.mark_time > 0)
+       if (global.mark_time > 0)
        {
                global.mark_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
                dispatch_source_set_event_handler(global.mark_timer, ^{ 
                        asl_mark();
                });
-               dispatch_source_set_timer(global.mark_timer, dispatch_walltime(NULL, global.mark_time * NSEC_PER_SEC), global.mark_time * NSEC_PER_SEC, 0);
+               dispatch_source_set_timer(global.mark_timer, dispatch_time(DISPATCH_TIME_NOW, global.mark_time * NSEC_PER_SEC), global.mark_time * NSEC_PER_SEC, 0);
                dispatch_resume(global.mark_timer);
        }
 
-       /*
-        * Start launchd service
-        * This pins a thread in _vprocmgr_log_drain.  Eventually we will either
-        * remove the whole stderr/stdout -> ASL mechanism entirely, or come up 
-        * with a communication channel that we can trigger with a dispatch source.
-        */
-       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-               forever _vprocmgr_log_drain(NULL, NULL, launchd_callback);
-       });
-
+       asldebug("starting mach service\n");
        /*
         * Start mach server
         * Parks a thread in database_server.  In notifyd, we found that the overhead of
@@ -635,6 +728,9 @@ main(int argc, const char *argv[])
                database_server();
        });
 
+       /* go to work */
+       asldebug("starting work queue\n");
+       dispatch_resume(global.work_queue);
        dispatch_main();
 
        /* NOTREACHED */