]> git.saurik.com Git - apple/syslog.git/blob - syslogd.tproj/syslogd.c
f5c3f54b5fbcae13141aed8987df5811e536590c
[apple/syslog.git] / syslogd.tproj / syslogd.c
1 /*
2 * Copyright (c) 2004-2012 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <TargetConditionals.h>
25
26 #include <assert.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <mach/mach.h>
32 #include <mach/mach_error.h>
33 #include <mach/mach_time.h>
34 #include <servers/bootstrap.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/sysctl.h>
38 #include <sys/stat.h>
39 #include <sys/fcntl.h>
40 #include <sys/errno.h>
41 #include <sys/queue.h>
42 #include <sys/time.h>
43 #include <sys/un.h>
44 #include <pthread.h>
45 #include <dirent.h>
46 #include <dlfcn.h>
47 #include <libgen.h>
48 #include <notify.h>
49 #include <notify_keys.h>
50 #include <utmpx.h>
51 #include <vproc_priv.h>
52 #include <asl_private.h>
53 #if !TARGET_OS_IPHONE
54 #include <quarantine.h>
55 #endif
56 #include "daemon.h"
57
58 #define SERVICE_NAME "com.apple.system.logger"
59 #define SERVER_STATUS_ERROR -1
60 #define SERVER_STATUS_INACTIVE 0
61 #define SERVER_STATUS_ACTIVE 1
62 #define SERVER_STATUS_ON_DEMAND 2
63
64 #define BILLION 1000000000
65
66 #define NOTIFY_DELAY 1
67
68 #define forever for(;;)
69
70 extern int _malloc_no_asl_log;
71
72 #if TARGET_IPHONE_SIMULATOR
73 const char *_path_pidfile;
74 const char *_path_syslogd_log;
75 #endif
76
77 /* global */
78 struct global_s global;
79
80 #if !TARGET_IPHONE_SIMULATOR
81 /* Input Modules */
82 int klog_in_init(void);
83 int klog_in_reset(void);
84 int klog_in_close(void);
85 static int activate_klog_in = 1;
86 #endif
87
88 int bsd_in_init(void);
89 int bsd_in_reset(void);
90 int bsd_in_close(void);
91 static int activate_bsd_in = 1;
92
93 #if !TARGET_IPHONE_SIMULATOR
94 int udp_in_init(void);
95 int udp_in_reset(void);
96 int udp_in_close(void);
97 static int activate_udp_in = 1;
98
99 /* Output Modules */
100 int bsd_out_init(void);
101 int bsd_out_reset(void);
102 int bsd_out_close(void);
103 static int activate_bsd_out = 1;
104 #endif
105
106 int asl_action_init(void);
107 int asl_action_reset(void);
108 int asl_action_close(void);
109 static int activate_asl_action = 1;
110
111 #if !TARGET_IPHONE_SIMULATOR
112 /* Interactive Module */
113 int remote_init(void);
114 int remote_reset(void);
115 int remote_close(void);
116 static int remote_enabled = 0;
117 #endif
118
119 extern void database_server();
120
121 static void
122 init_modules()
123 {
124 #if !TARGET_IPHONE_SIMULATOR
125 module_t *m_klog_in, *m_bsd_out, *m_udp_in, *m_remote;
126 #endif
127 module_t *m_asl, *m_bsd_in;
128 int m = 0;
129
130 /* ASL module (configured by /etc/asl.conf) */
131 m_asl = (module_t *)calloc(1, sizeof(module_t));
132 if (m_asl == NULL)
133 {
134 asldebug("alloc failed (init_modules asl_action)\n");
135 exit(1);
136 }
137
138 m_asl->name = "asl_action";
139 m_asl->enabled = activate_asl_action;
140 m_asl->init = asl_action_init;
141 m_asl->reset = asl_action_reset;
142 m_asl->close = asl_action_close;
143
144 if (m_asl->enabled) m_asl->init();
145
146 #if !TARGET_IPHONE_SIMULATOR
147 /* BSD output module (configured by /etc/syslog.conf) */
148 m_bsd_out = (module_t *)calloc(1, sizeof(module_t));
149 if (m_bsd_out == NULL)
150 {
151 asldebug("alloc failed (init_modules bsd_out)\n");
152 exit(1);
153 }
154
155 m_bsd_out->name = "bsd_out";
156 m_bsd_out->enabled = activate_bsd_out;
157 m_bsd_out->init = bsd_out_init;
158 m_bsd_out->reset = bsd_out_reset;
159 m_bsd_out->close = bsd_out_close;
160
161 if (m_bsd_out->enabled)
162 {
163 m_bsd_out->init();
164 global.bsd_out_enabled = 1;
165 }
166
167 /* kernel input module */
168 m_klog_in = (module_t *)calloc(1, sizeof(module_t));
169 if (m_klog_in == NULL)
170 {
171 asldebug("alloc failed (init_modules klog_in)\n");
172 exit(1);
173 }
174
175 m_klog_in->name = "klog_in";
176 m_klog_in->enabled = activate_klog_in;
177 m_klog_in->init = klog_in_init;
178 m_klog_in->reset = klog_in_reset;
179 m_klog_in->close = klog_in_close;
180
181 if (m_klog_in->enabled) m_klog_in->init();
182 #endif
183
184 /* BSD (UNIX domain socket) input module */
185 m_bsd_in = (module_t *)calloc(1, sizeof(module_t));
186 if (m_bsd_in == NULL)
187 {
188 asldebug("alloc failed (init_modules bsd_in)\n");
189 exit(1);
190 }
191
192 m_bsd_in->name = "bsd_in";
193 m_bsd_in->enabled = activate_bsd_in;
194 m_bsd_in->init = bsd_in_init;
195 m_bsd_in->reset = bsd_in_reset;
196 m_bsd_in->close = bsd_in_close;
197
198 if (m_bsd_in->enabled) m_bsd_in->init();
199
200 #if !TARGET_IPHONE_SIMULATOR
201 /* network (syslog protocol) input module */
202 m_udp_in = (module_t *)calloc(1, sizeof(module_t));
203 if (m_udp_in == NULL)
204 {
205 asldebug("alloc failed (init_modules udp_in)\n");
206 exit(1);
207 }
208
209 m_udp_in->name = "udp_in";
210 m_udp_in->enabled = activate_udp_in;
211 m_udp_in->init = udp_in_init;
212 m_udp_in->reset = udp_in_reset;
213 m_udp_in->close = udp_in_close;
214
215 if (m_udp_in->enabled) m_udp_in->init();
216
217 /* remote (iOS support) module */
218 m_remote = (module_t *)calloc(1, sizeof(module_t));
219 if (m_remote == NULL)
220 {
221 asldebug("alloc failed (init_modules remote)\n");
222 exit(1);
223 }
224
225 m_remote->name = "remote";
226 m_remote->enabled = remote_enabled;
227 m_remote->init = remote_init;
228 m_remote->reset = remote_reset;
229 m_remote->close = remote_close;
230
231 if (m_remote->enabled) m_remote->init();
232 #endif /* TARGET_IPHONE_SIMULATOR */
233
234 /* save modules in global.module array */
235 #if TARGET_IPHONE_SIMULATOR
236 global.module_count = 2;
237 #else
238 global.module_count = 6;
239 #endif
240 global.module = (module_t **)calloc(global.module_count, sizeof(module_t *));
241 if (global.module == NULL)
242 {
243 asldebug("alloc failed (init_modules)\n");
244 exit(1);
245 }
246
247 global.module[m++] = m_asl;
248 global.module[m++] = m_bsd_in;
249 #if !TARGET_IPHONE_SIMULATOR
250 global.module[m++] = m_bsd_out;
251 global.module[m++] = m_klog_in;
252 global.module[m++] = m_udp_in;
253 global.module[m++] = m_remote;
254 #endif
255 }
256
257 static void
258 writepid(int *first)
259 {
260 struct stat sb;
261 FILE *fp;
262
263 if (first != NULL)
264 {
265 *first = 1;
266 memset(&sb, 0, sizeof(struct stat));
267 if (stat(_PATH_PIDFILE, &sb) == 0)
268 {
269 if (S_ISREG(sb.st_mode)) *first = 0;
270 }
271 }
272
273 fp = fopen(_PATH_PIDFILE, "w");
274 if (fp != NULL)
275 {
276 fprintf(fp, "%d\n", global.pid);
277 fclose(fp);
278 }
279 }
280
281 void
282 launch_config()
283 {
284 launch_data_t tmp, pdict;
285 kern_return_t status;
286
287 tmp = launch_data_new_string(LAUNCH_KEY_CHECKIN);
288 global.launch_dict = launch_msg(tmp);
289 launch_data_free(tmp);
290
291 if (global.launch_dict == NULL)
292 {
293 asldebug("%d launchd checkin failed\n", global.pid);
294 exit(1);
295 }
296
297 tmp = launch_data_dict_lookup(global.launch_dict, LAUNCH_JOBKEY_MACHSERVICES);
298 if (tmp == NULL)
299 {
300 asldebug("%d launchd lookup of LAUNCH_JOBKEY_MACHSERVICES failed\n", global.pid);
301 exit(1);
302 }
303
304 pdict = launch_data_dict_lookup(tmp, SERVICE_NAME);
305 if (pdict == NULL)
306 {
307 asldebug("%d launchd lookup of SERVICE_NAME failed\n", global.pid);
308 exit(1);
309 }
310
311 global.server_port = launch_data_get_machport(pdict);
312
313 /* port for receiving MACH_NOTIFY_DEAD_NAME notifications */
314 status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &(global.dead_session_port));
315 if (status != KERN_SUCCESS)
316 {
317 asldebug("mach_port_allocate dead_session_port failed: %d", status);
318 exit(1);
319 }
320
321 status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &(global.listen_set));
322 if (status != KERN_SUCCESS)
323 {
324 asldebug("mach_port_allocate listen_set failed: %d", status);
325 exit(1);
326 }
327
328 status = mach_port_move_member(mach_task_self(), global.server_port, global.listen_set);
329 if (status != KERN_SUCCESS)
330 {
331 asldebug("mach_port_move_member server_port failed: %d", status);
332 exit(1);
333 }
334
335 status = mach_port_move_member(mach_task_self(), global.dead_session_port, global.listen_set);
336 if (status != KERN_SUCCESS)
337 {
338 asldebug("mach_port_move_member dead_session_port failed (%u)", status);
339 exit(1);
340 }
341 }
342
343 void
344 config_debug(int enable, const char *path)
345 {
346 OSSpinLockLock(&global.lock);
347
348 global.debug = enable;
349 free(global.debug_file);
350 global.debug_file = NULL;
351 if (path != NULL) global.debug_file = strdup(path);
352
353 OSSpinLockUnlock(&global.lock);
354 }
355
356 void
357 config_data_store(int type, uint32_t file_max, uint32_t memory_max, uint32_t str_memory_max)
358 {
359 pthread_mutex_lock(global.db_lock);
360
361 if (global.dbtype & DB_TYPE_FILE)
362 {
363 asl_store_close(global.file_db);
364 global.file_db = NULL;
365 }
366
367 if (global.dbtype & DB_TYPE_MEMORY)
368 {
369 asl_memory_close(global.memory_db);
370 global.memory_db = NULL;
371 }
372
373 global.dbtype = type;
374 global.db_file_max = file_max;
375 global.db_memory_max = memory_max;
376 global.db_memory_str_max = str_memory_max;
377
378 pthread_mutex_unlock(global.db_lock);
379 }
380
381 void
382 write_boot_log(int first)
383 {
384 int mib[2] = {CTL_KERN, KERN_BOOTTIME};
385 size_t len;
386 asl_msg_t *msg;
387 char buf[256];
388 struct utmpx utx;
389
390 if (first == 0)
391 {
392 /* syslogd restart */
393 msg = asl_msg_new(ASL_TYPE_MSG);
394 if (msg == NULL) return;
395
396 asl_msg_set_key_val(msg, ASL_KEY_SENDER, "syslogd");
397 asl_msg_set_key_val(msg, ASL_KEY_FACILITY, "daemon");
398 asl_msg_set_key_val(msg, ASL_KEY_LEVEL, "Notice");
399 asl_msg_set_key_val(msg, ASL_KEY_UID, "0");
400 asl_msg_set_key_val(msg, ASL_KEY_GID, "0");
401 snprintf(buf, sizeof(buf), "%u", global.pid);
402 asl_msg_set_key_val(msg, ASL_KEY_PID, buf);
403 asl_msg_set_key_val(msg, ASL_KEY_MSG, "--- syslogd restarted ---");
404 process_message(msg, SOURCE_INTERNAL);
405 return;
406 }
407
408 bzero(&utx, sizeof(utx));
409 utx.ut_type = BOOT_TIME;
410 utx.ut_pid = 1;
411
412 /* get the boot time */
413 len = sizeof(struct timeval);
414 if (sysctl(mib, 2, &utx.ut_tv, &len, NULL, 0) < 0)
415 {
416 gettimeofday(&utx.ut_tv, NULL);
417 }
418
419 pututxline(&utx);
420
421 msg = asl_msg_new(ASL_TYPE_MSG);
422 if (msg == NULL) return;
423
424 asl_msg_set_key_val(msg, ASL_KEY_SENDER, "bootlog");
425 asl_msg_set_key_val(msg, ASL_KEY_FACILITY, "com.apple.system.utmpx");
426 asl_msg_set_key_val(msg, ASL_KEY_LEVEL, "Notice");
427 asl_msg_set_key_val(msg, ASL_KEY_UID, "0");
428 asl_msg_set_key_val(msg, ASL_KEY_GID, "0");
429 asl_msg_set_key_val(msg, ASL_KEY_PID, "0");
430 snprintf(buf, sizeof(buf), "BOOT_TIME %lu %u", (unsigned long)utx.ut_tv.tv_sec, (unsigned int)utx.ut_tv.tv_usec);
431 asl_msg_set_key_val(msg, ASL_KEY_MSG, buf);
432 asl_msg_set_key_val(msg, "ut_id", "0x00 0x00 0x00 0x00");
433 asl_msg_set_key_val(msg, "ut_pid", "1");
434 asl_msg_set_key_val(msg, "ut_type", "2");
435 snprintf(buf, sizeof(buf), "%lu", (unsigned long)utx.ut_tv.tv_sec);
436 asl_msg_set_key_val(msg, ASL_KEY_TIME, buf);
437 asl_msg_set_key_val(msg, "ut_tv.tv_sec", buf);
438 snprintf(buf, sizeof(buf), "%u", (unsigned int)utx.ut_tv.tv_usec);
439 asl_msg_set_key_val(msg, "ut_tv.tv_usec", buf);
440 snprintf(buf, sizeof(buf), "%u%s", (unsigned int)utx.ut_tv.tv_usec, (utx.ut_tv.tv_usec == 0) ? "" : "000");
441 asl_msg_set_key_val(msg, ASL_KEY_TIME_NSEC, buf);
442
443 process_message(msg, SOURCE_INTERNAL);
444 }
445
446 int
447 main(int argc, const char *argv[])
448 {
449 int32_t i;
450 uint64_t master_val;
451 #if !TARGET_IPHONE_SIMULATOR
452 int network_change_token;
453 #endif
454 int quota_file_token, asl_db_token, master_token;
455 char tstr[32], *notify_key;
456 time_t now;
457 int first_syslogd_start = 1;
458
459 #if TARGET_IPHONE_SIMULATOR
460 const char *sim_log_dir = getenv("SIMULATOR_LOG_ROOT");
461 const char *sim_resource_dir = getenv("SIMULATOR_SHARED_RESOURCES_DIRECTORY");
462 char *p;
463
464 /* assert is evil */
465 assert(sim_log_dir && sim_resource_dir);
466
467 asprintf((char **)&_path_syslogd_log, "%s/syslogd.log", sim_log_dir);
468 asprintf((char **)&_path_pidfile, "%s/var/run/syslog.pid", sim_resource_dir);
469
470 if (_path_syslogd_log == NULL) _path_syslogd_log = "/tmp/syslogd.log";
471 else mkpath_np(sim_log_dir, 0755);
472
473 if (_path_pidfile == NULL)
474 {
475 _path_pidfile = "/tmp/syslog.pid";
476 }
477 else
478 {
479 p = strrchr(_path_pidfile, '/');
480 *p = '\0';
481 mkpath_np(_path_pidfile, 0755);
482 *p = '/';
483 }
484 #endif
485
486 #if TARGET_OS_IPHONE
487 /*
488 * Reset owner, group, and permissions in /var/mobile/Library/Logs
489 * in case something created them incorrectly. syslogd was
490 * guilty of this in the past, creating them with owner root.
491 */
492
493 asl_secure_chown_chmod_dir("/private/var/mobile/Library/Logs", 501, 501, 0755);
494 asl_secure_chown_chmod_dir("/private/var/mobile/Library/Logs/CrashReporter", 501, 501, 0755);
495 asl_secure_chown_chmod_dir("/private/var/mobile/Library/Logs/CrashReporter/DiagnosticLogs", 501, 501, 0755);
496 #endif
497
498 /* Set I/O policy */
499 setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_PASSIVE);
500
501 #if !TARGET_OS_IPHONE
502 /* Set Quarantine */
503 qtn_proc_t qp = qtn_proc_alloc();
504 qtn_proc_set_identifier(qp, "com.apple.syslogd");
505 qtn_proc_set_flags(qp, QTN_FLAG_SANDBOX | QTN_FLAG_HARD);
506 qtn_proc_apply_to_self(qp);
507 qtn_proc_free(qp);
508 #endif
509
510 memset(&global, 0, sizeof(struct global_s));
511
512 global.db_lock = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));
513 pthread_mutex_init(global.db_lock, NULL);
514
515 /*
516 * Create work queue, but suspend until output modules are initialized.
517 */
518 global.work_queue = dispatch_queue_create("Work Queue", NULL);
519 dispatch_suspend(global.work_queue);
520
521 init_globals();
522
523 #if TARGET_OS_EMBEDDED
524 remote_enabled = 1;
525 activate_bsd_out = 0;
526 #endif
527
528 /* prevent malloc from calling ASL on error */
529 _malloc_no_asl_log = 1;
530
531 /* first pass sets up default configurations */
532 for (i = 1; i < argc; i++)
533 {
534 if (streq(argv[i], "-config"))
535 {
536 if (((i + 1) < argc) && (argv[i+1][0] != '-'))
537 {
538 i++;
539 if (streq(argv[i], "mac"))
540 {
541 global.dbtype = DB_TYPE_FILE;
542 global.db_file_max = 25600000;
543 }
544 else if (streq(argv[i], "appletv"))
545 {
546 global.dbtype = DB_TYPE_FILE;
547 global.db_file_max = 10240000;
548 }
549 else if (streq(argv[i], "iphone"))
550 {
551 #if TARGET_IPHONE_SIMULATOR
552 global.dbtype = DB_TYPE_FILE;
553 global.db_file_max = 25600000;
554 #else
555 global.dbtype = DB_TYPE_MEMORY;
556 remote_enabled = 1;
557 #endif
558 }
559 }
560 }
561 }
562
563 for (i = 1; i < argc; i++)
564 {
565 if (streq(argv[i], "-d"))
566 {
567 global.debug = 1;
568 if (((i+1) < argc) && (argv[i+1][0] != '-')) global.debug_file = strdup(argv[++i]);
569 }
570 else if (streq(argv[i], "-db"))
571 {
572 if (((i + 1) < argc) && (argv[i+1][0] != '-'))
573 {
574 i++;
575 if (streq(argv[i], "file"))
576 {
577 global.dbtype |= DB_TYPE_FILE;
578 if (((i + 1) < argc) && (argv[i+1][0] != '-')) global.db_file_max = atol(argv[++i]);
579 }
580 else if (streq(argv[i], "memory"))
581 {
582 global.dbtype |= DB_TYPE_MEMORY;
583 if (((i + 1) < argc) && (argv[i+1][0] != '-')) global.db_memory_max = atol(argv[++i]);
584 }
585 }
586 }
587 else if (streq(argv[i], "-m"))
588 {
589 if ((i + 1) < argc) global.mark_time = 60 * atoll(argv[++i]);
590 }
591 else if (streq(argv[i], "-utmp_ttl"))
592 {
593 if ((i + 1) < argc) global.utmp_ttl = atol(argv[++i]);
594 }
595 else if (streq(argv[i], "-mps_limit"))
596 {
597 if ((i + 1) < argc) global.mps_limit = atol(argv[++i]);
598 }
599 else if (streq(argv[i], "-dup_delay"))
600 {
601 if ((i + 1) < argc) global.bsd_max_dup_time = atoll(argv[++i]);
602 }
603 #if !TARGET_IPHONE_SIMULATOR
604 else if (streq(argv[i], "-klog_in"))
605 {
606 if ((i + 1) < argc) activate_klog_in = atoi(argv[++i]);
607 }
608 else if (streq(argv[i], "-bsd_in"))
609 {
610 if ((i + 1) < argc) activate_bsd_in = atoi(argv[++i]);
611 }
612 else if (streq(argv[i], "-udp_in"))
613 {
614 if ((i + 1) < argc) activate_udp_in = atoi(argv[++i]);
615 }
616 #endif
617 else if (streq(argv[i], "-launchd_in"))
618 {
619 if ((i + 1) < argc) global.launchd_enabled = atoi(argv[++i]);
620 }
621 #if !TARGET_IPHONE_SIMULATOR
622 else if (streq(argv[i], "-bsd_out"))
623 {
624 if ((i + 1) < argc) activate_bsd_out = atoi(argv[++i]);
625 }
626 else if (streq(argv[i], "-remote"))
627 {
628 if ((i + 1) < argc) remote_enabled = atoi(argv[++i]);
629 }
630 #endif
631 }
632
633 if (global.dbtype == 0)
634 {
635 global.dbtype = DB_TYPE_FILE;
636 global.db_file_max = 25600000;
637 }
638
639 signal(SIGHUP, SIG_IGN);
640
641 memset(tstr, 0, sizeof(tstr));
642 now = time(NULL);
643 ctime_r(&now, tstr);
644 tstr[19] = '\0';
645 asldebug("\n%s syslogd PID %d starting\n", tstr, global.pid);
646
647 writepid(&first_syslogd_start);
648
649 /*
650 * Log UTMPX boot time record
651 */
652 write_boot_log(first_syslogd_start);
653
654 /* default NOTIFY_SYSTEM_MASTER settings */
655 master_val = 0x0;
656 notify_register_plain(NOTIFY_SYSTEM_MASTER, &master_token);
657 notify_set_state(master_token, master_val);
658
659 asldebug("reading launch plist\n");
660 launch_config();
661
662 asldebug("initializing modules\n");
663 init_modules();
664
665 #if !TARGET_IPHONE_SIMULATOR
666 asldebug("setting up network change notification handler\n");
667
668 /* network change notification resets UDP and BSD modules */
669 notify_register_dispatch(kNotifySCNetworkChange, &network_change_token, global.work_queue, ^(int x){
670 if (activate_udp_in != 0) udp_in_reset();
671 if (activate_bsd_out != 0) bsd_out_reset();
672 });
673 #endif
674
675 asldebug("setting up quota notification handler\n");
676
677 notify_key = NULL;
678 asprintf(&notify_key, "%s%s", NOTIFY_PATH_SERVICE, NOQUOTA_FILE_PATH);
679 if (notify_key != NULL)
680 {
681 int status;
682
683 status = notify_register_dispatch(notify_key, &quota_file_token, dispatch_get_main_queue(), ^(int t){
684 struct stat sb;
685 memset(&sb, 0, sizeof(sb));
686 if (stat(NOQUOTA_FILE_PATH, &sb) == 0)
687 {
688 char *str = NULL;
689 asprintf(&str, "[Sender syslogd] [Level 2] [PID %u] [Facility syslog] [Message *** MESSAGE QUOTAS DISABLED FOR ALL PROCESSES ***]", global.pid);
690 internal_log_message(str);
691 free(str);
692 }
693 else
694 {
695 char *str = NULL;
696 asprintf(&str, "[Sender syslogd] [Level 2] [PID %u] [Facility syslog] [Message *** MESSAGE QUOTAS ENABLED ***]", global.pid);
697 internal_log_message(str);
698 free(str);
699 }
700 });
701
702 free(notify_key);
703 }
704
705 /* SIGHUP resets all modules */
706 global.sig_hup_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, (uintptr_t)SIGHUP, 0, dispatch_get_main_queue());
707 dispatch_source_set_event_handler(global.sig_hup_src, ^{
708 dispatch_async(global.work_queue, ^{
709 int i;
710
711 asldebug("SIGHUP reset\n");
712 for (i = 0; i < global.module_count; i++)
713 {
714 if (global.module[i]->enabled != 0) global.module[i]->reset();
715 }
716 });
717 });
718
719 dispatch_resume(global.sig_hup_src);
720
721 /* register for DB notification (posted by dbserver) for performance */
722 notify_register_plain(kNotifyASLDBUpdate, &asl_db_token);
723
724 /* timer for MARK facility */
725 if (global.mark_time > 0)
726 {
727 global.mark_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
728 dispatch_source_set_event_handler(global.mark_timer, ^{
729 asl_mark();
730 });
731 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);
732 dispatch_resume(global.mark_timer);
733 }
734
735 #if !TARGET_IPHONE_SIMULATOR
736 asldebug("starting launchd input channel\n");
737 /*
738 * Start launchd service
739 * This pins a thread in _vprocmgr_log_drain. Eventually we will either
740 * remove the whole stderr/stdout -> ASL mechanism entirely, or come up
741 * with a communication channel that we can trigger with a dispatch source.
742 */
743 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
744 forever _vprocmgr_log_drain(NULL, NULL, launchd_callback);
745 });
746 #endif
747
748 asldebug("starting mach service\n");
749 /*
750 * Start mach server
751 * Parks a thread in database_server. In notifyd, we found that the overhead of
752 * a dispatch source for mach calls was too high, especially on iOS.
753 */
754 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
755 database_server();
756 });
757
758 /* go to work */
759 asldebug("starting work queue\n");
760 dispatch_resume(global.work_queue);
761 dispatch_main();
762
763 /* NOTREACHED */
764 return 0;
765 }