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
, "securityd")) {
285 fprintf(stderr
, "Could not dump the ASL log for securityd\n");
289 if (dump_asl_sender(log_file
, "secd")) {
291 fprintf(stderr
, "Could not dump the ASL log for secd\n");
295 /* Set the result to success. */
300 /* Close the diagnostics file? */
301 if (log_file
!= NULL
) {
307 /* Close the diagnostics file descriptor? */
320 enable_cloud_keychain_diagnostics(
321 const unsigned int enable_flag
)
323 int result
= FAILURE
;
325 /* Set the result to success. */
336 int result
= FAILURE
;
338 struct tm
*time_cube
;
339 CFDictionaryRef system_version_dict
= NULL
;
340 CFStringRef product_name
= NULL
;
342 /* Get the current time. */
345 /* Convert the time into something usable. */
346 time_cube
= localtime(&now
);
347 if (time_cube
== NULL
) {
349 fprintf(stderr
, "I don't know what time it is.\n");
353 /* Copy the system version dictionary. */
354 system_version_dict
= _CFCopySystemVersionDictionary();
355 if (system_version_dict
== NULL
) {
357 fprintf(stderr
, "Could not copy the system version dictionary\n");
361 /* Extract the product name. */
362 product_name
= CFDictionaryGetValue(system_version_dict
, _kCFSystemVersionProductNameKey
);
363 if (product_name
== NULL
) {
365 fprintf(stderr
, "Could not extract the product name from the system version dictionary\n");
370 if (CFEqual(product_name
, CFSTR("Mac OS X"))) {
372 /* Prepare the file template to go into /tmp. */
376 "/tmp/cloud_keychain_diagnostics.%d_%d_%d.%d%d%d.XXXX.txt",
377 1900 + time_cube
->tm_year
,
385 /* Prepare the file template to go into CrashReporter. */
389 "/Library/Logs/CrashReporter/cloud_keychain_diagnostics.%d_%d_%d.%d%d%d.XXXX.txt",
390 1900 + time_cube
->tm_year
,
398 /* Set the result to success. */
403 /* Release the system version dictionary? */
404 if (system_version_dict
!= NULL
) {
406 CFRelease(system_version_dict
);
407 system_version_dict
= NULL
;
415 dump_system_information(
418 int result
= FAILURE
;
419 CFDictionaryRef dict
= NULL
;
420 char buffer
[BUFFER_SIZE
];
421 CFStringRef product_name
;
422 CFStringRef product_version
;
423 CFStringRef product_build_version
;
425 CFTypeRef shim_flag
= NULL
;
426 int keybag_handle
= bad_keybag_handle
;
427 kern_return_t kr
= 0;
428 keybag_state_t keybag_state
= 0;
431 * Dump the system information.
434 * ProductBuildVersion
439 fprintf(log_file
, "Host Information:\n");
440 fprintf(log_file
, "=================\n");
442 /* Copy the system version dictionary. */
443 dict
= _CFCopySystemVersionDictionary();
446 fprintf(stderr
, "Could not copy the system version dictionary\n");
450 /* Extract the product name. */
451 product_name
= CFDictionaryGetValue(dict
, _kCFSystemVersionProductNameKey
);
452 if (product_name
== NULL
) {
454 fprintf(stderr
, "Could not extract the product name from the system version dictionary\n");
458 /* Convert the product name to a C string. */
459 if (!CFStringGetCString(product_name
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
461 fprintf(stderr
, "Could not convert the product name to a C string\n");
465 /* Dump the product name. */
466 fprintf(log_file
, "Product Name: %s\n", buffer
);
468 /* Extract the product version. */
469 product_version
= CFDictionaryGetValue(dict
, _kCFSystemVersionProductVersionKey
);
470 if (product_version
== NULL
) {
472 fprintf(stderr
, "Could not extract the product version from the system version dictionary\n");
476 /* Convert the product version to a C string. */
477 if (!CFStringGetCString(product_version
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
479 fprintf(stderr
, "Could not convert the product version to a C string\n");
483 /* Dump the product version */
484 fprintf(log_file
, "Product Version: %s\n", buffer
);
486 /* Extract the product build version. */
487 product_build_version
= CFDictionaryGetValue(dict
, _kCFSystemVersionBuildVersionKey
);
488 if (product_build_version
== NULL
) {
490 fprintf(stderr
, "Could not extract the product build version from the system version dictionary\n");
494 /* Convert the product build version to a C string. */
495 if (!CFStringGetCString(product_build_version
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
497 fprintf(stderr
, "Could not convert the product build version to a C string\n");
501 /* Dump the product build version. */
502 fprintf(log_file
, "Product Build Version: %s\n", buffer
);
504 /* Lookup the host name. */
505 if (gethostname(buffer
, BUFFER_SIZE
) == -1) {
507 fprintf(stderr
, "Could not lookup the host name\n");
511 /* Dump the host name. */
512 fprintf(log_file
, "Host Name: %s\n", buffer
);
514 /* Lookup the current time. */
515 if (gethostname(buffer
, BUFFER_SIZE
) == -1) {
517 fprintf(stderr
, "Could not lookup the host name\n");
521 /* Get the current time. */
524 /* Dump the current time. */
525 fprintf(log_file
, "Time: %s", ctime(&now
));
528 if (CFEqual(product_name
, CFSTR("Mac OS X"))) {
530 /* Set the keybag handle. */
531 keybag_handle
= session_keybag_handle
;
533 /* Lookup the state of the shim. */
534 shim_flag
= (CFNumberRef
)CFPreferencesCopyValue(CFSTR("SecItemSynchronizable"), CFSTR("com.apple.security"), kCFPreferencesAnyUser
, kCFPreferencesCurrentHost
);
535 if (shim_flag
&& CFGetTypeID(shim_flag
) == CFBooleanGetTypeID()) {
537 /* Is the shim enabled? */
538 if (CFBooleanGetValue((CFBooleanRef
)shim_flag
)) {
540 fprintf(log_file
, "The SecItem shim is enabled\n");
543 fprintf(log_file
, "The SecItem shim is disabled\n");
547 fprintf(log_file
, "The SecItem shim is disabled\n");
551 /* Set the keybag handle. */
552 keybag_handle
= device_keybag_handle
;
555 /* Get the keybag state. */
556 kr
= aks_get_lock_state(keybag_handle
, &keybag_state
);
559 fprintf(stderr
, "Could not call aks_get_lock_state\n");
562 switch (keybag_state
) {
564 case keybag_state_unlocked
: {
566 fprintf(log_file
, "Keybag State: Unlocked\n");
569 case keybag_state_locked
: {
571 fprintf(log_file
, "Keybag State: Locked\n");
574 case keybag_state_no_pin
: {
576 fprintf(log_file
, "Keybag State: No Passcode\n");
579 case keybag_state_been_unlocked
: {
581 fprintf(log_file
, "Keybag State: Been Unlocked\n");
584 case my_keybag_state_bio_unlock
: {
586 fprintf(log_file
, "Keybag State: Bio Unlock\n");
591 fprintf(log_file
, "Keybag State: UNKNOWN\n");
597 fprintf(log_file
, "=================\n\n");
599 /* Set the result to success. */
604 /* Release the shim flag? */
607 CFRelease(shim_flag
);
611 /* Release the system version dictionary? */
626 int result
= FAILURE
;
627 CFErrorRef error
= NULL
;
628 SOSCCStatus circle_status
;
629 CFArrayRef peer_list
= NULL
;
632 SOSPeerInfoRef peer_info
;
633 CFDictionaryRef peer_gestalt
= NULL
;
634 CFStringRef peer_name
;
635 CFStringRef peer_device_type
;
637 char buffer
[BUFFER_SIZE
] = {};
640 * Dump the SOS circle state.
644 fprintf(log_file
, "SOS Circle State:\n");
645 fprintf(log_file
, "=================\n");
647 /* Are we in a circle? */
648 circle_status
= SOSCCThisDeviceIsInCircle(&error
);
651 /* Dump and consume the error. */
652 dump_cferror(log_file
, "Could not call SOSCCThisDeviceIsInCircle", error
);
654 char *circle_state_string
= NULL
;
656 switch (circle_status
) {
658 case kSOSCCInCircle
: {
659 circle_state_string
= "kSOSCCInCircle";
662 case kSOSCCNotInCircle
: {
663 circle_state_string
= "kSOSCCNotInCircle";
666 case kSOSCCRequestPending
: {
667 circle_state_string
= "kSOSCCRequestPending";
670 case kSOSCCCircleAbsent
: {
671 circle_state_string
= "kSOSCCCircleAbsent";
675 circle_state_string
= "kSOSCCError";
679 sprintf(buffer
, "Unknown circle status (%d)?", circle_status
);
680 circle_state_string
= buffer
;
684 fprintf(log_file
, "Circle Status: %s\n", circle_state_string
);
687 /* Can we authenticate? */
688 if (!SOSCCCanAuthenticate(&error
)) {
692 /* Dump and consume the error. */
693 dump_cferror(log_file
, "Could not call SOSCCCanAuthenticate", error
);
696 fprintf(log_file
, "Can Authenticate: NO\n");
700 fprintf(log_file
, "Can Authenticate: YES\n");
703 /* Copy the peers. */
704 peer_list
= SOSCCCopyPeerPeerInfo(&error
);
707 /* Dump the error. */
708 dump_cferror(log_file
, "Could not call SOSCCCopyPeerPeerInfo", error
);
711 /* Get the number of peers. */
712 num_peers
= CFArrayGetCount(peer_list
);
714 fprintf(log_file
, "Number of syncing peers: %ld\n", num_peers
);
718 fprintf(log_file
, "\n");
721 /* Enumerate the peers. */
722 for (i
= 0; i
< num_peers
; i
++) {
724 peer_info
= (SOSPeerInfoRef
) CFArrayGetValueAtIndex(peer_list
, i
);
725 if (peer_info
== NULL
) {
727 fprintf(stderr
, "Could not extract peer %ld of %ld\n", i
, num_peers
);
732 peer_gestalt = SOSPeerInfoCopyPeerGestalt(peer_info);
733 if (peer_gestalt == NULL) {
735 fprintf(stderr, "Could not copy peer gestalt %ld of %ld\n", i, num_peers);
740 /* Get the peer name. */
741 peer_name
= SOSPeerInfoGetPeerName(peer_info
);
742 if (peer_name
== NULL
) {
744 fprintf(stderr
, "Could not extract peer name %ld of %ld\n", i
, num_peers
);
748 /* Convert the peer name to a C string. */
749 if (!CFStringGetCString(peer_name
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
751 fprintf(stderr
, "Could not convert the peer name to a C string\n");
755 /* Dump the peer name. */
756 fprintf(log_file
, " Peer Name: %s\n", buffer
);
758 /* Get the peer device type. */
759 peer_device_type
= SOSPeerInfoGetPeerDeviceType(peer_info
);
760 if (peer_device_type
== NULL
) {
762 fprintf(stderr
, "Could not extract peer device type %ld of %ld\n", i
, num_peers
);
766 /* Convert the peer device type to a C string. */
767 if (!CFStringGetCString(peer_device_type
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
769 fprintf(stderr
, "Could not convert the peer device type to a C string\n");
773 /* Dump the peer name. */
774 fprintf(log_file
, " Peer Device Type: %s\n", buffer
);
776 /* Get the peer ID. */
777 peerID
= SOSPeerInfoGetPeerID(peer_info
);
778 if (peerID
== NULL
) {
780 fprintf(stderr
, "Could not extract peer ID %ld of %ld\n", i
, num_peers
);
784 /* Dump the peer name. */
785 fprintf(log_file
, " Peer ID: %s\n", buffer
);
787 /* Convert the peer ID to a C string. */
788 if (!CFStringGetCString(peerID
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
790 fprintf(stderr
, "Could not convert the peer ID to a C string\n");
794 /* Make it pretty. */
795 fprintf(log_file
, "\n");
798 /* Release the peer list. */
799 CFRelease(peer_list
);
803 /* Copy the applicant peers. */
804 peer_list
= SOSCCCopyApplicantPeerInfo(&error
);
807 /* Dump the error. */
808 dump_cferror(log_file
, "Could not call SOSCCCopyApplicantPeerInfo", error
);
811 /* Get the number of peers. */
812 num_peers
= CFArrayGetCount(peer_list
);
814 fprintf(log_file
, "Number of applicant peers: %ld\n", num_peers
);
818 fprintf(log_file
, "\n");
821 /* Enumerate the peers. */
822 for (i
= 0; i
< num_peers
; i
++) {
824 peer_info
= (SOSPeerInfoRef
) CFArrayGetValueAtIndex(peer_list
, i
);
825 if (peer_info
== NULL
) {
827 fprintf(stderr
, "Could not extract peer %ld of %ld\n", i
, num_peers
);
832 peer_gestalt = SOSPeerInfoCopyPeerGestalt(peer_info);
833 if (peer_gestalt == NULL) {
835 fprintf(stderr, "Could not copy peer gestalt %ld of %ld\n", i, num_peers);
840 /* Get the peer name. */
841 peer_name
= SOSPeerInfoGetPeerName(peer_info
);
842 if (peer_name
== NULL
) {
844 fprintf(stderr
, "Could not extract peer name %ld of %ld\n", i
, num_peers
);
848 /* Convert the peer name to a C string. */
849 if (!CFStringGetCString(peer_name
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
851 fprintf(stderr
, "Could not convert the peer name to a C string\n");
855 /* Dump the peer name. */
856 fprintf(log_file
, " Applicant Name: %s\n", buffer
);
858 /* Get the peer device type. */
859 peer_device_type
= SOSPeerInfoGetPeerDeviceType(peer_info
);
860 if (peer_device_type
== NULL
) {
862 fprintf(stderr
, "Could not extract peer device type %ld of %ld\n", i
, num_peers
);
866 /* Convert the peer device type to a C string. */
867 if (!CFStringGetCString(peer_device_type
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
869 fprintf(stderr
, "Could not convert the peer device type to a C string\n");
873 /* Dump the peer name. */
874 fprintf(log_file
, " Applicant Device Type: %s\n", buffer
);
876 /* Get the peer ID. */
877 peerID
= SOSPeerInfoGetPeerID(peer_info
);
878 if (peerID
== NULL
) {
880 fprintf(stderr
, "Could not extract peer ID %ld of %ld\n", i
, num_peers
);
884 /* Dump the peer name. */
885 fprintf(log_file
, " Applicant ID: %s\n", buffer
);
887 /* Convert the peer ID to a C string. */
888 if (!CFStringGetCString(peerID
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
890 fprintf(stderr
, "Could not convert the peer ID to a C string\n");
894 /* Make it pretty. */
895 if (i
< num_peers
- 1) {
897 fprintf(log_file
, "\n");
901 /* Release the peer list. */
902 CFRelease(peer_list
);
907 fprintf(log_file
, "=================\n\n");
909 /* Set the result to success. */
914 /* Release the peer gestalt? */
915 if (peer_gestalt
!= NULL
) {
917 CFRelease(peer_gestalt
);
921 /* Release the peer list? */
922 if (peer_list
!= NULL
) {
924 CFRelease(peer_list
);
928 /* Release the error string? */
940 dump_keychain_sync_kvs(
943 int result
= FAILURE
;
944 dispatch_group_t cloud_group
;
945 dispatch_queue_t cloud_queue
;
946 dispatch_semaphore_t waitSemaphore
;
947 dispatch_time_t finishTime
;
948 __block CFDictionaryRef kvs_dict
= NULL
;
951 * Dump the keychain syncing KVS.
955 fprintf(log_file
, "Keychain Syncing KVS:\n");
956 fprintf(log_file
, "=================\n");
958 /* Create the serial dispatch queue to talk to CloudKeychainProxy. */
959 cloud_queue
= dispatch_queue_create("cloud_queue", DISPATCH_QUEUE_SERIAL
);
961 /* Create a semaphore. */
962 waitSemaphore
= dispatch_semaphore_create(0);
964 /* Create the finish time. */
965 finishTime
= dispatch_time(DISPATCH_TIME_NOW
, 30ull * NSEC_PER_SEC
);
967 /* Create the dispatch group. */
968 cloud_group
= dispatch_group_create();
970 /* Enter the dispatch group. */
971 dispatch_group_enter(cloud_group
);
973 /* Establish the CloudKeychainProxy reply hander. */
974 CloudKeychainReplyBlock replyBlock
= ^(CFDictionaryRef returnedValues
, CFErrorRef error
)
976 /* Did we get back some values? */
977 if (returnedValues
) {
979 kvs_dict
= (returnedValues
);
983 /* Leave the cloud group. */
984 dispatch_group_leave(cloud_group
);
986 /* Signal the other queue we're done. */
987 dispatch_semaphore_signal(waitSemaphore
);
990 /* Ask CloudKeychainProxy for all of the raw KVS data. */
991 SOSCloudKeychainGetAllObjectsFromCloud(cloud_queue
, replyBlock
);
993 /* Wait for CloudKeychainProxy to respond, up to 30 seconds. */
994 dispatch_semaphore_wait(waitSemaphore
, finishTime
);
996 /* Release the semaphore. */
997 dispatch_release(waitSemaphore
);
999 /* Did we get any raw KVS data from CloudKeychainProxy? */
1002 dump_dict(log_file
, kvs_dict
, 0);
1005 /* Dump a footer. */
1006 fprintf(log_file
, "=================\n\n");
1008 /* Set the result to success. */
1011 /* Release the KVS dictionary? */
1012 if (kvs_dict
!= NULL
) {
1014 CFRelease(kvs_dict
);
1025 CFDictionaryRef dict
,
1026 const unsigned int indent_level
)
1028 struct dict_dump_state dump_state
;
1030 /* Setup the context. */
1031 dump_state
.log_file
= log_file
;
1032 dump_state
.dict
= dict
;
1033 dump_state
.indent_level
= indent_level
;
1035 /* Apply the dumper to each element in the dictionary. */
1036 CFDictionaryApplyFunction(dict
, dump_dict_applier
, (void *)&dump_state
);
1046 CFTypeRef key_object
;
1047 CFTypeRef value_object
;
1048 struct dict_dump_state
*dump_state
;
1050 char buffer
[BUFFER_SIZE
];
1054 /* Assign the CF types. */
1055 key_object
= (CFTypeRef
) key
;
1056 value_object
= (CFTypeRef
) value
;
1058 /* Get the context. */
1059 dump_state
= (struct dict_dump_state
*)context
;
1061 /* Indent appropriately. */
1062 for (i
= 0; i
< dump_state
->indent_level
; i
++) {
1064 fprintf(dump_state
->log_file
, " ");
1067 /* Determine the key type. */
1068 if (CFGetTypeID(key_object
) == CFStringGetTypeID()) {
1070 /* Convert the key to a C string. */
1071 if (!CFStringGetCString((CFStringRef
) key_object
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
1073 fprintf(stderr
, "Could not convert the key to a C string\n");
1074 fprintf(dump_state
->log_file
, "[Failed Key Type]: ");
1077 fprintf(dump_state
->log_file
, "%s: ", buffer
);
1081 /* Determine the value type. */
1082 if (CFGetTypeID(value_object
) == CFStringGetTypeID()) {
1084 /* Convert the value to a C string. */
1085 if (!CFStringGetCString((CFStringRef
) value_object
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
)) {
1087 fprintf(stderr
, "Could not convert the value to a C string\n");
1088 fprintf(dump_state
->log_file
, "[Failed Value Type]: ");
1091 fprintf(dump_state
->log_file
, "%s\n", buffer
);
1093 } else if (CFGetTypeID(value_object
) == CFDataGetTypeID()) {
1095 length
= CFDataGetLength((CFDataRef
)value_object
);
1096 bytes
= CFDataGetBytePtr((CFDataRef
) value_object
);
1098 fprintf(dump_state
->log_file
, "0x");
1100 for (i
= 0; i
< (unsigned int)length
&& i
< MAX_DATA_RATE
; i
++) {
1102 fprintf(dump_state
->log_file
, "%02x", (unsigned char)bytes
[i
]);
1105 fprintf(dump_state
->log_file
, " (%ld bytes)\n", length
);
1108 } else if (CFGetTypeID(value_object
) == CFDictionaryGetTypeID()) {
1111 fprintf(dump_state
->log_file
, "\n");
1112 dump_dict(dump_state
->log_file
, (CFDictionaryRef
) value_object
, dump_state
->indent_level
+ 1);
1115 fprintf(dump_state
->log_file
, "[Unknown Value Type]\n");
1123 const char *asl_sender
)
1125 int result
= FAILURE
;
1126 aslmsg log_query
= NULL
;
1127 aslresponse log_response
= NULL
;
1129 char *message_string
;
1130 uint32_t message_length
;
1133 * Dump the ASL logs for the given sender.
1136 /* Dump a header. */
1137 fprintf(log_file
, "ASL: %s\n", asl_sender
);
1138 fprintf(log_file
, "=================\n");
1140 /* Create the ASL query. */
1141 log_query
= asl_new(ASL_TYPE_QUERY
);
1142 if (log_query
== NULL
) {
1144 fprintf(stderr
, "Could not create ASL query\n");
1148 /* Setup the ASL query. */
1149 asl_set_query(log_query
, ASL_KEY_SENDER
, asl_sender
, ASL_QUERY_OP_EQUAL
);
1151 /* Perform the ASL search. */
1152 log_response
= asl_search(NULL
, log_query
);
1153 if (log_response
== NULL
) {
1155 fprintf(log_file
, "Could not perform ASL search for %s\n", asl_sender
);
1158 /* Enumerate the ASL messages in the response. */
1159 while ((log_message
= asl_next(log_response
)) != NULL
) {
1161 /* Format the message entry. */
1162 message_string
= asl_format_message((asl_msg_t
*)log_message
, ASL_MSG_FMT_STD
, ASL_TIME_FMT_LCL
, ASL_ENCODE_SAFE
, &message_length
);
1163 if (message_string
== NULL
) {
1165 fprintf(stderr
, "Could not create ASL message string\n");
1169 fprintf(log_file
, "%s", message_string
);
1171 /* Release the message string. */
1172 free(message_string
);
1173 message_string
= NULL
;
1177 /* Dump a footer. */
1178 fprintf(log_file
, "=================\n\n");
1180 /* Set the result to success. */
1185 /* Release the ASL response? */
1186 if (log_response
!= NULL
) {
1188 asl_free(log_response
);
1189 log_response
= NULL
;
1192 /* Release the ASL query? */
1193 if (log_query
!= NULL
) {
1195 asl_free(log_query
);
1206 const char *description
,
1209 CFStringRef error_string
= NULL
;
1210 char buffer
[BUFFER_SIZE
];
1212 error_string
= CFErrorCopyDescription(error
);
1213 if (error_string
== NULL
) {
1215 fprintf(stderr
, "Could not copy error description?\n");
1219 (void) CFStringGetCString(error_string
, buffer
, BUFFER_SIZE
, kCFStringEncodingUTF8
);
1221 fprintf(stderr
, "%s: %s\n", description
, buffer
);
1222 fprintf(log_file
, "%s: %s\n", description
, buffer
);
1226 /* Release the error string? */
1227 if (error_string
!= NULL
) {
1229 CFRelease(error_string
);
1230 error_string
= NULL
;
1234 #else // TARGET_IPHONE_SIMULATOR
1241 #pragma unused (argc, argv)