/** * Process the iq set request. */ static void xmpp_stream_process_iq_set(XmppStream *stream, xmlnode *root) { gchar *id; gchar *value; xmlnode *node; gint count = 0; g_return_if_fail(stream != NULL); g_return_if_fail(root != NULL); node = xmlnode_child(root); for (; node; node = node->next, count ++); /* * An IQ stanza of type "get" or "set" MUST contain exactly one * child element, which specifies the semantics of the particular * request. */ if (count != 1) { /* TODO send error stanza. */ return; } node = xmlnode_child(root); if (g_strcmp0(node->name, "query") == 0) { value = xmlnode_get_namespace(node); if (g_strcmp0(value, NS_IQ_ROSTER) == 0) { xmpp_stream_process_set_roster(stream, node); } g_free(value); } /* send a result response. */ IqRequest *iq; iq = iq_request_create(stream, IQ_TYPE_RESULT); xmlnode_new_prop(iq->node, "from", stream->jid); if (xmlnode_has_prop(root, "id")) { id = xmlnode_prop(root, "id"); xmlnode_set_prop(iq->node, "id", id); g_free(id); } iq_request_send(iq); iq_request_destroy(iq); }
GSList* hybrid_logs_read(HybridAccount *account, const gchar *id, const gchar *logname) { gchar *log_path = NULL; gchar *log_name = NULL; gchar *tmp; GSList *list = NULL; xmlnode *root = NULL, *node, *child; HybridLogEntry *entry; log_path = hybrid_logs_get_path(account, id); log_name = g_strdup_printf("%s/%s", log_path, logname); root = xmlnode_root_from_file(log_name); if (!root) { hybrid_debug_error("log", "log %s read error.\n", log_name); goto out; } node = xmlnode_child(root); while (node) { if (!xmlnode_has_prop(node, "type")) goto next; entry = g_new0(HybridLogEntry, 1); tmp = xmlnode_prop(node, "type"); if (g_strcmp0(tmp, "o")) { entry->is_send = 1; } else { entry->is_send = 0; } g_free(tmp); child = xmlnode_find(node, "t"); entry->time = xmlnode_content(child); child = xmlnode_find(node, "n"); entry->name = xmlnode_content(child); child = xmlnode_find(node, "c"); entry->content = xmlnode_content(child); list = g_slist_append(list, entry); next: node = xmlnode_next(node); } out: free(log_path); free(log_name); xmlnode_free(root); return list; }
/** * Process the roster set request. */ static void xmpp_stream_process_set_roster(XmppStream *stream, xmlnode *query) { xmlnode *node; gchar *value; XmppBuddy *buddy; g_return_if_fail(stream != NULL); g_return_if_fail(query != NULL); if (!(node = xmlnode_child(query))) { return; } while (node) { if (g_strcmp0(node->name, "item") != 0) { node = node->next; continue; } if (!xmlnode_has_prop(node, "jid")) { node = node->next; continue; } value = xmlnode_prop(node, "jid"); if (!(buddy = xmpp_buddy_find(stream->account, value))) { g_free(value); node = node->next; continue; } g_free(value); if (xmlnode_has_prop(node, "subscription")) { value = xmlnode_prop(node, "subscription"); xmpp_buddy_set_subscription(buddy, value); g_free(value); } if (xmlnode_has_prop(node, "name")) { value = xmlnode_prop(node, "name"); xmpp_buddy_set_name(buddy, value); g_free(value); } node = node->next; } }
gchar* get_province_name(const gchar *province) { xmlnode *root; xmlnode *node; gchar *name; gchar *value; g_return_val_if_fail(province != NULL, NULL); if (!(root = xmlnode_root_from_file(FETION_RES_DIR"province.xml"))) { return NULL; } if (!(node = xmlnode_child(root)) || g_strcmp0(node->name, "Province")) { hybrid_debug_error("fetion", "get full province name"); return NULL; } for (; node; node = xmlnode_next(node)) { if (!xmlnode_has_prop(node, "id")) { continue; } value = xmlnode_prop(node, "id"); if (g_strcmp0(value, province) == 0) { name = xmlnode_content(node); /* found, do cleanup. */ g_free(value); xmlnode_free(root); return name; } g_free(value); } xmlnode_free(root); return NULL; }
GSList* sip_parse_presence(fetion_account *ac, const gchar *sipmsg) { gchar *pos; gchar *temp; xmlnode *root; xmlnode *node; xmlnode *pnode; GSList *list = NULL; fetion_buddy *buddy; if (!(pos = strstr(sipmsg, "\r\n\r\n"))) { return list; } pos += 4; root = xmlnode_root(pos, strlen(pos)); node = xmlnode_find(root, "contacts"); node = xmlnode_child(node); while (node) { temp = xmlnode_prop(node, "id"); if (!(buddy = fetion_buddy_find_by_userid(ac, temp))) { /* Maybe yourself's presence, we just ignore it. */ g_free(temp); node = node->next; continue; } g_free(temp); list = g_slist_append(list, buddy); if ((pnode = xmlnode_find(node, "p"))) { if (xmlnode_has_prop(pnode, "m")) { temp = xmlnode_prop(pnode, "m"); g_free(buddy->mobileno); buddy->mobileno = g_strdup(temp); g_free(temp); } if (xmlnode_has_prop(pnode, "n")) { temp = xmlnode_prop(pnode, "n"); g_free(buddy->nickname); buddy->nickname = g_strdup(temp); g_free(temp); } if (xmlnode_has_prop(pnode, "i")) { temp = xmlnode_prop(pnode, "i"); g_free(buddy->mood_phrase); buddy->mood_phrase = g_strdup(temp); g_free(temp); } if (xmlnode_has_prop(pnode, "c")) { temp = xmlnode_prop(pnode, "c"); g_free(buddy->carrier); buddy->carrier = g_strdup(temp); g_free(temp); } if (xmlnode_has_prop(pnode, "p")) { temp = xmlnode_prop(pnode, "p"); g_free(buddy->portrait_crc); if (*temp == '\0') { g_free(temp); temp = g_strdup("0"); } buddy->portrait_crc = temp; } else { g_free(buddy->portrait_crc); buddy->portrait_crc = g_strdup("0"); } if (xmlnode_has_prop(pnode, "cs")) { temp = xmlnode_prop(pnode, "cs"); buddy->carrier_status = atoi(temp); g_free(temp); } } if ((pnode = xmlnode_find(node, "pr"))) { if (xmlnode_has_prop(pnode, "b")) { temp = xmlnode_prop(pnode, "b"); buddy->state = atoi(temp); g_free(temp); } } node = node->next; } xmlnode_free(root); return list; }
GSList* sip_parse_sync(fetion_account *account, const gchar *sipmsg) { gchar *pos; gchar *action; gchar *userid; gchar *status; xmlnode *root; xmlnode *node; fetion_buddy *buddy; GSList *list = NULL; if (!(pos = strstr(sipmsg, "\r\n\r\n"))) { goto sync_info_err; } pos += 4; if (!(root = xmlnode_root(pos, strlen(pos)))) { goto sync_info_err; } if (!(node = xmlnode_find(root, "buddies"))) { xmlnode_free(root); return list; } node = xmlnode_child(node); while (node) { if (!xmlnode_has_prop(node, "action")) { goto next; } action = xmlnode_prop(node, "action"); if (g_strcmp0(action, "update") == 0) { if (!xmlnode_has_prop(node, "user-id") || !xmlnode_has_prop(node, "relation-status")) { g_free(action); goto next; } userid = xmlnode_prop(node, "user-id"); status = xmlnode_prop(node, "relation-status"); if (!(buddy = fetion_buddy_find_by_userid(account, userid))) { g_free(action); g_free(userid); g_free(status); goto next; } buddy->status = atoi(status); list = g_slist_append(list, buddy); g_free(status); g_free(userid); } g_free(action); next: node = xmlnode_next(node); } return list; sync_info_err: hybrid_debug_error("fetion", "invalid sync info"); return list; }
gchar* get_city_name(const gchar *province, const gchar *city) { xmlnode *root; xmlnode *node; gchar *name; gchar *value; if (!(root = xmlnode_root_from_file(FETION_RES_DIR"city.xml"))) { return NULL; } if (!(node = xmlnode_child(root)) || g_strcmp0(node->name, "Province")) { hybrid_debug_error("fetion", "get full city name"); return NULL; } for (; node; node = xmlnode_next(node)) { if (!xmlnode_has_prop(node, "id")) { continue; } value = xmlnode_prop(node, "id"); if (g_strcmp0(value, province) == 0) { /* found, do cleanup. */ g_free(value); goto province_found; } g_free(value); } xmlnode_free(root); return NULL; province_found: if (!(node = xmlnode_child(node)) || g_strcmp0(node->name, "City")) { hybrid_debug_error("fetion", "get full city name"); xmlnode_free(root); return NULL; } for (; node; node = xmlnode_next(node)) { if (!xmlnode_has_prop(node, "id")) { continue; } value = xmlnode_prop(node, "id"); if (g_strcmp0(value, city) == 0) { name= xmlnode_content(node); /* found, do cleanup. */ g_free(value); xmlnode_free(root); return name; } g_free(value); } xmlnode_free(root); return NULL; }
/** * Get the contact list from the xmlnode with name 'contact-list', * note that this node can either be a child node of the sipc * response xml message , or a child node of the local xml file. */ static void get_contact_list(fetion_account *ac, xmlnode *contact_node) { gchar *temp; gchar *temp1; xmlnode *node; fetion_group *group; fetion_buddy *buddy; gboolean has_ungroup = FALSE; g_return_if_fail(ac != NULL); g_return_if_fail(contact_node != NULL); /* group list */ node = xmlnode_find(contact_node, "buddy-lists"); node = xmlnode_child(node); while (node) { temp = xmlnode_prop(node, "name"); temp1 = xmlnode_prop(node, "id"); group = fetion_group_create(atoi(temp1), temp); ac->groups = g_slist_append(ac->groups, group); g_free(temp); g_free(temp1); node = node->next; } /* contact list */ node = xmlnode_find(contact_node, "buddies"); node = xmlnode_child(node); while (node) { buddy = fetion_buddy_create(); buddy->userid = xmlnode_prop(node, "i"); buddy->sipuri = xmlnode_prop(node, "u"); buddy->localname = xmlnode_prop(node, "n"); buddy->groups = xmlnode_prop(node, "l"); buddy->sid = get_sid_from_sipuri(buddy->sipuri); if (xmlnode_has_prop(node, "r")) { temp = xmlnode_prop(node, "r"); buddy->status = atoi(temp); g_free(temp); } else { buddy->status = 0; } ac->buddies = g_slist_append(ac->buddies, buddy); /* ungrouped */ if (*(buddy->groups) == '\0' || buddy->groups[0] == '0') { g_free(buddy->groups); buddy->groups = g_strdup("0"); if (!has_ungroup) { /**< add an "ungroup" group */ group = fetion_group_create(0, _("Ungrouped")); ac->groups = g_slist_append(ac->groups, group); has_ungroup = TRUE; } } node = node->next; } }