2 * clang cloud_keychain_diagnose.c -laks -framework CoreFoundation -framework IOKit -framework Security -o /tmp/cloud_keychain_diagnose
6 #if !TARGET_OS_EMBEDDED
7 #include "sec/Security/SecBase.h"
8 #include "sec/Security/SecKey.h"
11 #include <CoreFoundation/CoreFoundation.h>
12 #include <CoreFoundation/CFPriv.h>
14 #if !TARGET_IPHONE_SIMULATOR
16 /* Header Declarations */
23 #if TARGET_OS_EMBEDDED
31 #include "SOSCloudCircle.h"
32 #include "SOSPeerInfo.h"
35 /* Constant Declarations */
39 #define MAX_PATH_LEN 1024
40 #define SUFFIX_LENGTH 4
41 #define BUFFER_SIZE 1024
42 #define MAX_DATA_RATE 32
44 /* External CloudKeychain Bridge Types */
45 typedef void (^CloudKeychainReplyBlock
)(CFDictionaryRef returnedValues
, CFErrorRef error
);
46 extern void SOSCloudKeychainGetAllObjectsFromCloud(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
);
48 /* External AppleKeyStore Types */
50 my_keybag_state_bio_unlock
= 1 << 3
54 /* Dictionary Dump State */
55 struct dict_dump_state
59 unsigned int indent_level
;
62 /* Static Function Declarations */
73 enable_cloud_keychain_diagnostics(
74 const unsigned int enable_flag
);
83 dump_system_information(
93 dump_keychain_sync_kvs(
100 CFDictionaryRef dict
,
101 const unsigned int indent_level
);
114 const char *asl_sender
);
120 const char *description
,
123 /* Function Definitions */
129 int result
= EXIT_FAILURE
;
131 /* Parse the arguments. */
137 /* Should we just gather logs and status? */
140 if (gather_diagnostics()) {
142 fprintf(stderr
, "Could not gather diagnostics\n");
147 /* Should we enable or disable logging? */
148 if (strncmp(argv
[1], "enable", 6) == 0) {
151 if (enable_cloud_keychain_diagnostics(1)) {
153 fprintf(stderr
, "Could not enable additional cloud keychain diagnostics\n");
156 } else if (strncmp(argv
[1], "disable", 7) == 0) {
159 if (enable_cloud_keychain_diagnostics(1)) {
161 fprintf(stderr
, "Could not disable additional cloud keychain diagnostics\n");
166 /* Get a job, hippy. */
171 /* Set the exit status to success. */
172 result
= EXIT_FAILURE
;
179 /* Static Function Definitions */
184 fprintf(stderr
, "usage: cloud_keychain_diagnose [enable|disable]\n");
192 int result
= FAILURE
;
193 char log_path
[MAX_PATH_LEN
] = "";
195 FILE *log_file
= NULL
;
198 * Create the diagnostics file.
200 * Dump the system information.
201 * on OS X, defaults read if the shim is active
202 * Dump the circle state.
203 * Dump the raw KVS data.
204 * Dump known ASL logs
206 * Remaining work to do from rdar://12479351
208 * query for all items with sync=1
210 * enable push notification logging
213 /* Build the log path. */
214 if (build_log_path(log_path
)) {
216 fprintf(stderr
, "Could not build the log path\n");
220 /* Create it with a randomized suffix. */
221 log_fd
= mkstemps(log_path
, SUFFIX_LENGTH
);
224 fprintf(stderr
, "Could not create the log file: %s\n", strerror(errno
));
228 /* Create a file object from the descriptor. */
229 log_file
= fdopen(log_fd
, "w");
230 if (log_file
== NULL
) {
232 fprintf(stderr
, "Could not recreate the log file: %s\n", strerror(errno
));
238 printf("Writing cloud keychain diagnostics to %s\n", log_path
);
240 /* Dump the system information. */
241 if (dump_system_information(log_file
)) {
243 fprintf(stderr
, "Could not dump the system information\n");
247 /* Dump the SOS circle state. */
248 if (dump_circle_state(log_file
)) {
250 fprintf(stderr
, "Could not dump the SOS circle state\n");
254 /* Dump the raw keychain syncing KVS. */
255 if (dump_keychain_sync_kvs(log_file
)) {
257 fprintf(stderr
, "Could not the raw keychain syncing KVS\n");
262 * Dump the various and sundry ASL logs.
265 if (dump_asl_sender(log_file
, "com.apple.kb-service")) {
267 fprintf(stderr
, "Could not dump the ASL log for com.apple.kb-service\n");
271 if (dump_asl_sender(log_file
, "com.apple.securityd")) {
273 fprintf(stderr
, "Could not dump the ASL log for com.apple.securityd\n");
277 if (dump_asl_sender(log_file
, "com.apple.secd")) {
279 fprintf(stderr
, "Could not dump the ASL log for com.apple.secd\n");
283 if (dump_asl_sender(log_file
, "CloudKeychainProxy")) {
285 fprintf(stderr
, "Could not dump the ASL log for CloudKeychainProxy\n");
289 if (dump_asl_sender(log_file
, "securityd")) {
291 fprintf(stderr
, "Could not dump the ASL log for securityd\n");
295 if (dump_asl_sender(log_file
, "secd")) {
297 fprintf(stderr
, "Could not dump the ASL log for secd\n");
301 /* Set the result to success. */
306 /* Close the diagnostics file? */
307 if (log_file
!= NULL
) {
313 /* Close the diagnostics file descriptor? */
325 enable_cloud_keychain_diagnostics(
326 const unsigned int enable_flag
)
328 int result
= FAILURE
;
330 /* Set the result to success. */
341 int result
= FAILURE
;
343 struct tm
*time_cube
;
344 CFDictionaryRef system_version_dict
= NULL
;
345 CFStringRef product_name
= NULL
;
347 /* Get the current time. */
350 /* Convert the time into something usable. */
351 time_cube
= localtime(&now
);
352 if (time_cube
== NULL
) {
354 fprintf(stderr
, "I don't know what time it is.\n");
358 /* Copy the system version dictionary. */
359 system_version_dict
= _CFCopySystemVersionDictionary();
360 if (system_version_dict
== NULL
) {
362 fprintf(stderr
, "Could not copy the system version dictionary\n");
366 /* Extract the product name. */
367 product_name
= CFDictionaryGetValue(system_version_dict
, _kCFSystemVersionProductNameKey
);
368 if (product_name
== NULL
) {
370 fprintf(stderr
, "Could not extract the product name from the system version dictionary\n");
375 if (CFEqual(product_name
, CFSTR("Mac OS X"))) {
377 /* Prepare the file template to go into /tmp. */
381 "/tmp/cloud_keychain_diagnostics.%d_%d_%d.%d%d%d.XXXX.txt",
382 1900 + time_cube
->tm_year
,
390 /* Prepare the file template to go into CrashReporter. */
394 "/Library/Logs/CrashReporter/cloud_keychain_diagnostics.%d_%d_%d.%d%d%d.XXXX.txt",
395 1900 + time_cube
->tm_year
,
403 /* Set the result to success. */
408 /* Release the system version dictionary? */
409 if (system_version_dict
!= NULL
) {
411 CFRelease(system_version_dict
);
412 system_version_dict
= NULL
;
420 dump_system_information(
423 int result
= FAILURE
;
424 CFDictionaryRef dict
= NULL
;
425 char buffer
[BUFFER_SIZE
];
426 CFStringRef product_name
;
427 CFStringRef product_version
;
428 CFStringRef product_build_version
;
430 CFTypeRef shim_flag
= NULL
;
431 int keybag_handle
= bad_keybag_handle
;
432 kern_return_t kr
= 0;
433 keybag_state_t keybag_state
= 0;
436 * Dump the system information.
439 * ProductBuildVersion
444 fprintf(log_file
, "Host Information:\n");
445 fprintf(log_file
, "=================\n");
447 /* Copy the system version dictionary. */
448 dict
= _CFCopySystemVersionDictionary();
451 fprintf(stderr
, "Could not copy the system version dictionary\n");
455 /* Extract the product name. */
456 product_name
= CFDictionaryGetValue(dict
, _kCFSystemVersionProductNameKey
);
457 if (product_name
== NULL
) {
459 fprintf(stderr
, "Could not extract the product name from the system version dictionary\n");
463 /* Convert the product name to a C string. */
464 if (!CFStringGetCString(product_name
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
466 fprintf(stderr
, "Could not convert the product name to a C string\n");
470 /* Dump the product name. */
471 fprintf(log_file
, "Product Name: %s\n", buffer
);
473 /* Extract the product version. */
474 product_version
= CFDictionaryGetValue(dict
, _kCFSystemVersionProductVersionKey
);
475 if (product_version
== NULL
) {
477 fprintf(stderr
, "Could not extract the product version from the system version dictionary\n");
481 /* Convert the product version to a C string. */
482 if (!CFStringGetCString(product_version
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
484 fprintf(stderr
, "Could not convert the product version to a C string\n");
488 /* Dump the product version */
489 fprintf(log_file
, "Product Version: %s\n", buffer
);
491 /* Extract the product build version. */
492 product_build_version
= CFDictionaryGetValue(dict
, _kCFSystemVersionBuildVersionKey
);
493 if (product_build_version
== NULL
) {
495 fprintf(stderr
, "Could not extract the product build version from the system version dictionary\n");
499 /* Convert the product build version to a C string. */
500 if (!CFStringGetCString(product_build_version
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
502 fprintf(stderr
, "Could not convert the product build version to a C string\n");
506 /* Dump the product build version. */
507 fprintf(log_file
, "Product Build Version: %s\n", buffer
);
509 /* Lookup the host name. */
510 if (gethostname(buffer
, BUFFER_SIZE
) == -1) {
512 fprintf(stderr
, "Could not lookup the host name\n");
516 /* Dump the host name. */
517 fprintf(log_file
, "Host Name: %s\n", buffer
);
519 /* Lookup the current time. */
520 if (gethostname(buffer
, BUFFER_SIZE
) == -1) {
522 fprintf(stderr
, "Could not lookup the host name\n");
526 /* Get the current time. */
529 /* Dump the current time. */
530 fprintf(log_file
, "Time: %s", ctime(&now
));
533 if (CFEqual(product_name
, CFSTR("Mac OS X"))) {
535 /* Set the keybag handle. */
536 keybag_handle
= session_keybag_handle
;
538 /* Lookup the state of the shim. */
539 shim_flag
= (CFNumberRef
)CFPreferencesCopyValue(CFSTR("SecItemSynchronizable"), CFSTR("com.apple.security"), kCFPreferencesAnyUser
, kCFPreferencesCurrentHost
);
540 if (shim_flag
&& CFGetTypeID(shim_flag
) == CFBooleanGetTypeID()) {
542 /* Is the shim enabled? */
543 if (CFBooleanGetValue((CFBooleanRef
)shim_flag
)) {
545 fprintf(log_file
, "The SecItem shim is enabled\n");
548 fprintf(log_file
, "The SecItem shim is disabled\n");
552 fprintf(log_file
, "The SecItem shim is disabled\n");
556 /* Set the keybag handle. */
557 keybag_handle
= device_keybag_handle
;
560 /* Get the keybag state. */
561 kr
= aks_get_lock_state(keybag_handle
, &keybag_state
);
564 fprintf(stderr
, "Could not call aks_get_lock_state\n");
567 switch (keybag_state
) {
569 case keybag_state_unlocked
: {
571 fprintf(log_file
, "Keybag State: Unlocked\n");
574 case keybag_state_locked
: {
576 fprintf(log_file
, "Keybag State: Locked\n");
579 case keybag_state_no_pin
: {
581 fprintf(log_file
, "Keybag State: No Passcode\n");
584 case keybag_state_been_unlocked
: {
586 fprintf(log_file
, "Keybag State: Been Unlocked\n");
589 case my_keybag_state_bio_unlock
: {
591 fprintf(log_file
, "Keybag State: Bio Unlock\n");
596 fprintf(log_file
, "Keybag State: UNKNOWN\n");
602 fprintf(log_file
, "=================\n\n");
604 /* Set the result to success. */
609 /* Release the shim flag? */
612 CFRelease(shim_flag
);
616 /* Release the system version dictionary? */
631 int result
= FAILURE
;
632 CFErrorRef error
= NULL
;
633 SOSCCStatus circle_status
;
634 char *circle_state_string
= NULL
;
635 CFArrayRef peer_list
= NULL
;
638 SOSPeerInfoRef peer_info
;
639 CFDictionaryRef peer_gestalt
= NULL
;
640 CFStringRef peer_name
;
641 CFStringRef peer_device_type
;
643 char buffer
[BUFFER_SIZE
];
646 * Dump the SOS circle state.
650 fprintf(log_file
, "SOS Circle State:\n");
651 fprintf(log_file
, "=================\n");
653 /* Are we in a circle? */
654 circle_status
= SOSCCThisDeviceIsInCircle(&error
);
657 /* Dump and consume the error. */
658 dump_cferror(log_file
, "Could not call SOSCCThisDeviceIsInCircle", error
);
661 switch (circle_status
) {
663 case kSOSCCInCircle
: {
664 circle_state_string
= "kSOSCCInCircle";
667 case kSOSCCNotInCircle
: {
668 circle_state_string
= "kSOSCCNotInCircle";
671 case kSOSCCRequestPending
: {
672 circle_state_string
= "kSOSCCRequestPending";
675 case kSOSCCCircleAbsent
: {
676 circle_state_string
= "kSOSCCCircleAbsent";
680 circle_state_string
= "kSOSCCError";
683 case kSOSCCParamErr
: {
684 circle_state_string
= "kSOSCCParamErr";
687 case kSOSCCMemoryErr
: {
688 circle_state_string
= "kSOSCCMemoryErr";
692 circle_state_string
= "Unknown circle status?";
696 fprintf(log_file
, "Circle Status: %s\n", circle_state_string
);
699 /* Can we authenticate? */
700 if (!SOSCCCanAuthenticate(&error
)) {
704 /* Dump and consume the error. */
705 dump_cferror(log_file
, "Could not call SOSCCCanAuthenticate", error
);
708 fprintf(log_file
, "Can Authenticate: NO\n");
712 fprintf(log_file
, "Can Authenticate: YES\n");
715 /* Copy the peers. */
716 peer_list
= SOSCCCopyPeerPeerInfo(&error
);
719 /* Dump the error. */
720 dump_cferror(log_file
, "Could not call SOSCCCopyPeerPeerInfo", error
);
723 /* Get the number of peers. */
724 num_peers
= CFArrayGetCount(peer_list
);
726 fprintf(log_file
, "Number of syncing peers: %ld\n", num_peers
);
730 fprintf(log_file
, "\n");
733 /* Enumerate the peers. */
734 for (i
= 0; i
< num_peers
; i
++) {
736 peer_info
= (SOSPeerInfoRef
) CFArrayGetValueAtIndex(peer_list
, i
);
737 if (peer_info
== NULL
) {
739 fprintf(stderr
, "Could not extract peer %ld of %ld\n", i
, num_peers
);
744 peer_gestalt = SOSPeerInfoCopyPeerGestalt(peer_info);
745 if (peer_gestalt == NULL) {
747 fprintf(stderr, "Could not copy peer gestalt %ld of %ld\n", i, num_peers);
752 /* Get the peer name. */
753 peer_name
= SOSPeerInfoGetPeerName(peer_info
);
754 if (peer_name
== NULL
) {
756 fprintf(stderr
, "Could not extract peer name %ld of %ld\n", i
, num_peers
);
760 /* Convert the peer name to a C string. */
761 if (!CFStringGetCString(peer_name
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
763 fprintf(stderr
, "Could not convert the peer name to a C string\n");
767 /* Dump the peer name. */
768 fprintf(log_file
, " Peer Name: %s\n", buffer
);
770 /* Get the peer device type. */
771 peer_device_type
= SOSPeerInfoGetPeerDeviceType(peer_info
);
772 if (peer_device_type
== NULL
) {
774 fprintf(stderr
, "Could not extract peer device type %ld of %ld\n", i
, num_peers
);
778 /* Convert the peer device type to a C string. */
779 if (!CFStringGetCString(peer_device_type
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
781 fprintf(stderr
, "Could not convert the peer device type to a C string\n");
785 /* Dump the peer name. */
786 fprintf(log_file
, " Peer Device Type: %s\n", buffer
);
788 /* Get the peer ID. */
789 peerID
= SOSPeerInfoGetPeerID(peer_info
);
790 if (peerID
== NULL
) {
792 fprintf(stderr
, "Could not extract peer ID %ld of %ld\n", i
, num_peers
);
796 /* Dump the peer name. */
797 fprintf(log_file
, " Peer ID: %s\n", buffer
);
799 /* Convert the peer ID to a C string. */
800 if (!CFStringGetCString(peerID
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
802 fprintf(stderr
, "Could not convert the peer ID to a C string\n");
806 /* Make it pretty. */
807 fprintf(log_file
, "\n");
810 /* Release the peer list. */
811 CFRelease(peer_list
);
815 /* Copy the applicant peers. */
816 peer_list
= SOSCCCopyApplicantPeerInfo(&error
);
819 /* Dump the error. */
820 dump_cferror(log_file
, "Could not call SOSCCCopyApplicantPeerInfo", error
);
823 /* Get the number of peers. */
824 num_peers
= CFArrayGetCount(peer_list
);
826 fprintf(log_file
, "Number of applicant peers: %ld\n", num_peers
);
830 fprintf(log_file
, "\n");
833 /* Enumerate the peers. */
834 for (i
= 0; i
< num_peers
; i
++) {
836 peer_info
= (SOSPeerInfoRef
) CFArrayGetValueAtIndex(peer_list
, i
);
837 if (peer_info
== NULL
) {
839 fprintf(stderr
, "Could not extract peer %ld of %ld\n", i
, num_peers
);
844 peer_gestalt = SOSPeerInfoCopyPeerGestalt(peer_info);
845 if (peer_gestalt == NULL) {
847 fprintf(stderr, "Could not copy peer gestalt %ld of %ld\n", i, num_peers);
852 /* Get the peer name. */
853 peer_name
= SOSPeerInfoGetPeerName(peer_info
);
854 if (peer_name
== NULL
) {
856 fprintf(stderr
, "Could not extract peer name %ld of %ld\n", i
, num_peers
);
860 /* Convert the peer name to a C string. */
861 if (!CFStringGetCString(peer_name
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
863 fprintf(stderr
, "Could not convert the peer name to a C string\n");
867 /* Dump the peer name. */
868 fprintf(log_file
, " Applicant Name: %s\n", buffer
);
870 /* Get the peer device type. */
871 peer_device_type
= SOSPeerInfoGetPeerDeviceType(peer_info
);
872 if (peer_device_type
== NULL
) {
874 fprintf(stderr
, "Could not extract peer device type %ld of %ld\n", i
, num_peers
);
878 /* Convert the peer device type to a C string. */
879 if (!CFStringGetCString(peer_device_type
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
881 fprintf(stderr
, "Could not convert the peer device type to a C string\n");
885 /* Dump the peer name. */
886 fprintf(log_file
, " Applicant Device Type: %s\n", buffer
);
888 /* Get the peer ID. */
889 peerID
= SOSPeerInfoGetPeerID(peer_info
);
890 if (peerID
== NULL
) {
892 fprintf(stderr
, "Could not extract peer ID %ld of %ld\n", i
, num_peers
);
896 /* Dump the peer name. */
897 fprintf(log_file
, " Applicant ID: %s\n", buffer
);
899 /* Convert the peer ID to a C string. */
900 if (!CFStringGetCString(peerID
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
902 fprintf(stderr
, "Could not convert the peer ID to a C string\n");
906 /* Make it pretty. */
907 if (i
< num_peers
- 1) {
909 fprintf(log_file
, "\n");
913 /* Release the peer list. */
914 CFRelease(peer_list
);
919 fprintf(log_file
, "=================\n\n");
921 /* Set the result to success. */
926 /* Release the peer gestalt? */
927 if (peer_gestalt
!= NULL
) {
929 CFRelease(peer_gestalt
);
933 /* Release the peer list? */
934 if (peer_list
!= NULL
) {
936 CFRelease(peer_list
);
940 /* Release the error string? */
952 dump_keychain_sync_kvs(
955 int result
= FAILURE
;
956 dispatch_group_t cloud_group
;
957 dispatch_queue_t cloud_queue
;
958 dispatch_semaphore_t waitSemaphore
;
959 dispatch_time_t finishTime
;
960 __block CFDictionaryRef kvs_dict
= NULL
;
963 * Dump the keychain syncing KVS.
967 fprintf(log_file
, "Keychain Syncing KVS:\n");
968 fprintf(log_file
, "=================\n");
970 /* Create the serial dispatch queue to talk to CloudKeychainProxy. */
971 cloud_queue
= dispatch_queue_create("cloud_queue", DISPATCH_QUEUE_SERIAL
);
973 /* Create a semaphore. */
974 waitSemaphore
= dispatch_semaphore_create(0);
976 /* Create the finish time. */
977 finishTime
= dispatch_time(DISPATCH_TIME_NOW
, 30ull * NSEC_PER_SEC
);
979 /* Create the dispatch group. */
980 cloud_group
= dispatch_group_create();
982 /* Enter the dispatch group. */
983 dispatch_group_enter(cloud_group
);
985 /* Establish the CloudKeychainProxy reply hander. */
986 CloudKeychainReplyBlock replyBlock
= ^(CFDictionaryRef returnedValues
, CFErrorRef error
)
988 /* Did we get back some values? */
989 if (returnedValues
) {
991 kvs_dict
= (returnedValues
);
995 /* Leave the cloud group. */
996 dispatch_group_leave(cloud_group
);
998 /* Signal the other queue we're done. */
999 dispatch_semaphore_signal(waitSemaphore
);
1002 /* Ask CloudKeychainProxy for all of the raw KVS data. */
1003 SOSCloudKeychainGetAllObjectsFromCloud(cloud_queue
, replyBlock
);
1005 /* Wait for CloudKeychainProxy to respond, up to 30 seconds. */
1006 dispatch_semaphore_wait(waitSemaphore
, finishTime
);
1008 /* Release the semaphore. */
1009 dispatch_release(waitSemaphore
);
1011 /* Did we get any raw KVS data from CloudKeychainProxy? */
1014 dump_dict(log_file
, kvs_dict
, 0);
1017 /* Dump a footer. */
1018 fprintf(log_file
, "=================\n\n");
1020 /* Set the result to success. */
1023 /* Release the KVS dictionary? */
1024 if (kvs_dict
!= NULL
) {
1026 CFRelease(kvs_dict
);
1037 CFDictionaryRef dict
,
1038 const unsigned int indent_level
)
1040 struct dict_dump_state dump_state
;
1042 /* Setup the context. */
1043 dump_state
.log_file
= log_file
;
1044 dump_state
.dict
= dict
;
1045 dump_state
.indent_level
= indent_level
;
1047 /* Apply the dumper to each element in the dictionary. */
1048 CFDictionaryApplyFunction(dict
, dump_dict_applier
, (void *)&dump_state
);
1058 CFTypeRef key_object
;
1059 CFTypeRef value_object
;
1060 struct dict_dump_state
*dump_state
;
1062 char buffer
[BUFFER_SIZE
];
1066 /* Assign the CF types. */
1067 key_object
= (CFTypeRef
) key
;
1068 value_object
= (CFTypeRef
) value
;
1070 /* Get the context. */
1071 dump_state
= (struct dict_dump_state
*)context
;
1073 /* Indent appropriately. */
1074 for (i
= 0; i
< dump_state
->indent_level
; i
++) {
1076 fprintf(dump_state
->log_file
, " ");
1079 /* Determine the key type. */
1080 if (CFGetTypeID(key_object
) == CFStringGetTypeID()) {
1082 /* Convert the key to a C string. */
1083 if (!CFStringGetCString((CFStringRef
) key_object
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
1085 fprintf(stderr
, "Could not convert the key to a C string\n");
1086 fprintf(dump_state
->log_file
, "[Failed Key Type]: ");
1089 fprintf(dump_state
->log_file
, "%s: ", buffer
);
1093 /* Determine the value type. */
1094 if (CFGetTypeID(value_object
) == CFStringGetTypeID()) {
1096 /* Convert the value to a C string. */
1097 if (!CFStringGetCString((CFStringRef
) value_object
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
1099 fprintf(stderr
, "Could not convert the value to a C string\n");
1100 fprintf(dump_state
->log_file
, "[Failed Value Type]: ");
1103 fprintf(dump_state
->log_file
, "%s\n", buffer
);
1105 } else if (CFGetTypeID(value_object
) == CFDataGetTypeID()) {
1107 length
= CFDataGetLength((CFDataRef
)value_object
);
1108 bytes
= CFDataGetBytePtr((CFDataRef
) value_object
);
1110 fprintf(dump_state
->log_file
, "0x");
1112 for (i
= 0; i
< (unsigned int)length
&& i
< MAX_DATA_RATE
; i
++) {
1114 fprintf(dump_state
->log_file
, "%02x", (unsigned char)bytes
[i
]);
1117 fprintf(dump_state
->log_file
, " (%ld bytes)\n", length
);
1120 } else if (CFGetTypeID(value_object
) == CFDictionaryGetTypeID()) {
1122 /* Recurse motherfucker! */
1123 fprintf(dump_state
->log_file
, "\n");
1124 dump_dict(dump_state
->log_file
, (CFDictionaryRef
) value_object
, dump_state
->indent_level
+ 1);
1127 fprintf(dump_state
->log_file
, "[Unknown Value Type]\n");
1135 const char *asl_sender
)
1137 int result
= FAILURE
;
1138 aslmsg log_query
= NULL
;
1139 aslresponse log_response
= NULL
;
1141 char *message_string
;
1142 uint32_t message_length
;
1145 * Dump the ASL logs for the given sender.
1148 /* Dump a header. */
1149 fprintf(log_file
, "ASL: %s\n", asl_sender
);
1150 fprintf(log_file
, "=================\n");
1152 /* Create the ASL query. */
1153 log_query
= asl_new(ASL_TYPE_QUERY
);
1154 if (log_query
== NULL
) {
1156 fprintf(stderr
, "Could not create ASL query\n");
1160 /* Setup the ASL query. */
1161 asl_set_query(log_query
, ASL_KEY_SENDER
, asl_sender
, ASL_QUERY_OP_EQUAL
);
1163 /* Perform the ASL search. */
1164 log_response
= asl_search(NULL
, log_query
);
1165 if (log_response
== NULL
) {
1167 fprintf(log_file
, "Could not perform ASL search for %s\n", asl_sender
);
1170 /* Enumerate the ASL messages in the response. */
1171 while ((log_message
= aslresponse_next(log_response
)) != NULL
) {
1173 /* Format the message entry. */
1174 message_string
= asl_format_message((asl_msg_t
*)log_message
, ASL_MSG_FMT_STD
, ASL_TIME_FMT_LCL
, ASL_ENCODE_SAFE
, &message_length
);
1175 if (message_string
== NULL
) {
1177 fprintf(stderr
, "Could not create ASL message string\n");
1181 fprintf(log_file
, "%s", message_string
);
1183 /* Release the message string. */
1184 free(message_string
);
1185 message_string
= NULL
;
1189 /* Dump a footer. */
1190 fprintf(log_file
, "=================\n\n");
1192 /* Set the result to success. */
1197 /* Release the ASL response? */
1198 if (log_response
!= NULL
) {
1200 aslresponse_free(log_response
);
1201 log_response
= NULL
;
1204 /* Release the ASL query? */
1205 if (log_query
!= NULL
) {
1207 asl_free(log_query
);
1218 const char *description
,
1221 CFStringRef error_string
= NULL
;
1222 char buffer
[BUFFER_SIZE
];
1224 error_string
= CFErrorCopyDescription(error
);
1225 if (error_string
== NULL
) {
1227 fprintf(stderr
, "Could not copy error description?\n");
1231 (void) CFStringGetCString(error_string
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
);
1233 fprintf(stderr
, "%s: %s\n", description
, buffer
);
1234 fprintf(log_file
, "%s: %s\n", description
, buffer
);
1238 /* Release the error string? */
1239 if (error_string
!= NULL
) {
1241 CFRelease(error_string
);
1242 error_string
= NULL
;
1246 #else // TARGET_IPHONE_SIMULATOR
1253 #pragma unused (argc, argv)