]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_transform/lib/misc.c
Security-55163.44.tar.gz
[apple/security.git] / libsecurity_transform / lib / misc.c
diff --git a/libsecurity_transform/lib/misc.c b/libsecurity_transform/lib/misc.c
new file mode 100644 (file)
index 0000000..a82293a
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ *  misc.c
+ *  libsecurity_transform
+ *
+ *  Created by JOsborne on 3/14/10.
+ *  Copyright 2010 Apple. All rights reserved.
+ *
+ */
+
+#include "misc.h"
+
+
+// NOTE: the return may or allocate a fair bit more space then it needs.
+// Use it for short lived conversions (or strdup the result).
+char *utf8(CFStringRef s) {
+       CFIndex sz = CFStringGetMaximumSizeForEncoding(CFStringGetLength(s), kCFStringEncodingUTF8) + 1;
+       CFIndex used = 0;
+       UInt8 *buf = (UInt8 *)malloc(sz);
+       if (!buf) {
+               return NULL;
+       }
+       CFStringGetBytes(s, CFRangeMake(0, CFStringGetLength(s)), kCFStringEncodingUTF8, '?', FALSE, buf, sz, &used);
+       buf[used] = 0;
+       
+       return (char*)buf;
+}
+
+void CFfprintf(FILE *f, const char *format, ...) {
+       va_list ap;
+       va_start(ap, format);
+       
+       CFStringRef fmt = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8);
+       CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, fmt, ap);
+       va_end(ap);
+       CFRelease(fmt);
+       
+       CFIndex sz = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
+       sz += 1;
+       CFIndex used = 0;
+       unsigned char *buf;
+       bool needs_free = false;
+       if (sz < 1024) {
+               buf = alloca(sz);
+       } else {
+               buf = malloc(sz);
+               needs_free = true;
+       }
+       if (buf) {
+               CFStringGetBytes(str, CFRangeMake(0, CFStringGetLength(str)), kCFStringEncodingUTF8, '?', FALSE, buf, sz, &used);
+       } else {
+               buf = (unsigned char *)"malloc failue during CFfprintf\n";
+       }
+       
+       fwrite(buf, 1, used, f);
+       if (needs_free) {
+               free(buf);
+       }
+       
+       CFRelease(str);
+}
+
+CFErrorRef fancy_error(CFStringRef domain, CFIndex code, CFStringRef description) {
+       const void *v_ekey = kCFErrorDescriptionKey;
+       const void *v_description = description;
+       CFErrorRef err = CFErrorCreateWithUserInfoKeysAndValues(NULL, domain, code, &v_ekey, &v_description, 1);
+       
+       return err;
+}
+
+void add_t2ca(CFMutableDictionaryRef t2ca, CFStringRef t, CFStringRef a) {
+       CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, t);
+       if (!ca) {
+               ca = CFSetCreateMutable(NULL, 0, &kCFCopyStringSetCallBacks);
+               CFDictionarySetValue(t2ca, t, ca);
+       }
+       CFSetAddValue(ca, a);
+}
+
+void CFSafeRelease(CFTypeRef object) {
+       if (object) {
+               CFRelease(object);
+       }
+}
+
+void graphviz(FILE *f, SecTransformRef tr) {
+       CFDictionaryRef d = SecTransformCopyExternalRepresentation(tr);
+       
+       CFfprintf(f, "digraph TR {\n\tnode [shape=plaintext];\n\n");
+       CFIndex i, j;
+       CFArrayRef transforms = CFDictionaryGetValue(d, CFSTR("TRANSFORMS"));
+       CFArrayRef connections = CFDictionaryGetValue(d, CFSTR("ARRAY"));
+       
+       
+       // map transforms to connected attributes
+       CFMutableDictionaryRef t2ca = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       for(i = 0; i < CFArrayGetCount(connections); i++) {
+               CFDictionaryRef c = CFArrayGetValueAtIndex(connections, i);
+               
+               CFStringRef t_from = CFDictionaryGetValue(c, CFSTR("FROM_NAME"));
+               CFStringRef t_to = CFDictionaryGetValue(c, CFSTR("TO_NAME"));
+               CFStringRef a_from = CFDictionaryGetValue(c, CFSTR("FROM_ATTRIBUTE"));
+               CFStringRef a_to = CFDictionaryGetValue(c, CFSTR("TO_ATTRIBUTE"));
+               
+               add_t2ca(t2ca, t_from, a_from);
+               add_t2ca(t2ca, t_to, a_to);
+       }
+       
+       
+       for(i = 0; i < CFArrayGetCount(transforms); i++) {
+               CFDictionaryRef t = CFArrayGetValueAtIndex(transforms, i);
+               // NAME STATE(dict) TYPE
+               CFStringRef name = CFDictionaryGetValue(t, CFSTR("NAME"));              
+               
+               CFfprintf(f, "\tsubgraph \"cluster_%@\"{\n", name);
+               
+               CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, name);
+               if (ca) {
+                       CFIndex cnt = CFSetGetCount(ca);
+                       CFStringRef *attrs = malloc(cnt * sizeof(CFStringRef));
+                       CFSetGetValues(ca, (const void **)attrs);
+                       
+                       for(j = 0; j < cnt; j++) {
+                               CFfprintf(f, "\t\t\"%@#%@\" [label=\"%@\"];\n", name, attrs[j], attrs[j]);
+                       }
+                       CFfprintf(f, "\t\t\"%@\" [fontcolor=blue, fontsize=20];\n\t}\n");
+               }
+       }
+       
+       CFfprintf(f, "\n");
+       
+       for(i = 0; i < CFArrayGetCount(connections); i++) {
+               CFDictionaryRef c = CFArrayGetValueAtIndex(connections, i);
+               
+               CFStringRef t_from = CFDictionaryGetValue(c, CFSTR("FROM_NAME"));
+               CFStringRef t_to = CFDictionaryGetValue(c, CFSTR("TO_NAME"));
+               CFStringRef a_from = CFDictionaryGetValue(c, CFSTR("FROM_ATTRIBUTE"));
+               CFStringRef a_to = CFDictionaryGetValue(c, CFSTR("TO_ATTRIBUTE"));
+               
+               CFfprintf(f, "\t\"%@#%@\" -> \"%@#%@\";\n", t_from, a_from, t_to, a_to);
+       }
+       
+       CFfprintf(f, "}\n");
+       
+       CFfprintf(f, "\n/*\n%@\n/*\n", d);
+}
\ No newline at end of file