From d560cf5a15d1aef74e95b208ed69b7d324d94354 Mon Sep 17 00:00:00 2001 From: Jonathan Beck Date: Sun, 30 Nov 2008 21:49:56 +0100 Subject: complete xml plist abstraction and migrate lockdownd_hello to new plist API. --- dev/plutil.c | 3 +- src/lockdown.c | 62 ++++++++++++++----------- src/plist.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++-------- src/plist.h | 12 +++-- 4 files changed, 168 insertions(+), 50 deletions(-) diff --git a/dev/plutil.c b/dev/plutil.c index d1f1cd4..0e25291 100644 --- a/dev/plutil.c +++ b/dev/plutil.c @@ -47,7 +47,8 @@ int main(int argc, char *argv[]) return 0; } char *plist_xml = NULL; - plist_to_xml(root_node, &plist_xml); + int size = 0; + plist_to_xml(root_node, &plist_xml, &size); printf("%s\n", plist_xml); return 0; } diff --git a/src/lockdown.c b/src/lockdown.c index 6b8f298..2906fdf 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -201,49 +201,57 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control) { if (!control) return IPHONE_E_INVALID_ARG; - xmlDocPtr plist = new_plist(); - xmlNode *dict, *key; - char **dictionary; + int bytes = 0, i = 0; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; + plist_t plist = NULL; + plist_new_plist(&plist); + + dict_t dict = NULL; + plist_new_dict_in_plist(plist, &dict); + + plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "QueryType"); + log_debug_msg("lockdownd_hello() called\n"); - dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); - key = add_key_str_dict_element(plist, dict, "Request", "QueryType", 1); - char *XML_content; - uint32_t length; + char *XML_content = NULL; + uint32_t length = 0; - xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); + plist_to_xml(plist, &XML_content, &length); + log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); ret = iphone_lckd_send(control, XML_content, length, &bytes); xmlFree(XML_content); - xmlFreeDoc(plist); + XML_content = NULL; + plist_free(plist); plist = NULL; + ret = iphone_lckd_recv(control, &XML_content, &bytes); + log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); + xml_to_plist(XML_content, bytes, &plist); - plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); if (!plist) return IPHONE_E_PLIST_ERROR; - dict = xmlDocGetRootElement(plist); - for (dict = dict->children; dict; dict = dict->next) { - if (!xmlStrcmp(dict->name, "dict")) - break; - } - if (!dict) - return IPHONE_E_DICT_ERROR; - dictionary = read_dict_element_strings(dict); - xmlFreeDoc(plist); - free(XML_content); - for (i = 0; dictionary[i]; i += 2) { - if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) { - log_debug_msg("lockdownd_hello(): success\n"); - ret = IPHONE_E_SUCCESS; - break; - } + plist_t query_node = find_query_node(plist, "Request", "QueryType"); + plist_t result_node = g_node_next_sibling(query_node); + plist_t value_node = g_node_next_sibling(result_node); + + plist_type result_type; + plist_type value_type; + + char *result_value = NULL; + char *value_value = NULL; + + get_type_and_value(result_node, &result_type, (void *) (&result_value)); + get_type_and_value(value_node, &value_type, (void *) (&value_value)); + + if (result_type == PLIST_KEY && + value_type == PLIST_STRING && !strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { + log_debug_msg("lockdownd_hello(): success\n"); + ret = IPHONE_E_SUCCESS; } - free_dictionary(dictionary); return ret; } diff --git a/src/plist.c b/src/plist.c index 377646d..5b61570 100644 --- a/src/plist.c +++ b/src/plist.c @@ -286,8 +286,6 @@ void byte_convert(char *address, size_t size) } } - - void print_bytes(char *val, size_t size) { int i = 0; @@ -421,11 +419,17 @@ void plist_free(plist_t plist) g_node_destroy(plist); } -void node_to_xml(GNode * node, gpointer data) +struct xml_node { + xmlNodePtr xml; + uint32_t depth; +}; + +void node_to_xml(GNode * node, gpointer xml_struct) { if (!node) return; + struct xml_node *xstruct = (struct xml_node *) xml_struct; struct plist_data *node_data = (struct plist_data *) node->data; xmlNodePtr child_node = NULL; @@ -510,12 +514,31 @@ void node_to_xml(GNode * node, gpointer data) break; } - child_node = xmlNewChild(data, NULL, tag, val); - xmlNodeAddContent(child_node, "\n"); + int i = 0; + for (i = 0; i < xstruct->depth; i++) { + xmlNodeAddContent(xstruct->xml, "\t"); + } + child_node = xmlNewChild(xstruct->xml, NULL, tag, val); + xmlNodeAddContent(xstruct->xml, "\n"); g_free(val); - if (isStruct) - g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, child_node); + //add return for structured types + if (node_data->type == PLIST_ARRAY || + node_data->type == PLIST_DICT || node_data->type == PLIST_DATA || node_data->type == PLIST_PLIST) + xmlNodeAddContent(child_node, "\n"); + + if (isStruct) { + struct xml_node child = { child_node, xstruct->depth + 1 }; + g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, &child); + } + //fix indent for structured types + if (node_data->type == PLIST_ARRAY || + node_data->type == PLIST_DICT || node_data->type == PLIST_DATA || node_data->type == PLIST_PLIST) { + + for (i = 0; i < xstruct->depth; i++) { + xmlNodeAddContent(child_node, "\t"); + } + } return; } @@ -523,12 +546,18 @@ void node_to_xml(GNode * node, gpointer data) void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) { xmlNodePtr node = NULL; - struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); - GNode *subnode = g_node_new(data); - g_node_append(plist_node, subnode); for (node = xml_node->children; node; node = node->next) { + while (node && !xmlStrcmp(node->name, "text")) + node = node->next; + if (!node) + break; + + struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); + GNode *subnode = g_node_new(data); + g_node_append(plist_node, subnode); + if (!xmlStrcmp(node->name, "true")) { data->boolval = 1; data->type = PLIST_BOOLEAN; @@ -590,15 +619,15 @@ void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) } } -void plist_to_xml(plist_t plist, char **plist_xml) +void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) { if (!plist || !plist_xml || *plist_xml) return; xmlDocPtr plist_doc = new_plist(); xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); - g_node_children_foreach(plist, G_TRAVERSE_ALL, node_to_xml, root_node); - int size = 0; - xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, &size); + struct xml_node root = { root_node, 0 }; + g_node_children_foreach(plist, G_TRAVERSE_ALL, node_to_xml, &root); + xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, length); } GNode *parse_raw_node(const char *bpbuffer, uint32_t bplength, uint32_t * position, uint8_t ref_size) @@ -869,13 +898,13 @@ plist_t parse_nodes(const char *bpbuffer, uint32_t bplength, uint32_t * position return root_node; } -void plist_to_bin(plist_t plist, char **plist_bin, int *length) +void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) { } -void xml_to_plist(const char *plist_xml, plist_t * plist) +void xml_to_plist(const char *plist_xml, uint32_t length, plist_t * plist) { - xmlDocPtr plist_doc = xmlReadMemory(plist_xml, strlen(plist_xml), NULL, NULL, 0); + xmlDocPtr plist_doc = xmlReadMemory(plist_xml, length, NULL, NULL, 0); xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); @@ -885,8 +914,84 @@ void xml_to_plist(const char *plist_xml, plist_t * plist) } -void bin_to_plist(const char *plist_bin, int length, plist_t * plist) +void bin_to_plist(const char *plist_bin, uint32_t length, plist_t * plist) { uint32_t pos = 0; *plist = parse_nodes(plist_bin, length, &pos); } + + +GNode *find_query_node(plist_t plist, char *key, char *request) +{ + if (!plist) + return NULL; + + GNode *current = NULL; + for (current = plist->children; current; current = current->next) { + + struct plist_data *data = (struct plist_data *) current->data; + + if (data->type == PLIST_KEY && !strcmp(data->strval, key) && current->next) { + + data = (struct plist_data *) current->next->data; + if (data->type == PLIST_STRING && !strcmp(data->strval, request)) + return current->next; + } + if (data->type == PLIST_DICT || data->type == PLIST_ARRAY || data->type == PLIST_PLIST) { + GNode *sub = find_query_node(current, key, request); + if (sub) + return sub; + } + } + return NULL; +} + +void get_type_and_value(GNode * node, plist_type * type, void *value) +{ + if (!node) + return; + + struct plist_data *data = (struct plist_data *) node->data; + + *type = data->type; + + switch (*type) { + case PLIST_BOOLEAN: + *((char *) value) = data->boolval; + break; + case PLIST_UINT8: + *((uint8_t *) value) = data->intval8; + break; + case PLIST_UINT16: + *((uint16_t *) value) = data->intval16; + break; + case PLIST_UINT32: + *((uint32_t *) value) = data->intval32; + break; + case PLIST_UINT64: + *((uint64_t *) value) = data->intval64; + break; + case PLIST_FLOAT32: + *((float *) value) = data->realval32; + break; + case PLIST_FLOAT64: + *((double *) value) = data->realval64; + break; + case PLIST_STRING: + *((char **) value) = strdup(data->strval); + break; + case PLIST_UNICODE: + *((wchar_t **) value) = wcsdup(data->unicodeval); + break; + case PLIST_KEY: + *((char **) value) = strdup(data->strval); + break; + case PLIST_DATA: + case PLIST_ARRAY: + case PLIST_DICT: + case PLIST_DATE: + case PLIST_PLIST: + default: + break; + } +} diff --git a/src/plist.h b/src/plist.h index 1ca55f9..ffc00e4 100644 --- a/src/plist.h +++ b/src/plist.h @@ -70,15 +70,19 @@ typedef GNode *plist_t; typedef GNode *dict_t; typedef GNode *array_t; + void plist_new_plist(plist_t * plist); void plist_new_dict_in_plist(plist_t plist, dict_t * dict); void plist_new_array_in_plist(plist_t plist, int length, plist_type type, void **values, array_t * array); void plist_add_dict_element(dict_t dict, char *key, plist_type type, void *value); void plist_free(plist_t plist); -void plist_to_xml(plist_t plist, char **plist_xml); -void plist_to_bin(plist_t plist, char **plist_bin, int *length); +void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); +void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length); + +void xml_to_plist(const char *plist_xml, uint32_t length, plist_t * plist); +void bin_to_plist(const char *plist_bin, uint32_t length, plist_t * plist); -void xml_to_plist(const char *plist_xml, plist_t * plist); -void bin_to_plist(const char *plist_bin, int length, plist_t * plist); +GNode *find_query_node(plist_t plist, char *key, char *request); +void get_type_and_value(GNode * node, plist_type * type, void *value); #endif -- cgit v1.1-32-gdbae