diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/Makefile.am | 21 | ||||
| -rw-r--r-- | tools/iphone_id.c | 94 | ||||
| -rw-r--r-- | tools/iphoneinfo.c | 281 | ||||
| -rw-r--r-- | tools/iphonesyslog.c | 169 | 
4 files changed, 565 insertions, 0 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 0000000..7f1be1c --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,21 @@ +INCLUDES = -I$(top_srcdir)/include + +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS) +AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) + +bin_PROGRAMS = iphone_id iphoneinfo iphonesyslog + +iphoneinfo_SOURCES = iphoneinfo.c +iphoneinfo_CFLAGS = $(AM_CFLAGS) +iphoneinfo_LDFLAGS = $(AM_LDFLAGS) +iphoneinfo_LDADD = ../src/libiphone.la + +iphonesyslog_SOURCES = iphonesyslog.c +iphonesyslog_CFLAGS = $(AM_CFLAGS) +iphonesyslog_LDFLAGS = $(AM_LDFLAGS) +iphonesyslog_LDADD = ../src/libiphone.la + +iphone_id_SOURCES = iphone_id.c +iphone_id_CFLAGS = $(AM_CFLAGS) +iphone_id_LDFLAGS = $(AM_LDFLAGS) +iphone_id_LDADD = ../src/libiphone.la diff --git a/tools/iphone_id.c b/tools/iphone_id.c new file mode 100644 index 0000000..f68fc8b --- /dev/null +++ b/tools/iphone_id.c @@ -0,0 +1,94 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> +#include <libiphone/libiphone.h> +#include <libiphone/lockdown.h> +#include <usbmuxd.h> + +static void usage() +{ +	printf("usage: iphone_id <device_uuid>\n" +		"\tdevice_uuid is the 40-digit hexadecimal UUID of the device\n" +		"\tfor which the name should be retrieved.\n\n" +		"usage: iphone_id -l\n" +		"\tList all attached devices.\n"); +	exit(0); +} + +int main(int argc, char **argv) +{ +	iphone_device_t phone = NULL; +	lockdownd_client_t client = NULL; +	usbmuxd_scan_result *dev_list; +	char *devname = NULL; +	int ret = 0; +	int c; +	int i; +	int opt_list = 0; + +	while ((c = getopt(argc, argv, "lh")) != -1) { +		switch (c) { +		    case 'l': +			opt_list = 1; +			break; +		    case 'h': +		    default: +			usage(); +		} +	} + +	if (argc < 2) { +		usage(); +	} + +	argc -= optind; +	argv += optind; + +	if ((!opt_list) && (strlen(argv[0]) != 40)) { +		usage(); +	} + +	if (opt_list) { +		if (usbmuxd_scan(&dev_list) < 0) { +			fprintf(stderr, "ERROR: usbmuxd is not running!\n"); +			return -1; +		} +		for (i = 0; dev_list[i].handle > 0; i++) { +			printf("handle=%d product_id=%04x uuid=%s\n", dev_list[i].handle, dev_list[i].product_id, dev_list[i].serial_number); +		} +		return 0; +	} + +	iphone_set_debug_level(0); + +	iphone_get_device_by_uuid(&phone, argv[0]); +	if (!phone) { +		fprintf(stderr, "ERROR: No device with UUID=%s attached.\n", argv[0]); +		return -2; +	} + +	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { +		iphone_device_free(phone); +		fprintf(stderr, "ERROR: Connecting to device failed!\n"); +		return -2; +	} + +	if ((LOCKDOWN_E_SUCCESS != lockdownd_get_device_name(client, &devname)) || !devname) { +		fprintf(stderr, "ERROR: Could not get device name!\n"); +		ret = -2; +	} + +	lockdownd_client_free(client); +	iphone_device_free(phone); + +	if (ret == 0) { +		printf("%s\n", devname); +	} + +	if (devname) { +		free(devname); +	} + +	return ret; +} diff --git a/tools/iphoneinfo.c b/tools/iphoneinfo.c new file mode 100644 index 0000000..7e275b2 --- /dev/null +++ b/tools/iphoneinfo.c @@ -0,0 +1,281 @@ +/* + * iphoneinfo.c + * Simple utility to show information about an attached device + * + * Copyright (c) 2009 Martin Szulecki 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA  + */ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +#include <libiphone/libiphone.h> +#include <libiphone/lockdown.h> + +#define FORMAT_KEY_VALUE 1 +#define FORMAT_XML 2 + +static const char *domains[] = { +	"com.apple.disk_usage", +	"com.apple.mobile.battery", +/* FIXME: For some reason lockdownd segfaults on this, works sometimes though  +	"com.apple.mobile.debug",. */ +	"com.apple.xcode.developerdomain", +	"com.apple.international", +	"com.apple.mobile.mobile_application_usage", +	"com.apple.mobile.backup", +	"com.apple.mobile.user_preferences", +	"com.apple.mobile.sync_data_class", +	"com.apple.mobile.software_behavior", +	"com.apple.mobile.iTunes.SQLMusicLibraryPostProcessCommands", +	"com.apple.iTunes", +	"com.apple.mobile.iTunes.store", +	"com.apple.mobile.iTunes", +	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); + +int main(int argc, char *argv[]) +{ +	lockdownd_client_t client = NULL; +	iphone_device_t phone = NULL; +	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; +	int i; +	int format = FORMAT_KEY_VALUE; +	char uuid[41]; +	char *domain = NULL; +	char *key = NULL; +	char *xml_doc = NULL; +	uint32_t xml_length; +	plist_t node = NULL; +	uuid[0] = 0; + +	/* parse cmdline args */ +	for (i = 1; i < argc; i++) { +		if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { +			iphone_set_debug_mask(DBGMASK_ALL); +			iphone_set_debug_level(1); +			continue; +		} +		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { +			i++; +			if (!argv[i] || (strlen(argv[i]) != 40)) { +				print_usage(argc, argv); +				return 0; +			} +			strcpy(uuid, argv[i]); +			continue; +		} +		else if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "--domain")) { +			i++; +			if (!argv[i] || (strlen(argv[i]) < 4)) { +				print_usage(argc, argv); +				return 0; +			} +			if (!is_domain_known(argv[i])) { +				fprintf(stderr, "WARNING: Sending query with unknown domain \"%s\".\n", argv[i]); +			} +			domain = strdup(argv[i]); +			continue; +		} +		else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--key")) { +			i++; +			if (!argv[i] || (strlen(argv[i]) <= 1)) { +				print_usage(argc, argv); +				return 0; +			} +			key = strdup(argv[i]); +			continue; +		} +		else if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--xml")) { +			format = FORMAT_XML; +			continue; +		} +		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { +			print_usage(argc, argv); +			return 0; +		} +		else { +			print_usage(argc, argv); +			return 0; +		} +	} + +	if (uuid[0] != 0) { +		ret = iphone_get_device_by_uuid(&phone, uuid); +		if (ret != IPHONE_E_SUCCESS) { +			printf("No device found with uuid %s, is it plugged in?\n", uuid); +			return -1; +		} +	} +	else +	{ +		ret = iphone_get_device(&phone); +		if (ret != IPHONE_E_SUCCESS) { +			printf("No device found, is it plugged in?\n"); +			return -1; +		} +	} + +	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { +		iphone_device_free(phone); +		return -1; +	} + +	/* 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_get_first_child(node)) +			{ +				switch (format) { +				case FORMAT_XML: +					plist_to_xml(node, &xml_doc, &xml_length); +					printf(xml_doc); +					free(xml_doc); +					break; +				case FORMAT_KEY_VALUE: +				default: +					plist_children_to_string(node); +					break; +				} +			} +		} +		else if(node && (key != NULL)) +			plist_node_to_string(node); +		if (node) +			plist_free(node); +		node = NULL; +	} + +	if (domain != NULL) +		free(domain); +	lockdownd_client_free(client); +	iphone_device_free(phone); + +	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 */ +	for ( +		node = plist_get_first_child(node); +		node != NULL; +		node = plist_get_next_sibling(node) +	) { +		plist_node_to_string(node); +	} +} + diff --git a/tools/iphonesyslog.c b/tools/iphonesyslog.c new file mode 100644 index 0000000..a096101 --- /dev/null +++ b/tools/iphonesyslog.c @@ -0,0 +1,169 @@ +/* + * syslog_relay.c + * Relay the syslog of a device to stdout + * + * Copyright (c) 2009 Martin Szulecki 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA  + */ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <netinet/in.h> +#include <signal.h> +#include <stdlib.h> + +#include <libiphone/libiphone.h> +#include <libiphone/lockdown.h> +#include <usbmuxd.h> + +static int quit_flag = 0; + +void print_usage(int argc, char **argv); + +/** + * signal handler function for cleaning up properly + */ +static void clean_exit(int sig) +{ +	fprintf(stderr, "Exiting...\n"); +	quit_flag++; +} + +int main(int argc, char *argv[]) +{ +	lockdownd_client_t client = NULL; +	iphone_device_t phone = NULL; +	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; +	int i; +	char uuid[41]; +	int port = 0; +	uuid[0] = 0; +	uint32_t handle = 0; + +	signal(SIGINT, clean_exit); +	signal(SIGQUIT, clean_exit); +	signal(SIGTERM, clean_exit); +	signal(SIGPIPE, SIG_IGN); + +	/* parse cmdline args */ +	for (i = 1; i < argc; i++) { +		if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { +			iphone_set_debug_mask(DBGMASK_ALL); +			iphone_set_debug_level(1); +			continue; +		} +		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { +			i++; +			if (!argv[i] || (strlen(argv[i]) != 40)) { +				print_usage(argc, argv); +				return 0; +			} +			strcpy(uuid, argv[i]); +			continue; +		} +		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { +			print_usage(argc, argv); +			return 0; +		} +		else { +			print_usage(argc, argv); +			return 0; +		} +	} + +	if (uuid[0] != 0) { +		ret = iphone_get_device_by_uuid(&phone, uuid); +		if (ret != IPHONE_E_SUCCESS) { +			printf("No device found with uuid %s, is it plugged in?\n", uuid); +			return -1; +		} +	} +	else +	{ +		ret = iphone_get_device(&phone); +		if (ret != IPHONE_E_SUCCESS) { +			printf("No device found, is it plugged in?\n"); +			return -1; +		} +	} + +	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { +		iphone_device_free(phone); +		return -1; +	} + +	/* start syslog_relay service and retrieve port */ +	ret = lockdownd_start_service(client, "com.apple.syslog_relay", &port); +	if ((ret == LOCKDOWN_E_SUCCESS) && port) { +		lockdownd_client_free(client); +		 +		/* connect to socket relay messages */ +		iphone_device_get_handle(phone, &handle); +		int sfd = usbmuxd_connect(handle, port); +		if (sfd < 0) { +			printf("ERROR: Could not open usbmux connection.\n"); +		} else { +			while (!quit_flag) { +				char *receive = NULL; +				uint32_t datalen = 0, bytes = 0, recv_bytes = 0; + +				ret = usbmuxd_recv(sfd, (char *) &datalen, sizeof(datalen), &bytes); +				datalen = ntohl(datalen); + +				if (datalen == 0) +					continue; + +				recv_bytes += bytes; +				receive = (char *) malloc(sizeof(char) * datalen); + +				while (!quit_flag && (recv_bytes <= datalen)) { +					ret = usbmuxd_recv(sfd, receive, datalen, &bytes); + +					if (bytes == 0) +						break; + +					recv_bytes += bytes; + +					fwrite(receive, sizeof(char), bytes, stdout); +				} + +				free(receive); +			} +		} +		usbmuxd_disconnect(sfd); +	} else { +		printf("ERROR: Could not start service com.apple.syslog_relay.\n"); +	} + +	iphone_device_free(phone); + +	return 0; +} + +void print_usage(int argc, char **argv) +{ +	char *name = NULL; +	 +	name = strrchr(argv[0], '/'); +	printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); +	printf("Relay syslog of a 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("  -h, --help\t\tprints usage information\n"); +	printf("\n"); +} +  | 
