diff options
| author | 2008-11-30 21:49:56 +0100 | |
|---|---|---|
| committer | 2008-11-30 21:49:56 +0100 | |
| commit | d560cf5a15d1aef74e95b208ed69b7d324d94354 (patch) | |
| tree | dbb5ffacf09ae6abbe002c53604f580996d5cdb6 /src/plist.c | |
| parent | 889cb32a1231c41762d7e2bbe6c891bd3a6c9a7d (diff) | |
| download | libimobiledevice-d560cf5a15d1aef74e95b208ed69b7d324d94354.tar.gz libimobiledevice-d560cf5a15d1aef74e95b208ed69b7d324d94354.tar.bz2 | |
complete xml plist abstraction and migrate lockdownd_hello to new plist API.
Diffstat (limited to 'src/plist.c')
| -rw-r--r-- | src/plist.c | 141 |
1 files changed, 123 insertions, 18 deletions
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) | |||
| 286 | } | 286 | } |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | |||
| 290 | |||
| 291 | void print_bytes(char *val, size_t size) | 289 | void print_bytes(char *val, size_t size) |
| 292 | { | 290 | { |
| 293 | int i = 0; | 291 | int i = 0; |
| @@ -421,11 +419,17 @@ void plist_free(plist_t plist) | |||
| 421 | g_node_destroy(plist); | 419 | g_node_destroy(plist); |
| 422 | } | 420 | } |
| 423 | 421 | ||
| 424 | void node_to_xml(GNode * node, gpointer data) | 422 | struct xml_node { |
| 423 | xmlNodePtr xml; | ||
| 424 | uint32_t depth; | ||
| 425 | }; | ||
| 426 | |||
| 427 | void node_to_xml(GNode * node, gpointer xml_struct) | ||
| 425 | { | 428 | { |
| 426 | if (!node) | 429 | if (!node) |
| 427 | return; | 430 | return; |
| 428 | 431 | ||
| 432 | struct xml_node *xstruct = (struct xml_node *) xml_struct; | ||
| 429 | struct plist_data *node_data = (struct plist_data *) node->data; | 433 | struct plist_data *node_data = (struct plist_data *) node->data; |
| 430 | 434 | ||
| 431 | xmlNodePtr child_node = NULL; | 435 | xmlNodePtr child_node = NULL; |
| @@ -510,12 +514,31 @@ void node_to_xml(GNode * node, gpointer data) | |||
| 510 | break; | 514 | break; |
| 511 | } | 515 | } |
| 512 | 516 | ||
| 513 | child_node = xmlNewChild(data, NULL, tag, val); | 517 | int i = 0; |
| 514 | xmlNodeAddContent(child_node, "\n"); | 518 | for (i = 0; i < xstruct->depth; i++) { |
| 519 | xmlNodeAddContent(xstruct->xml, "\t"); | ||
| 520 | } | ||
| 521 | child_node = xmlNewChild(xstruct->xml, NULL, tag, val); | ||
| 522 | xmlNodeAddContent(xstruct->xml, "\n"); | ||
| 515 | g_free(val); | 523 | g_free(val); |
| 516 | 524 | ||
| 517 | if (isStruct) | 525 | //add return for structured types |
| 518 | g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, child_node); | 526 | if (node_data->type == PLIST_ARRAY || |
| 527 | node_data->type == PLIST_DICT || node_data->type == PLIST_DATA || node_data->type == PLIST_PLIST) | ||
| 528 | xmlNodeAddContent(child_node, "\n"); | ||
| 529 | |||
| 530 | if (isStruct) { | ||
| 531 | struct xml_node child = { child_node, xstruct->depth + 1 }; | ||
| 532 | g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, &child); | ||
| 533 | } | ||
| 534 | //fix indent for structured types | ||
| 535 | if (node_data->type == PLIST_ARRAY || | ||
| 536 | node_data->type == PLIST_DICT || node_data->type == PLIST_DATA || node_data->type == PLIST_PLIST) { | ||
| 537 | |||
| 538 | for (i = 0; i < xstruct->depth; i++) { | ||
| 539 | xmlNodeAddContent(child_node, "\t"); | ||
| 540 | } | ||
| 541 | } | ||
| 519 | 542 | ||
| 520 | return; | 543 | return; |
| 521 | } | 544 | } |
| @@ -523,12 +546,18 @@ void node_to_xml(GNode * node, gpointer data) | |||
| 523 | void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) | 546 | void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) |
| 524 | { | 547 | { |
| 525 | xmlNodePtr node = NULL; | 548 | xmlNodePtr node = NULL; |
| 526 | struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); | ||
| 527 | GNode *subnode = g_node_new(data); | ||
| 528 | g_node_append(plist_node, subnode); | ||
| 529 | 549 | ||
| 530 | for (node = xml_node->children; node; node = node->next) { | 550 | for (node = xml_node->children; node; node = node->next) { |
| 531 | 551 | ||
| 552 | while (node && !xmlStrcmp(node->name, "text")) | ||
| 553 | node = node->next; | ||
| 554 | if (!node) | ||
| 555 | break; | ||
| 556 | |||
| 557 | struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); | ||
| 558 | GNode *subnode = g_node_new(data); | ||
| 559 | g_node_append(plist_node, subnode); | ||
| 560 | |||
| 532 | if (!xmlStrcmp(node->name, "true")) { | 561 | if (!xmlStrcmp(node->name, "true")) { |
| 533 | data->boolval = 1; | 562 | data->boolval = 1; |
| 534 | data->type = PLIST_BOOLEAN; | 563 | data->type = PLIST_BOOLEAN; |
| @@ -590,15 +619,15 @@ void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) | |||
| 590 | } | 619 | } |
| 591 | } | 620 | } |
| 592 | 621 | ||
| 593 | void plist_to_xml(plist_t plist, char **plist_xml) | 622 | void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) |
| 594 | { | 623 | { |
| 595 | if (!plist || !plist_xml || *plist_xml) | 624 | if (!plist || !plist_xml || *plist_xml) |
| 596 | return; | 625 | return; |
| 597 | xmlDocPtr plist_doc = new_plist(); | 626 | xmlDocPtr plist_doc = new_plist(); |
| 598 | xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); | 627 | xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); |
| 599 | g_node_children_foreach(plist, G_TRAVERSE_ALL, node_to_xml, root_node); | 628 | struct xml_node root = { root_node, 0 }; |
| 600 | int size = 0; | 629 | g_node_children_foreach(plist, G_TRAVERSE_ALL, node_to_xml, &root); |
| 601 | xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, &size); | 630 | xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, length); |
| 602 | } | 631 | } |
| 603 | 632 | ||
| 604 | GNode *parse_raw_node(const char *bpbuffer, uint32_t bplength, uint32_t * position, uint8_t ref_size) | 633 | 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 | |||
| 869 | return root_node; | 898 | return root_node; |
| 870 | } | 899 | } |
| 871 | 900 | ||
| 872 | void plist_to_bin(plist_t plist, char **plist_bin, int *length) | 901 | void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) |
| 873 | { | 902 | { |
| 874 | } | 903 | } |
| 875 | 904 | ||
| 876 | void xml_to_plist(const char *plist_xml, plist_t * plist) | 905 | void xml_to_plist(const char *plist_xml, uint32_t length, plist_t * plist) |
| 877 | { | 906 | { |
| 878 | xmlDocPtr plist_doc = xmlReadMemory(plist_xml, strlen(plist_xml), NULL, NULL, 0); | 907 | xmlDocPtr plist_doc = xmlReadMemory(plist_xml, length, NULL, NULL, 0); |
| 879 | xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); | 908 | xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); |
| 880 | 909 | ||
| 881 | struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); | 910 | 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) | |||
| 885 | 914 | ||
| 886 | } | 915 | } |
| 887 | 916 | ||
| 888 | void bin_to_plist(const char *plist_bin, int length, plist_t * plist) | 917 | void bin_to_plist(const char *plist_bin, uint32_t length, plist_t * plist) |
| 889 | { | 918 | { |
| 890 | uint32_t pos = 0; | 919 | uint32_t pos = 0; |
| 891 | *plist = parse_nodes(plist_bin, length, &pos); | 920 | *plist = parse_nodes(plist_bin, length, &pos); |
| 892 | } | 921 | } |
| 922 | |||
| 923 | |||
| 924 | GNode *find_query_node(plist_t plist, char *key, char *request) | ||
| 925 | { | ||
| 926 | if (!plist) | ||
| 927 | return NULL; | ||
| 928 | |||
| 929 | GNode *current = NULL; | ||
| 930 | for (current = plist->children; current; current = current->next) { | ||
| 931 | |||
| 932 | struct plist_data *data = (struct plist_data *) current->data; | ||
| 933 | |||
| 934 | if (data->type == PLIST_KEY && !strcmp(data->strval, key) && current->next) { | ||
| 935 | |||
| 936 | data = (struct plist_data *) current->next->data; | ||
| 937 | if (data->type == PLIST_STRING && !strcmp(data->strval, request)) | ||
| 938 | return current->next; | ||
| 939 | } | ||
| 940 | if (data->type == PLIST_DICT || data->type == PLIST_ARRAY || data->type == PLIST_PLIST) { | ||
| 941 | GNode *sub = find_query_node(current, key, request); | ||
| 942 | if (sub) | ||
| 943 | return sub; | ||
| 944 | } | ||
| 945 | } | ||
| 946 | return NULL; | ||
| 947 | } | ||
| 948 | |||
| 949 | void get_type_and_value(GNode * node, plist_type * type, void *value) | ||
| 950 | { | ||
| 951 | if (!node) | ||
| 952 | return; | ||
| 953 | |||
| 954 | struct plist_data *data = (struct plist_data *) node->data; | ||
| 955 | |||
| 956 | *type = data->type; | ||
| 957 | |||
| 958 | switch (*type) { | ||
| 959 | case PLIST_BOOLEAN: | ||
| 960 | *((char *) value) = data->boolval; | ||
| 961 | break; | ||
| 962 | case PLIST_UINT8: | ||
| 963 | *((uint8_t *) value) = data->intval8; | ||
| 964 | break; | ||
| 965 | case PLIST_UINT16: | ||
| 966 | *((uint16_t *) value) = data->intval16; | ||
| 967 | break; | ||
| 968 | case PLIST_UINT32: | ||
| 969 | *((uint32_t *) value) = data->intval32; | ||
| 970 | break; | ||
| 971 | case PLIST_UINT64: | ||
| 972 | *((uint64_t *) value) = data->intval64; | ||
| 973 | break; | ||
| 974 | case PLIST_FLOAT32: | ||
| 975 | *((float *) value) = data->realval32; | ||
| 976 | break; | ||
| 977 | case PLIST_FLOAT64: | ||
| 978 | *((double *) value) = data->realval64; | ||
| 979 | break; | ||
| 980 | case PLIST_STRING: | ||
| 981 | *((char **) value) = strdup(data->strval); | ||
| 982 | break; | ||
| 983 | case PLIST_UNICODE: | ||
| 984 | *((wchar_t **) value) = wcsdup(data->unicodeval); | ||
| 985 | break; | ||
| 986 | case PLIST_KEY: | ||
| 987 | *((char **) value) = strdup(data->strval); | ||
| 988 | break; | ||
| 989 | case PLIST_DATA: | ||
| 990 | case PLIST_ARRAY: | ||
| 991 | case PLIST_DICT: | ||
| 992 | case PLIST_DATE: | ||
| 993 | case PLIST_PLIST: | ||
| 994 | default: | ||
| 995 | break; | ||
| 996 | } | ||
| 997 | } | ||
