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