char compare_plist(plist_t node_l, plist_t node_r) { plist_t cur_l = NULL; plist_t cur_r = NULL; int res = 1; cur_l = plist_get_first_child(node_l); cur_r = plist_get_first_child(node_r); if ( (!cur_l && cur_r) || (cur_l && !cur_r)) return 0; if ( !cur_l && !cur_r ) return plist_compare_node_value( node_l, node_r ); while (cur_l && cur_r && res) { if (!(res = compare_plist(cur_l, cur_r))) return res; cur_l = plist_get_next_sibling(cur_l); cur_r = plist_get_next_sibling(cur_r); if ( (!cur_l && cur_r) || (cur_l && !cur_r)) return 0; } return res; }
plist_t plist_get_dict_el_from_key(plist_t node, const char *key) { plist_t ret = NULL; if (node && PLIST_DICT == plist_get_node_type(node)) { plist_t key_node = plist_find_node_by_key(node, key); ret = plist_get_next_sibling(key_node); } return ret; }
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); } }
plist_t plist_get_array_nth_el(plist_t node, uint32_t n) { plist_t ret = NULL; if (node && PLIST_ARRAY == plist_get_node_type(node)) { uint32_t i = 0; plist_t temp = plist_get_first_child(node); while (i <= n && temp) { if (i == n) ret = temp; temp = plist_get_next_sibling(temp); i++; } } return ret; }
static plist_t plist_find_node(plist_t plist, plist_type type, const void *value, uint64_t length) { plist_t current = NULL; if (!plist) return NULL; for (current = plist_get_first_child(plist); current; current = plist_get_next_sibling(current)) { plist_data_t data = plist_get_data(current); if (data->type == type && data->length == length && compare_node_value(type, data, value, length)) { return current; } if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) { plist_t sub = plist_find_node(current, type, value, length); if (sub) return sub; } } return NULL; }
/** * Checks if a notification has been sent. * * @param client NP to get a notification from * @param notification Pointer to a buffer that will be allocated and filled * with the notification that has been received. * * @return 0 if a notification has been received or nothing has been received, * or an error value if an error occured. * * @note You probably want to check out np_set_notify_callback * @see np_set_notify_callback */ static int np_get_notification(np_client_t client, char **notification) { uint32_t bytes = 0; int res = 0; uint32_t pktlen = 0; char *XML_content = NULL; plist_t dict = NULL; if (!client || !client->connection || *notification) return -1; np_lock(client); iphone_device_recv_timeout(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes, 500); log_debug_msg("NotificationProxy: initial read=%i\n", bytes); if (bytes < 4) { log_debug_msg("NotificationProxy: no notification received!\n"); res = 0; } else { if ((char)pktlen == 0) { pktlen = ntohl(pktlen); log_debug_msg("NotificationProxy: %d bytes following\n", pktlen); XML_content = (char*)malloc(pktlen); log_debug_msg("pointer %p\n", XML_content); iphone_device_recv_timeout(client->connection, XML_content, pktlen, &bytes, 1000); if (bytes <= 0) { res = -1; } else { log_debug_msg("NotificationProxy: received data:\n"); log_debug_buffer(XML_content, pktlen); plist_from_xml(XML_content, bytes, &dict); if (!dict) { np_unlock(client); return -2; } plist_t cmd_key_node = plist_find_node_by_key(dict, "Command"); plist_t cmd_value_node = plist_get_next_sibling(cmd_key_node); char *cmd_value = NULL; if (plist_get_node_type(cmd_value_node) == PLIST_STRING) { plist_get_string_val(cmd_value_node, &cmd_value); } if (cmd_value && !strcmp(cmd_value, "RelayNotification")) { plist_t name_key_node = plist_get_next_sibling(cmd_value_node); plist_t name_value_node = plist_get_next_sibling(name_key_node); char *name_key = NULL; char *name_value = NULL; if (plist_get_node_type(name_key_node) == PLIST_KEY) { plist_get_key_val(name_key_node, &name_key); } if (plist_get_node_type(name_value_node) == PLIST_STRING) { plist_get_string_val(name_value_node, &name_value); } res = -2; if (name_key && name_value && !strcmp(name_key, "Name")) { *notification = name_value; log_debug_msg("%s: got notification %s\n", __func__, name_value); res = 0; } free(name_key); } else if (cmd_value && !strcmp(cmd_value, "ProxyDeath")) { log_debug_msg("%s: ERROR: NotificationProxy died!\n", __func__); res = -1; } else if (cmd_value) { log_debug_msg("%d: unknown NotificationProxy command '%s' received!\n", __func__); res = -1; } else { res = -2; } if (cmd_value) { free(cmd_value); } plist_free(dict); dict = NULL; free(XML_content); XML_content = NULL; } } else { res = -1; } } np_unlock(client); return res; }
mobilesync_error_t mobilesync_client_new(iphone_device_t device, int dst_port, mobilesync_client_t * client) { if (!device || dst_port == 0 || !client || *client) return MOBILESYNC_E_INVALID_ARG; mobilesync_error_t ret = MOBILESYNC_E_UNKNOWN_ERROR; /* Attempt connection */ iphone_connection_t connection = NULL; if (iphone_device_connect(device, dst_port, &connection) != IPHONE_E_SUCCESS) { return ret; } mobilesync_client_t client_loc = (mobilesync_client_t) malloc(sizeof(struct mobilesync_client_int)); client_loc->connection = connection; /* perform handshake */ plist_t array = NULL; /* first receive version */ ret = mobilesync_recv(client_loc, &array); plist_t msg_node = plist_find_node_by_string(array, "DLMessageVersionExchange"); plist_t ver_1 = plist_get_next_sibling(msg_node); plist_t ver_2 = plist_get_next_sibling(ver_1); plist_type ver_1_type = plist_get_node_type(ver_1); plist_type ver_2_type = plist_get_node_type(ver_2); if (PLIST_UINT == ver_1_type && PLIST_UINT == ver_2_type) { uint64_t ver_1_val = 0; uint64_t ver_2_val = 0; plist_get_uint_val(ver_1, &ver_1_val); plist_get_uint_val(ver_2, &ver_2_val); plist_free(array); array = NULL; if (ver_1_type == PLIST_UINT && ver_2_type == PLIST_UINT && ver_1_val == MSYNC_VERSION_INT1 && ver_2_val == MSYNC_VERSION_INT2) { array = plist_new_array(); plist_array_append_item(array, plist_new_string("DLMessageVersionExchange")); plist_array_append_item(array, plist_new_string("DLVersionsOk")); ret = mobilesync_send(client_loc, array); plist_free(array); array = NULL; ret = mobilesync_recv(client_loc, &array); plist_t rep_node = plist_find_node_by_string(array, "DLMessageDeviceReady"); if (rep_node) { ret = MOBILESYNC_E_SUCCESS; *client = client_loc; } else { ret = MOBILESYNC_E_BAD_VERSION; } plist_free(array); array = NULL; } } if (MOBILESYNC_E_SUCCESS != ret) mobilesync_client_free(client_loc); return ret; }
void print_lckd_request_result(iphone_lckd_client_t control, const char *domain, const char *request, const char *key, int format) { char *xml_doc = NULL; char *s = NULL; uint32_t xml_length = 0; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; plist_t node = plist_new_dict(); if (domain) { plist_add_sub_key_el(node, "Domain"); plist_add_sub_string_el(node, domain); } if (key) { plist_add_sub_key_el(node, "Key"); plist_add_sub_string_el(node, key); } plist_add_sub_key_el(node, "Request"); plist_add_sub_string_el(node, request); ret = iphone_lckd_send(control, node); if (ret == IPHONE_E_SUCCESS) { plist_free(node); node = NULL; ret = iphone_lckd_recv(control, &node); if (ret == IPHONE_E_SUCCESS) { /* seek to value node */ for ( node = plist_get_first_child(node); node != NULL; node = plist_get_next_sibling(node) ) { if(plist_get_node_type(node) == PLIST_KEY) { plist_get_key_val(node, &s); if (strcmp("Value", s)) continue; node = plist_get_next_sibling(node); 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; }