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