]> git.saurik.com Git - apple/security.git/blob - libsecurity_transform/lib/misc.c
a82293a7656dac5b48c892fc066140f257cde27c
[apple/security.git] / libsecurity_transform / lib / misc.c
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).
15 char *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
28 void 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
62 CFErrorRef 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
70 void add_t2ca(CFMutableDictionaryRef t2ca, CFStringRef t, CFStringRef a) {
71 CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, t);
72 if (!ca) {
73 ca = CFSetCreateMutable(NULL, 0, &kCFCopyStringSetCallBacks);
74 CFDictionarySetValue(t2ca, t, ca);
75 }
76 CFSetAddValue(ca, a);
77 }
78
79 void CFSafeRelease(CFTypeRef object) {
80 if (object) {
81 CFRelease(object);
82 }
83 }
84
85 void graphviz(FILE *f, SecTransformRef tr) {
86 CFDictionaryRef d = SecTransformCopyExternalRepresentation(tr);
87
88 CFfprintf(f, "digraph TR {\n\tnode [shape=plaintext];\n\n");
89 CFIndex i, j;
90 CFArrayRef transforms = CFDictionaryGetValue(d, CFSTR("TRANSFORMS"));
91 CFArrayRef connections = CFDictionaryGetValue(d, CFSTR("ARRAY"));
92
93
94 // map transforms to connected attributes
95 CFMutableDictionaryRef t2ca = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
96 for(i = 0; i < CFArrayGetCount(connections); i++) {
97 CFDictionaryRef c = CFArrayGetValueAtIndex(connections, i);
98
99 CFStringRef t_from = CFDictionaryGetValue(c, CFSTR("FROM_NAME"));
100 CFStringRef t_to = CFDictionaryGetValue(c, CFSTR("TO_NAME"));
101 CFStringRef a_from = CFDictionaryGetValue(c, CFSTR("FROM_ATTRIBUTE"));
102 CFStringRef a_to = CFDictionaryGetValue(c, CFSTR("TO_ATTRIBUTE"));
103
104 add_t2ca(t2ca, t_from, a_from);
105 add_t2ca(t2ca, t_to, a_to);
106 }
107
108
109 for(i = 0; i < CFArrayGetCount(transforms); i++) {
110 CFDictionaryRef t = CFArrayGetValueAtIndex(transforms, i);
111 // NAME STATE(dict) TYPE
112 CFStringRef name = CFDictionaryGetValue(t, CFSTR("NAME"));
113
114 CFfprintf(f, "\tsubgraph \"cluster_%@\"{\n", name);
115
116 CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, name);
117 if (ca) {
118 CFIndex cnt = CFSetGetCount(ca);
119 CFStringRef *attrs = malloc(cnt * sizeof(CFStringRef));
120 CFSetGetValues(ca, (const void **)attrs);
121
122 for(j = 0; j < cnt; j++) {
123 CFfprintf(f, "\t\t\"%@#%@\" [label=\"%@\"];\n", name, attrs[j], attrs[j]);
124 }
125 CFfprintf(f, "\t\t\"%@\" [fontcolor=blue, fontsize=20];\n\t}\n");
126 }
127 }
128
129 CFfprintf(f, "\n");
130
131 for(i = 0; i < CFArrayGetCount(connections); i++) {
132 CFDictionaryRef c = CFArrayGetValueAtIndex(connections, i);
133
134 CFStringRef t_from = CFDictionaryGetValue(c, CFSTR("FROM_NAME"));
135 CFStringRef t_to = CFDictionaryGetValue(c, CFSTR("TO_NAME"));
136 CFStringRef a_from = CFDictionaryGetValue(c, CFSTR("FROM_ATTRIBUTE"));
137 CFStringRef a_to = CFDictionaryGetValue(c, CFSTR("TO_ATTRIBUTE"));
138
139 CFfprintf(f, "\t\"%@#%@\" -> \"%@#%@\";\n", t_from, a_from, t_to, a_to);
140 }
141
142 CFfprintf(f, "}\n");
143
144 CFfprintf(f, "\n/*\n%@\n/*\n", d);
145 }