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