static void ggp_pubdir_got_data(PurpleHttpConnection *http_conn, PurpleHttpResponse *response, gpointer _request) { ggp_pubdir_request *request = _request; PurpleConnection *gc = request->gc; gboolean succ = TRUE; PurpleXmlNode *xml; const gchar *xml_raw; unsigned int status, next_offset; int record_count, i; ggp_pubdir_record *records; xml_raw = purple_http_response_get_data(response, NULL); if (purple_debug_is_verbose() && purple_debug_is_unsafe()) { purple_debug_misc("gg", "ggp_pubdir_got_data: xml=[%s]\n", xml_raw); } xml = purple_xmlnode_from_str(xml_raw, -1); if (xml == NULL) { purple_debug_error("gg", "ggp_pubdir_got_data: " "invalid xml\n"); request->cb(gc, -1, NULL, 0, request->user_data); ggp_pubdir_request_free(request); return; } succ &= ggp_xml_get_uint(xml, "status", &status); if (!ggp_xml_get_uint(xml, "nextOffset", &next_offset)) next_offset = 0; xml = purple_xmlnode_get_child(xml, "users"); if (!succ || status != 0 || !xml) { purple_debug_error("gg", "ggp_pubdir_got_data: " "invalid reply\n"); request->cb(gc, -1, NULL, 0, request->user_data); ggp_pubdir_request_free(request); return; } record_count = ggp_xml_child_count(xml, "user"); records = g_new0(ggp_pubdir_record, record_count); xml = purple_xmlnode_get_child(xml, "user"); i = 0; while (xml) { ggp_pubdir_record *record = &records[i++]; gchar *city = NULL, *birth_s = NULL; unsigned int gender = 0; const gchar *uin_s; g_assert(i <= record_count); record->uin = ggp_str_to_uin(purple_xmlnode_get_attrib(xml, "uin")); if (record->uin == 0) ggp_xml_get_uint(xml, "uin", &record->uin); if (record->uin == 0) purple_debug_error("gg", "ggp_pubdir_got_data:" " invalid uin\n"); uin_s = ggp_uin_to_str(record->uin); ggp_xml_get_string(xml, "label", &record->label); ggp_xml_get_string(xml, "nick", &record->nickname); ggp_xml_get_string(xml, "name", &record->first_name); ggp_xml_get_string(xml, "surname", &record->last_name); ggp_xml_get_string(xml, "city", &city); ggp_xml_get_string(xml, "birth", &birth_s); ggp_xml_get_uint(xml, "gender", &gender); ggp_xml_get_uint(xml, "age", &record->age); ggp_xml_get_uint(xml, "province", &record->province); record->label = ggp_free_if_equal(record->label, uin_s); record->label = ggp_free_if_equal(record->label, ""); record->nickname = ggp_free_if_equal(record->nickname, uin_s); record->nickname = ggp_free_if_equal(record->nickname, ""); record->first_name = ggp_free_if_equal(record->first_name, ""); record->last_name = ggp_free_if_equal(record->last_name, ""); if (record->label) {} else if (record->nickname) record->label = g_strdup(record->nickname); else if (record->first_name && record->last_name) record->label = g_strdup_printf("%s %s", record->first_name, record->last_name); else if (record->first_name) record->label = g_strdup(record->first_name); else if (record->last_name) record->label = g_strdup(record->last_name); if (record->label) g_strstrip(record->label); if (record->nickname) g_strstrip(record->nickname); if (gender == 1) record->gender = GGP_PUBDIR_GENDER_FEMALE; else if (gender == 2) record->gender = GGP_PUBDIR_GENDER_MALE; else record->gender = GGP_PUBDIR_GENDER_UNSPECIFIED; if (city && city[0] != '\0') record->city = g_strdup(city); if (record->city) g_strstrip(record->city); if (!record->city) { g_free(record->city); record->city = NULL; } record->birth = ggp_date_from_iso8601(birth_s); /*TODO: calculate age from birth */ if (purple_debug_is_verbose()) { purple_debug_misc("gg", "ggp_pubdir_got_data: [uin:%d] " "[label:%s] [nick:%s] [first name:%s] " "[last name:%s] [city:%s] [gender:%d] [age:%d] " "[birth:%lu]\n", record->uin, record->label, record->nickname, record->first_name, record->last_name, record->city, record->gender, record->age, record->birth); } g_free(city); xml = purple_xmlnode_get_next_twin(xml); } request->cb(gc, record_count, records, next_offset, request->user_data); ggp_pubdir_request_free(request); ggp_pubdir_record_free(records, record_count); }
static gboolean ggp_roster_reply_list_read_buddy(PurpleConnection *gc, PurpleXmlNode *node, ggp_roster_content *content, GHashTable *remove_buddies) { gchar *alias, *group_name = NULL; uin_t uin; gboolean succ = TRUE; PurpleXmlNode *group_list, *group_elem; PurpleBuddy *buddy = NULL; PurpleGroup *group = NULL; PurpleGroup *currentGroup; gboolean alias_changed; PurpleAccount *account = purple_connection_get_account(gc); succ &= ggp_xml_get_string(node, "ShowName", &alias); succ &= ggp_xml_get_uint(node, "GGNumber", &uin); group_list = purple_xmlnode_get_child(node, "Groups"); succ &= (group_list != NULL); if (!succ) { g_free(alias); g_return_val_if_reached(FALSE); } g_hash_table_insert(content->contact_nodes, GINT_TO_POINTER(uin), node); /* check, if alias is set */ if (strlen(alias) == 0 || strcmp(alias, ggp_uin_to_str(uin)) == 0) { g_free(alias); alias = NULL; } /* getting (eventually creating) group */ group_elem = purple_xmlnode_get_child(group_list, "GroupId"); while (group_elem != NULL) { gchar *id; gboolean isbot; if (!ggp_xml_get_string(group_elem, NULL, &id)) continue; isbot = (0 == g_strcmp0(id, content->bots_group_id)); group_name = g_hash_table_lookup(content->group_names, id); g_free(id); /* we don't want to import bots; * they are inserted to roster by default */ if (isbot) { g_free(alias); return TRUE; } if (group_name != NULL) break; group_elem = purple_xmlnode_get_next_twin(group_elem); } if (group_name) { group = purple_blist_find_group(group_name); if (!group) { group = purple_group_new(group_name); purple_blist_add_group(group, NULL); } } /* add buddy, if doesn't exists */ buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin)); g_hash_table_remove(remove_buddies, GINT_TO_POINTER(uin)); if (!buddy) { purple_debug_info("gg", "ggp_roster_reply_list_read_buddy: " "adding %u (%s) to buddy list\n", uin, alias); buddy = purple_buddy_new(account, ggp_uin_to_str(uin), alias); purple_blist_add_buddy(buddy, NULL, group, NULL); ggp_roster_set_synchronized(gc, buddy, TRUE); g_free(alias); return TRUE; } /* buddy exists, but is not synchronized - local list has priority */ if (!ggp_roster_is_synchronized(buddy)) { purple_debug_misc("gg", "ggp_roster_reply_list_read_buddy: " "ignoring not synchronized %u (%s)\n", uin, purple_buddy_get_name(buddy)); g_free(alias); return TRUE; } currentGroup = ggp_purplew_buddy_get_group_only(buddy); alias_changed = (0 != g_strcmp0(alias, purple_buddy_get_alias_only(buddy))); if (currentGroup == group && !alias_changed) { g_free(alias); return TRUE; } purple_debug_misc("gg", "ggp_roster_reply_list_read_buddy: " "updating %u (%s) - alias=\"%s\"->\"%s\", group=%p->%p (%s)\n", uin, purple_buddy_get_name(buddy), purple_buddy_get_alias(buddy), alias, currentGroup, group, group_name); if (alias_changed) purple_buddy_set_local_alias(buddy, alias); if (currentGroup != group) purple_blist_add_buddy(buddy, NULL, group, NULL); g_free(alias); return TRUE; }