2 * clang cloud_keychain_diagnose.c -laks -framework CoreFoundation -framework IOKit -framework Security -o /tmp/cloud_keychain_diagnose
5 #include <CoreFoundation/CoreFoundation.h>
6 #include <CoreFoundation/CFPriv.h>
8 #if !TARGET_IPHONE_SIMULATOR
10 /* Header Declarations */
17 #if TARGET_OS_EMBEDDED
25 #include "SOSCloudCircle.h"
26 #include "SOSPeerInfo.h"
29 /* Constant Declarations */
33 #define MAX_PATH_LEN 1024
34 #define SUFFIX_LENGTH 4
35 #define BUFFER_SIZE 1024
36 #define MAX_DATA_RATE 32
38 /* External CloudKeychain Bridge Types */
39 typedef void (^CloudKeychainReplyBlock
)(CFDictionaryRef returnedValues
, CFErrorRef error
);
40 extern void SOSCloudKeychainGetAllObjectsFromCloud(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
);
42 /* External AppleKeyStore Types */
44 my_keybag_state_bio_unlock
= 1 << 3
48 /* Dictionary Dump State */
49 struct dict_dump_state
53 unsigned int indent_level
;
56 /* Static Function Declarations */
67 enable_cloud_keychain_diagnostics(
68 const unsigned int enable_flag
);
77 dump_system_information(
87 dump_keychain_sync_kvs(
95 const unsigned int indent_level
);
108 const char *asl_sender
);
114 const char *description
,
117 /* Function Definitions */
123 int result
= EXIT_FAILURE
;
125 /* Parse the arguments. */
131 /* Should we just gather logs and status? */
134 if (gather_diagnostics()) {
136 fprintf(stderr
, "Could not gather diagnostics\n");
141 /* Should we enable or disable logging? */
142 if (strncmp(argv
[1], "enable", 6) == 0) {
145 if (enable_cloud_keychain_diagnostics(1)) {
147 fprintf(stderr
, "Could not enable additional cloud keychain diagnostics\n");
150 } else if (strncmp(argv
[1], "disable", 7) == 0) {
153 if (enable_cloud_keychain_diagnostics(1)) {
155 fprintf(stderr
, "Could not disable additional cloud keychain diagnostics\n");
160 /* Get a job, hippy. */
165 /* Set the exit status to success. */
166 result
= EXIT_FAILURE
;
173 /* Static Function Definitions */
178 fprintf(stderr
, "usage: cloud_keychain_diagnose [enable|disable]\n");
186 int result
= FAILURE
;
187 char log_path
[MAX_PATH_LEN
] = "";
189 FILE *log_file
= NULL
;
192 * Create the diagnostics file.
194 * Dump the system information.
195 * on OS X, defaults read if the shim is active
196 * Dump the circle state.
197 * Dump the raw KVS data.
198 * Dump known ASL logs
200 * Remaining work to do from rdar://12479351
202 * query for all items with sync=1
204 * enable push notification logging
207 /* Build the log path. */
208 if (build_log_path(log_path
)) {
210 fprintf(stderr
, "Could not build the log path\n");
214 /* Create it with a randomized suffix. */
215 log_fd
= mkstemps(log_path
, SUFFIX_LENGTH
);
218 fprintf(stderr
, "Could not create the log file: %s\n", strerror(errno
));
222 /* Create a file object from the descriptor. */
223 log_file
= fdopen(log_fd
, "w");
224 if (log_file
== NULL
) {
226 fprintf(stderr
, "Could not recreate the log file: %s\n", strerror(errno
));
232 printf("Writing cloud keychain diagnostics to %s\n", log_path
);
234 /* Dump the system information. */
235 if (dump_system_information(log_file
)) {
237 fprintf(stderr
, "Could not dump the system information\n");
241 /* Dump the SOS circle state. */
242 if (dump_circle_state(log_file
)) {
244 fprintf(stderr
, "Could not dump the SOS circle state\n");
248 /* Dump the raw keychain syncing KVS. */
249 if (dump_keychain_sync_kvs(log_file
)) {
251 fprintf(stderr
, "Could not the raw keychain syncing KVS\n");
256 * Dump the various and sundry ASL logs.
259 if (dump_asl_sender(log_file
, "com.apple.kb-service")) {
261 fprintf(stderr
, "Could not dump the ASL log for com.apple.kb-service\n");
265 if (dump_asl_sender(log_file
, "com.apple.securityd")) {
267 fprintf(stderr
, "Could not dump the ASL log for com.apple.securityd\n");
271 if (dump_asl_sender(log_file
, "com.apple.secd")) {
273 fprintf(stderr
, "Could not dump the ASL log for com.apple.secd\n");
277 if (dump_asl_sender(log_file
, "CloudKeychainProxy")) {
279 fprintf(stderr
, "Could not dump the ASL log for CloudKeychainProxy\n");
283 if (dump_asl_sender(log_file
, "IDSKeychainSyncingProxy")) {
285 fprintf(stderr
, "Could not dump the ASL log for IDSKeychainSyncingProxy\n");
290 if (dump_asl_sender(log_file
, "securityd")) {
292 fprintf(stderr
, "Could not dump the ASL log for securityd\n");
296 if (dump_asl_sender(log_file
, "secd")) {
298 fprintf(stderr
, "Could not dump the ASL log for secd\n");
302 /* Set the result to success. */
307 /* Close the diagnostics file? */
308 if (log_file
!= NULL
) {
314 /* Close the diagnostics file descriptor? */
327 enable_cloud_keychain_diagnostics(
328 const unsigned int enable_flag
)
330 int result
= FAILURE
;
332 /* Set the result to success. */
343 int result
= FAILURE
;
345 struct tm
*time_cube
;
346 CFDictionaryRef system_version_dict
= NULL
;
347 CFStringRef product_name
= NULL
;
349 /* Get the current time. */
352 /* Convert the time into something usable. */
353 time_cube
= localtime(&now
);
354 if (time_cube
== NULL
) {
356 fprintf(stderr
, "I don't know what time it is.\n");
360 /* Copy the system version dictionary. */
361 system_version_dict
= _CFCopySystemVersionDictionary();
362 if (system_version_dict
== NULL
) {
364 fprintf(stderr
, "Could not copy the system version dictionary\n");
368 /* Extract the product name. */
369 product_name
= CFDictionaryGetValue(system_version_dict
, _kCFSystemVersionProductNameKey
);
370 if (product_name
== NULL
) {
372 fprintf(stderr
, "Could not extract the product name from the system version dictionary\n");
377 if (CFEqual(product_name
, CFSTR("Mac OS X"))) {
379 /* Prepare the file template to go into /tmp. */
383 "/tmp/cloud_keychain_diagnostics.%d_%d_%d.%d%d%d.XXXX.txt",
384 1900 + time_cube
->tm_year
,
392 /* Prepare the file template to go into CrashReporter. */
396 "/Library/Logs/CrashReporter/cloud_keychain_diagnostics.%d_%d_%d.%d%d%d.XXXX.txt",
397 1900 + time_cube
->tm_year
,
405 /* Set the result to success. */
410 /* Release the system version dictionary? */
411 if (system_version_dict
!= NULL
) {
413 CFRelease(system_version_dict
);
414 system_version_dict
= NULL
;
422 dump_system_information(
425 int result
= FAILURE
;
426 CFDictionaryRef dict
= NULL
;
427 char buffer
[BUFFER_SIZE
];
428 CFStringRef product_name
;
429 CFStringRef product_version
;
430 CFStringRef product_build_version
;
432 CFTypeRef shim_flag
= NULL
;
433 int keybag_handle
= bad_keybag_handle
;
434 kern_return_t kr
= 0;
435 keybag_state_t keybag_state
= 0;
438 * Dump the system information.
441 * ProductBuildVersion
446 fprintf(log_file
, "Host Information:\n");
447 fprintf(log_file
, "=================\n");
449 /* Copy the system version dictionary. */
450 dict
= _CFCopySystemVersionDictionary();
453 fprintf(stderr
, "Could not copy the system version dictionary\n");
457 /* Extract the product name. */
458 product_name
= CFDictionaryGetValue(dict
, _kCFSystemVersionProductNameKey
);
459 if (product_name
== NULL
) {
461 fprintf(stderr
, "Could not extract the product name from the system version dictionary\n");
465 /* Convert the product name to a C string. */
466 if (!CFStringGetCString(product_name
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
468 fprintf(stderr
, "Could not convert the product name to a C string\n");
472 /* Dump the product name. */
473 fprintf(log_file
, "Product Name: %s\n", buffer
);
475 /* Extract the product version. */
476 product_version
= CFDictionaryGetValue(dict
, _kCFSystemVersionProductVersionKey
);
477 if (product_version
== NULL
) {
479 fprintf(stderr
, "Could not extract the product version from the system version dictionary\n");
483 /* Convert the product version to a C string. */
484 if (!CFStringGetCString(product_version
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
486 fprintf(stderr
, "Could not convert the product version to a C string\n");
490 /* Dump the product version */
491 fprintf(log_file
, "Product Version: %s\n", buffer
);
493 /* Extract the product build version. */
494 product_build_version
= CFDictionaryGetValue(dict
, _kCFSystemVersionBuildVersionKey
);
495 if (product_build_version
== NULL
) {
497 fprintf(stderr
, "Could not extract the product build version from the system version dictionary\n");
501 /* Convert the product build version to a C string. */
502 if (!CFStringGetCString(product_build_version
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
504 fprintf(stderr
, "Could not convert the product build version to a C string\n");
508 /* Dump the product build version. */
509 fprintf(log_file
, "Product Build Version: %s\n", buffer
);
511 /* Lookup the host name. */
512 if (gethostname(buffer
, BUFFER_SIZE
) == -1) {
514 fprintf(stderr
, "Could not lookup the host name\n");
518 /* Dump the host name. */
519 fprintf(log_file
, "Host Name: %s\n", buffer
);
521 /* Lookup the current time. */
522 if (gethostname(buffer
, BUFFER_SIZE
) == -1) {
524 fprintf(stderr
, "Could not lookup the host name\n");
528 /* Get the current time. */
531 /* Dump the current time. */
532 fprintf(log_file
, "Time: %s", ctime(&now
));
535 if (CFEqual(product_name
, CFSTR("Mac OS X"))) {
537 /* Set the keybag handle. */
538 keybag_handle
= session_keybag_handle
;
540 /* Lookup the state of the shim. */
541 shim_flag
= (CFNumberRef
)CFPreferencesCopyValue(CFSTR("SecItemSynchronizable"), CFSTR("com.apple.security"), kCFPreferencesAnyUser
, kCFPreferencesCurrentHost
);
542 if (shim_flag
&& CFGetTypeID(shim_flag
) == CFBooleanGetTypeID()) {
544 /* Is the shim enabled? */
545 if (CFBooleanGetValue((CFBooleanRef
)shim_flag
)) {
547 fprintf(log_file
, "The SecItem shim is enabled\n");
550 fprintf(log_file
, "The SecItem shim is disabled\n");
554 fprintf(log_file
, "The SecItem shim is disabled\n");
558 /* Set the keybag handle. */
559 keybag_handle
= device_keybag_handle
;
562 /* Get the keybag state. */
563 kr
= aks_get_lock_state(keybag_handle
, &keybag_state
);
566 fprintf(stderr
, "Could not call aks_get_lock_state\n");
569 switch (keybag_state
) {
571 case keybag_state_unlocked
: {
573 fprintf(log_file
, "Keybag State: Unlocked\n");
576 case keybag_state_locked
: {
578 fprintf(log_file
, "Keybag State: Locked\n");
581 case keybag_state_no_pin
: {
583 fprintf(log_file
, "Keybag State: No Passcode\n");
586 case keybag_state_been_unlocked
: {
588 fprintf(log_file
, "Keybag State: Been Unlocked\n");
591 case my_keybag_state_bio_unlock
: {
593 fprintf(log_file
, "Keybag State: Bio Unlock\n");
598 fprintf(log_file
, "Keybag State: UNKNOWN\n");
604 fprintf(log_file
, "=================\n\n");
606 /* Set the result to success. */
611 /* Release the shim flag? */
614 CFRelease(shim_flag
);
618 /* Release the system version dictionary? */
633 int result
= FAILURE
;
634 CFErrorRef error
= NULL
;
635 SOSCCStatus circle_status
;
636 CFArrayRef peer_list
= NULL
;
639 SOSPeerInfoRef peer_info
;
640 CFDictionaryRef peer_gestalt
= NULL
;
641 CFStringRef peer_name
;
642 CFStringRef peer_device_type
;
644 char buffer
[BUFFER_SIZE
] = {};
647 * Dump the SOS circle state.
651 fprintf(log_file
, "SOS Circle State:\n");
652 fprintf(log_file
, "=================\n");
654 /* Are we in a circle? */
655 circle_status
= SOSCCThisDeviceIsInCircle(&error
);
658 /* Dump and consume the error. */
659 dump_cferror(log_file
, "Could not call SOSCCThisDeviceIsInCircle", error
);
661 char *circle_state_string
= NULL
;
663 switch (circle_status
) {
665 case kSOSCCInCircle
: {
666 circle_state_string
= "kSOSCCInCircle";
669 case kSOSCCNotInCircle
: {
670 circle_state_string
= "kSOSCCNotInCircle";
673 case kSOSCCRequestPending
: {
674 circle_state_string
= "kSOSCCRequestPending";
677 case kSOSCCCircleAbsent
: {
678 circle_state_string
= "kSOSCCCircleAbsent";
682 circle_state_string
= "kSOSCCError";
686 sprintf(buffer
, "Unknown circle status (%d)?", circle_status
);
687 circle_state_string
= buffer
;
691 fprintf(log_file
, "Circle Status: %s\n", circle_state_string
);
694 /* Can we authenticate? */
695 if (!SOSCCCanAuthenticate(&error
)) {
699 /* Dump and consume the error. */
700 dump_cferror(log_file
, "Could not call SOSCCCanAuthenticate", error
);
703 fprintf(log_file
, "Can Authenticate: NO\n");
707 fprintf(log_file
, "Can Authenticate: YES\n");
710 /* Copy the peers. */
711 peer_list
= SOSCCCopyPeerPeerInfo(&error
);
714 /* Dump the error. */
715 dump_cferror(log_file
, "Could not call SOSCCCopyPeerPeerInfo", error
);
718 /* Get the number of peers. */
719 num_peers
= CFArrayGetCount(peer_list
);
721 fprintf(log_file
, "Number of syncing peers: %ld\n", num_peers
);
725 fprintf(log_file
, "\n");
728 /* Enumerate the peers. */
729 for (i
= 0; i
< num_peers
; i
++) {
731 peer_info
= (SOSPeerInfoRef
) CFArrayGetValueAtIndex(peer_list
, i
);
732 if (peer_info
== NULL
) {
734 fprintf(stderr
, "Could not extract peer %ld of %ld\n", i
, num_peers
);
739 peer_gestalt = SOSPeerInfoCopyPeerGestalt(peer_info);
740 if (peer_gestalt == NULL) {
742 fprintf(stderr, "Could not copy peer gestalt %ld of %ld\n", i, num_peers);
747 /* Get the peer name. */
748 peer_name
= SOSPeerInfoGetPeerName(peer_info
);
749 if (peer_name
== NULL
) {
751 fprintf(stderr
, "Could not extract peer name %ld of %ld\n", i
, num_peers
);
755 /* Convert the peer name to a C string. */
756 if (!CFStringGetCString(peer_name
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
758 fprintf(stderr
, "Could not convert the peer name to a C string\n");
762 /* Dump the peer name. */
763 fprintf(log_file
, " Peer Name: %s\n", buffer
);
765 /* Get the peer device type. */
766 peer_device_type
= SOSPeerInfoGetPeerDeviceType(peer_info
);
767 if (peer_device_type
== NULL
) {
769 fprintf(stderr
, "Could not extract peer device type %ld of %ld\n", i
, num_peers
);
773 /* Convert the peer device type to a C string. */
774 if (!CFStringGetCString(peer_device_type
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
776 fprintf(stderr
, "Could not convert the peer device type to a C string\n");
780 /* Dump the peer name. */
781 fprintf(log_file
, " Peer Device Type: %s\n", buffer
);
783 /* Get the peer ID. */
784 peerID
= SOSPeerInfoGetPeerID(peer_info
);
785 if (peerID
== NULL
) {
787 fprintf(stderr
, "Could not extract peer ID %ld of %ld\n", i
, num_peers
);
791 /* Dump the peer name. */
792 fprintf(log_file
, " Peer ID: %s\n", buffer
);
794 /* Convert the peer ID to a C string. */
795 if (!CFStringGetCString(peerID
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
797 fprintf(stderr
, "Could not convert the peer ID to a C string\n");
801 /* Make it pretty. */
802 fprintf(log_file
, "\n");
805 /* Release the peer list. */
806 CFRelease(peer_list
);
810 /* Copy the applicant peers. */
811 peer_list
= SOSCCCopyApplicantPeerInfo(&error
);
814 /* Dump the error. */
815 dump_cferror(log_file
, "Could not call SOSCCCopyApplicantPeerInfo", error
);
818 /* Get the number of peers. */
819 num_peers
= CFArrayGetCount(peer_list
);
821 fprintf(log_file
, "Number of applicant peers: %ld\n", num_peers
);
825 fprintf(log_file
, "\n");
828 /* Enumerate the peers. */
829 for (i
= 0; i
< num_peers
; i
++) {
831 peer_info
= (SOSPeerInfoRef
) CFArrayGetValueAtIndex(peer_list
, i
);
832 if (peer_info
== NULL
) {
834 fprintf(stderr
, "Could not extract peer %ld of %ld\n", i
, num_peers
);
839 peer_gestalt = SOSPeerInfoCopyPeerGestalt(peer_info);
840 if (peer_gestalt == NULL) {
842 fprintf(stderr, "Could not copy peer gestalt %ld of %ld\n", i, num_peers);
847 /* Get the peer name. */
848 peer_name
= SOSPeerInfoGetPeerName(peer_info
);
849 if (peer_name
== NULL
) {
851 fprintf(stderr
, "Could not extract peer name %ld of %ld\n", i
, num_peers
);
855 /* Convert the peer name to a C string. */
856 if (!CFStringGetCString(peer_name
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
858 fprintf(stderr
, "Could not convert the peer name to a C string\n");
862 /* Dump the peer name. */
863 fprintf(log_file
, " Applicant Name: %s\n", buffer
);
865 /* Get the peer device type. */
866 peer_device_type
= SOSPeerInfoGetPeerDeviceType(peer_info
);
867 if (peer_device_type
== NULL
) {
869 fprintf(stderr
, "Could not extract peer device type %ld of %ld\n", i
, num_peers
);
873 /* Convert the peer device type to a C string. */
874 if (!CFStringGetCString(peer_device_type
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
876 fprintf(stderr
, "Could not convert the peer device type to a C string\n");
880 /* Dump the peer name. */
881 fprintf(log_file
, " Applicant Device Type: %s\n", buffer
);
883 /* Get the peer ID. */
884 peerID
= SOSPeerInfoGetPeerID(peer_info
);
885 if (peerID
== NULL
) {
887 fprintf(stderr
, "Could not extract peer ID %ld of %ld\n", i
, num_peers
);
891 /* Dump the peer name. */
892 fprintf(log_file
, " Applicant ID: %s\n", buffer
);
894 /* Convert the peer ID to a C string. */
895 if (!CFStringGetCString(peerID
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
897 fprintf(stderr
, "Could not convert the peer ID to a C string\n");
901 /* Make it pretty. */
902 if (i
< num_peers
- 1) {
904 fprintf(log_file
, "\n");
908 /* Release the peer list. */
909 CFRelease(peer_list
);
914 fprintf(log_file
, "=================\n\n");
916 /* Set the result to success. */
921 /* Release the peer gestalt? */
922 if (peer_gestalt
!= NULL
) {
924 CFRelease(peer_gestalt
);
928 /* Release the peer list? */
929 if (peer_list
!= NULL
) {
931 CFRelease(peer_list
);
935 /* Release the error string? */
947 dump_keychain_sync_kvs(
950 int result
= FAILURE
;
951 dispatch_group_t cloud_group
;
952 dispatch_queue_t cloud_queue
;
953 dispatch_semaphore_t waitSemaphore
;
954 dispatch_time_t finishTime
;
955 __block CFDictionaryRef kvs_dict
= NULL
;
958 * Dump the keychain syncing KVS.
962 fprintf(log_file
, "Keychain Syncing KVS:\n");
963 fprintf(log_file
, "=================\n");
965 /* Create the serial dispatch queue to talk to CloudKeychainProxy. */
966 cloud_queue
= dispatch_queue_create("cloud_queue", DISPATCH_QUEUE_SERIAL
);
968 /* Create a semaphore. */
969 waitSemaphore
= dispatch_semaphore_create(0);
971 /* Create the finish time. */
972 finishTime
= dispatch_time(DISPATCH_TIME_NOW
, 30ull * NSEC_PER_SEC
);
974 /* Create the dispatch group. */
975 cloud_group
= dispatch_group_create();
977 /* Enter the dispatch group. */
978 dispatch_group_enter(cloud_group
);
980 /* Establish the CloudKeychainProxy reply hander. */
981 CloudKeychainReplyBlock replyBlock
= ^(CFDictionaryRef returnedValues
, CFErrorRef error
)
983 /* Did we get back some values? */
984 if (returnedValues
) {
986 kvs_dict
= (returnedValues
);
990 /* Leave the cloud group. */
991 dispatch_group_leave(cloud_group
);
993 /* Signal the other queue we're done. */
994 dispatch_semaphore_signal(waitSemaphore
);
997 /* Ask CloudKeychainProxy for all of the raw KVS data. */
998 SOSCloudKeychainGetAllObjectsFromCloud(cloud_queue
, replyBlock
);
1000 /* Wait for CloudKeychainProxy to respond, up to 30 seconds. */
1001 dispatch_semaphore_wait(waitSemaphore
, finishTime
);
1003 /* Release the semaphore. */
1004 dispatch_release(waitSemaphore
);
1006 /* Did we get any raw KVS data from CloudKeychainProxy? */
1009 dump_dict(log_file
, kvs_dict
, 0);
1012 /* Dump a footer. */
1013 fprintf(log_file
, "=================\n\n");
1015 /* Set the result to success. */
1018 /* Release the KVS dictionary? */
1019 if (kvs_dict
!= NULL
) {
1021 CFRelease(kvs_dict
);
1032 CFDictionaryRef dict
,
1033 const unsigned int indent_level
)
1035 struct dict_dump_state dump_state
;
1037 /* Setup the context. */
1038 dump_state
.log_file
= log_file
;
1039 dump_state
.dict
= dict
;
1040 dump_state
.indent_level
= indent_level
;
1042 /* Apply the dumper to each element in the dictionary. */
1043 CFDictionaryApplyFunction(dict
, dump_dict_applier
, (void *)&dump_state
);
1053 CFTypeRef key_object
;
1054 CFTypeRef value_object
;
1055 struct dict_dump_state
*dump_state
;
1057 char buffer
[BUFFER_SIZE
];
1061 /* Assign the CF types. */
1062 key_object
= (CFTypeRef
) key
;
1063 value_object
= (CFTypeRef
) value
;
1065 /* Get the context. */
1066 dump_state
= (struct dict_dump_state
*)context
;
1068 /* Indent appropriately. */
1069 for (i
= 0; i
< dump_state
->indent_level
; i
++) {
1071 fprintf(dump_state
->log_file
, " ");
1074 /* Determine the key type. */
1075 if (CFGetTypeID(key_object
) == CFStringGetTypeID()) {
1077 /* Convert the key to a C string. */
1078 if (!CFStringGetCString((CFStringRef
) key_object
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
1080 fprintf(stderr
, "Could not convert the key to a C string\n");
1081 fprintf(dump_state
->log_file
, "[Failed Key Type]: ");
1084 fprintf(dump_state
->log_file
, "%s: ", buffer
);
1088 /* Determine the value type. */
1089 if (CFGetTypeID(value_object
) == CFStringGetTypeID()) {
1091 /* Convert the value to a C string. */
1092 if (!CFStringGetCString((CFStringRef
) value_object
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
1094 fprintf(stderr
, "Could not convert the value to a C string\n");
1095 fprintf(dump_state
->log_file
, "[Failed Value Type]: ");
1098 fprintf(dump_state
->log_file
, "%s\n", buffer
);
1100 } else if (CFGetTypeID(value_object
) == CFDataGetTypeID()) {
1102 length
= CFDataGetLength((CFDataRef
)value_object
);
1103 bytes
= CFDataGetBytePtr((CFDataRef
) value_object
);
1105 fprintf(dump_state
->log_file
, "0x");
1107 for (i
= 0; i
< (unsigned int)length
&& i
< MAX_DATA_RATE
; i
++) {
1109 fprintf(dump_state
->log_file
, "%02x", (unsigned char)bytes
[i
]);
1112 fprintf(dump_state
->log_file
, " (%ld bytes)\n", length
);
1115 } else if (CFGetTypeID(value_object
) == CFDictionaryGetTypeID()) {
1118 fprintf(dump_state
->log_file
, "\n");
1119 dump_dict(dump_state
->log_file
, (CFDictionaryRef
) value_object
, dump_state
->indent_level
+ 1);
1122 fprintf(dump_state
->log_file
, "[Unknown Value Type]\n");
1130 const char *asl_sender
)
1132 int result
= FAILURE
;
1133 aslmsg log_query
= NULL
;
1134 aslresponse log_response
= NULL
;
1136 char *message_string
;
1137 uint32_t message_length
;
1140 * Dump the ASL logs for the given sender.
1143 /* Dump a header. */
1144 fprintf(log_file
, "ASL: %s\n", asl_sender
);
1145 fprintf(log_file
, "=================\n");
1147 /* Create the ASL query. */
1148 log_query
= asl_new(ASL_TYPE_QUERY
);
1149 if (log_query
== NULL
) {
1151 fprintf(stderr
, "Could not create ASL query\n");
1155 /* Setup the ASL query. */
1156 asl_set_query(log_query
, ASL_KEY_SENDER
, asl_sender
, ASL_QUERY_OP_EQUAL
);
1158 /* Perform the ASL search. */
1159 log_response
= asl_search(NULL
, log_query
);
1160 if (log_response
== NULL
) {
1162 fprintf(log_file
, "Could not perform ASL search for %s\n", asl_sender
);
1165 /* Enumerate the ASL messages in the response. */
1166 while ((log_message
= asl_next(log_response
)) != NULL
) {
1168 /* Format the message entry. */
1169 message_string
= asl_format_message((asl_msg_t
*)log_message
, ASL_MSG_FMT_STD
, ASL_TIME_FMT_LCL
, ASL_ENCODE_SAFE
, &message_length
);
1170 if (message_string
== NULL
) {
1172 fprintf(stderr
, "Could not create ASL message string\n");
1176 fprintf(log_file
, "%s", message_string
);
1178 /* Release the message string. */
1179 free(message_string
);
1180 message_string
= NULL
;
1184 /* Dump a footer. */
1185 fprintf(log_file
, "=================\n\n");
1187 /* Set the result to success. */
1192 /* Release the ASL response? */
1193 if (log_response
!= NULL
) {
1195 asl_free(log_response
);
1196 log_response
= NULL
;
1199 /* Release the ASL query? */
1200 if (log_query
!= NULL
) {
1202 asl_free(log_query
);
1213 const char *description
,
1216 CFStringRef error_string
= NULL
;
1217 char buffer
[BUFFER_SIZE
];
1219 error_string
= CFErrorCopyDescription(error
);
1220 if (error_string
== NULL
) {
1222 fprintf(stderr
, "Could not copy error description?\n");
1226 (void) CFStringGetCString(error_string
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
);
1228 fprintf(stderr
, "%s: %s\n", description
, buffer
);
1229 fprintf(log_file
, "%s: %s\n", description
, buffer
);
1233 /* Release the error string? */
1234 if (error_string
!= NULL
) {
1236 CFRelease(error_string
);
1237 error_string
= NULL
;
1241 #else // TARGET_IPHONE_SIMULATOR
1248 #pragma unused (argc, argv)