]> git.saurik.com Git - apple/configd.git/blob - Plugins/Logger/logger.c
configd-453.18.tar.gz
[apple/configd.git] / Plugins / Logger / logger.c
1 /*
2 * Copyright (c) 2005-2011 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 /*
25 * Modification History
26 *
27 * January 15, 2005 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <sys/filio.h>
34 #include <sys/ioctl.h>
35 #include <sys/socket.h>
36 #include <sys/time.h>
37 #include <sys/types.h>
38 #include <net/ethernet.h>
39 #include <net/if.h>
40 #include <net/if_dl.h>
41 #include <net/if_media.h>
42 #include <net/if_types.h>
43 #include <net/if_var.h>
44 #include <sys/kern_event.h>
45 #include <netinet/in.h>
46 #include <netinet/in_var.h>
47 #include <netinet6/in6_var.h>
48 #include <ifaddrs.h>
49 #include <arpa/inet.h>
50
51 #include <TargetConditionals.h>
52 #include <CoreFoundation/CoreFoundation.h>
53 #include <SystemConfiguration/SystemConfiguration.h>
54 #include <SystemConfiguration/SCPrivate.h>
55 #include <IOKit/IOKitLib.h>
56 #include <IOKit/IOMessage.h>
57 #include <IOKit/pwr_mgt/IOPM.h>
58 #include <IOKit/pwr_mgt/IOPMLib.h>
59 #include <IOKit/pwr_mgt/IOPMLibPrivate.h>
60
61 #include <dnsinfo.h>
62 #include <network_information.h>
63 #include <notify.h>
64 #if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
65 #include <utmpx.h>
66 #include <utmpx_thread.h>
67 #endif // !(__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
68
69
70 /* generic MessageTracer keys */
71 #define MSGTRACER_KEY_DOMAIN "com.apple.message.domain"
72 #define MSGTRACER_KEY_SIG "com.apple.message.signature"
73 #define MSGTRACER_KEY_UUID "com.apple.message.uuid"
74 #define MSGTRACER_KEY_VALUE1 "com.apple.message.value"
75
76
77 #define MY_ASL_FACILITY "com.apple.SystemConfiguration.Logger"
78 #define MY_MSGTRACER_DOMAIN "com.apple.network.log"
79
80
81 static aslmsg log_msg = NULL;
82 static io_connect_t power = MACH_PORT_NULL;
83 static Boolean verbose = FALSE;
84
85
86 static char *
87 elapsed()
88 {
89 static char str[128];
90 struct tm tm_diff;
91 struct tm tm_now;
92 struct timeval tv_diff;
93 struct timeval tv_now;
94 static struct timeval tv_then = { 0, 0 };
95
96 (void)gettimeofday(&tv_now, NULL);
97
98 (void)localtime_r(&tv_now.tv_sec, &tm_now);
99
100 timersub(&tv_now, &tv_then, &tv_diff);
101 (void)localtime_r(&tv_diff.tv_sec, &tm_diff);
102 #ifdef MAIN
103 sprintf(str, "%2d:%02d:%02d.%03d (+%ld.%03d)",
104 tm_now.tm_hour,
105 tm_now.tm_min,
106 tm_now.tm_sec,
107 tv_now.tv_usec / 1000,
108 tv_diff.tv_sec,
109 tv_diff.tv_usec / 1000);
110 #else
111 sprintf(str, ".%03d (+%ld.%03d)",
112 tv_now.tv_usec / 1000,
113 tv_diff.tv_sec,
114 tv_diff.tv_usec / 1000);
115 #endif
116
117 tv_then = tv_now;
118 return str;
119 }
120
121
122 #pragma mark -
123 #pragma mark [Network] Kernel Events
124
125
126 static CFStringRef
127 copyInterfaceFlags(const char *if_name)
128 {
129 const char * iff_up = "? ";
130 struct ifreq ifr;
131 const char *ifm_active = "? ";
132 int sock;
133 CFStringRef str = NULL;
134
135 sock = socket(AF_INET, SOCK_DGRAM, 0);
136 if (sock == -1) {
137 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("socket() failed"));
138 return NULL;
139 }
140
141 bzero((char *)&ifr, sizeof(ifr));
142 (void) strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
143 if (ioctl(sock, SIOCGIFFLAGS, (caddr_t)&ifr) == 0) {
144 struct ifmediareq ifm;
145
146 iff_up = (ifr.ifr_flags & IFF_UP) ? "yes" : "no ";
147
148 bzero((char *)&ifm, sizeof(ifm));
149 (void) strncpy(ifm.ifm_name, if_name, sizeof(ifm.ifm_name));
150 if ((ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifm) == 0) &&
151 (ifm.ifm_count > 0) &&
152 (ifm.ifm_status & IFM_AVALID)) {
153 ifm_active = (ifm.ifm_status & IFM_ACTIVE) ? "yes" : "no ";
154 }
155
156 str = CFStringCreateWithFormat(NULL,
157 NULL,
158 CFSTR("\n%-5s: IFF_UP = %s IFM_ACTIVE = %s"),
159 if_name,
160 iff_up,
161 ifm_active);
162 }
163
164 (void)close(sock);
165
166 return str;
167 }
168
169
170 static int
171 prefixLength(struct sockaddr_in6 *sin6)
172 {
173 register u_int8_t *name = &sin6->sin6_addr.s6_addr[0];
174 register int byte;
175 register int bit;
176 int plen = 0;
177
178 for (byte = 0; byte < sizeof(struct in6_addr); byte++, plen += 8) {
179 if (name[byte] != 0xff) {
180 break;
181 }
182 }
183
184 if (byte == sizeof(struct in6_addr)) {
185 return plen;
186 }
187
188 for (bit = 7; bit != 0; bit--, plen++) {
189 if (!(name[byte] & (1 << bit))) {
190 break;
191 }
192 }
193
194 for (; bit != 0; bit--) {
195 if (name[byte] & (1 << bit)) {
196 return 0;
197 }
198 }
199
200 byte++;
201 for (; byte < sizeof(struct in6_addr); byte++) {
202 if (name[byte]) {
203 return 0;
204 }
205 }
206
207 return plen;
208 }
209
210
211 static void
212 KernelEvent_notification(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
213 {
214 int so = CFSocketGetNative(s);
215 int status;
216 union {
217 char bytes[1024];
218 struct kern_event_msg ev_msg1; // first kernel event
219 } buf;
220 struct kern_event_msg *ev_msg = &buf.ev_msg1;
221 int offset = 0;
222
223 status = recv(so, &buf, sizeof(buf), 0);
224 if (status == -1) {
225 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("recv() failed: %s"), strerror(errno));
226 CFSocketInvalidate(s);
227 return;
228 }
229
230 while (offset < status) {
231 if ((offset + ev_msg->total_size) > status) {
232 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("missed SYSPROTO_EVENT event, buffer not big enough"));
233 break;
234 }
235
236 switch (ev_msg->vendor_code) {
237 case KEV_VENDOR_APPLE :
238 switch (ev_msg->kev_class) {
239 case KEV_NETWORK_CLASS : {
240 void *event_data = &ev_msg->event_data[0];
241
242 switch (ev_msg->kev_subclass) {
243 case KEV_DL_SUBCLASS : {
244 struct net_event_data *ev;
245 char if_name[IFNAMSIZ];
246
247 ev = (struct net_event_data *)event_data;
248
249 snprintf(if_name, IFNAMSIZ, "%s%d",
250 ev->if_name,
251 ev->if_unit);
252
253 switch (ev_msg->event_code) {
254 case KEV_DL_IF_ATTACHED : {
255 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
256 CFSTR("%s kernel event: %s: attached"),
257 elapsed(),
258 if_name);
259 break;
260 }
261 case KEV_DL_IF_DETACHING : {
262 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
263 CFSTR("%s kernel event: %s: detaching"),
264 elapsed(),
265 if_name);
266 break;
267 }
268 case KEV_DL_IF_DETACHED : {
269 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
270 CFSTR("%s kernel event: %s: detached"),
271 elapsed(),
272 if_name);
273 break;
274 }
275 case KEV_DL_LINK_OFF : {
276 CFStringRef str;
277
278 str = verbose ? copyInterfaceFlags(if_name) : NULL;
279 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
280 CFSTR("%s kernel event: %s: link down%@"),
281 elapsed(),
282 if_name,
283 str != NULL ? str : CFSTR(""));
284 if (str != NULL) CFRelease(str);
285 break;
286 }
287 case KEV_DL_LINK_ON : {
288 CFStringRef str;
289
290 str = verbose ? copyInterfaceFlags(if_name) : NULL;
291 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
292 CFSTR("%s kernel event: %s: link up%@"),
293 elapsed(),
294 if_name,
295 str != NULL ? str : CFSTR(""));
296 if (str != NULL) CFRelease(str);
297 break;
298 }
299 default :
300 break;
301 }
302 break;
303 }
304 case KEV_INET_SUBCLASS : {
305 char addr[128];
306 struct kev_in_data *ev;
307 char if_name[IFNAMSIZ];
308 char mask[128];
309
310 ev = (struct kev_in_data *)event_data;
311
312 snprintf(if_name, IFNAMSIZ, "%s%d",
313 ev->link_data.if_name,
314 ev->link_data.if_unit);
315
316 switch (ev_msg->event_code) {
317 case KEV_INET_NEW_ADDR :
318 case KEV_INET_CHANGED_ADDR :
319 case KEV_INET_ADDR_DELETED : {
320 struct sockaddr_in sin;
321
322 bzero(&sin, sizeof(sin));
323 sin.sin_len = sizeof(sin);
324 sin.sin_family = AF_INET;
325 sin.sin_addr = ev->ia_addr;
326 _SC_sockaddr_to_string((struct sockaddr *)&sin, addr, sizeof(addr));
327
328 bzero(&sin, sizeof(sin));
329 sin.sin_len = sizeof(sin);
330 sin.sin_family = AF_INET;
331 sin.sin_addr.s_addr = ntohl(ev->ia_subnetmask);
332 _SC_sockaddr_to_string((struct sockaddr *)&sin, mask, sizeof(mask));
333 break;
334 }
335 default :
336 break;
337 }
338
339 switch (ev_msg->event_code) {
340 case KEV_INET_NEW_ADDR : {
341 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
342 CFSTR("%s kernel event: %s: IPv4 address added (%s/%s)"),
343 elapsed(),
344 if_name,
345 addr,
346 mask);
347 break;
348 }
349 case KEV_INET_CHANGED_ADDR : {
350 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
351 CFSTR("%s kernel event: %s: IPv4 address changed (%s/%s)"),
352 elapsed(),
353 if_name,
354 addr,
355 mask);
356 break;
357 }
358 case KEV_INET_ADDR_DELETED : {
359 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
360 CFSTR("%s kernel event: %s: IPv4 address removed (%s/%s)"),
361 elapsed(),
362 if_name,
363 addr,
364 mask);
365 break;
366 }
367 default :
368 break;
369 }
370 break;
371 }
372 case KEV_INET6_SUBCLASS : {
373 char addr[128];
374 struct kev_in6_data *ev;
375 char if_name[IFNAMSIZ];
376 int plen = 0;
377
378 ev = (struct kev_in6_data *)event_data;
379
380 snprintf(if_name, IFNAMSIZ, "%s%d",
381 ev->link_data.if_name,
382 ev->link_data.if_unit);
383
384 switch (ev_msg->event_code) {
385 case KEV_INET6_NEW_USER_ADDR :
386 case KEV_INET6_NEW_LL_ADDR :
387 case KEV_INET6_CHANGED_ADDR :
388 case KEV_INET6_ADDR_DELETED : {
389 _SC_sockaddr_to_string((struct sockaddr *)&ev->ia_addr, addr, sizeof(addr));
390 plen = prefixLength(&ev->ia_prefixmask);
391 break;
392 }
393 default :
394 break;
395 }
396
397 switch (ev_msg->event_code) {
398 case KEV_INET6_NEW_USER_ADDR :
399 case KEV_INET6_NEW_LL_ADDR : {
400 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
401 CFSTR("%s kernel event: %s: IPv6 address added (%s/%d)"),
402 elapsed(),
403 if_name,
404 addr,
405 plen);
406 break;
407 }
408 case KEV_INET6_CHANGED_ADDR : {
409 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
410 CFSTR("%s kernel event: %s: IPv6 address changed (%s/%d)"),
411 elapsed(),
412 if_name,
413 addr,
414 plen);
415 break;
416 }
417 case KEV_INET6_ADDR_DELETED : {
418 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
419 CFSTR("%s kernel event: %s: IPv6 address removed"),
420 elapsed(),
421 if_name);
422 break;
423 }
424 default :
425 break;
426 }
427 break;
428 }
429 default :
430 break;
431 }
432 break;
433 }
434 default :
435 break;
436 }
437 break;
438 default :
439 /* unrecognized vendor code */
440 break;
441 }
442 offset += ev_msg->total_size;
443 ev_msg = (struct kern_event_msg *)(void *)&buf.bytes[offset];
444 }
445
446 return;
447 }
448
449
450 static void
451 add_KernelEvent_notification()
452 {
453 CFSocketRef es;
454 CFSocketContext es_context = { 0, NULL, NULL, NULL, NULL };
455 struct kev_request kev_req;
456 CFRunLoopSourceRef rls;
457 int so;
458 int yes = 1;
459
460 /* Open an event socket */
461 so = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT);
462 if (so == -1) {
463 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("socket() failed"));
464 return;
465 }
466
467 /* establish filter to return all events */
468 kev_req.vendor_code = KEV_VENDOR_APPLE;
469 kev_req.kev_class = KEV_NETWORK_CLASS;
470 kev_req.kev_subclass = KEV_ANY_SUBCLASS;
471 if (ioctl(so, SIOCSKEVFILT, &kev_req) == -1) {
472 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("ioctl(, SIOCSKEVFILT, ) failed"));
473 (void)close(so);
474 return;
475 }
476
477 if (ioctl(so, FIONBIO, &yes) == -1) {
478 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("ioctl(, FIONBIO, ) failed"));
479 (void)close(so);
480 return;
481 }
482
483 /* Create a CFSocketRef for the PF_SYSTEM kernel event socket */
484 es = CFSocketCreateWithNative(NULL,
485 so,
486 kCFSocketReadCallBack,
487 KernelEvent_notification,
488 &es_context);
489
490 /* Create and add a run loop source for the event socket */
491 rls = CFSocketCreateRunLoopSource(NULL, es, -1);
492 CFRelease(es);
493
494 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
495 CFRelease(rls);
496
497 return;
498 }
499
500
501 #pragma mark -
502 #pragma mark Power Management Events
503
504
505 static void
506 power_notification(void *refcon, io_service_t service, natural_t messageType, void *messageArgument)
507 {
508 switch (messageType) {
509 case kIOMessageCanDevicePowerOff :
510 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
511 CFSTR("%s IORegisterForSystemPower: can device power off?"),
512 elapsed());
513 break;
514 case kIOMessageDeviceWillPowerOff :
515 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
516 CFSTR("%s IORegisterForSystemPower: device will power off"),
517 elapsed());
518 break;
519 case kIOMessageDeviceWillNotPowerOff :
520 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
521 CFSTR("%s IORegisterForSystemPower: device will not power off"),
522 elapsed());
523 break;
524 case kIOMessageDeviceHasPoweredOn :
525 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
526 CFSTR("%s IORegisterForSystemPower: device has powered on"),
527 elapsed());
528 break;
529 case kIOMessageCanSystemPowerOff :
530 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
531 CFSTR("%s IORegisterForSystemPower: can system power off?"),
532 elapsed());
533 break;
534 case kIOMessageSystemWillPowerOff :
535 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
536 CFSTR("%s IORegisterForSystemPower: system will power off"),
537 elapsed());
538 break;
539 case kIOMessageSystemWillNotPowerOff :
540 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
541 CFSTR("%s IORegisterForSystemPower: system will not power off"),
542 elapsed());
543 break;
544 case kIOMessageCanSystemSleep :
545 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
546 CFSTR("%s IORegisterForSystemPower: can system sleep?"),
547 elapsed());
548 /*
549 * Idle sleep is about to kick in, but applications have
550 * a chance to allow sleep (by calling IOAllowPowerChange)
551 * or to prevent sleep (by calling IOCancelPowerChange).
552 */
553 IOAllowPowerChange(power, (long)messageArgument);
554 break;
555 case kIOMessageSystemWillSleep :
556 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
557 CFSTR("%s IORegisterForSystemPower: system will sleep"),
558 elapsed());
559 IOAllowPowerChange(power, (long)messageArgument);
560 break;
561 case kIOMessageSystemWillNotSleep :
562 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
563 CFSTR("%s IORegisterForSystemPower: system will not sleep"),
564 elapsed());
565 break;
566 case kIOMessageSystemHasPoweredOn :
567 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
568 CFSTR("%s IORegisterForSystemPower: system has powered on"),
569 elapsed());
570 break;
571 case kIOMessageSystemWillRestart :
572 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
573 CFSTR("%s IORegisterForSystemPower: system will restart"),
574 elapsed());
575 break;
576 case kIOMessageSystemWillPowerOn :
577 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
578 CFSTR("%s IORegisterForSystemPower: system will power on"),
579 elapsed());
580 break;
581 default :
582 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
583 CFSTR("%s IORegisterForSystemPower: message=%08lx"),
584 elapsed(),
585 (long unsigned int)messageType);
586 break;
587 }
588
589 return;
590 }
591
592
593 static void
594 add_power_notification()
595 {
596 io_object_t iterator;
597 IONotificationPortRef notify;
598
599 power = IORegisterForSystemPower(0, &notify, power_notification, &iterator);
600 if (power == MACH_PORT_NULL) {
601 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("IORegisterForSystemPower() failed"));
602 return;
603 }
604
605 CFRunLoopAddSource(CFRunLoopGetCurrent(),
606 IONotificationPortGetRunLoopSource(notify),
607 kCFRunLoopCommonModes);
608
609 return;
610 }
611
612
613 #ifdef kIOPMMessageSleepWakeUUIDChange
614 static void
615 wake_uuid_notification(void *refcon, io_service_t service, natural_t messageType, void *messageArgument)
616 {
617 CFStringRef wake_uuid = NULL;
618
619 if (messageType == kIOPMMessageSleepWakeUUIDChange) {
620 if (messageArgument == kIOPMMessageSleepWakeUUIDSet) {
621 wake_uuid = IORegistryEntryCreateCFProperty(service, CFSTR(kIOPMSleepWakeUUIDKey), NULL, 0);
622 }
623
624 if (wake_uuid != NULL) {
625 char uuid[256];
626
627 _SC_cfstring_to_cstring(wake_uuid, uuid, sizeof(uuid), kCFStringEncodingUTF8);
628 asl_set(log_msg, MSGTRACER_KEY_DOMAIN, MY_MSGTRACER_DOMAIN);
629 asl_set(log_msg, MSGTRACER_KEY_UUID , uuid);
630
631 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
632 CFSTR("%s wake UUID notification: UUID set (%@)"),
633 elapsed(),
634 wake_uuid);
635
636 CFRelease(wake_uuid);
637 } else {
638 asl_unset(log_msg, MSGTRACER_KEY_DOMAIN);
639 asl_unset(log_msg, MSGTRACER_KEY_UUID);
640
641 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
642 CFSTR("%s wake UUID notification: UUID not set"),
643 elapsed());
644 }
645 }
646
647 return;
648 }
649
650
651 static void
652 add_wake_uuid_notification()
653 {
654 kern_return_t kr;
655 io_object_t notification = IO_OBJECT_NULL;
656 IONotificationPortRef notifyPort;
657 io_service_t service;
658
659 notifyPort = IONotificationPortCreate(kIOMasterPortDefault);
660 service = IORegistryEntryFromPath(kIOMasterPortDefault,
661 kIOPowerPlane ":/IOPowerConnection/IOPMrootDomain");
662 kr = IOServiceAddInterestNotification(notifyPort,
663 service,
664 kIOGeneralInterest,
665 wake_uuid_notification,
666 NULL, // refCon
667 &notification);
668 if (kr != KERN_SUCCESS) {
669 SCLOG(NULL, NULL, ASL_LEVEL_ERR,
670 CFSTR("IOServiceAddInterestNotification() failed, kr=0x%x"),
671 kr);
672 return;
673 }
674
675 CFRunLoopAddSource(CFRunLoopGetCurrent(),
676 IONotificationPortGetRunLoopSource(notifyPort),
677 kCFRunLoopDefaultMode);
678
679 wake_uuid_notification(NULL,
680 service,
681 kIOPMMessageSleepWakeUUIDChange,
682 kIOPMMessageSleepWakeUUIDSet);
683
684 return;
685 }
686 #endif // kIOPMMessageSleepWakeUUIDChange
687
688
689 #pragma mark -
690 #pragma mark SCDynamicStore "network" Events
691
692
693 static void
694 NetworkChange_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
695 {
696 CFIndex i;
697 CFIndex nk;
698 CFMutableStringRef str;
699
700 str = CFStringCreateMutable(NULL, 0);
701 CFStringAppendFormat(str,
702 NULL,
703 CFSTR("%s SCDynamicStore \"network\" notification"),
704 elapsed());
705
706 nk = CFArrayGetCount(changedKeys);
707 for (i = 0; i < nk; i++) {
708 CFArrayRef components;
709 CFStringRef key;
710 CFIndex nc;
711
712 key = CFArrayGetValueAtIndex(changedKeys, i);
713
714 components = CFStringCreateArrayBySeparatingStrings(NULL, key, CFSTR("/"));
715 if (components == NULL) {
716 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
717 continue;
718 }
719
720 nc = CFArrayGetCount(components);
721 switch (nc) {
722 case 5 : {
723 CFStringRef entity_id;
724
725 entity_id = CFArrayGetValueAtIndex(components, 4);
726 if (CFEqual(entity_id, kSCEntNetLink)) {
727 CFDictionaryRef dict;
728 const char *val = "?";
729
730 dict = SCDynamicStoreCopyValue(store, key);
731 if (dict != NULL) {
732 CFBooleanRef link;
733
734 link = CFDictionaryGetValue(dict, kSCPropNetLinkActive);
735 if (link != NULL) {
736 val = CFBooleanGetValue(link) ? "up" : "down";
737 }
738
739 CFRelease(dict);
740 }
741 CFStringAppendFormat(str, NULL, CFSTR("\n%@ (%s)"), key, val);
742 } else if (CFEqual(entity_id, kSCEntNetIPv4) ||
743 CFEqual(entity_id, kSCEntNetIPv6) ||
744 CFEqual(entity_id, kSCEntNetDNS)) {
745 CFDictionaryRef dict;
746
747 dict = SCDynamicStoreCopyValue(store, key);
748 if (dict != NULL) {
749 CFStringRef val;
750
751 val = _SCCopyDescription(dict, NULL);
752 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : %@"), key, val);
753 CFRelease(val);
754 CFRelease(dict);
755 } else {
756 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : removed"), key);
757 }
758 } else if (CFEqual(entity_id, kSCEntNetAirPort)) {
759 CFDictionaryRef dict;
760
761 dict = SCDynamicStoreCopyValue(store, key);
762 if (dict != NULL) {
763 CFStringRef ssid_str;
764
765 ssid_str = CFDictionaryGetValue(dict, CFSTR("SSID_STR"));
766 if (ssid_str != NULL) {
767 CFDataRef bssid;
768
769 bssid = CFDictionaryGetValue(dict, CFSTR("BSSID"));
770 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : SSID: %@ BSSID: %s"),
771 key,
772 ssid_str,
773 (bssid != NULL) ? ether_ntoa((struct ether_addr *)CFDataGetBytePtr(bssid)) : "<unknown>");
774 } else {
775 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : no SSID"), key);
776 }
777 CFRelease(dict);
778 } else {
779 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : removed"), key);
780 }
781 } else if (CFEqual(entity_id, kSCEntNetService)) {
782 CFDictionaryRef dict;
783 CFStringRef rank = kSCNetworkServicePrimaryRankDefault;
784
785 dict = SCDynamicStoreCopyValue(store, key);
786 if ((dict == NULL) ||
787 !CFDictionaryGetValueIfPresent(dict,
788 kSCPropNetServicePrimaryRank,
789 (const void **)&rank)) {
790 rank = kSCNetworkServicePrimaryRankDefault;
791 }
792 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : Rank = %@"), key, rank);
793 if (dict != NULL) CFRelease(dict);
794 } else {
795 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
796 }
797 break;
798 }
799
800 case 4 : {
801 static CFStringRef rank_setup_prefix = NULL;
802 static CFStringRef rank_state_prefix = NULL;
803
804 if (rank_setup_prefix == NULL) {
805 rank_setup_prefix = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
806 kSCDynamicStoreDomainSetup,
807 CFSTR(""),
808 NULL);
809 rank_state_prefix = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
810 kSCDynamicStoreDomainState,
811 CFSTR(""),
812 NULL);
813 }
814
815 if (CFStringHasPrefix(key, rank_setup_prefix) ||
816 CFStringHasPrefix(key, rank_state_prefix)) {
817 CFDictionaryRef dict;
818 CFStringRef rank = kSCNetworkServicePrimaryRankDefault;
819
820 dict = SCDynamicStoreCopyValue(store, key);
821 if ((dict == NULL) ||
822 !CFDictionaryGetValueIfPresent(dict,
823 kSCPropNetServicePrimaryRank,
824 (const void **)&rank)) {
825 rank = kSCNetworkServicePrimaryRankDefault;
826 }
827 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : Rank = %@"), key, rank);
828 if (dict != NULL) CFRelease(dict);
829 } else {
830 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
831 }
832 break;
833 }
834
835 case 2 :
836 if (CFEqual(CFArrayGetValueAtIndex(components, 1),
837 CFSTR(kIOPMSystemPowerCapabilitiesKeySuffix))) {
838 CFNumberRef num;
839
840 num = SCDynamicStoreCopyValue(store, key);
841 if (num != NULL) {
842 IOPMSystemPowerStateCapabilities capabilities;
843
844 if (isA_CFNumber(num) &&
845 CFNumberGetValue(num, kCFNumberSInt32Type, &capabilities)) {
846 CFStringAppendFormat(str, NULL, CFSTR("\n%@ (0x%x)"), key, capabilities);
847 }
848
849 CFRelease(num);
850 }
851 } else {
852 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
853 }
854 break;
855
856 default :
857 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
858 break;
859 }
860
861 CFRelease(components);
862 }
863
864 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO, CFSTR("%@"), str);
865 CFRelease(str);
866 return;
867 }
868
869
870 static void
871 add_NetworkChange_keys(CFMutableArrayRef keys,
872 CFMutableArrayRef patterns,
873 CFStringRef entity,
874 Boolean doGlobal,
875 Boolean doService,
876 Boolean doInterface)
877 {
878 CFStringRef key;
879 CFStringRef pattern;
880
881 if (doGlobal) {
882 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainSetup, entity);
883 CFArrayAppendValue(keys, key);
884 CFRelease(key);
885
886 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, entity);
887 CFArrayAppendValue(keys, key);
888 CFRelease(key);
889 }
890
891 if (doService) {
892 pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, kSCCompAnyRegex, entity);
893 CFArrayAppendValue(patterns, pattern);
894 CFRelease(pattern);
895
896 pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, entity);
897 CFArrayAppendValue(patterns, pattern);
898 CFRelease(pattern);
899 }
900
901 if (doInterface) {
902 pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, entity);
903 CFArrayAppendValue(patterns, pattern);
904 CFRelease(pattern);
905 }
906
907 return;
908 }
909
910
911 static void
912 add_NetworkChange_notification()
913 {
914 CFStringRef dns_key;
915 CFStringRef key;
916 CFMutableArrayRef keys;
917 Boolean ok;
918 CFMutableArrayRef patterns;
919 SCDynamicStoreRef store;
920 CFRunLoopSourceRef rls;
921
922 store = SCDynamicStoreCreate(NULL, CFSTR("Logger.bundle-NetworkChange"), NetworkChange_notification, NULL);
923 if (store == NULL) {
924 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreate() failed"));
925 return;
926 }
927
928 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
929 patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
930
931 // Interface list
932
933 key = SCDynamicStoreKeyCreateNetworkInterface(NULL, kSCDynamicStoreDomainState);
934 CFArrayAppendValue(keys, key);
935 CFRelease(key);
936
937 // IPv4
938
939 add_NetworkChange_keys(keys, patterns, kSCEntNetIPv4, TRUE, TRUE, TRUE);
940
941 // IPv6
942
943 add_NetworkChange_keys(keys, patterns, kSCEntNetIPv6, TRUE, TRUE, TRUE);
944
945 // PPP, VPN
946
947 add_NetworkChange_keys(keys, patterns, kSCEntNetPPP, FALSE, TRUE, TRUE);
948 add_NetworkChange_keys(keys, patterns, kSCEntNetVPN, FALSE, TRUE, TRUE);
949 add_NetworkChange_keys(keys, patterns, kSCEntNetL2TP, FALSE, TRUE, TRUE);
950 add_NetworkChange_keys(keys, patterns, kSCEntNetPPTP, FALSE, TRUE, TRUE);
951 add_NetworkChange_keys(keys, patterns, kSCEntNetIPSec, FALSE, TRUE, TRUE);
952
953 // Link
954
955 add_NetworkChange_keys(keys, patterns, kSCEntNetLink, FALSE, FALSE, TRUE);
956
957 // AirPort (e.g. BSSID)
958
959 add_NetworkChange_keys(keys, patterns, kSCEntNetAirPort, FALSE, FALSE, TRUE);
960
961 // DNS
962
963 add_NetworkChange_keys(keys, patterns, kSCEntNetDNS, TRUE, TRUE, TRUE);
964
965 dns_key = CFStringCreateWithCString(NULL,
966 dns_configuration_notify_key(),
967 kCFStringEncodingASCII);
968 key = CFStringCreateWithFormat(NULL, NULL, CFSTR("Notify:%@"), dns_key);
969 CFRelease(dns_key);
970 CFArrayAppendValue(keys, key);
971 CFRelease(key);
972
973 // Proxies
974
975 key = SCDynamicStoreKeyCreateProxies(NULL);
976 CFArrayAppendValue(keys, key);
977 CFRelease(key);
978
979 // Rank
980
981 add_NetworkChange_keys(keys, patterns, NULL, FALSE, TRUE, FALSE); // per-service
982 add_NetworkChange_keys(keys, patterns, kSCEntNetService, FALSE, FALSE, TRUE); // per-interface
983
984 // ComputerName, LocalHostName
985
986 key = SCDynamicStoreKeyCreateComputerName(NULL);
987 CFArrayAppendValue(keys, key);
988 CFRelease(key);
989
990 key = SCDynamicStoreKeyCreateHostNames(NULL);
991 CFArrayAppendValue(keys, key);
992 CFRelease(key);
993
994 // Power Management
995
996 key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@%@"),
997 kSCDynamicStoreDomainState,
998 CFSTR(kIOPMSystemPowerCapabilitiesKeySuffix));
999 CFArrayAppendValue(keys, key);
1000 CFRelease(key);
1001
1002
1003 // Setup monitoring
1004
1005 ok = SCDynamicStoreSetNotificationKeys(store, keys, patterns);
1006 CFRelease(keys);
1007 CFRelease(patterns);
1008 if (!ok) {
1009 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed"));
1010 CFRelease(store);
1011 return;
1012 }
1013
1014 rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1);
1015 if (rls == NULL) {
1016 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1017 CFRelease(store);
1018 return;
1019 }
1020 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1021 CFRelease(rls);
1022
1023 CFRelease(store);
1024 return;
1025 }
1026
1027
1028 static void
1029 PrimaryService_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
1030 {
1031 CFDictionaryRef entity;
1032 CFStringRef key;
1033 static CFStringRef oldPrimary = NULL;
1034 CFStringRef newPrimary = NULL;
1035
1036 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4);
1037 entity = SCDynamicStoreCopyValue(store, key);
1038 CFRelease(key);
1039 if (isA_CFDictionary(entity) &&
1040 CFDictionaryGetValueIfPresent(entity,
1041 kSCDynamicStorePropNetPrimaryService,
1042 (const void **)&newPrimary) &&
1043 isA_CFString(newPrimary)) {
1044 CFRetain(newPrimary);
1045 } else {
1046 newPrimary = NULL;
1047 }
1048
1049 if (!_SC_CFEqual(oldPrimary, newPrimary)) {
1050 if (newPrimary != NULL) {
1051 CFStringRef newInterface;
1052
1053 newInterface = CFDictionaryGetValue(entity, kSCDynamicStorePropNetPrimaryInterface);
1054 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1055 CFSTR("%s Primary service: %@ (%@)"),
1056 elapsed(),
1057 newPrimary,
1058 newInterface != NULL ? newInterface : CFSTR("?"));
1059 } else {
1060 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1061 CFSTR("%s Primary service: removed"),
1062 elapsed());
1063 }
1064 }
1065
1066 if (oldPrimary != NULL) CFRelease(oldPrimary);
1067 oldPrimary = newPrimary;
1068
1069 if (entity != NULL) CFRelease(entity);
1070 return;
1071 }
1072
1073
1074 static void
1075 add_PrimaryService_notification()
1076 {
1077 CFStringRef key;
1078 CFMutableArrayRef keys;
1079 Boolean ok;
1080 SCDynamicStoreRef store;
1081 CFRunLoopSourceRef rls;
1082
1083 store = SCDynamicStoreCreate(NULL, CFSTR("Logger.bundle-PrimaryService"), PrimaryService_notification, NULL);
1084 if (store == NULL) {
1085 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreate() failed"));
1086 return;
1087 }
1088
1089 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1090 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4);
1091 CFArrayAppendValue(keys, key);
1092 CFRelease(key);
1093
1094 ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
1095 CFRelease(keys);
1096 if (!ok) {
1097 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed"));
1098 CFRelease(store);
1099 return;
1100 }
1101
1102 rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1);
1103 if (rls == NULL) {
1104 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1105 CFRelease(store);
1106 return;
1107 }
1108 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1109 CFRelease(rls);
1110
1111 CFRelease(store);
1112 return;
1113 }
1114
1115
1116 #pragma mark -
1117 #pragma mark Reachability Events
1118
1119
1120 static void
1121 reachability_notification(SCNetworkReachabilityRef ref, SCNetworkReachabilityFlags flags, void *info)
1122 {
1123 CFStringRef hostname = (CFStringRef)info;
1124
1125 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1126 CFSTR("%s reachability changed: %@: flags=0x%08x"),
1127 elapsed(),
1128 hostname,
1129 flags);
1130 return;
1131 }
1132
1133
1134 static void
1135 add_reachability_notification(CFArrayRef hosts)
1136 {
1137 SCNetworkReachabilityContext context = { 0, NULL, CFRetain, CFRelease, CFCopyDescription };
1138 CFIndex i;
1139 CFIndex n;
1140 SCNetworkReachabilityRef target;
1141
1142 struct watch {
1143 in_addr_t addr;
1144 CFStringRef name;
1145 } watchAddresses[] = { { 0, CFSTR("0.0.0.0") },
1146 { IN_LINKLOCALNETNUM, CFSTR("169.254.0.0") },
1147 { (u_int32_t)0xe00000fb, CFSTR("224.0.0.251") },
1148 };
1149
1150 for (i = 0; i < sizeof(watchAddresses)/sizeof(watchAddresses[0]); i++) {
1151 struct sockaddr_in sin;
1152
1153 bzero(&sin, sizeof(sin));
1154 sin.sin_len = sizeof(sin);
1155 sin.sin_family = AF_INET;
1156 sin.sin_addr.s_addr = htonl(watchAddresses[i].addr);
1157
1158 target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin);
1159 if (target == NULL) {
1160 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilityCreateWithAddress() failed"));
1161 return;
1162 }
1163
1164 context.info = (void *)watchAddresses[i].name;
1165 if (!SCNetworkReachabilitySetCallback(target, reachability_notification, &context)) {
1166 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilitySetCallback() failed"));
1167 CFRelease(target);
1168 return;
1169 }
1170
1171 if (!SCNetworkReachabilityScheduleWithRunLoop(target, CFRunLoopGetCurrent(), kCFRunLoopCommonModes)) {
1172 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilityScheduleWithRunLoop() failed"));
1173 CFRelease(target);
1174 return;
1175 }
1176
1177 CFRelease(target);
1178 }
1179
1180 n = (hosts != NULL) ? CFArrayGetCount(hosts) : 0;
1181 for (i = 0; i < n; i++) {
1182 CFStringRef host;
1183 char *nodename;
1184
1185 host = CFArrayGetValueAtIndex(hosts, i);
1186 if (!isA_CFString(host) || (CFStringGetLength(host) == 0)) {
1187 continue;
1188 }
1189
1190 nodename = _SC_cfstring_to_cstring(host, NULL, 0, kCFStringEncodingUTF8);
1191 target = SCNetworkReachabilityCreateWithName(NULL, nodename);
1192 CFAllocatorDeallocate(NULL, nodename);
1193 if (target == NULL) {
1194 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilityCreateWithName() failed"));
1195 return;
1196 }
1197
1198 context.info = (void *)host;
1199 if (!SCNetworkReachabilitySetCallback(target, reachability_notification, &context)) {
1200 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilitySetCallback() failed"));
1201 CFRelease(target);
1202 return;
1203 }
1204
1205 if (!SCNetworkReachabilityScheduleWithRunLoop(target, CFRunLoopGetCurrent(), kCFRunLoopCommonModes)) {
1206 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilityScheduleWithRunLoop() failed"));
1207 CFRelease(target);
1208 return;
1209 }
1210
1211 CFRelease(target);
1212 }
1213
1214 return;
1215 }
1216
1217
1218 #pragma mark -
1219 #pragma mark Console User/Information Events
1220
1221
1222 #if !TARGET_OS_EMBEDDED
1223 static void
1224 console_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
1225 {
1226 gid_t gid;
1227 CFArrayRef info;
1228 CFMutableStringRef str = CFStringCreateMutable(NULL, 0);
1229 uid_t uid;
1230 CFStringRef user;
1231
1232 CFStringAppendFormat(str,
1233 NULL,
1234 CFSTR("%s SCDynamicStore console notification"),
1235 elapsed());
1236
1237 user = SCDynamicStoreCopyConsoleUser(store, &uid, &gid);
1238 if (user != NULL) {
1239 CFStringAppendFormat(str, NULL, CFSTR("\nconsole user = %@"), user);
1240 CFRelease(user);
1241 } else {
1242 CFStringAppendFormat(str, NULL, CFSTR("\nno console user"));
1243 }
1244
1245 info = SCDynamicStoreCopyConsoleInformation(store);
1246 if (info != NULL) {
1247 CFIndex i;
1248 CFIndex n;
1249
1250 n = CFArrayGetCount(info);
1251 for (i = 0; i < n; i++) {
1252 CFDictionaryRef session;
1253 CFNumberRef sessionID;
1254 CFStringRef sessionUserName;
1255 CFBooleanRef sessionOnConsole;
1256
1257 session = CFArrayGetValueAtIndex(info, i);
1258 sessionID = CFDictionaryGetValue(session, kSCConsoleSessionID);
1259 sessionUserName = CFDictionaryGetValue(session, kSCConsoleSessionUserName);
1260 sessionOnConsole = CFDictionaryGetValue(session, kSCConsoleSessionOnConsole);
1261
1262 CFStringAppendFormat(str, NULL, CFSTR("\n%d : id=%@, user=%@, console=%s"),
1263 i,
1264 sessionID,
1265 sessionUserName != NULL ? sessionUserName : CFSTR("?"),
1266 sessionOnConsole != NULL ? CFBooleanGetValue(sessionOnConsole) ? "yes" : "no" : "?");
1267 }
1268
1269 CFRelease(info);
1270 }
1271
1272 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO, CFSTR("%@"), str);
1273 CFRelease(str);
1274 return;
1275 }
1276
1277
1278 static void
1279 add_console_notification()
1280 {
1281 CFStringRef key;
1282 CFMutableArrayRef keys;
1283 Boolean ok;
1284 SCDynamicStoreRef store;
1285 CFRunLoopSourceRef rls;
1286
1287 store = SCDynamicStoreCreate(NULL, CFSTR("Logger.bundle-console"), console_notification, NULL);
1288 if (store == NULL) {
1289 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreate() failed"));
1290 return;
1291 }
1292
1293 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1294
1295 key = SCDynamicStoreKeyCreateConsoleUser(NULL);
1296 CFArrayAppendValue(keys, key);
1297 CFRelease(key);
1298
1299 ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
1300 CFRelease(keys);
1301 if (!ok) {
1302 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed"));
1303 CFRelease(store);
1304 return;
1305 }
1306
1307 rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1);
1308 if (rls == NULL) {
1309 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1310 CFRelease(store);
1311 return;
1312 }
1313 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1314 CFRelease(rls);
1315
1316 CFRelease(store);
1317 return;
1318 }
1319 #endif // !TARGET_OS_EMBEDDED
1320
1321
1322 #pragma mark -
1323 #pragma mark Directory Services Events
1324
1325
1326 //#include <DirectoryServices/DirServicesPriv.h>
1327 #ifndef kDSStdNotifySearchPolicyChanged
1328 #define kDSStdNotifySearchPolicyChanged "com.apple.DirectoryService.NotifyTypeStandard:SearchPolicyChanged"
1329 #endif
1330
1331
1332 #if !TARGET_OS_EMBEDDED
1333 static void
1334 directoryServices_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
1335 {
1336 CFIndex i;
1337 CFIndex n;
1338 CFMutableStringRef str = CFStringCreateMutable(NULL, 0);
1339
1340 CFStringAppendFormat(str,
1341 NULL,
1342 CFSTR("%s SCDynamicStore DirectoryServices notification"),
1343 elapsed());
1344
1345 n = CFArrayGetCount(changedKeys);
1346 for (i = 0; i < n; i++) {
1347 CFStringRef key;
1348
1349 key = CFArrayGetValueAtIndex(changedKeys, i);
1350 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
1351 }
1352
1353 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO, CFSTR("%@"), str);
1354 CFRelease(str);
1355 return;
1356 }
1357
1358
1359 static void
1360 add_DirectoryServices_notification()
1361 {
1362 CFStringRef key;
1363 CFMutableArrayRef keys;
1364 Boolean ok;
1365 SCDynamicStoreRef store;
1366 CFRunLoopSourceRef rls;
1367
1368 store = SCDynamicStoreCreate(NULL, CFSTR("Logger.bundle-directoryServices"), directoryServices_notification, NULL);
1369 if (store == NULL) {
1370 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreate() failed"));
1371 return;
1372 }
1373
1374 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1375
1376 key = CFSTR(kDSStdNotifySearchPolicyChanged);
1377 CFArrayAppendValue(keys, key);
1378 // CFRelease(key);
1379
1380 ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
1381 CFRelease(keys);
1382 if (!ok) {
1383 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed"));
1384 CFRelease(store);
1385 return;
1386 }
1387
1388 rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1);
1389 if (rls == NULL) {
1390 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1391 CFRelease(store);
1392 return;
1393 }
1394 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1395 CFRelease(rls);
1396
1397 CFRelease(store);
1398 return;
1399 }
1400 #endif // !TARGET_OS_EMBEDDED
1401
1402
1403 #pragma mark -
1404 #pragma mark DNS Configuration Events
1405
1406
1407 static void
1408 dnsinfo_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
1409 {
1410 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1411 CFSTR("%s dnsinfo notification"),
1412 elapsed());
1413
1414 return;
1415 }
1416
1417
1418 static void
1419 add_dnsinfo_notification()
1420 {
1421 const char *key;
1422 CFMachPortRef mp;
1423 mach_port_t notify_port;
1424 int notify_token;
1425 CFRunLoopSourceRef rls;
1426 uint32_t status;
1427
1428 key = dns_configuration_notify_key();
1429 status = notify_register_mach_port(key, &notify_port, 0, &notify_token);
1430 if (status != NOTIFY_STATUS_OK) {
1431 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_register_mach_port() failed"));
1432 return;
1433 }
1434
1435 mp = _SC_CFMachPortCreateWithPort("Logger/dns_configuration", notify_port, dnsinfo_notification, NULL);
1436 if (mp == NULL) {
1437 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("CFMachPortCreateWithPort() failed"));
1438 (void)notify_cancel(notify_token);
1439 return;
1440 }
1441
1442 rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
1443 if (rls == NULL) {
1444 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1445 CFRelease(mp);
1446 (void)notify_cancel(notify_token);
1447 return;
1448 }
1449 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1450 CFRelease(rls);
1451
1452 CFRelease(mp);
1453 return;
1454 }
1455
1456
1457 #pragma mark -
1458 #pragma mark Network Information Events
1459
1460
1461 static void
1462 nwi_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
1463 {
1464 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1465 CFSTR("%s network_information notification"),
1466 elapsed());
1467
1468 return;
1469 }
1470
1471
1472 static void
1473 add_nwi_notification()
1474 {
1475 const char *key;
1476 CFMachPortRef mp;
1477 mach_port_t notify_port;
1478 int notify_token;
1479 CFRunLoopSourceRef rls;
1480 uint32_t status;
1481
1482 key = nwi_state_get_notify_key();
1483 status = notify_register_mach_port(key, &notify_port, 0, &notify_token);
1484 if (status != NOTIFY_STATUS_OK) {
1485 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_register_mach_port() failed"));
1486 return;
1487 }
1488
1489 mp = _SC_CFMachPortCreateWithPort("Logger/nwi", notify_port, nwi_notification, NULL);
1490 if (mp == NULL) {
1491 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("CFMachPortCreateWithPort() failed"));
1492 (void)notify_cancel(notify_token);
1493 return;
1494 }
1495
1496 rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
1497 if (rls == NULL) {
1498 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1499 CFRelease(mp);
1500 (void)notify_cancel(notify_token);
1501 return;
1502 }
1503 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1504 CFRelease(rls);
1505
1506 CFRelease(mp);
1507 return;
1508 }
1509
1510
1511 #pragma mark -
1512 #pragma mark Network Configuration Change Events
1513
1514
1515 #define NETWORKCHANGED_NOTIFY_KEY "com.apple.system.config.network_change"
1516
1517 static void
1518 network_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
1519 {
1520 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1521 CFSTR("%s network_change notification"),
1522 elapsed());
1523
1524 return;
1525 }
1526
1527
1528 static void
1529 add_network_notification()
1530 {
1531 CFMachPortRef mp;
1532 mach_port_t notify_port;
1533 int notify_token;
1534 CFRunLoopSourceRef rls;
1535 uint32_t status;
1536
1537 status = notify_register_mach_port(NETWORKCHANGED_NOTIFY_KEY,
1538 &notify_port,
1539 0,
1540 &notify_token);
1541 if (status != NOTIFY_STATUS_OK) {
1542 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_register_mach_port() failed"));
1543 return;
1544 }
1545
1546 mp = _SC_CFMachPortCreateWithPort("Logger/network_change", notify_port, network_notification, NULL);
1547 if (mp == NULL) {
1548 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("CFMachPortCreateWithPort() failed"));
1549 (void)notify_cancel(notify_token);
1550 return;
1551 }
1552
1553 rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
1554 if (rls == NULL) {
1555 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1556 CFRelease(mp);
1557 (void)notify_cancel(notify_token);
1558 return;
1559 }
1560 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1561 CFRelease(rls);
1562
1563 CFRelease(mp);
1564 return;
1565 }
1566
1567
1568 #pragma mark -
1569 #pragma mark SMB Configuration Events
1570
1571
1572 #define SMBCONFIGURATION_NOTIFY_KEY "com.apple.system.SystemConfiguration.smb_configuration"
1573
1574
1575 #if !TARGET_OS_EMBEDDED
1576 static void
1577 smbconf_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
1578 {
1579 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1580 CFSTR("%s smb.conf notification"),
1581 elapsed());
1582
1583 return;
1584 }
1585
1586
1587 static void
1588 add_smbconf_notification()
1589 {
1590 CFMachPortRef mp;
1591 mach_port_t notify_port;
1592 int notify_token;
1593 CFRunLoopSourceRef rls;
1594 uint32_t status;
1595
1596 status = notify_register_mach_port(SMBCONFIGURATION_NOTIFY_KEY,
1597 &notify_port,
1598 0,
1599 &notify_token);
1600 if (status != NOTIFY_STATUS_OK) {
1601 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_register_mach_port() failed"));
1602 return;
1603 }
1604
1605 mp = _SC_CFMachPortCreateWithPort("Logger/smb_configuration", notify_port, smbconf_notification, NULL);
1606 if (mp == NULL) {
1607 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("CFMachPortCreateWithPort() failed"));
1608 (void)notify_cancel(notify_token);
1609 return;
1610 }
1611
1612 rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
1613 if (rls == NULL) {
1614 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1615 CFRelease(mp);
1616 (void)notify_cancel(notify_token);
1617 return;
1618 }
1619 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1620 CFRelease(rls);
1621
1622 CFRelease(mp);
1623 return;
1624 }
1625 #endif // !TARGET_OS_EMBEDDED
1626
1627
1628 #pragma mark -
1629 #pragma mark pututxline Events
1630
1631
1632 #if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
1633 static const char *
1634 ut_time(struct utmpx *utmpx)
1635 {
1636 static char str[16];
1637 struct tm tm;
1638
1639 (void)localtime_r(&utmpx->ut_tv.tv_sec, &tm);
1640 snprintf(str, sizeof(str), "%2d:%02d:%02d.%03d",
1641 tm.tm_hour,
1642 tm.tm_min,
1643 tm.tm_sec,
1644 utmpx->ut_tv.tv_usec / 1000);
1645
1646 return str;
1647 }
1648
1649
1650 static const char *
1651 ut_id(struct utmpx *utmpx)
1652 {
1653 char *cp;
1654 static char str[16];
1655
1656 cp = utmpx->ut_id + sizeof(utmpx->ut_id);
1657 while(--cp >= utmpx->ut_id && isprint(*cp)) {}
1658 if(cp < utmpx->ut_id) {
1659 snprintf(str, sizeof(str), "%-4.4s", utmpx->ut_id);
1660 } else {
1661 snprintf(str, sizeof(str),
1662 "0x%2.2x%2.2x%2.2x%2.2x",
1663 utmpx->ut_id[0],
1664 utmpx->ut_id[1],
1665 utmpx->ut_id[2],
1666 utmpx->ut_id[3]);
1667 }
1668
1669 return str;
1670 }
1671
1672
1673 static const char *
1674 ut_pid(struct utmpx *utmpx)
1675 {
1676 static char pid[16];
1677
1678 snprintf(pid, sizeof(pid), "%d", utmpx->ut_pid);
1679
1680 return pid;
1681 }
1682
1683
1684 static void
1685 pututxline_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
1686 {
1687 CFMutableStringRef str = CFStringCreateMutable(NULL, 0);
1688 struct utmpx *utmpx;
1689 utmpx_t utx;
1690
1691 CFStringAppendFormat(str,
1692 NULL,
1693 CFSTR("%s pututxline notification"),
1694 elapsed());
1695
1696 utx = _openutx(NULL);
1697 while ((utmpx = _getutxent(utx)) != NULL) {
1698 const char * entry_id = NULL;
1699 const char * entry_line = NULL;
1700 const char * entry_pid = NULL;
1701 const char * entry_tv = NULL;
1702 const char * entry_type;
1703 const char * entry_user = NULL;
1704 char line[128];
1705 int n;
1706
1707 switch (utmpx->ut_type) {
1708 case BOOT_TIME : // Time of a system boot.
1709 entry_type = "Boot";
1710 entry_tv = ut_time(utmpx);
1711 break;
1712 case DEAD_PROCESS : // A session leader exited.
1713 entry_type = "Dead process";
1714 entry_id = ut_id (utmpx);
1715 entry_pid = ut_pid (utmpx);
1716 entry_tv = ut_time(utmpx);
1717 break;
1718 case EMPTY : // No valid user accounting information.
1719 continue;
1720 case INIT_PROCESS : // A process spawned by init(8).
1721 entry_type = "Init process";
1722 entry_id = ut_id (utmpx);
1723 entry_pid = ut_pid (utmpx);
1724 entry_tv = ut_time(utmpx);
1725 break;
1726 case LOGIN_PROCESS : // The session leader of a logged-in user.
1727 entry_type = "Login";
1728 entry_id = ut_id (utmpx);
1729 entry_user = utmpx->ut_user;
1730 entry_pid = ut_pid (utmpx);
1731 entry_tv = ut_time(utmpx);
1732 break;
1733 case NEW_TIME : // Time after system clock change.
1734 entry_type = "New time";
1735 entry_tv = ut_time(utmpx);
1736 break;
1737 case OLD_TIME : // Time before system clock change.
1738 entry_type = "Old time";
1739 entry_tv = ut_time(utmpx);
1740 break;
1741 case RUN_LVL : // Run level. Provided for compatibility, not used.
1742 entry_type = "Run level";
1743 break;
1744 case USER_PROCESS : // A user process.
1745 entry_type = "User Process";
1746 entry_id = ut_id (utmpx);
1747 entry_user = utmpx->ut_user;
1748 entry_line = utmpx->ut_line;
1749 entry_pid = ut_pid (utmpx);
1750 entry_tv = ut_time(utmpx);
1751 break;
1752 case SHUTDOWN_TIME : // Time of system shutdown
1753 entry_type = "Shutdown time";
1754 entry_tv = ut_time(utmpx);
1755 break;
1756 default :
1757 entry_type = "Unknown";
1758 break;
1759 }
1760
1761 snprintf(line, sizeof(line),
1762 // type time id=0x12345678 pid=12345 user=abcdefgh line
1763 "\n%-13s %2s%12s %3s%-10s %4s%-5s %5s%-8s %5s%s",
1764 entry_type,
1765 entry_tv != NULL ? "@ " : "",
1766 entry_tv != NULL ? entry_tv : "", // hh:mm:ss.ddd
1767 entry_id != NULL ? "id=" : "",
1768 entry_id != NULL ? entry_id : "", // 0x12345678
1769 entry_pid != NULL ? "pid=" : "",
1770 entry_pid != NULL ? entry_pid : "", // #####
1771 entry_user != NULL ? "user=" : "",
1772 entry_user != NULL ? entry_user : "", // <=256 chars
1773 entry_line != NULL ? "line=" : "",
1774 entry_line != NULL ? entry_line : "" // <= 32 chars
1775 );
1776
1777 n = strlen(line) - 1;
1778 while ((n > 0) && (line[n] == ' ')) {
1779 line[n] = '\0';
1780 --n;
1781 }
1782
1783 CFStringAppendFormat(str, NULL, CFSTR("%s"), line);
1784 }
1785 _endutxent(utx);
1786
1787 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO, CFSTR("%@"), str);
1788 CFRelease(str);
1789 return;
1790 }
1791
1792
1793 static void
1794 add_pututxline_notification()
1795 {
1796 CFMachPortRef mp;
1797 mach_port_t notify_port;
1798 int notify_token;
1799 CFRunLoopSourceRef rls;
1800 uint32_t status;
1801
1802 status = notify_register_mach_port(UTMPX_CHANGE_NOTIFICATION, &notify_port, 0, &notify_token);
1803 if (status != NOTIFY_STATUS_OK) {
1804 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_register_mach_port() failed"));
1805 return;
1806 }
1807
1808 mp = _SC_CFMachPortCreateWithPort("Logger/utmpx", notify_port, pututxline_notification, NULL);
1809 if (mp == NULL) {
1810 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("CFMachPortCreateWithPort() failed"));
1811 (void)notify_cancel(notify_token);
1812 return;
1813 }
1814
1815 rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
1816 if (rls == NULL) {
1817 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1818 CFRelease(mp);
1819 (void)notify_cancel(notify_token);
1820 return;
1821 }
1822 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1823 CFRelease(rls);
1824
1825 CFRelease(mp);
1826 return;
1827 }
1828 #endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
1829
1830
1831 #pragma mark -
1832 #pragma mark BackToMyMac Status Events
1833
1834
1835 #ifndef kDSStdNotifyBTMMStatusChanged
1836 #define kDSStdNotifyBTMMStatusChanged "State:/Network/BackToMyMac"
1837 #endif
1838
1839
1840 #if !TARGET_OS_EMBEDDED
1841 static void
1842 BTMM_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
1843 {
1844 CFIndex i;
1845 CFIndex n;
1846 CFMutableStringRef str = CFStringCreateMutable(NULL, 0);
1847
1848 CFStringAppendFormat(str,
1849 NULL,
1850 CFSTR("%s SCDynamicStore Back to My Mac notification"),
1851 elapsed());
1852
1853 n = CFArrayGetCount(changedKeys);
1854 for (i = 0; i < n; i++) {
1855 CFStringRef key;
1856 CFDictionaryRef dict;
1857
1858 key = CFArrayGetValueAtIndex(changedKeys, i);
1859 dict = SCDynamicStoreCopyValue(store, key);
1860 if (dict != NULL) {
1861 CFStringRef val;
1862
1863 val = _SCCopyDescription(dict, NULL);
1864 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : %@"), key, val);
1865 CFRelease(val);
1866 CFRelease(dict);
1867 } else {
1868 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : removed"), key);
1869 }
1870 }
1871
1872 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO, CFSTR("%@"), str);
1873 CFRelease(str);
1874 return;
1875 }
1876
1877
1878 static void
1879 add_BTMM_notification()
1880 {
1881 CFStringRef key;
1882 CFMutableArrayRef keys;
1883 Boolean ok;
1884 SCDynamicStoreRef store;
1885 CFRunLoopSourceRef rls;
1886
1887 store = SCDynamicStoreCreate(NULL, CFSTR("Logger.bundle-BackToMyMac"), BTMM_notification, NULL);
1888 if (store == NULL) {
1889 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreate() failed"));
1890 return;
1891 }
1892
1893 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1894
1895 key = CFSTR(kDSStdNotifyBTMMStatusChanged);
1896 CFArrayAppendValue(keys, key);
1897
1898 ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
1899 CFRelease(keys);
1900 if (!ok) {
1901 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed"));
1902 CFRelease(store);
1903 return;
1904 }
1905
1906 rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1);
1907 if (rls == NULL) {
1908 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1909 CFRelease(store);
1910 return;
1911 }
1912 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1913 CFRelease(rls);
1914
1915 CFRelease(store);
1916 return;
1917 }
1918 #endif // !TARGET_OS_EMBEDDED
1919
1920
1921 #pragma mark -
1922
1923
1924 static __inline__ Boolean
1925 bValFromDictionary(CFDictionaryRef dict, CFStringRef key)
1926 {
1927 CFBooleanRef bVal;
1928 Boolean result = FALSE;
1929
1930 if ((dict != NULL) &&
1931 CFDictionaryGetValueIfPresent(dict, key, (const void **)&bVal) &&
1932 isA_CFBoolean(bVal)) {
1933 result = CFBooleanGetValue(bVal);
1934 }
1935
1936 return result;
1937 }
1938
1939
1940 void
1941 load(CFBundleRef bundle, Boolean bundleVerbose)
1942 {
1943 CFDictionaryRef config;
1944 Boolean log_all;
1945
1946 verbose = bundleVerbose;
1947
1948 log_msg = asl_new(ASL_TYPE_MSG);
1949 asl_set(log_msg, ASL_KEY_FACILITY, MY_ASL_FACILITY);
1950
1951 elapsed();
1952
1953 config = CFBundleGetInfoDictionary(bundle);
1954 config = isA_CFDictionary(config);
1955 log_all = bValFromDictionary(config, CFSTR("LOG_ALL"));
1956
1957 #ifdef kIOPMMessageSleepWakeUUIDChange
1958 if (log_all || bValFromDictionary(config, CFSTR("LOG_IO_WAKEUUID_EVENTS"))) {
1959 add_wake_uuid_notification();
1960 }
1961 #endif // kIOPMMessageSleepWakeUUIDChange
1962
1963 if (log_all || bValFromDictionary(config, CFSTR("LOG_IO_SYSTEMPOWER_EVENTS"))) {
1964 add_power_notification();
1965 }
1966
1967 if (log_all || bValFromDictionary(config, CFSTR("LOG_NETWORK_KERNEL_EVENTS"))) {
1968 add_KernelEvent_notification();
1969 }
1970
1971 if (log_all || bValFromDictionary(config, CFSTR("LOG_NETWORK_INFORMATION"))) {
1972 add_nwi_notification();
1973 }
1974
1975 if (log_all || bValFromDictionary(config, CFSTR("LOG_NOTIFY_DNS_CONFIGURATION"))) {
1976 add_dnsinfo_notification();
1977 }
1978
1979 if (log_all || bValFromDictionary(config, CFSTR("LOG_NOTIFY_NETWORK_CHANGE"))) {
1980 add_network_notification();
1981 }
1982
1983 #if !TARGET_OS_EMBEDDED
1984 if (log_all || bValFromDictionary(config, CFSTR("LOG_NOTIFY_SMB_CONFIGURATION"))) {
1985 add_smbconf_notification();
1986 }
1987 #endif // !TARGET_OS_EMBEDDED
1988
1989 #if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
1990 if (log_all || bValFromDictionary(config, CFSTR("LOG_NOTIFY_UTMPX_CHANGE"))) {
1991 add_pututxline_notification();
1992 }
1993 #endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
1994
1995 #if !TARGET_OS_EMBEDDED
1996 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_BTMM_CONFIGURATION"))) {
1997 add_BTMM_notification();
1998 }
1999 #endif // !TARGET_OS_EMBEDDED
2000
2001 #if !TARGET_OS_EMBEDDED
2002 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_CONSOLEUSER"))) {
2003 add_console_notification();
2004 }
2005 #endif // !TARGET_OS_EMBEDDED
2006
2007 #if !TARGET_OS_EMBEDDED
2008 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_DIRECTORYSERVICES_SEARCHPOLICY"))) {
2009 add_DirectoryServices_notification();
2010 }
2011 #endif // !TARGET_OS_EMBEDDED
2012
2013 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_NETWORKCHANGE"))) {
2014 add_NetworkChange_notification();
2015 }
2016
2017 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_PRIMARYSERVICE"))) {
2018 add_PrimaryService_notification();
2019 }
2020
2021 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_REACHABILITY"))) {
2022 CFArrayRef hosts = NULL;
2023
2024 if ((config == NULL) ||
2025 !CFDictionaryGetValueIfPresent(config, CFSTR("LOG_SC_REACHABILITY_HOSTS"), (const void **)&hosts) ||
2026 !isA_CFArray(hosts) ||
2027 (CFArrayGetCount(hosts) == 0)) {
2028 hosts = NULL;
2029 }
2030
2031 if (verbose) {
2032 _sc_debug = TRUE;
2033 }
2034
2035 add_reachability_notification(hosts);
2036 }
2037
2038 return;
2039 }
2040
2041 #ifdef MAIN
2042
2043 int
2044 main(int argc, char **argv)
2045 {
2046 _sc_log = FALSE;
2047 _sc_verbose = (argc > 1) ? TRUE : FALSE;
2048 _sc_debug = TRUE;
2049
2050 load(CFBundleGetMainBundle(), (argc > 1) ? TRUE : FALSE);
2051 CFRunLoopRun();
2052 /* not reached */
2053 exit(0);
2054 return 0;
2055 }
2056
2057 #endif /* MAIN */