X-Git-Url: https://git.saurik.com/apple/syslog.git/blobdiff_plain/57b0aad2c678a02fcc3e8b5756d4a13d9061babf..c58972950480a3550c3586696faabadc23bea1e4:/syslogd.tproj/syslogd.c diff --git a/syslogd.tproj/syslogd.c b/syslogd.tproj/syslogd.c index 230655a..2d45dc5 100644 --- a/syslogd.tproj/syslogd.c +++ b/syslogd.tproj/syslogd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2008 Apple Inc. All rights reserved. + * Copyright (c) 2004-2012 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,25 +21,38 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include + +#include #include #include #include #include -#include #include #include #include #include #include #include +#include +#include #include +#include #include #include +#include #include #include #include #include #include +#include +#include +#include + +#if !TARGET_OS_IPHONE +#include +#endif #include "daemon.h" #define SERVICE_NAME "com.apple.system.logger" @@ -48,528 +61,455 @@ #define SERVER_STATUS_ACTIVE 1 #define SERVER_STATUS_ON_DEMAND 2 -#define DEFAULT_MARK_SEC 0 -#define DEFAULT_UTMP_TTL_SEC 31622400 -#define DEFAULT_FS_TTL_SEC 31622400 -#define DEFAULT_BSD_MAX_DUP_SEC 30 #define BILLION 1000000000 #define NOTIFY_DELAY 1 -#define NETWORK_CHANGE_NOTIFICATION "com.apple.system.config.network_change" - -#define streq(A,B) (strcmp(A,B)==0) -#define forever for(;;) - -static int reset = 0; -static uint64_t time_start = 0; -static uint64_t mark_last = 0; -static uint64_t mark_time = 0; -static uint64_t time_last = 0; - -extern int __notify_78945668_info__; extern int _malloc_no_asl_log; -static TAILQ_HEAD(ml, module_list) Moduleq; +#if TARGET_IPHONE_SIMULATOR +const char *_path_pidfile; +const char *_path_syslogd_log; +#endif /* global */ struct global_s global; -/* Static Modules */ -int asl_in_init(); -int asl_in_reset(); -int asl_in_close(); -static int activate_asl_in = 1; - -int asl_action_init(); -int asl_action_reset(); -int asl_action_close(); -static int activate_asl_action = 1; - -int klog_in_init(); -int klog_in_reset(); -int klog_in_close(); +#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(); -int bsd_in_reset(); -int bsd_in_close(); +int bsd_in_init(void); +int bsd_in_reset(void); +int bsd_in_close(void); static int activate_bsd_in = 1; -int bsd_out_init(); -int bsd_out_reset(); -int bsd_out_close(); +#if !TARGET_IPHONE_SIMULATOR +int udp_in_init(void); +int udp_in_reset(void); +int udp_in_close(void); +static int activate_udp_in = 1; + +/* Output Modules */ +int bsd_out_init(void); +int bsd_out_reset(void); +int bsd_out_close(void); static int activate_bsd_out = 1; +#endif -int remote_init(); -int remote_reset(); -int remote_close(); -static int activate_remote = 0; +int asl_action_init(void); +int asl_action_reset(void); +int asl_action_close(void); +static int activate_asl_action = 1; -int udp_in_init(); -int udp_in_reset(); -int udp_in_close(); -static int activate_udp_in = 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(); -extern void db_worker(); -extern void launchd_drain(); -extern void bsd_flush_duplicates(time_t now); -/* - * Module approach: only one type of module. This module may implement - * the set of functions necessary for any of the functions (input, output, - * etc.) Prior to using the modules, dlsym() is consulted to see what it - * implements. - */ - -static int -static_modules() +static void +init_modules() { - struct module_list *tmp; +#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; - /* - * The order of these initializations is important. - * When messages are sent to output modules, they are - * sent in the same order as these initializations. - * asl_action may add modify messages, for example to - * add access controls, so it must come first. - */ - if (activate_asl_action != 0) + /* ASL module (configured by /etc/asl.conf) */ + m_asl = (module_t *)calloc(1, sizeof(module_t)); + if (m_asl == NULL) { - tmp = calloc(1, sizeof(struct module_list)); - if (tmp == NULL) return 1; + asldebug("alloc failed (init_modules asl_action)\n"); + exit(1); + } - tmp->name = strdup("asl_action"); - if (tmp->name == NULL) - { - free(tmp); - return 1; - } + m_asl->name = "asl_action"; + m_asl->enabled = activate_asl_action; + m_asl->init = asl_action_init; + m_asl->reset = asl_action_reset; + m_asl->close = asl_action_close; - tmp->module = NULL; - tmp->init = asl_action_init; - tmp->reset = asl_action_reset; - tmp->close = asl_action_close; - TAILQ_INSERT_TAIL(&Moduleq, tmp, entries); - } + if (m_asl->enabled) m_asl->init(); - if (activate_asl_in != 0) +#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) { - tmp = calloc(1, sizeof(struct module_list)); - if (tmp == NULL) return 1; + asldebug("alloc failed (init_modules bsd_out)\n"); + exit(1); + } - tmp->name = strdup("asl_in"); - if (tmp->name == NULL) - { - free(tmp); - return 1; - } + m_bsd_out->name = "bsd_out"; + m_bsd_out->enabled = activate_bsd_out; + m_bsd_out->init = bsd_out_init; + m_bsd_out->reset = bsd_out_reset; + m_bsd_out->close = bsd_out_close; - tmp->module = NULL; - tmp->init = asl_in_init; - tmp->reset = asl_in_reset; - tmp->close = asl_in_close; - TAILQ_INSERT_TAIL(&Moduleq, tmp, entries); + if (m_bsd_out->enabled) + { + m_bsd_out->init(); + global.bsd_out_enabled = 1; } - if (activate_klog_in != 0) + /* kernel input module */ + m_klog_in = (module_t *)calloc(1, sizeof(module_t)); + if (m_klog_in == NULL) { - tmp = calloc(1, sizeof(struct module_list)); - if (tmp == NULL) return 1; - - tmp->name = strdup("klog_in"); - if (tmp->name == NULL) - { - free(tmp); - return 1; - } - - tmp->module = NULL; - tmp->init = klog_in_init; - tmp->reset = klog_in_reset; - tmp->close = klog_in_close; - TAILQ_INSERT_TAIL(&Moduleq, tmp, entries); + asldebug("alloc failed (init_modules klog_in)\n"); + exit(1); } - if (activate_bsd_in != 0) - { - tmp = calloc(1, sizeof(struct module_list)); - if (tmp == NULL) return 1; + m_klog_in->name = "klog_in"; + m_klog_in->enabled = activate_klog_in; + m_klog_in->init = klog_in_init; + m_klog_in->reset = klog_in_reset; + m_klog_in->close = klog_in_close; - tmp->name = strdup("bsd_in"); - if (tmp->name == NULL) - { - free(tmp); - return 1; - } + if (m_klog_in->enabled) m_klog_in->init(); +#endif - tmp->module = NULL; - tmp->init = bsd_in_init; - tmp->reset = bsd_in_reset; - tmp->close = bsd_in_close; - TAILQ_INSERT_TAIL(&Moduleq, tmp, entries); + /* BSD (UNIX domain socket) input module */ + m_bsd_in = (module_t *)calloc(1, sizeof(module_t)); + if (m_bsd_in == NULL) + { + asldebug("alloc failed (init_modules bsd_in)\n"); + exit(1); } - if (activate_bsd_out != 0) - { - tmp = calloc(1, sizeof(struct module_list)); - if (tmp == NULL) return 1; + m_bsd_in->name = "bsd_in"; + m_bsd_in->enabled = activate_bsd_in; + m_bsd_in->init = bsd_in_init; + m_bsd_in->reset = bsd_in_reset; + m_bsd_in->close = bsd_in_close; - tmp->name = strdup("bsd_out"); - if (tmp->name == NULL) - { - free(tmp); - return 1; - } + if (m_bsd_in->enabled) m_bsd_in->init(); - tmp->module = NULL; - tmp->init = bsd_out_init; - tmp->reset = bsd_out_reset; - tmp->close = bsd_out_close; - TAILQ_INSERT_TAIL(&Moduleq, tmp, entries); +#if !TARGET_IPHONE_SIMULATOR + /* network (syslog protocol) input module */ + m_udp_in = (module_t *)calloc(1, sizeof(module_t)); + if (m_udp_in == NULL) + { + asldebug("alloc failed (init_modules udp_in)\n"); + exit(1); } - if (activate_remote != 0) - { - tmp = calloc(1, sizeof(struct module_list)); - if (tmp == NULL) return 1; + m_udp_in->name = "udp_in"; + m_udp_in->enabled = activate_udp_in; + m_udp_in->init = udp_in_init; + m_udp_in->reset = udp_in_reset; + m_udp_in->close = udp_in_close; - tmp->name = strdup("remote"); - if (tmp->name == NULL) - { - free(tmp); - return 1; - } + if (m_udp_in->enabled) m_udp_in->init(); - tmp->module = NULL; - tmp->init = remote_init; - tmp->reset = remote_reset; - tmp->close = remote_close; - TAILQ_INSERT_TAIL(&Moduleq, tmp, entries); + /* remote (iOS support) module */ + m_remote = (module_t *)calloc(1, sizeof(module_t)); + if (m_remote == NULL) + { + asldebug("alloc failed (init_modules remote)\n"); + exit(1); } - if (activate_udp_in != 0) - { - tmp = calloc(1, sizeof(struct module_list)); - if (tmp == NULL) return 1; + m_remote->name = "remote"; + m_remote->enabled = remote_enabled; + m_remote->init = remote_init; + m_remote->reset = remote_reset; + m_remote->close = remote_close; - tmp->name = strdup("udp_in"); - if (tmp->name == NULL) - { - free(tmp); - return 1; - } + if (m_remote->enabled) m_remote->init(); +#endif /* TARGET_IPHONE_SIMULATOR */ - tmp->module = NULL; - tmp->init = udp_in_init; - tmp->reset = udp_in_reset; - tmp->close = udp_in_close; - TAILQ_INSERT_TAIL(&Moduleq, tmp, entries); + /* 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) + { + asldebug("alloc failed (init_modules)\n"); + exit(1); } - return 0; + 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 } -/* - * Loads all the modules. This DOES NOT call the modules initializer - * functions. It simply scans the modules directory looking for modules - * and loads them. This does not mean the module will be used. - */ -static int -load_modules(const char *mp) +static void +writepid(int *first) { - DIR *d; - struct dirent *de; - struct module_list *tmp; - void *c, *bn; - char *modulepath = NULL; - - d = opendir(mp); - if (d == NULL) return -1; + struct stat sb; + FILE *fp; - while (NULL != (de = readdir(d))) + if (first != NULL) { - if (de->d_name[0] == '.') continue; - - /* Must have ".so" in the name" */ - if (!strstr(de->d_name, ".so")) continue; - - asprintf(&modulepath, "%s/%s", mp, de->d_name); - if (!modulepath) continue; - - c = dlopen(modulepath, RTLD_LOCAL); - if (c == NULL) - { - free(modulepath); - continue; - } - - tmp = calloc(1, sizeof(struct module_list)); - if (tmp == NULL) - { - free(modulepath); - dlclose(c); - continue; - } - - bn = basename(modulepath); - tmp->name = strdup(bn); - if (tmp->name == NULL) + *first = 1; + memset(&sb, 0, sizeof(struct stat)); + if (stat(_PATH_PIDFILE, &sb) == 0) { - free(tmp); - return 1; + if (S_ISREG(sb.st_mode)) *first = 0; } - - tmp->module = c; - TAILQ_INSERT_TAIL(&Moduleq, tmp, entries); - - tmp->init = dlsym(tmp->module, "aslmod_init"); - tmp->reset = dlsym(tmp->module, "aslmod_reset"); - tmp->close = dlsym(tmp->module, "aslmod_close"); - - free(modulepath); } - closedir(d); - - return 0; -} - -static void -writepid(void) -{ - FILE *fp; - fp = fopen(_PATH_PIDFILE, "w"); if (fp != NULL) { - fprintf(fp, "%d\n", getpid()); + fprintf(fp, "%d\n", global.pid); fclose(fp); } } -static void -closeall(void) -{ - int i; - - for (i = getdtablesize() - 1; i >= 0; i--) close(i); - - open("/dev/null", O_RDWR, 0); - dup(0); - dup(0); -} - -static void -detach(void) -{ - signal(SIGINT, SIG_IGN); - signal(SIGPIPE, SIG_IGN); - setsid(); -} - -static void -catch_sighup(int x) +void +launch_config() { - reset = 1; -} + launch_data_t tmp, pdict; + kern_return_t status; -static void -send_reset(void) -{ - struct module_list *mod; + tmp = launch_data_new_string(LAUNCH_KEY_CHECKIN); + global.launch_dict = launch_msg(tmp); + launch_data_free(tmp); - for (mod = Moduleq.tqh_first; mod != NULL; mod = mod->entries.tqe_next) + if (global.launch_dict == NULL) { - if (mod->reset != NULL) mod->reset(); + asldebug("%d launchd checkin failed\n", global.pid); + exit(1); } -} - -/* - * perform timed activities and set next run-loop timeout - */ -static void -timed_events(struct timeval **run) -{ - uint64_t now, delta, t; - static struct timeval next; - - now = time(NULL); - - *run = NULL; - next.tv_sec = 0; - next.tv_usec = 0; - if (time_start == 0) + tmp = launch_data_dict_lookup(global.launch_dict, LAUNCH_JOBKEY_MACHSERVICES); + if (tmp == NULL) { - /* startup */ - time_start = now; - time_last = now; - mark_last = now; + asldebug("%d launchd lookup of LAUNCH_JOBKEY_MACHSERVICES failed\n", global.pid); + exit(1); } - /* - * At startup, we try sending a notification once a second. - * Once it succeeds, we set the Libc global __notify_78945668_info__ to 0 - * which lets Libc's localtime calculations use notifyd to invalidate - * cached timezones. This prevents a deadlock in localtime. - */ - if (__notify_78945668_info__ < 0) + pdict = launch_data_dict_lookup(tmp, SERVICE_NAME); + if (pdict == NULL) { - if (notify_post("com.apple.system.syslogd") == NOTIFY_STATUS_OK) __notify_78945668_info__ = 0; - else next.tv_sec = 1; + asldebug("%d launchd lookup of SERVICE_NAME failed\n", global.pid); + exit(1); } - if (time_last > now) + global.server_port = launch_data_get_machport(pdict); + + /* port for receiving MACH_NOTIFY_DEAD_NAME notifications */ + status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &(global.dead_session_port)); + if (status != KERN_SUCCESS) { - /* - * Despite Albert Einstein's assurance, time has gone backward. - * Reset "last" times to current time. - */ - time_last = now; - mark_last = now; + asldebug("mach_port_allocate dead_session_port failed: %d", status); + exit(1); } - /* - * Tickle bsd_out module to flush duplicates. - */ - if (global.bsd_flush_time > 0) + status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &(global.listen_set)); + if (status != KERN_SUCCESS) { - bsd_flush_duplicates(now); - if (global.bsd_flush_time > 0) - { - if (next.tv_sec == 0) next.tv_sec = global.bsd_flush_time; - else if (global.bsd_flush_time < next.tv_sec) next.tv_sec = global.bsd_flush_time; - } + asldebug("mach_port_allocate listen_set failed: %d", status); + exit(1); } - /* - * Tickle asl_store - */ - if (global.asl_store_ping_time > 0) + status = mach_port_move_member(mach_task_self(), global.server_port, global.listen_set); + if (status != KERN_SUCCESS) { - db_ping_store(now); - if (global.asl_store_ping_time > 0) - { - if (next.tv_sec == 0) next.tv_sec = global.asl_store_ping_time; - else if (global.asl_store_ping_time < next.tv_sec) next.tv_sec = global.asl_store_ping_time; - } + asldebug("mach_port_move_member server_port failed: %d", status); + exit(1); } - /* - * Send MARK - */ - if (mark_time > 0) + status = mach_port_move_member(mach_task_self(), global.dead_session_port, global.listen_set); + if (status != KERN_SUCCESS) { - delta = now - mark_last; - if (delta >= mark_time) - { - asl_mark(); - mark_last = now; - t = mark_time; - } - else - { - t = mark_time - delta; - } - - if (next.tv_sec == 0) next.tv_sec = t; - else if (t < next.tv_sec) next.tv_sec = t; + asldebug("mach_port_move_member dead_session_port failed (%u)", status); + exit(1); } +} - /* - * set output timeout parameter if runloop needs to have a timer - */ - if (next.tv_sec > 0) *run = &next; +void +config_debug(int enable, const char *path) +{ + OSSpinLockLock(&global.lock); + + global.debug = enable; + free(global.debug_file); + global.debug_file = NULL; + if (path != NULL) global.debug_file = strdup(path); - time_last = now; + OSSpinLockUnlock(&global.lock); } void -init_config() +config_data_store(int type, uint32_t file_max, uint32_t memory_max, uint32_t str_memory_max) { - launch_data_t tmp, pdict; - kern_return_t status; - - tmp = launch_data_new_string(LAUNCH_KEY_CHECKIN); - global.launch_dict = launch_msg(tmp); - launch_data_free(tmp); + pthread_mutex_lock(global.db_lock); - if (global.launch_dict == NULL) + if (global.dbtype & DB_TYPE_FILE) { - fprintf(stderr, "%d launchd checkin failed\n", getpid()); - exit(1); + asl_store_close(global.file_db); + global.file_db = NULL; } - tmp = launch_data_dict_lookup(global.launch_dict, LAUNCH_JOBKEY_MACHSERVICES); - if (tmp == NULL) + if (global.dbtype & DB_TYPE_MEMORY) { - fprintf(stderr, "%d launchd lookup of LAUNCH_JOBKEY_MACHSERVICES failed\n", getpid()); - exit(1); + asl_memory_close(global.memory_db); + global.memory_db = NULL; } - pdict = launch_data_dict_lookup(tmp, SERVICE_NAME); - if (pdict == NULL) + global.dbtype = type; + global.db_file_max = file_max; + global.db_memory_max = memory_max; + global.db_memory_str_max = str_memory_max; + + pthread_mutex_unlock(global.db_lock); +} + +void +write_boot_log(int first) +{ + int mib[2] = {CTL_KERN, KERN_BOOTTIME}; + size_t len; + asl_msg_t *msg; + char buf[256]; + struct utmpx utx; + + if (first == 0) { - fprintf(stderr, "%d launchd lookup of SERVICE_NAME failed\n", getpid()); - exit(1); + /* syslogd restart */ + msg = asl_msg_new(ASL_TYPE_MSG); + if (msg == NULL) return; + + 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; } - global.server_port = launch_data_get_machport(pdict); + bzero(&utx, sizeof(utx)); + utx.ut_type = BOOT_TIME; + utx.ut_pid = 1; - status = mach_port_insert_right(mach_task_self(), global.server_port, global.server_port, MACH_MSG_TYPE_MAKE_SEND); - if (status != KERN_SUCCESS) fprintf(stderr, "Warning! Can't make send right for server_port: %x\n", status); + /* 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_msg_new(ASL_TYPE_MSG); + if (msg == NULL) return; + + 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_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_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_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_msg_set_key_val(msg, ASL_KEY_TIME_NSEC, buf); + + process_message(msg, SOURCE_INTERNAL); } int main(int argc, const char *argv[]) { - struct module_list *mod; - fd_set rd, wr, ex, kern; - int32_t fd, i, max, status, daemonize; - const char *mp; - struct timeval *runloop_timer, zto; - pthread_attr_t attr; - pthread_t t; - int nctoken; - char tstr[32]; + int32_t i; + 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; - memset(&global, 0, sizeof(struct global_s)); +#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); - global.asl_log_filter = ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE); - global.db_file_max = 16384000; - global.db_memory_max = 8192; - global.db_mini_max = 256; - global.bsd_max_dup_time = DEFAULT_BSD_MAX_DUP_SEC; - global.utmp_ttl = DEFAULT_UTMP_TTL_SEC; - global.fs_ttl = DEFAULT_FS_TTL_SEC; - global.kfd = -1; - -#ifdef CONFIG_MAC - global.dbtype = DB_TYPE_FILE; - global.db_file_max = 25600000; - global.asl_store_ping_time = 150; + 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 - -#ifdef CONFIG_APPLETV - global.dbtype = DB_TYPE_FILE; - global.db_file_max = 10240000; + + /* 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 -#ifdef CONFIG_IPHONE - global.dbtype = DB_TYPE_MINI; - activate_remote = 1; + memset(&global, 0, sizeof(struct global_s)); + + global.db_lock = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t)); + pthread_mutex_init(global.db_lock, NULL); + + /* + * Create work queue, but suspend until output modules are initialized. + */ + global.work_queue = dispatch_queue_create("Work Queue", NULL); + dispatch_suspend(global.work_queue); + + init_globals(); + +#if TARGET_OS_EMBEDDED + remote_enabled = 1; activate_bsd_out = 0; #endif - - mp = _PATH_MODULE_LIB; - daemonize = 0; - __notify_78945668_info__ = -1; - zto.tv_sec = 0; - zto.tv_usec = 0; - FD_ZERO(&kern); /* prevent malloc from calling ASL on error */ _malloc_no_asl_log = 1; @@ -594,8 +534,13 @@ main(int argc, const char *argv[]) } else if (streq(argv[i], "iphone")) { - global.dbtype = DB_TYPE_MINI; - activate_remote = 1; +#if TARGET_IPHONE_SIMULATOR + global.dbtype = DB_TYPE_FILE; + global.db_file_max = 25600000; +#else + global.dbtype = DB_TYPE_MEMORY; + remote_enabled = 1; +#endif } } } @@ -606,12 +551,7 @@ main(int argc, const char *argv[]) if (streq(argv[i], "-d")) { global.debug = 1; - if (((i+1) < argc) && (argv[i+1][0] != '-')) global.debug_file = 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()); + if (((i+1) < argc) && (argv[i+1][0] != '-')) global.debug_file = strdup(argv[++i]); } else if (streq(argv[i], "-db")) { @@ -628,53 +568,25 @@ 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], "-D")) - { - daemonize = 1; - } else if (streq(argv[i], "-m")) { - if ((i + 1) < argc) mark_time = 60 * atoll(argv[++i]); + if ((i + 1) < argc) global.mark_time = 60 * atoll(argv[++i]); } else if (streq(argv[i], "-utmp_ttl")) { if ((i + 1) < argc) global.utmp_ttl = atol(argv[++i]); } - else if (streq(argv[i], "-fs_ttl")) + else if (streq(argv[i], "-mps_limit")) { - if ((i + 1) < argc) global.fs_ttl = atol(argv[++i]); - } - else if (streq(argv[i], "-l")) - { - if ((i + 1) < argc) mp = argv[++i]; - } - else if (streq(argv[i], "-c")) - { - if ((i + 1) < argc) - { - i++; - if ((argv[i][0] >= '0') && (argv[i][0] <= '7') && (argv[i][1] == '\0')) global.asl_log_filter = ASL_FILTER_MASK_UPTO(atoi(argv[i])); - } + if ((i + 1) < argc) global.mps_limit = atol(argv[++i]); } else if (streq(argv[i], "-dup_delay")) { if ((i + 1) < argc) global.bsd_max_dup_time = atoll(argv[++i]); } - else if (streq(argv[i], "-asl_in")) - { - if ((i + 1) < argc) activate_asl_in = atoi(argv[++i]); - } - else if (streq(argv[i], "-asl_action")) - { - if ((i + 1) < argc) activate_asl_action = atoi(argv[++i]); - } +#if !TARGET_IPHONE_SIMULATOR else if (streq(argv[i], "-klog_in")) { if ((i + 1) < argc) activate_klog_in = atoi(argv[++i]); @@ -683,120 +595,144 @@ main(int argc, const char *argv[]) { if ((i + 1) < argc) activate_bsd_in = atoi(argv[++i]); } + else if (streq(argv[i], "-udp_in")) + { + 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]); } else if (streq(argv[i], "-remote")) { - if ((i + 1) < argc) activate_remote = atoi(argv[++i]); - } - else if (streq(argv[i], "-udp_in")) - { - if ((i + 1) < argc) activate_udp_in = atoi(argv[++i]); + if ((i + 1) < argc) remote_enabled = atoi(argv[++i]); } +#endif } - if (global.dbtype == 0) global.dbtype = DB_TYPE_FILE; - - TAILQ_INIT(&Moduleq); - static_modules(); - load_modules(mp); - aslevent_init(); - - if (global.debug == 0) + if (global.dbtype == 0) { - if (daemonize != 0) - { - if (fork() != 0) exit(0); - - detach(); - closeall(); - } - - writepid(); + global.dbtype = DB_TYPE_FILE; + global.db_file_max = 25600000; } - init_config(); + signal(SIGHUP, SIG_IGN); - signal(SIGHUP, catch_sighup); + 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); - nctoken = -1; - notify_register_signal(NETWORK_CHANGE_NOTIFICATION, SIGHUP, &nctoken); - - for (mod = Moduleq.tqh_first; mod != NULL; mod = mod->entries.tqe_next) - { - fd = mod->init(); - if (fd < 0) continue; - } + writepid(&first_syslogd_start); /* - * Start database server thread + * Log UTMPX boot time record */ - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&t, &attr, (void *(*)(void *))database_server, NULL); - pthread_attr_destroy(&attr); + write_boot_log(first_syslogd_start); - /* - * Start database worker thread - */ - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&t, &attr, (void *(*)(void *))db_worker, NULL); - pthread_attr_destroy(&attr); + /* default NOTIFY_SYSTEM_MASTER settings */ + master_val = 0x0; + notify_register_plain(NOTIFY_SYSTEM_MASTER, &master_token); + notify_set_state(master_token, master_val); - FD_ZERO(&rd); - FD_ZERO(&wr); - FD_ZERO(&ex); + asldebug("reading launch plist\n"); + launch_config(); - /* - * drain /dev/klog first - */ - if (global.kfd >= 0) - { - max = global.kfd + 1; - while (select(max, &kern, NULL, NULL, &zto) > 0) - { - aslevent_handleevent(&kern, &wr, &ex); - } - } + asldebug("initializing modules\n"); + init_modules(); - /* - * Start launchd drain thread - */ - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&t, &attr, (void *(*)(void *))launchd_drain, NULL); - pthread_attr_destroy(&attr); +#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(); + }); +#endif - runloop_timer = NULL; - timed_events(&runloop_timer); + asldebug("setting up quota notification handler\n"); - forever + notify_key = NULL; + asprintf(¬ify_key, "%s%s", NOTIFY_PATH_SERVICE, NOQUOTA_FILE_PATH); + if (notify_key != NULL) { - max = aslevent_fdsets(&rd, &wr, &ex) + 1; + int status; - status = select(max, &rd, &wr, &ex, runloop_timer); - if ((global.kfd >= 0) && FD_ISSET(global.kfd, &rd)) - { - /* drain /dev/klog */ - max = global.kfd + 1; + status = notify_register_dispatch(notify_key, "a_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()); + dispatch_source_set_event_handler(global.sig_hup_src, ^{ + dispatch_async(global.work_queue, ^{ + int i; - while (select(max, &kern, NULL, NULL, &zto) > 0) + asldebug("SIGHUP reset\n"); + for (i = 0; i < global.module_count; i++) { - aslevent_handleevent(&kern, &wr, &ex); + if (global.module[i]->enabled != 0) global.module[i]->reset(); } - } + }); + }); - if (reset != 0) - { - send_reset(); - reset = 0; - } + dispatch_resume(global.sig_hup_src); + + /* register for DB notification (posted by dbserver) for performance */ + notify_register_plain(kNotifyASLDBUpdate, &asl_db_token); - if (status != 0) aslevent_handleevent(&rd, &wr, &ex); + /* timer for MARK facility */ + 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_time(DISPATCH_TIME_NOW, global.mark_time * NSEC_PER_SEC), global.mark_time * NSEC_PER_SEC, 0); + dispatch_resume(global.mark_timer); + } + + asldebug("starting mach service\n"); + /* + * Start mach server + * Parks a thread in database_server. In notifyd, we found that the overhead of + * a dispatch source for mach calls was too high, especially on iOS. + */ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + database_server(); + }); - timed_events(&runloop_timer); - } + /* go to work */ + asldebug("starting work queue\n"); + dispatch_resume(global.work_queue); + dispatch_main(); + + /* NOTREACHED */ + return 0; }