3 * libsecurity_transform
5 * Created by JOsborne on 3/14/10.
6 * Copyright 2010 Apple. All rights reserved.
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;
18 UInt8
*buf
= (UInt8
*)malloc(sz
);
22 CFStringGetBytes(s
, CFRangeMake(0, CFStringGetLength(s
)), kCFStringEncodingUTF8
, '?', FALSE
, buf
, sz
, &used
);
28 void CFfprintf(FILE *f
, const char *format
, ...) {
32 CFStringRef fmt
= CFStringCreateWithCString(NULL
, format
, kCFStringEncodingUTF8
);
33 CFStringRef str
= CFStringCreateWithFormatAndArguments(NULL
, NULL
, fmt
, ap
);
37 CFIndex sz
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(str
), kCFStringEncodingUTF8
);
41 bool needs_free
= false;
49 CFStringGetBytes(str
, CFRangeMake(0, CFStringGetLength(str
)), kCFStringEncodingUTF8
, '?', FALSE
, buf
, sz
, &used
);
51 buf
= (unsigned char *)"malloc failue during CFfprintf\n";
54 fwrite(buf
, 1, used
, f
);
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);
71 void add_t2ca(CFMutableDictionaryRef t2ca
, CFStringRef t
, CFStringRef a
) {
72 CFMutableSetRef ca
= (CFMutableSetRef
)CFDictionaryGetValue(t2ca
, t
);
74 ca
= CFSetCreateMutable(NULL
, 0, &kCFCopyStringSetCallBacks
);
75 CFDictionarySetValue(t2ca
, t
, ca
);
80 void CFSafeRelease(CFTypeRef object
) {
86 void graphviz(FILE *f
, SecTransformRef tr
) {
87 CFDictionaryRef d
= SecTransformCopyExternalRepresentation(tr
);
89 CFfprintf(f
, "digraph TR {\n\tnode [shape=plaintext];\n\n");
91 CFArrayRef transforms
= CFDictionaryGetValue(d
, CFSTR("TRANSFORMS"));
92 CFArrayRef connections
= CFDictionaryGetValue(d
, CFSTR("ARRAY"));
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
);
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"));
105 add_t2ca(t2ca
, t_from
, a_from
);
106 add_t2ca(t2ca
, t_to
, a_to
);
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"));
115 CFfprintf(f
, "\tsubgraph \"cluster_%@\"{\n", name
);
117 CFMutableSetRef ca
= (CFMutableSetRef
)CFDictionaryGetValue(t2ca
, name
);
119 CFIndex cnt
= CFSetGetCount(ca
);
120 CFStringRef
*attrs
= malloc(cnt
* sizeof(CFStringRef
));
121 CFSetGetValues(ca
, (const void **)attrs
);
123 for(j
= 0; j
< cnt
; j
++) {
124 CFfprintf(f
, "\t\t\"%@#%@\" [label=\"%@\"];\n", name
, attrs
[j
], attrs
[j
]);
126 CFfprintf(f
, "\t\t\"%@\" [fontcolor=blue, fontsize=20];\n\t}\n");
132 for(i
= 0; i
< CFArrayGetCount(connections
); i
++) {
133 CFDictionaryRef c
= CFArrayGetValueAtIndex(connections
, i
);
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"));
140 CFfprintf(f
, "\t\"%@#%@\" -> \"%@#%@\";\n", t_from
, a_from
, t_to
, a_to
);
145 CFfprintf(f
, "\n/*\n%@\n/*\n", d
);