Commit d560cf5a authored by Jonathan Beck's avatar Jonathan Beck

complete xml plist abstraction and migrate lockdownd_hello to new plist API.

parent 889cb32a
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
}
}
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment