1/* 2 * misc.c 3 * libsecurity_transform 4 * 5 * Created by JOsborne on 3/14/10. 6 * Copyright 2010 Apple. All rights reserved. 7 * 8 */ 9 10#include "misc.h" 11 12 13// NOTE: the return may or allocate a fair bit more space then it needs. 14// Use it for short lived conversions (or strdup the result). 15char *utf8(CFStringRef s) { 16 CFIndex sz = CFStringGetMaximumSizeForEncoding(CFStringGetLength(s), kCFStringEncodingUTF8) + 1; 17 CFIndex used = 0; 18 UInt8 *buf = (UInt8 *)malloc(sz); 19 if (!buf) { 20 return NULL; 21 } 22 CFStringGetBytes(s, CFRangeMake(0, CFStringGetLength(s)), kCFStringEncodingUTF8, '?', FALSE, buf, sz, &used); 23 buf[used] = 0; 24 25 return (char*)buf; 26} 27 28void CFfprintf(FILE *f, const char *format, ...) { 29 va_list ap; 30 va_start(ap, format); 31 32 CFStringRef fmt = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8); 33 CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, fmt, ap); 34 va_end(ap); 35 CFRelease(fmt); 36 37 CFIndex sz = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8); 38 sz += 1; 39 CFIndex used = 0; 40 unsigned char *buf; 41 bool needs_free = false; 42 if (sz < 1024) { 43 buf = alloca(sz); 44 } else { 45 buf = malloc(sz); 46 needs_free = true; 47 } 48 if (buf) { 49 CFStringGetBytes(str, CFRangeMake(0, CFStringGetLength(str)), kCFStringEncodingUTF8, '?', FALSE, buf, sz, &used); 50 } else { 51 buf = (unsigned char *)"malloc failue during CFfprintf\n"; 52 } 53 54 fwrite(buf, 1, used, f); 55 if (needs_free) { 56 free(buf); 57 } 58 59 CFRelease(str); 60} 61 62CFErrorRef fancy_error(CFStringRef domain, CFIndex code, CFStringRef description) { 63 const void *v_ekey = kCFErrorDescriptionKey; 64 const void *v_description = description; 65 CFErrorRef err = CFErrorCreateWithUserInfoKeysAndValues(NULL, domain, code, &v_ekey, &v_description, 1); 66 67 return err; 68} 69 70static 71void add_t2ca(CFMutableDictionaryRef t2ca, CFStringRef t, CFStringRef a) { 72 CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, t); 73 if (!ca) { 74 ca = CFSetCreateMutable(NULL, 0, &kCFCopyStringSetCallBacks); 75 CFDictionarySetValue(t2ca, t, ca); 76 } 77 CFSetAddValue(ca, a); 78} 79 80void CFSafeRelease(CFTypeRef object) { 81 if (object) { 82 CFRelease(object); 83 } 84} 85 86void graphviz(FILE *f, SecTransformRef tr) { 87 CFDictionaryRef d = SecTransformCopyExternalRepresentation(tr); 88 89 CFfprintf(f, "digraph TR {\n\tnode [shape=plaintext];\n\n"); 90 CFIndex i, j; 91 CFArrayRef transforms = CFDictionaryGetValue(d, CFSTR("TRANSFORMS")); 92 CFArrayRef connections = CFDictionaryGetValue(d, CFSTR("ARRAY")); 93 94 95 // map transforms to connected attributes 96 CFMutableDictionaryRef t2ca = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 97 for(i = 0; i < CFArrayGetCount(connections); i++) { 98 CFDictionaryRef c = CFArrayGetValueAtIndex(connections, i); 99 100 CFStringRef t_from = CFDictionaryGetValue(c, CFSTR("FROM_NAME")); 101 CFStringRef t_to = CFDictionaryGetValue(c, CFSTR("TO_NAME")); 102 CFStringRef a_from = CFDictionaryGetValue(c, CFSTR("FROM_ATTRIBUTE")); 103 CFStringRef a_to = CFDictionaryGetValue(c, CFSTR("TO_ATTRIBUTE")); 104 105 add_t2ca(t2ca, t_from, a_from); 106 add_t2ca(t2ca, t_to, a_to); 107 } 108 109 110 for(i = 0; i < CFArrayGetCount(transforms); i++) { 111 CFDictionaryRef t = CFArrayGetValueAtIndex(transforms, i); 112 // NAME STATE(dict) TYPE 113 CFStringRef name = CFDictionaryGetValue(t, CFSTR("NAME")); 114 115 CFfprintf(f, "\tsubgraph \"cluster_%@\"{\n", name); 116 117 CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, name); 118 if (ca) { 119 CFIndex cnt = CFSetGetCount(ca); 120 CFStringRef *attrs = malloc(cnt * sizeof(CFStringRef)); 121 CFSetGetValues(ca, (const void **)attrs); 122 123 for(j = 0; j < cnt; j++) { 124 CFfprintf(f, "\t\t\"%@#%@\" [label=\"%@\"];\n", name, attrs[j], attrs[j]); 125 } 126 CFfprintf(f, "\t\t\"%@\" [fontcolor=blue, fontsize=20];\n\t}\n"); 127 } 128 } 129 130 CFfprintf(f, "\n"); 131 132 for(i = 0; i < CFArrayGetCount(connections); i++) { 133 CFDictionaryRef c = CFArrayGetValueAtIndex(connections, i); 134 135 CFStringRef t_from = CFDictionaryGetValue(c, CFSTR("FROM_NAME")); 136 CFStringRef t_to = CFDictionaryGetValue(c, CFSTR("TO_NAME")); 137 CFStringRef a_from = CFDictionaryGetValue(c, CFSTR("FROM_ATTRIBUTE")); 138 CFStringRef a_to = CFDictionaryGetValue(c, CFSTR("TO_ATTRIBUTE")); 139 140 CFfprintf(f, "\t\"%@#%@\" -> \"%@#%@\";\n", t_from, a_from, t_to, a_to); 141 } 142 143 CFfprintf(f, "}\n"); 144 145 CFfprintf(f, "\n/*\n%@\n/*\n", d); 146}