diff options
| -rw-r--r-- | include/libiphone/lockdown.h | 1 | ||||
| -rw-r--r-- | src/debug.c | 16 | ||||
| -rw-r--r-- | src/debug.h | 9 | ||||
| -rw-r--r-- | src/lockdown.c | 13 | ||||
| -rw-r--r-- | tools/iphoneinfo.c | 312 | 
5 files changed, 209 insertions, 142 deletions
| diff --git a/include/libiphone/lockdown.h b/include/libiphone/lockdown.h index 7fa5384..e80851b 100644 --- a/include/libiphone/lockdown.h +++ b/include/libiphone/lockdown.h @@ -48,6 +48,7 @@ extern "C" {  #define LOCKDOWN_E_PASSWORD_PROTECTED       -14  #define LOCKDOWN_E_NO_RUNNING_SESSION       -15  #define LOCKDOWN_E_INVALID_HOST_ID          -16 +#define LOCKDOWN_E_INVALID_SERVICE          -17  #define LOCKDOWN_E_UNKNOWN_ERROR           -256 diff --git a/src/debug.c b/src/debug.c index 2cdeebf..b194b0d 100644 --- a/src/debug.c +++ b/src/debug.c @@ -3,6 +3,7 @@   * contains utilitary functions for debugging   *   * Copyright (c) 2008 Jonathan Beck All Rights Reserved. + * Copyright (c) 2010 Martin S. All Rights Reserved.   *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public @@ -56,10 +57,12 @@ static void debug_print_line(const char *func, const char *file, int line, const  	(void)asprintf(&header, "%s %s:%d %s()", str_time, file, line, func);  	free (str_time); -	/* always in light green */ +	/* trim ending newlines */ + +	/* print header */  	printf ("%s: ", header); -	/* different colors according to the severity */ +	/* print actual debug content */  	printf ("%s\n", buffer);  	/* flush this output, as we need to debug */ @@ -135,7 +138,7 @@ inline void debug_buffer_to_file(const char *file, const char *data, const int l  #endif  } -inline void debug_plist(plist_t plist) +inline void debug_plist_real(const char *func, const char *file, int line, plist_t plist)  {  #ifndef STRIP_DEBUG_CODE  	if (!plist) @@ -144,7 +147,12 @@ inline void debug_plist(plist_t plist)  	char *buffer = NULL;  	uint32_t length = 0;  	plist_to_xml(plist, &buffer, &length); -	debug_info("plist size: %i\nbuffer :\n%s", length, buffer); + +	/* get rid of ending newline as one is already added in the debug line */ +	if (buffer[length-1] == '\n') +		buffer[length-1] = '\0'; + +	debug_info_real(func, file, line, "printing %i bytes plist:\n%s", length, buffer);  	free(buffer);  #endif  } diff --git a/src/debug.h b/src/debug.h index 0a29be3..2fd0960 100644 --- a/src/debug.h +++ b/src/debug.h @@ -3,6 +3,7 @@   * contains utilitary functions for debugging   *   * Copyright (c) 2008 Jonathan Beck All Rights Reserved. + * Copyright (c) 2010 Martin S. All Rights Reserved.   *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public @@ -27,10 +28,13 @@  #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && !defined(STRIP_DEBUG_CODE)  #define debug_info(...) debug_info_real (__func__, __FILE__, __LINE__, __VA_ARGS__) +#define debug_plist(a) debug_plist_real (__func__, __FILE__, __LINE__, a)  #elif defined(__GNUC__) && __GNUC__ >= 3 && !defined(STRIP_DEBUG_CODE)  #define debug_info(...) debug_info_real (__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) +#define debug_plist(a) debug_plist_real (__FUNCTION__, __FILE__, __LINE__, a)  #else  #define debug_info(...) +#define debug_plist(a)  #endif  G_GNUC_INTERNAL inline void debug_info_real(const char *func, @@ -40,6 +44,9 @@ G_GNUC_INTERNAL inline void debug_info_real(const char *func,  G_GNUC_INTERNAL inline void debug_buffer(const char *data, const int length);  G_GNUC_INTERNAL inline void debug_buffer_to_file(const char *file, const char *data, const int length); -G_GNUC_INTERNAL inline void debug_plist(plist_t plist); +G_GNUC_INTERNAL inline void debug_plist_real(const char *func, +											const char *file, +											int	line, +											plist_t plist);  #endif diff --git a/src/lockdown.c b/src/lockdown.c index 1befb72..8f15b3f 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -1262,9 +1262,18 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char  			if (port && ret == LOCKDOWN_E_SUCCESS)  				*port = port_loc;  		} -	} -	else +	} else {  		ret = LOCKDOWN_E_START_SERVICE_FAILED; +		plist_t error_node = plist_dict_get_item(dict, "Error"); +		if (error_node && PLIST_STRING == plist_get_node_type(error_node)) { +			char *error = NULL; +			plist_get_string_val(error_node, &error); +			if (!strcmp(error, "InvalidService")) { +				ret = LOCKDOWN_E_INVALID_SERVICE; +			} +			free(error); +		} +	}  	plist_free(dict);  	dict = NULL; diff --git a/tools/iphoneinfo.c b/tools/iphoneinfo.c index 7c41033..5ee92f5 100644 --- a/tools/iphoneinfo.c +++ b/tools/iphoneinfo.c @@ -23,6 +23,7 @@  #include <string.h>  #include <errno.h>  #include <stdlib.h> +#include <glib.h>  #include <libiphone/libiphone.h>  #include <libiphone/lockdown.h> @@ -55,10 +56,161 @@ static const char *domains[] = {  	NULL  }; -int is_domain_known(char *domain); -void print_usage(int argc, char **argv); -void plist_node_to_string(plist_t node); -void plist_children_to_string(plist_t node); +static int indent_level = 0; + +static int is_domain_known(char *domain) +{ +	int i = 0; +	while (domains[i] != NULL) { +		if (strstr(domain, domains[i++])) { +			return 1; +		} +	} +	return 0; +} + +static void plist_node_to_string(plist_t node); + +static void plist_array_to_string(plist_t node) +{ +	/* iterate over items */ +	int i, count; +	plist_t subnode = NULL; + +	count = plist_array_get_size(node); + +	for (i = 0; i < count; i++) { +		subnode = plist_array_get_item(node, i); +		printf("%*s", indent_level, ""); +		printf("%d: ", i); +		plist_node_to_string(subnode); +	} +} + +static void plist_dict_to_string(plist_t node) +{ +	/* iterate over key/value pairs */ +	plist_dict_iter it = NULL; + +	char* key = NULL; +	plist_t subnode = NULL; +	plist_dict_new_iter(node, &it); +	plist_dict_next_item(node, it, &key, &subnode); +	while (subnode) +	{ +		printf("%*s", indent_level, ""); +		printf("%s", key); +		if (plist_get_node_type(subnode) == PLIST_ARRAY) +			printf("[%d]: ", plist_array_get_size(subnode)); +		else +			printf(": "); +		free(key); +		key = NULL; +		plist_node_to_string(subnode); +		plist_dict_next_item(node, it, &key, &subnode); +	} +	free(it); +} + +static void plist_node_to_string(plist_t node) +{ +	char *s = NULL; +	char *data = NULL; +	double d; +	uint8_t b; +	uint64_t u = 0; +	GTimeVal tv = { 0, 0 }; + +	plist_type t; + +	if (!node) +		return; + +	t = plist_get_node_type(node); + +	switch (t) { +	case PLIST_BOOLEAN: +		plist_get_bool_val(node, &b); +		printf("%s\n", (b ? "true" : "false")); +		break; + +	case PLIST_UINT: +		plist_get_uint_val(node, &u); +		printf("%llu\n", (long long)u); +		break; + +	case PLIST_REAL: +		plist_get_real_val(node, &d); +		printf("%f\n", d); +		break; + +	case PLIST_STRING: +		plist_get_string_val(node, &s); +		printf("%s\n", s); +		free(s); +		break; + +	case PLIST_KEY: +		plist_get_key_val(node, &s); +		printf("%s: ", s); +		free(s); +		break; + +	case PLIST_DATA: +		plist_get_data_val(node, &data, &u); +		s = g_base64_encode((guchar *)data, u); +		free(data); +		printf("%s\n", s); +		g_free(s); +		break; + +	case PLIST_DATE: +		plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec); +		s = g_time_val_to_iso8601(&tv); +		printf("%s\n", s); +		free(s); +		break; + +	case PLIST_ARRAY: +		printf("\n"); +		indent_level++; +		plist_array_to_string(node); +		indent_level--; +		break; + +	case PLIST_DICT: +		printf("\n"); +		indent_level++; +		plist_dict_to_string(node); +		indent_level--; +		break; + +	default: +		break; +	} +} + +static void print_usage(int argc, char **argv) +{ +	int i = 0; +	char *name = NULL; +	 +	name = strrchr(argv[0], '/'); +	printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); +	printf("Show information about the first connected iPhone/iPod Touch.\n\n"); +	printf("  -d, --debug\t\tenable communication debugging\n"); +	printf("  -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); +	printf("  -q, --domain NAME\tset domain of query to NAME. Default: None\n"); +	printf("  -k, --key NAME\tonly query key specified by NAME. Default: All keys.\n"); +	printf("  -x, --xml\t\toutput information as xml plist instead of key/value pairs\n"); +	printf("  -h, --help\t\tprints usage information\n"); +	printf("\n"); +	printf("  Known domains are:\n\n"); +	while (domains[i] != NULL) { +		printf("  %s\n", domains[i++]); +	} +	printf("\n"); +}  int main(int argc, char *argv[])  { @@ -73,6 +225,7 @@ int main(int argc, char *argv[])  	char *xml_doc = NULL;  	uint32_t xml_length;  	plist_t node = NULL; +	plist_type node_type;  	uuid[0] = 0;  	/* parse cmdline args */ @@ -147,29 +300,30 @@ int main(int argc, char *argv[])  	}  	/* run query and output information */ -	if(lockdownd_get_value(client, domain, key, &node) == LOCKDOWN_E_SUCCESS) -	{ -		if (plist_get_node_type(node) == PLIST_DICT) { -			if (plist_dict_get_size(node)) -			{ -				switch (format) { -				case FORMAT_XML: -					plist_to_xml(node, &xml_doc, &xml_length); -					printf("%s", xml_doc); -					free(xml_doc); -					break; -				case FORMAT_KEY_VALUE: -				default: -					plist_children_to_string(node); +	if(lockdownd_get_value(client, domain, key, &node) == LOCKDOWN_E_SUCCESS) { +		if (node) { +			switch (format) { +			case FORMAT_XML: +				plist_to_xml(node, &xml_doc, &xml_length); +				printf("%s", xml_doc); +				free(xml_doc); +				break; +			case FORMAT_KEY_VALUE: +				node_type = plist_get_node_type(node); +				if (node_type == PLIST_DICT) { +					plist_dict_to_string(node); +				} else if (node_type == PLIST_ARRAY) { +					plist_array_to_string(node);  					break;  				} +			default: +				if (key != NULL) +					plist_node_to_string(node); +			break;  			} -		} -		else if(node && (key != NULL)) -			plist_node_to_string(node); -		if (node)  			plist_free(node); -		node = NULL; +			node = NULL; +		}  	}  	if (domain != NULL) @@ -180,115 +334,3 @@ int main(int argc, char *argv[])  	return 0;  } -int is_domain_known(char *domain) -{ -	int i = 0; -	while (domains[i] != NULL) { -		if (strstr(domain, domains[i++])) { -			return 1; -		} -	} -	return 0; -} - -void print_usage(int argc, char **argv) -{ -	int i = 0; -	char *name = NULL; -	 -	name = strrchr(argv[0], '/'); -	printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); -	printf("Show information about the first connected iPhone/iPod Touch.\n\n"); -	printf("  -d, --debug\t\tenable communication debugging\n"); -	printf("  -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); -	printf("  -q, --domain NAME\tset domain of query to NAME. Default: None\n"); -	printf("  -k, --key NAME\tonly query key specified by NAME. Default: All keys.\n"); -	printf("  -x, --xml\t\toutput information as xml plist instead of key/value pairs\n"); -	printf("  -h, --help\t\tprints usage information\n"); -	printf("\n"); -	printf("  Known domains are:\n\n"); -	while (domains[i] != NULL) { -		printf("  %s\n", domains[i++]); -	} -	printf("\n"); -} - -void plist_node_to_string(plist_t node) -{ -	char *s = NULL; -	double d; -	uint8_t b; - -	uint64_t u = 0; - -	plist_type t; - -	if (!node) -		return; - -	t = plist_get_node_type(node); - -	switch (t) { -	case PLIST_BOOLEAN: -		plist_get_bool_val(node, &b); -		printf("%s\n", (b ? "true" : "false")); -		break; - -	case PLIST_UINT: -		plist_get_uint_val(node, &u); -		printf("%llu\n", (long long)u); -		break; - -	case PLIST_REAL: -		plist_get_real_val(node, &d); -		printf("%f\n", d); -		break; - -	case PLIST_STRING: -		plist_get_string_val(node, &s); -		printf("%s\n", s); -		free(s); -		break; - -	case PLIST_KEY: -		plist_get_key_val(node, &s); -		printf("%s: ", s); -		free(s); -		break; - -	case PLIST_DATA: -		printf("\n"); -		break; -	case PLIST_DATE: -		printf("\n"); -		break; -	case PLIST_ARRAY: -	case PLIST_DICT: -		printf("\n"); -		plist_children_to_string(node); -		break; -	default: -		break; -	} -} - -void plist_children_to_string(plist_t node) -{ -	/* iterate over key/value pairs */ -	plist_dict_iter it = NULL; - -	char* key = NULL; -	plist_t subnode = NULL; -	plist_dict_new_iter(node, &it); -	plist_dict_next_item(node, it, &key, &subnode); -	while (subnode) -	{ -		printf("%s: ", key); -		free(key); -		key = NULL; -		plist_node_to_string(subnode); -		plist_dict_next_item(node, it, &key, &subnode); -	} -	free(it); -} - | 
