]> git.saurik.com Git - apple/xnu.git/blob - libkdd/kdd_main.m
xnu-4903.241.1.tar.gz
[apple/xnu.git] / libkdd / kdd_main.m
1 //
2 // main.m
3 // kdd command
4 //
5 // Created by Lawrence D'Anna on 11/9/15.
6 // Copyright © 2015 Apple Inc. All rights reserved.
7 //
8
9 #import <Foundation/Foundation.h>
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <zlib.h>
13 #import "kdd.h"
14
15 void usage(char *const* argv) {
16 fprintf(stderr, "usage: %s [-p] FILE\n", argv[0]);
17 exit(1);
18 }
19
20 int main(int argc, char *const*argv) {
21
22 int c ;
23 int plist = 0;
24
25 while ((c = getopt(argc, argv, "p")) != EOF) {
26 switch(c) {
27 case 'p':
28 plist = TRUE;
29 break;
30 case '?':
31 case 'h':
32 default:
33 usage(argv);
34 break;
35 }
36 }
37
38 if (optind != argc -1) {
39 usage(argv);
40 }
41
42 NSError *error = nil;
43 NSData *data;
44
45 if (0 == strcmp(argv[optind], "-")) {
46 data = [[NSFileHandle fileHandleWithStandardInput] readDataToEndOfFile];
47 } else {
48 data = [NSData dataWithContentsOfFile:[NSString stringWithUTF8String:argv[optind]]
49 options:NSDataReadingMappedIfSafe
50 error:&error];
51 }
52
53 if (!data || error) {
54 NSLog(@"couldn't read data: %@", error);
55 return 1;
56 }
57
58 if (data.length > UINT32_MAX) {
59 NSLog(@"data too big");
60 return 1;
61 }
62
63 NSDictionary *dict = parseKCDataBuffer((void*)data.bytes, (uint32_t)data.length, &error);
64
65 if (error && error.code == KERN_INVALID_VALUE) {
66 uint8_t buffer[100];
67 z_stream stream;
68 bzero(&stream, sizeof(stream));
69 stream.next_in = (void*) data.bytes;
70 stream.avail_in = data.length;
71 stream.next_out = buffer;
72 stream.avail_out = sizeof(buffer);
73 inflateInit2(&stream, 16+MAX_WBITS);
74 NSMutableData *inflated = [[NSMutableData alloc] init];
75 while (1) {
76 int z = inflate(&stream, Z_NO_FLUSH);
77 if (z == Z_OK || z == Z_STREAM_END) {
78 [inflated appendBytes:buffer length:sizeof(buffer) - stream.avail_out];
79 stream.avail_out = sizeof(buffer);
80 stream.next_out = buffer;
81 if (z == Z_STREAM_END) {
82 break;
83 }
84 } else {
85 inflated = nil;
86 break;
87 }
88 }
89 if (inflated) {
90 error = nil;
91 dict = parseKCDataBuffer((void*)inflated.bytes, (uint32_t)inflated.length, &error);
92 }
93 }
94
95 if (error && error.code == KERN_INVALID_VALUE) {
96 NSData *decoded = [[NSData alloc] initWithBase64EncodedData:data options:NSDataBase64DecodingIgnoreUnknownCharacters];
97 if (decoded) {
98 error = nil;
99 dict = parseKCDataBuffer((void*)decoded.bytes, (uint32_t)decoded.length, &error);
100 }
101 }
102
103 if (!dict || error) {
104 NSLog(@"error parsing kcdata: %@", error);
105 return 1;
106 }
107
108 if (plist) {
109 NSData *plist = [NSPropertyListSerialization dataWithPropertyList:dict
110 format:NSPropertyListXMLFormat_v1_0
111 options:0
112 error:&error];
113 if (!plist || error) {
114 NSLog(@"couldn't write plist: %@", error);
115 return 1;
116 }
117
118 fwrite(plist.bytes, plist.length, 1, stdout);
119
120 } else {
121 puts([[NSString stringWithFormat: @"%@", dict] UTF8String]);
122 }
123
124
125 return 0;
126 }