<commit_before>/*
 *  SDMMD_Debugger.c
 *  SDMMobileDevice
 *
 * Copyright (c) 2013, <NAME>
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* 
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* 
* 3. Neither the name of Sam Marshall nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */

#ifndef _SDM_MD_DEBUGGER_C_
#define _SDM_MD_DEBUGGER_C_

#include "SDMMD_Debugger.h"
#include "SDMMD_Functions.h"
#include "SDMMD_AppleFileConduit.h"
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <signal.h>
#include <getopt.h>
#include "Core.h"

#define kChecksumHashLength 0x3

static char *kHexEncodeString = "0123456789ABCDEF";
#define kHexDecode(byte) ((byte >= '0' && byte <= '9') ? (byte - '0') : ( (byte >= 'a' && byte <= 'f') ? (10 + byte - 'a') : ((byte >= 'A' && byte <= 'F') ? (10 + byte - 'A') : byte)))


#define kHexCodeApplyMask(byte) (byte & 0xf)
#define kHexCodeApplyShift(byte) (byte >> 0x4)

#define kHexEncodeFirstByte(byte) kHexEncodeString[kHexDecodeFirstByte(byte)]
#define kHexEncodeSecondByte(byte) kHexEncodeString[(byte & 0x0f)]

#define kHexDecodeFirstByte(byte) (kHexCodeApplyMask(kHexCodeApplyShift(byte)))
#define kHexDecodeSecondByte(byte) (kHexCodeApplyMask(byte))

SDMMD_AMDebugConnectionRef SDMMD_AMDebugConnectionCreateForDevice(SDMMD_AMDeviceRef device) {
	SDMMD_AMDebugConnectionRef dconn = calloc(0x1, sizeof(struct SDMMD_AMDebugConnection));
	if (dconn) {
		dconn->device = SDMMD_AMDeviceCreateCopy(device);
		dconn->connection = NULL;
		dconn->ackEnabled = true;
	}
	return dconn;
}

void SDMMD_AMDebugConnectionClose(SDMMD_AMDebugConnectionRef dconn) {
	CFSafeRelease(dconn->device);
	SDMMD_AMDServiceConnectionInvalidate(dconn->connection);
	Safe(free, dconn->connection);
	Safe(free, dconn);
}

sdmmd_return_t SDMMD_AMDebugConnectionStart(SDMMD_AMDebugConnectionRef dconn) {
	sdmmd_return_t result = SDMMD_AMDeviceConnect(dconn->device);
	if (SDM_MD_CallSuccessful(result)) {
		result = SDMMD_AMDeviceStartSession(dconn->device);
		if (SDM_MD_CallSuccessful(result)) {
			dconn->connection = SDMMD_AMDServiceConnectionCreate(0, NULL, NULL);
			result = SDMMD_AMDeviceStartService(dconn->device, CFSTR(AMSVC_DEBUG_SERVER), NULL, &(dconn->connection));
		}
	}
	return result;
}

sdmmd_return_t SDMMD_AMDebugConnectionStop(SDMMD_AMDebugConnectionRef dconn) {
	sdmmd_return_t result = kAMDSuccess;
	if (SDM_MD_CallSuccessful(result)) {
		SDMMD_AMDServiceConnectionInvalidate(dconn->connection);
		result = SDMMD_AMDeviceStopSession(dconn->device);
		if (SDM_MD_CallSuccessful(result)) {
			result = SDMMD_AMDeviceDisconnect(dconn->device);
		}
	}
	return result;
}

bool SDMMD_device_os_is_at_least(SDMMD_AMDeviceRef device, CFStringRef version) {
	bool result = false;
	if (device) {
		SDMMD_AMDeviceConnect(device);
		CFStringRef prodVers = SDMMD_AMDeviceCopyValue(device, NULL, CFSTR(kProductVersion));
		if (prodVers) {
			result = (CFStringCompare(prodVers, version, kCFCompareNumerically) != kCFCompareLessThan ? true : false);
		}
		CFSafeRelease(prodVers);
	}
	return result;
}


sdmmd_return_t SDMMD_copy_image(SDMMD_AMDeviceRef device, CFStringRef path) {
	sdmmd_return_t result = kAMDUndefinedError;
	if (device) {
		result = kAMDSuccess;//SDMMD_AMDeviceConnect(device);
		if (SDM_MD_CallSuccessful(result)) {
			result = SDMMD_AMDeviceStartSession(device);
			if (SDM_MD_CallSuccessful(result)) {
				SDMMD_AMConnectionRef copyConn = NULL;
				result = SDMMD_AMDeviceSecureStartService(device, CFSTR(AMSVC_AFC), NULL, &copyConn);
				if (SDM_MD_CallSuccessful(result)) {
					SDMMD_AFCConnectionRef copyAFCConn = SDMMD_AFCConnectionCreate(copyConn);
					SDMMD_AFCOperationRef makeStaging = SDMMD_AFCOperationCreateMakeDirectory(CFSTR("PublicStaging"));
					result = SDMMD_AFCProcessOperation(copyAFCConn, &makeStaging);
					if (SDM_MD_CallSuccessful(result)) {
						// SDM copy file AFC
						char *pathString = SDMCFStringGetString(path);
						result = SDMMD_AMDeviceCopyFile(NULL, NULL, NULL, copyAFCConn, pathString,"PublicStaging/staging.dimage");
						//SDMMD_AMDeviceRemoteCopyFile(NULL, NULL, NULL, copyAFCConn, pathString,"PublicStaging/staging.dimage");
						Safe(free, pathString);
					}
				}
			}
		}
		else {
			
		}
	}
	return result;
}

sdmmd_return_t SDMMD__hangup_with_image_mounter_service(SDMMD_AMConnectionRef connection) {
	sdmmd_return_t result = kAMDNoResourcesError;
	CFMutableDictionaryRef dict = SDMMD_create_dict();
	if (dict) {
		CFDictionarySetValue(dict, CFSTR("Command"), CFSTR("Hangup"));
	}
	if (connection) {
		SocketConnection socket = SDMMD_TranslateConnectionToSocket(connection);
		result = SDMMD_ServiceSendMessage(socket, dict, kCFPropertyListXMLFormat_v1_0);
		if (SDM_MD_CallSuccessful(result)) {
			CFPropertyListRef response = NULL;
			result = SDMMD_ServiceReceiveMessage(socket, &response);
			PrintCFDictionary(response);
		}
	}
	return result;
}

CFStringRef SDMMD_CopyDeviceSupportPathFromXCRUN() {
    FILE *output_pipe;
    char *xcrun_command = "xcrun -sdk iphoneos --show-sdk-platform-path";

	output_pipe = (FILE *)popen(xcrun_command, "r");
    if (output_pipe == NULL) {
		perror("Error encountered while opening pipe");
	}
	char *path = calloc(1, sizeof(char[1024]));
    fgets(path, sizeof(char[1024]), output_pipe);
    pclose(output_pipe);
	strtok(path, "\n");
	CFStringRef xcrun_path = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
	Safe(free,path);
    return xcrun_path;
}

CFStringRef SDMMD_PathToDeviceSupport(SDMMD_AMDeviceRef device) {
	CFStringRef dev_support_path = NULL;
	if (device) {
		SDMMD_AMDeviceConnect(device);
		SDMMD_AMDeviceStartSession(device);
		CFStringRef os_version = SDMMD_AMDeviceCopyValue(device, NULL, CFSTR(kProductVersion));
		CFStringRef build_version = SDMMD_AMDeviceCopyValue(device, NULL, CFSTR(kBuildVersion));
		SDMMD_AMDeviceStopSession(device);
		SDMMD_AMDeviceDisconnect(device);
		if (os_version && build_version) {
			CFStringRef sdk_path = CFSTR("/Users/sam");//SDMMD_CopyDeviceSupportPathFromXCRUN();
			CFStringRef device_support = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@/DeviceSupport/%@"), sdk_path, os_version);
			char *device_support_cstr = SDMCFStringGetString(device_support);
			bool isDir = false;
			bool file_exists = FileExistsAtPathIsDir(device_support_cstr, &isDir);
			if (file_exists && isDir) {
				dev_support_path = CFStringCreateCopy(kCFAllocatorDefault, device_support);
			}
			else {
				CFStringRef device_support_build = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ (%@)"), device_support, build_version);
				char *device_support_build_cstr = SDMCFStringGetString(device_support_build);
				file_exists = FileExistsAtPathIsDir(device_support_build_cstr, &isDir);
				if (file_exists && isDir) {
					dev_support_path = CFStringCreateCopy(kCFAllocatorDefault, device_support_build);
				}
				Safe(free, device_support_build_cstr);
				CFSafeRelease(device_support_build);
			}
			Safe(free, device_support_cstr);
			CFSafeRelease(sdk_path);
			CFSafeRelease(device_support);
		}
		CFSafeRelease(os_version);
		CFSafeRelease(build_version);
	}
	return dev_support_path;
}

CFStringRef SDMMD_PathToDeviceSupportDiskImage(CFStringRef device_support) {<commit_msg>removing local device support path<commit_after>/*
 *  SDMMD_Debugger.c
 *  SDMMobileDevice
 *
 * Copyright (c) 2013, <NAME>
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* 
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* 
* 3. Neither the name of Sam Marshall nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */

#ifndef _SDM_MD_DEBUGGER_C_
#define _SDM_MD_DEBUGGER_C_

#include "SDMMD_Debugger.h"
#include "SDMMD_Functions.h"
#include "SDMMD_AppleFileConduit.h"
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <signal.h>
#include <getopt.h>
#include "Core.h"

#define kChecksumHashLength 0x3

static char *kHexEncodeString = "0123456789ABCDEF";
#define kHexDecode(byte) ((byte >= '0' && byte <= '9') ? (byte - '0') : ( (byte >= 'a' && byte <= 'f') ? (10 + byte - 'a') : ((byte >= 'A' && byte <= 'F') ? (10 + byte - 'A') : byte)))


#define kHexCodeApplyMask(byte) (byte & 0xf)
#define kHexCodeApplyShift(byte) (byte >> 0x4)

#define kHexEncodeFirstByte(byte) kHexEncodeString[kHexDecodeFirstByte(byte)]
#define kHexEncodeSecondByte(byte) kHexEncodeString[(byte & 0x0f)]

#define kHexDecodeFirstByte(byte) (kHexCodeApplyMask(kHexCodeApplyShift(byte)))
#define kHexDecodeSecondByte(byte) (kHexCodeApplyMask(byte))

SDMMD_AMDebugConnectionRef SDMMD_AMDebugConnectionCreateForDevice(SDMMD_AMDeviceRef device) {
	SDMMD_AMDebugConnectionRef dconn = calloc(0x1, sizeof(struct SDMMD_AMDebugConnection));
	if (dconn) {
		dconn->device = SDMMD_AMDeviceCreateCopy(device);
		dconn->connection = NULL;
		dconn->ackEnabled = true;
	}
	return dconn;
}

void SDMMD_AMDebugConnectionClose(SDMMD_AMDebugConnectionRef dconn) {
	CFSafeRelease(dconn->device);
	SDMMD_AMDServiceConnectionInvalidate(dconn->connection);
	Safe(free, dconn->connection);
	Safe(free, dconn);
}

sdmmd_return_t SDMMD_AMDebugConnectionStart(SDMMD_AMDebugConnectionRef dconn) {
	sdmmd_return_t result = SDMMD_AMDeviceConnect(dconn->device);
	if (SDM_MD_CallSuccessful(result)) {
		result = SDMMD_AMDeviceStartSession(dconn->device);
		if (SDM_MD_CallSuccessful(result)) {
			dconn->connection = SDMMD_AMDServiceConnectionCreate(0, NULL, NULL);
			result = SDMMD_AMDeviceStartService(dconn->device, CFSTR(AMSVC_DEBUG_SERVER), NULL, &(dconn->connection));
		}
	}
	return result;
}

sdmmd_return_t SDMMD_AMDebugConnectionStop(SDMMD_AMDebugConnectionRef dconn) {
	sdmmd_return_t result = kAMDSuccess;
	if (SDM_MD_CallSuccessful(result)) {
		SDMMD_AMDServiceConnectionInvalidate(dconn->connection);
		result = SDMMD_AMDeviceStopSession(dconn->device);
		if (SDM_MD_CallSuccessful(result)) {
			result = SDMMD_AMDeviceDisconnect(dconn->device);
		}
	}
	return result;
}

bool SDMMD_device_os_is_at_least(SDMMD_AMDeviceRef device, CFStringRef version) {
	bool result = false;
	if (device) {
		SDMMD_AMDeviceConnect(device);
		CFStringRef prodVers = SDMMD_AMDeviceCopyValue(device, NULL, CFSTR(kProductVersion));
		if (prodVers) {
			result = (CFStringCompare(prodVers, version, kCFCompareNumerically) != kCFCompareLessThan ? true : false);
		}
		CFSafeRelease(prodVers);
	}
	return result;
}


sdmmd_return_t SDMMD_copy_image(SDMMD_AMDeviceRef device, CFStringRef path) {
	sdmmd_return_t result = kAMDUndefinedError;
	if (device) {
		result = kAMDSuccess;//SDMMD_AMDeviceConnect(device);
		if (SDM_MD_CallSuccessful(result)) {
			result = SDMMD_AMDeviceStartSession(device);
			if (SDM_MD_CallSuccessful(result)) {
				SDMMD_AMConnectionRef copyConn = NULL;
				result = SDMMD_AMDeviceSecureStartService(device, CFSTR(AMSVC_AFC), NULL, &copyConn);
				if (SDM_MD_CallSuccessful(result)) {
					SDMMD_AFCConnectionRef copyAFCConn = SDMMD_AFCConnectionCreate(copyConn);
					SDMMD_AFCOperationRef makeStaging = SDMMD_AFCOperationCreateMakeDirectory(CFSTR("PublicStaging"));
					result = SDMMD_AFCProcessOperation(copyAFCConn, &makeStaging);
					if (SDM_MD_CallSuccessful(result)) {
						// SDM copy file AFC
						char *pathString = SDMCFStringGetString(path);
						result = SDMMD_AMDeviceCopyFile(NULL, NULL, NULL, copyAFCConn, pathString,"PublicStaging/staging.dimage");
						//SDMMD_AMDeviceRemoteCopyFile(NULL, NULL, NULL, copyAFCConn, pathString,"PublicStaging/staging.dimage");
						Safe(free, pathString);
					}
				}
			}
		}
		else {
			
		}
	}
	return result;
}

sdmmd_return_t SDMMD__hangup_with_image_mounter_service(SDMMD_AMConnectionRef connection) {
	sdmmd_return_t result = kAMDNoResourcesError;
	CFMutableDictionaryRef dict = SDMMD_create_dict();
	if (dict) {
		CFDictionarySetValue(dict, CFSTR("Command"), CFSTR("Hangup"));
	}
	if (connection) {
		SocketConnection socket = SDMMD_TranslateConnectionToSocket(connection);
		result = SDMMD_ServiceSendMessage(socket, dict, kCFPropertyListXMLFormat_v1_0);
		if (SDM_MD_CallSuccessful(result)) {
			CFPropertyListRef response = NULL;
			result = SDMMD_ServiceReceiveMessage(socket, &response);
			PrintCFDictionary(response);
		}
	}
	return result;
}

CFStringRef SDMMD_CopyDeviceSupportPathFromXCRUN() {
    FILE *output_pipe;
    char *xcrun_command = "xcrun -sdk iphoneos --show-sdk-platform-path";

	output_pipe = (FILE *)popen(xcrun_command, "r");
    if (output_pipe == NULL) {
		perror("Error encountered while opening pipe");
	}
	char *path = calloc(1, sizeof(char[1024]));
    fgets(path, sizeof(char[1024]), output_pipe);
    pclose(output_pipe);
	strtok(path, "\n");
	CFStringRef xcrun_path = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
	Safe(free,path);
    return xcrun_path;
}

CFStringRef SDMMD_PathToDeviceSupport(SDMMD_AMDeviceRef device) {
	CFStringRef dev_support_path = NULL;
	if (device) {
		SDMMD_AMDeviceConnect(device);
		SDMMD_AMDeviceStartSession(device);
		CFStringRef os_version = SDMMD_AMDeviceCopyValue(device, NULL, CFSTR(kProductVersion));
		CFStringRef build_version = SDMMD_AMDeviceCopyValue(device, NULL, CFSTR(kBuildVersion));
		SDMMD_AMDeviceStopSession(device);
		SDMMD_AMDeviceDisconnect(device);
		if (os_version && build_version) {
			CFStringRef sdk_path = /*gCFSTR("/Users/sam");*/ SDMMD_CopyDeviceSupportPathFromXCRUN();
			CFStringRef device_support = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@/DeviceSupport/%@"), sdk_path, os_version);
			char *device_support_cstr = SDMCFStringGetString(device_support);
			bool isDir = false;
			bool file_exists = FileExistsAtPathIsDir(device_support_cstr, &isDir);
			if (file_exists && isDir) {
				dev_support_path = CFStringCreateCopy(kCFAllocatorDefault, device_support);
			}
			else {
				CFStringRef device_support_build = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ (%@)"), device_support, build_version);
				char *device_support_build_cstr = SDMCFStringGetString(device_support_build);
				file_exists = FileExistsAtPathIsDir(device_support_build_cstr, &isDir);
				if (file_exists && isDir) {
					dev_support_path = CFStringCreateCopy(kCFAllocatorDefault, device_support_build);
				}
				Safe(free, device_support_build_cstr);
				CFSafeRelease(device_support_build);
			}
			Safe(free, device_support_cstr);
			CFSafeRelease(sdk_path);
			CFSafeRelease(device_support);
		}
		CFSafeRelease(os_version);
		CFSafeRelease(build_version);
	}
	return dev_support_path;
}

CFStringRef SDMMD_PathToDeviceSupportDiskImage(CFStringRef device_support) {
{'fraction_non_alphanumeric': 0.09799659244462723, 'fraction_numerical': 0.005405087832677281, 'mean_word_length': 6.152100840336135, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6340371', 'n_tokens_mistral': 6134, 'n_tokens_neox': 5615, 'n_words': 1233}