From 4563ad4d2e6ad75e42737e6ae381a0648b65f958 Mon Sep 17 00:00:00 2001
From: Nikias Bassen
Date: Wed, 21 May 2014 11:56:51 +0200
Subject: ideviceinfo: Move plist print helper code to common

---
 common/utils.c      | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 common/utils.h      |   2 +
 tools/Makefile.am   |   2 +-
 tools/ideviceinfo.c | 193 ++-------------------------------------------------
 4 files changed, 202 insertions(+), 190 deletions(-)

diff --git a/common/utils.c b/common/utils.c
index 68b23b9..aa0332d 100644
--- a/common/utils.c
+++ b/common/utils.c
@@ -27,6 +27,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <sys/time.h>
+#include <inttypes.h>
 
 #include "utils.h"
 
@@ -222,3 +224,196 @@ int plist_write_to_filename(plist_t plist, const char *filename, enum plist_form
 
 	return 1;
 }
+
+static const char base64_str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char base64_pad = '=';
+
+static char *base64encode(const unsigned char *buf, size_t size)
+{
+	if (!buf || !(size > 0)) return NULL;
+	int outlen = (size / 3) * 4;
+	char *outbuf = (char*)malloc(outlen+5); // 4 spare bytes + 1 for '\0'
+	size_t n = 0;
+	size_t m = 0;
+	unsigned char input[3];
+	unsigned int output[4];
+	while (n < size) {
+		input[0] = buf[n];
+		input[1] = (n+1 < size) ? buf[n+1] : 0;
+		input[2] = (n+2 < size) ? buf[n+2] : 0;
+		output[0] = input[0] >> 2;
+		output[1] = ((input[0] & 3) << 4) + (input[1] >> 4);
+		output[2] = ((input[1] & 15) << 2) + (input[2] >> 6);
+		output[3] = input[2] & 63;
+		outbuf[m++] = base64_str[(int)output[0]];
+		outbuf[m++] = base64_str[(int)output[1]];
+		outbuf[m++] = (n+1 < size) ? base64_str[(int)output[2]] : base64_pad;
+		outbuf[m++] = (n+2 < size) ? base64_str[(int)output[3]] : base64_pad;
+		n+=3;
+	}
+	outbuf[m] = 0; // 0-termination!
+	return outbuf;
+}
+
+static void plist_node_print_to_stream(plist_t node, int* indent_level, FILE* stream);
+
+static void plist_array_print_to_stream(plist_t node, int* indent_level, FILE* stream)
+{
+	/* 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);
+		fprintf(stream, "%*s", *indent_level, "");
+		fprintf(stream, "%d: ", i);
+		plist_node_print_to_stream(subnode, indent_level, stream);
+	}
+}
+
+static void plist_dict_print_to_stream(plist_t node, int* indent_level, FILE* stream)
+{
+	/* 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)
+	{
+		fprintf(stream, "%*s", *indent_level, "");
+		fprintf(stream, "%s", key);
+		if (plist_get_node_type(subnode) == PLIST_ARRAY)
+			fprintf(stream, "[%d]: ", plist_array_get_size(subnode));
+		else
+			fprintf(stream, ": ");
+		free(key);
+		key = NULL;
+		plist_node_print_to_stream(subnode, indent_level, stream);
+		plist_dict_next_item(node, it, &key, &subnode);
+	}
+	free(it);
+}
+
+static void plist_node_print_to_stream(plist_t node, int* indent_level, FILE* stream)
+{
+	char *s = NULL;
+	char *data = NULL;
+	double d;
+	uint8_t b;
+	uint64_t u = 0;
+	struct timeval 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);
+		fprintf(stream, "%s\n", (b ? "true" : "false"));
+		break;
+
+	case PLIST_UINT:
+		plist_get_uint_val(node, &u);
+		fprintf(stream, "%"PRIu64"\n", (long long)u);
+		break;
+
+	case PLIST_REAL:
+		plist_get_real_val(node, &d);
+		fprintf(stream, "%f\n", d);
+		break;
+
+	case PLIST_STRING:
+		plist_get_string_val(node, &s);
+		fprintf(stream, "%s\n", s);
+		free(s);
+		break;
+
+	case PLIST_KEY:
+		plist_get_key_val(node, &s);
+		fprintf(stream, "%s: ", s);
+		free(s);
+		break;
+
+	case PLIST_DATA:
+		plist_get_data_val(node, &data, &u);
+		if (u > 0) {
+			s = base64encode((unsigned char*)data, u);
+			free(data);
+			if (s) {
+				fprintf(stream, "%s\n", s);
+				free(s);
+			} else {
+				fprintf(stream, "\n");
+			}
+		} else {
+			fprintf(stream, "\n");
+		}
+		break;
+
+	case PLIST_DATE:
+		plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec);
+		{
+			time_t ti = (time_t)tv.tv_sec;
+			struct tm *btime = localtime(&ti);
+			if (btime) {
+				s = (char*)malloc(24);
+ 				memset(s, 0, 24);
+				if (strftime(s, 24, "%Y-%m-%dT%H:%M:%SZ", btime) <= 0) {
+					free (s);
+					s = NULL;
+				}
+			}
+		}
+		if (s) {
+			fprintf(stream, "%s\n", s);
+			free(s);
+		} else {
+			fprintf(stream, "\n");
+		}
+		break;
+
+	case PLIST_ARRAY:
+		fprintf(stream, "\n");
+		(*indent_level)++;
+		plist_array_print_to_stream(node, indent_level, stream);
+		(*indent_level)--;
+		break;
+
+	case PLIST_DICT:
+		fprintf(stream, "\n");
+		(*indent_level)++;
+		plist_dict_print_to_stream(node, indent_level, stream);
+		(*indent_level)--;
+		break;
+
+	default:
+		break;
+	}
+}
+
+void plist_print_to_stream(plist_t plist, FILE* stream)
+{
+	int indent = 0;
+
+	if (!plist || !stream)
+		return;
+
+	switch (plist_get_node_type(plist)) {
+	case PLIST_DICT:
+		plist_dict_print_to_stream(plist, &indent, stream);
+		break;
+	case PLIST_ARRAY:
+		plist_array_print_to_stream(plist, &indent, stream);
+		break;
+	default:
+		plist_node_print_to_stream(plist, &indent, stream);
+	}
+}
diff --git a/common/utils.h b/common/utils.h
index c1b6c32..412eb45 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -50,4 +50,6 @@ enum plist_format_t {
 int plist_read_from_filename(plist_t *plist, const char *filename);
 int plist_write_to_filename(plist_t plist, const char *filename, enum plist_format_t format);
 
+void plist_print_to_stream(plist_t plist, FILE* stream);
+
 #endif
diff --git a/tools/Makefile.am b/tools/Makefile.am
index d87ef96..8a91234 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -7,7 +7,7 @@ bin_PROGRAMS = idevice_id ideviceinfo idevicename idevicepair idevicesyslog idev
 
 ideviceinfo_SOURCES = ideviceinfo.c
 ideviceinfo_CFLAGS = $(AM_CFLAGS)
-ideviceinfo_LDFLAGS = $(AM_LDFLAGS)
+ideviceinfo_LDFLAGS = $(top_builddir)/common/libinternalcommon.la $(AM_LDFLAGS)
 ideviceinfo_LDADD = $(top_builddir)/src/libimobiledevice.la
 
 idevicename_SOURCES = idevicename.c
diff --git a/tools/ideviceinfo.c b/tools/ideviceinfo.c
index d270b73..7b3b924 100644
--- a/tools/ideviceinfo.c
+++ b/tools/ideviceinfo.c
@@ -23,12 +23,10 @@
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
-#include <time.h>
-#include <sys/time.h>
-#include <inttypes.h>
 
 #include <libimobiledevice/libimobiledevice.h>
 #include <libimobiledevice/lockdown.h>
+#include "common/utils.h"
 
 #define FORMAT_KEY_VALUE 1
 #define FORMAT_XML 2
@@ -68,38 +66,6 @@ static const char *domains[] = {
 	NULL
 };
 
-static const char base64_str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-static const char base64_pad = '=';
-
-static char *base64encode(const unsigned char *buf, size_t size)
-{
-	if (!buf || !(size > 0)) return NULL;
-	int outlen = (size / 3) * 4;
-	char *outbuf = (char*)malloc(outlen+5); // 4 spare bytes + 1 for '\0'
-	size_t n = 0;
-	size_t m = 0;
-	unsigned char input[3];
-	unsigned int output[4];
-	while (n < size) {
-		input[0] = buf[n];
-		input[1] = (n+1 < size) ? buf[n+1] : 0;
-		input[2] = (n+2 < size) ? buf[n+2] : 0;
-		output[0] = input[0] >> 2;
-		output[1] = ((input[0] & 3) << 4) + (input[1] >> 4);
-		output[2] = ((input[1] & 15) << 2) + (input[2] >> 6);
-		output[3] = input[2] & 63;
-		outbuf[m++] = base64_str[(int)output[0]];
-		outbuf[m++] = base64_str[(int)output[1]];
-		outbuf[m++] = (n+1 < size) ? base64_str[(int)output[2]] : base64_pad;
-		outbuf[m++] = (n+2 < size) ? base64_str[(int)output[3]] : base64_pad;
-		n+=3;
-	}
-	outbuf[m] = 0; // 0-termination!
-	return outbuf;
-}
-
-static int indent_level = 0;
-
 static int is_domain_known(char *domain)
 {
 	int i = 0;
@@ -111,150 +77,6 @@ static int is_domain_known(char *domain)
 	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;
-	struct timeval 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("%"PRIu64"\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);
-		if (u > 0) {
-			s = base64encode((unsigned char*)data, u);
-			free(data);
-			if (s) {
-				printf("%s\n", s);
-				free(s);
-			} else {
-				printf("\n");
-			}
-		} else {
-			printf("\n");
-		}
-		break;
-
-	case PLIST_DATE:
-		plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec);
-		{
-			time_t ti = (time_t)tv.tv_sec;
-			struct tm *btime = localtime(&ti);
-			if (btime) {
-				s = (char*)malloc(24);
- 				memset(s, 0, 24);
-				if (strftime(s, 24, "%Y-%m-%dT%H:%M:%SZ", btime) <= 0) {
-					free (s);
-					s = NULL;
-				}
-			}
-		}
-		if (s) {
-			printf("%s\n", s);
-			free(s);
-		} else {
-			printf("\n");
-		}
-		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;
@@ -292,7 +114,6 @@ int main(int argc, char *argv[])
 	char *xml_doc = NULL;
 	uint32_t xml_length;
 	plist_t node = NULL;
-	plist_type node_type;
 
 	/* parse cmdline args */
 	for (i = 1; i < argc; i++) {
@@ -375,17 +196,11 @@ int main(int argc, char *argv[])
 				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);
-					break;
-				} else if (node_type == PLIST_ARRAY) {
-					plist_array_to_string(node);
-					break;
-				}
+				plist_print_to_stream(node, stdout);
+				break;
 			default:
 				if (key != NULL)
-					plist_node_to_string(node);
+					plist_print_to_stream(node, stdout);
 			break;
 			}
 			plist_free(node);
-- 
cgit v1.1-32-gdbae