static void ggp_chat_left(ggp_chat_local_info *chat, uin_t uin) { uin_t me; int idx = ggp_chat_participant_find(chat, uin); if (idx < 0) { purple_debug_warning("gg", "ggp_chat_joined: " "user %u isn't present in chat %" G_GUINT64_FORMAT "\n", uin, chat->id); return; } chat->participants[idx] = chat->participants[chat->participants_count - 1]; chat->participants_count--; chat->participants = g_realloc(chat->participants, sizeof(uin) * chat->participants_count); if (chat->conv == NULL) return; me = ggp_str_to_uin(purple_account_get_username( purple_connection_get_account(chat->gc))); if (me == uin) { purple_conversation_write_system_message( PURPLE_CONVERSATION(chat->conv), _("You have left the chat"), 0); purple_serv_got_chat_left(chat->gc, chat->local_id); chat->conv = NULL; chat->left = TRUE; } purple_chat_conversation_remove_user(chat->conv, ggp_uin_to_str(uin), NULL); }
void ggp_chat_leave(PurpleConnection *gc, int local_id) { GGPInfo *info = purple_connection_get_protocol_data(gc); ggp_chat_local_info *chat; uin_t me; chat = ggp_chat_get_local(gc, local_id); if (!chat) { purple_debug_error("gg", "ggp_chat_leave: " "chat %u doesn't exists\n", local_id); return; } if (gg_chat_leave(info->session, chat->id) < 0) { purple_debug_error("gg", "ggp_chat_leave: " "unable to leave chat %" G_GUINT64_FORMAT "\n", chat->id); } chat->conv = NULL; me = ggp_str_to_uin(purple_account_get_username( purple_connection_get_account(chat->gc))); ggp_chat_left(chat, me); chat->left = TRUE; }
void ggp_chat_got_message(PurpleConnection *gc, uint64_t chat_id, const char *message, time_t time, uin_t who) { ggp_chat_local_info *chat; uin_t me; me = ggp_str_to_uin(purple_account_get_username( purple_connection_get_account(gc))); chat = ggp_chat_get(gc, chat_id); if (!chat) { purple_debug_error("gg", "ggp_chat_got_message: " "chat %" G_GUINT64_FORMAT " doesn't exists\n", chat_id); return; } ggp_chat_open_conv(chat); if (who == me) { PurpleMessage *pmsg; pmsg = purple_message_new_outgoing( ggp_uin_to_str(who), message, 0); purple_message_set_time(pmsg, time); purple_conversation_write_message( PURPLE_CONVERSATION(chat->conv), pmsg); } else { purple_serv_got_chat_in(gc, chat->local_id, ggp_uin_to_str(who), PURPLE_MESSAGE_RECV, message, time); } }
int ggp_message_send_im(PurpleConnection *gc, const char *who, const char *message, PurpleMessageFlags flags) { GGPInfo *info = purple_connection_get_protocol_data(gc); PurpleIMConversation *im; ggp_buddy_data *buddy_data; gchar *gg_msg; gboolean succ; /* TODO: return -ENOTCONN, if not connected */ if (message == NULL || message[0] == '\0') return 0; buddy_data = ggp_buddy_get_data(purple_blist_find_buddy( purple_connection_get_account(gc), who)); if (buddy_data->blocked) return -1; im = purple_conversations_find_im_with_account( who, purple_connection_get_account(gc)); gg_msg = ggp_message_format_to_gg(PURPLE_CONVERSATION(im), message); /* TODO: splitting messages */ if (strlen(gg_msg) > GG_MSG_MAXSIZE) { g_free(gg_msg); return -E2BIG; } #if GGP_ENABLE_GG11 succ = (gg_send_message_html(info->session, GG_CLASS_CHAT, ggp_str_to_uin(who), (unsigned char *)gg_msg) >= 0); #else { gchar *plain = purple_markup_strip_html(gg_msg); succ = (gg_send_message(info->session, GG_CLASS_CHAT, ggp_str_to_uin(who), (unsigned char *)plain) >= 0); g_free(plain); } #endif g_free(gg_msg); return succ ? 1 : -1; }
void ggp_pubdir_request_buddy_alias(PurpleConnection *gc, PurpleBuddy *buddy) { uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy)); purple_debug_info("gg", "ggp_pubdir_request_buddy_alias: %u\n", uin); ggp_pubdir_get_info(gc, uin, ggp_pubdir_request_buddy_alias_got, NULL); }
void ggp_pubdir_get_info_protocol(PurpleConnection *gc, const char *name) { uin_t uin = ggp_str_to_uin(name); uin_t *uin_p = g_new0(uin_t, 1); *uin_p = uin; purple_debug_info("gg", "ggp_pubdir_get_info_protocol: %u\n", uin); ggp_pubdir_get_info(gc, uin, ggp_pubdir_get_info_protocol_got, uin_p); }
void ggp_chat_got_event(PurpleConnection *gc, const struct gg_event *ev) { ggp_chat_session_data *sdata = ggp_chat_get_sdata(gc); ggp_chat_local_info *chat; uint32_t i; if (ev->type == GG_EVENT_CHAT_INFO) { const struct gg_event_chat_info *eci = &ev->event.chat_info; chat = ggp_chat_new(gc, eci->id); for (i = 0; i < eci->participants_count; i++) ggp_chat_joined(chat, eci->participants[i]); } else if (ev->type == GG_EVENT_CHAT_INFO_GOT_ALL) { GSList *it = sdata->pending_joins; sdata->got_all_chats_info = TRUE; while (it) { uint64_t *id_p = it->data; ggp_chat_join_id(gc, *id_p); it = g_slist_next(it); } g_slist_free_full(sdata->pending_joins, g_free); sdata->pending_joins = NULL; } else if (ev->type == GG_EVENT_CHAT_INFO_UPDATE) { const struct gg_event_chat_info_update *eciu = &ev->event.chat_info_update; chat = ggp_chat_get(gc, eciu->id); if (!chat) { purple_debug_error("gg", "ggp_chat_got_event: " "chat %" G_GUINT64_FORMAT " not found\n", eciu->id); return; } if (eciu->type == GG_CHAT_INFO_UPDATE_ENTERED) ggp_chat_joined(chat, eciu->participant); else if (eciu->type == GG_CHAT_INFO_UPDATE_EXITED) ggp_chat_left(chat, eciu->participant); else purple_debug_warning("gg", "ggp_chat_got_event: " "unknown update type - %d", eciu->type); } else if (ev->type == GG_EVENT_CHAT_CREATED) { const struct gg_event_chat_created *ecc = &ev->event.chat_created; uin_t me = ggp_str_to_uin(purple_account_get_username( purple_connection_get_account(gc))); chat = ggp_chat_new(gc, ecc->id); ggp_chat_joined(chat, me); ggp_chat_open_conv(chat); } else if (ev->type == GG_EVENT_CHAT_INVITE_ACK) { /* ignore */ } else { purple_debug_fatal("gg", "ggp_chat_got_event: unexpected event " "- %d\n", ev->type); } }
void ggp_roster_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc); ggp_roster_change *change = g_new0(ggp_roster_change, 1); if (!ggp_roster_enabled()) return; change->type = GGP_ROSTER_CHANGE_CONTACT_REMOVE; change->data.uin = ggp_str_to_uin(purple_buddy_get_name(buddy)); rdata->pending_updates = g_list_append(rdata->pending_updates, change); }
static void ggp_roster_set_synchronized(PurpleConnection *gc, PurpleBuddy *buddy, gboolean synchronized) { ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc); uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy)); ggp_roster_change *change; purple_blist_node_set_bool(PURPLE_BLIST_NODE(buddy), GGP_ROSTER_SYNC_SETT, synchronized); if (!synchronized) { change = g_new0(ggp_roster_change, 1); change->type = GGP_ROSTER_CHANGE_CONTACT_UPDATE; change->data.uin = uin; rdata->pending_updates = g_list_append(rdata->pending_updates, change); } }
void ggp_roster_group_buddy(PurpleConnection *gc, const char *who, const char *old_group, const char *new_group) { ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc); ggp_roster_change *change = g_new0(ggp_roster_change, 1); if (!ggp_roster_enabled()) return; if (rdata->is_updating) return; purple_debug_misc("gg", "ggp_roster_group_buddy: " "who=\"%s\", group=\"%s\" -> \"%s\")\n", who, old_group, new_group); /* purple_blist_find_buddy(..., who) is not accessible at this moment */ change->type = GGP_ROSTER_CHANGE_CONTACT_UPDATE; change->data.uin = ggp_str_to_uin(who); rdata->pending_updates = g_list_append(rdata->pending_updates, change); }
static void ggp_avatar_own_got_token(PurpleConnection *gc, const gchar *token, gpointer _img) { PurpleHttpRequest *req; PurpleImage *img = _img; ggp_avatar_own_data *own_data = ggp_avatar_get_avdata(gc)->own_data; gchar *img_data, *img_data_e, *request_data; PurpleAccount *account = purple_connection_get_account(gc); uin_t uin = ggp_str_to_uin(purple_account_get_username(account)); if (img != own_data->img) { purple_debug_warning("gg", "ggp_avatar_own_got_token: " "avatar was changed in meantime\n"); return; } own_data->img = NULL; img_data = purple_base64_encode(purple_image_get_data(img), purple_image_get_size(img)); img_data_e = g_uri_escape_string(img_data, NULL, FALSE); g_free(img_data); request_data = g_strdup_printf("uin=%d&photo=%s", uin, img_data_e); g_free(img_data_e); purple_debug_misc("gg", "ggp_avatar_own_got_token: " "uploading new avatar...\n"); req = purple_http_request_new("http://avatars.nowe.gg/upload"); purple_http_request_set_max_len(req, GGP_AVATAR_RESPONSE_MAX); purple_http_request_set_method(req, "POST"); purple_http_request_header_set(req, "Authorization", token); purple_http_request_header_set(req, "From", "avatars to avatars"); purple_http_request_header_set(req, "Content-Type", "application/x-www-form-urlencoded"); purple_http_request_set_contents(req, request_data, -1); purple_http_request(gc, req, ggp_avatar_own_sent, NULL); purple_http_request_unref(req); g_free(request_data); }
void ggp_chat_invite(PurpleConnection *gc, int local_id, const char *message, const char *who) { GGPInfo *info = purple_connection_get_protocol_data(gc); ggp_chat_local_info *chat; uin_t invited; chat = ggp_chat_get_local(gc, local_id); if (!chat) { purple_debug_error("gg", "ggp_chat_invite: " "chat %u doesn't exists\n", local_id); return; } invited = ggp_str_to_uin(who); if (gg_chat_invite(info->session, chat->id, &invited, 1) < 0) { purple_debug_error("gg", "ggp_chat_invite: " "unable to invite %s to chat %" G_GUINT64_FORMAT "\n", who, chat->id); } }
static void ggp_pubdir_set_info_request(PurpleConnection *gc, PurpleRequestFields *fields) { gchar *url; uin_t uin = ggp_str_to_uin(purple_account_get_username( purple_connection_get_account(gc))); ggp_pubdir_record *record = g_new0(ggp_pubdir_record, 1); gchar *birth_s; purple_debug_info("gg", "ggp_pubdir_set_info_request\n"); record->uin = uin; record->first_name = g_strdup(purple_request_fields_get_string(fields, "first_name")); record->last_name = g_strdup(purple_request_fields_get_string(fields, "last_name")); record->gender = GPOINTER_TO_INT( purple_request_fields_get_choice(fields, "gender")); record->city = g_strdup(purple_request_fields_get_string(fields, "city")); record->province = GPOINTER_TO_INT( purple_request_fields_get_choice(fields, "province")); birth_s = g_strdup_printf("%sT10:00:00+00:00", purple_request_fields_get_string(fields, "birth_date")); record->birth = ggp_date_from_iso8601(birth_s); g_free(birth_s); purple_debug_info("gg", "ggp_pubdir_set_info_request: birth [%lu][%s]\n", record->birth, purple_request_fields_get_string( fields, "birth_date")); url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u.xml", uin); ggp_oauth_request(gc, ggp_pubdir_set_info_got_token, record, "PUT", url); g_free(url); }
/* this is for for notify purposes, not synchronizing buddy list */ void ggp_buddylist_send(PurpleConnection *gc) { GGPInfo *info = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc); GSList *buddies; uin_t *userlist; gchar *types; int i = 0, ret = 0; int size; buddies = purple_blist_find_buddies(account, NULL); size = g_slist_length(buddies); userlist = g_new(uin_t, size); types = g_new(gchar, size); for (buddies = purple_blist_find_buddies(account, NULL); buddies; buddies = g_slist_delete_link(buddies, buddies), ++i) { PurpleBuddy *buddy = buddies->data; const gchar *name = purple_buddy_get_name(buddy); userlist[i] = ggp_str_to_uin(name); types[i] = GG_USER_NORMAL; purple_debug_info("gg", "ggp_buddylist_send: adding %d\n", userlist[i]); } ret = gg_notify_ex(info->session, userlist, types, size); purple_debug_info("gg", "send: ret=%d; size=%d\n", ret, size); if (userlist) { g_free(userlist); g_free(types); } }
void ggp_image_send(PurpleConnection *gc, const struct gg_event_image_request *image_request) { GGPInfo *accdata = purple_connection_get_protocol_data(gc); ggp_image_session_data *sdata = ggp_image_get_sdata(gc); ggp_image_sent *sent_image; PurpleStoredImage *image; PurpleConversation *conv; uint64_t id; gchar *gg_filename; purple_debug_info("gg", "ggp_image_send: got image request " "[uin=%u, crc=%u, size=%u]\n", image_request->sender, image_request->crc32, image_request->size); id = ggp_image_params_to_id(image_request->crc32, image_request->size); sent_image = g_hash_table_lookup(sdata->sent_images, &id); if (sent_image == NULL && image_request->sender == ggp_str_to_uin( purple_account_get_username(purple_connection_get_account(gc)))) { purple_debug_misc("gg", "ggp_image_send: requested image " "not found, but this may be another session request\n"); return; } if (sent_image == NULL) { purple_debug_warning("gg", "ggp_image_send: requested image " "not found\n"); return; } purple_debug_misc("gg", "ggp_image_send: requested image found " "[id=" GGP_IMAGE_ID_FORMAT ", stored id=%d, conv=%s]\n", id, sent_image->id, sent_image->conv_name); image = purple_imgstore_find_by_id(sent_image->id); if (!image) { purple_debug_error("gg", "ggp_image_send: requested image " "found, but doesn't exists in image store\n"); g_hash_table_remove(sdata->sent_images, GINT_TO_POINTER(image_request->crc32)); return; } /* TODO: check allowed recipients */ gg_filename = g_strdup_printf(GGP_IMAGE_ID_FORMAT, id); gg_image_reply(accdata->session, image_request->sender, gg_filename, purple_imgstore_get_data(image), purple_imgstore_get_size(image)); g_free(gg_filename); conv = purple_conversations_find_with_account( sent_image->conv_name, purple_connection_get_account(gc)); if (conv != NULL) { gchar *msg = g_strdup_printf(_("Image delivered to %u."), image_request->sender); purple_conversation_write(conv, "", msg, PURPLE_MESSAGE_NO_LOG | PURPLE_MESSAGE_NOTIFY, time(NULL)); g_free(msg); } }
void ggp_pubdir_set_info(PurpleConnection *gc) { ggp_pubdir_get_info(gc, ggp_str_to_uin(purple_account_get_username( purple_connection_get_account(gc))), ggp_pubdir_set_info_dialog, NULL); }
static void ggp_roster_reply_list(PurpleConnection *gc, uint32_t version, const char *data) { ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc); PurpleXmlNode *xml, *xml_it; PurpleAccount *account; GSList *local_buddies; GHashTable *remove_buddies; GList *update_buddies = NULL, *local_groups, *it, *table_values; ggp_roster_content *content; g_return_if_fail(gc != NULL); g_return_if_fail(data != NULL); account = purple_connection_get_account(gc); purple_debug_info("gg", "ggp_roster_reply_list: got list, version=%u\n", version); xml = purple_xmlnode_from_str(data, -1); if (xml == NULL) { purple_debug_warning("gg", "ggp_roster_reply_list: " "invalid xml\n"); return; } ggp_roster_content_free(rdata->content); rdata->content = NULL; rdata->is_updating = TRUE; content = g_new0(ggp_roster_content, 1); content->version = version; content->xml = xml; content->contact_nodes = g_hash_table_new(NULL, NULL); content->group_nodes = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, NULL); content->group_ids = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free); content->group_names = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free); #if GGP_ROSTER_DEBUG ggp_roster_dump(content); #endif /* reading groups */ content->groups_node = purple_xmlnode_get_child(xml, "Groups"); if (content->groups_node == NULL) { ggp_roster_content_free(content); g_return_if_reached(); } xml_it = purple_xmlnode_get_child(content->groups_node, "Group"); while (xml_it != NULL) { if (!ggp_roster_reply_list_read_group(xml_it, content)) { ggp_roster_content_free(content); g_return_if_reached(); } xml_it = purple_xmlnode_get_next_twin(xml_it); } /* dumping current group list */ local_groups = ggp_purplew_account_get_groups(account, TRUE); /* dumping current buddy list * we will: * - remove synchronized ones, if not found in list at server * - upload not synchronized ones */ local_buddies = purple_blist_find_buddies(account, NULL); remove_buddies = g_hash_table_new(g_direct_hash, g_direct_equal); while (local_buddies) { PurpleBuddy *buddy = local_buddies->data; uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy)); local_buddies = g_slist_delete_link(local_buddies, local_buddies); if (!uin) continue; if (ggp_roster_is_synchronized(buddy)) g_hash_table_insert(remove_buddies, GINT_TO_POINTER(uin), buddy); else update_buddies = g_list_append(update_buddies, buddy); } /* reading buddies */ content->contacts_node = purple_xmlnode_get_child(xml, "Contacts"); if (content->contacts_node == NULL) { g_hash_table_destroy(remove_buddies); g_list_free(update_buddies); ggp_roster_content_free(content); g_return_if_reached(); } xml_it = purple_xmlnode_get_child(content->contacts_node, "Contact"); while (xml_it != NULL) { if (!ggp_roster_reply_list_read_buddy(gc, xml_it, content, remove_buddies)) { g_hash_table_destroy(remove_buddies); g_list_free(update_buddies); ggp_roster_content_free(content); g_return_if_reached(); } xml_it = purple_xmlnode_get_next_twin(xml_it); } /* removing buddies, which are not present in roster */ table_values = g_hash_table_get_values(remove_buddies); it = g_list_first(table_values); while (it) { PurpleBuddy *buddy = it->data; it = g_list_next(it); if (!ggp_roster_is_synchronized(buddy)) continue; purple_debug_info("gg", "ggp_roster_reply_list: " "removing %s from buddy list\n", purple_buddy_get_name(buddy)); purple_blist_remove_buddy(buddy); } g_list_free(table_values); g_hash_table_destroy(remove_buddies); /* remove groups, which are empty, but had contacts before * synchronization */ it = g_list_first(local_groups); while (it) { PurpleGroup *group = it->data; it = g_list_next(it); if (purple_counting_node_get_total_size(PURPLE_COUNTING_NODE(group)) != 0) continue; purple_debug_info("gg", "ggp_roster_reply_list: " "removing group %s\n", purple_group_get_name(group)); purple_blist_remove_group(group); } g_list_free(local_groups); /* adding not synchronized buddies */ it = g_list_first(update_buddies); while (it) { PurpleBuddy *buddy = it->data; uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy)); ggp_roster_change *change; it = g_list_next(it); g_assert(uin > 0); purple_debug_misc("gg", "ggp_roster_reply_list: " "adding change of %u for roster\n", uin); change = g_new0(ggp_roster_change, 1); change->type = GGP_ROSTER_CHANGE_CONTACT_UPDATE; change->data.uin = uin; rdata->pending_updates = g_list_append(rdata->pending_updates, change); } g_list_free(update_buddies); rdata->content = content; rdata->is_updating = FALSE; purple_debug_info("gg", "ggp_roster_reply_list: " "import done, version=%u\n", version); }
static void ggp_edisc_xfer_recv_ticket_update_got(PurpleHttpConnection *hc, PurpleHttpResponse *response, gpointer user_data) { PurpleConnection *gc = purple_http_conn_get_purple_connection(hc); PurpleXfer *xfer; ggp_edisc_xfer *edisc_xfer; JsonParser *parser; JsonObject *result; int status = -1; ggp_edisc_session_data *sdata; const gchar *ticket_id, *file_name, *send_mode_str; uin_t sender, recipient; int file_size; if (!purple_http_response_is_successful(response)) { purple_debug_error("gg", "ggp_edisc_xfer_recv_ticket_update_got: " "cannot fetch update for ticket (code=%d)\n", purple_http_response_get_code(response)); return; } sdata = ggp_edisc_get_sdata(gc); g_return_if_fail(sdata != NULL); parser = ggp_json_parse(purple_http_response_get_data(response, NULL)); result = json_node_get_object(json_parser_get_root(parser)); result = json_object_get_object_member(result, "result"); if (json_object_has_member(result, "status")) status = json_object_get_int_member(result, "status"); result = json_object_get_object_member(result, "send_ticket"); if (status != 0) { purple_debug_warning("gg", "ggp_edisc_xfer_recv_ticket_update_got: failed to get " "update (status=%d)\n", status); g_object_unref(parser); return; } ticket_id = json_object_get_string_member(result, "id"); sender = ggp_str_to_uin(json_object_get_string_member(result, "sender")); recipient = ggp_str_to_uin(json_object_get_string_member(result, "recipient")); file_size = g_ascii_strtoll(json_object_get_string_member(result, "file_size"), NULL, 10); file_name = json_object_get_string_member(result, "file_name"); /* GG11: normal * AQQ 2.4.2.10: direct_inbox */ send_mode_str = json_object_get_string_member(result, "send_mode"); /* more fields: * send_progress (float), ack_status, send_status */ if (purple_debug_is_verbose() && purple_debug_is_unsafe()) purple_debug_info("gg", "Got ticket update: id=%s, sender=%u, " "recipient=%u, file name=\"%s\", file size=%d, " "send mode=%s)\n", ticket_id, sender, recipient, file_name, file_size, send_mode_str); xfer = g_hash_table_lookup(sdata->xfers_initialized, ticket_id); if (xfer != NULL) { purple_debug_misc("gg", "ggp_edisc_xfer_recv_ticket_update_got:" " ticket %s already updated\n", purple_debug_is_unsafe() ? ticket_id : ""); g_object_unref(parser); return; } if (recipient != ggp_get_my_uin(gc)) { purple_debug_misc("gg", "ggp_edisc_xfer_recv_ticket_update_got:" " ticket %s is not for incoming transfer " "(its from %u to %u)\n", purple_debug_is_unsafe() ? ticket_id : "", sender, recipient); g_object_unref(parser); return; } xfer = ggp_edisc_xfer_recv_new(gc, ggp_uin_to_str(sender)); purple_xfer_set_filename(xfer, file_name); purple_xfer_set_size(xfer, file_size); purple_xfer_request(xfer); edisc_xfer = purple_xfer_get_protocol_data(xfer); edisc_xfer->ticket_id = g_strdup(ticket_id); g_hash_table_insert(sdata->xfers_initialized, edisc_xfer->ticket_id, xfer); g_hash_table_insert(sdata->xfers_history, g_strdup(ticket_id), GINT_TO_POINTER(1)); g_object_unref(parser); }
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); }
/* return TRUE if avatar update was performed or there is no new requests, FALSE if we can request another one immediately */ static gboolean ggp_avatar_buddy_update_next(PurpleConnection *gc) { PurpleHttpRequest *req; ggp_avatar_session_data *avdata = ggp_avatar_get_avdata(gc); GList *pending_update_it; ggp_avatar_buddy_update_req *pending_update; PurpleBuddy *buddy; PurpleAccount *account = purple_connection_get_account(gc); time_t old_timestamp; const char *old_timestamp_str; pending_update_it = g_list_first(avdata->pending_updates); if (pending_update_it == NULL) return TRUE; pending_update = pending_update_it->data; avdata->pending_updates = g_list_remove(avdata->pending_updates, pending_update); buddy = purple_blist_find_buddy(account, ggp_uin_to_str(pending_update->uin)); if (!buddy) { if (ggp_str_to_uin(purple_account_get_username(account)) == pending_update->uin) { purple_debug_misc("gg", "ggp_avatar_buddy_update_next(%p): own " "avatar update requested, but we don't have " "ourselves on buddy list\n", gc); } else { purple_debug_warning("gg", "ggp_avatar_buddy_update_next(%p): " "%u update requested, but he's not on buddy " "list\n", gc, pending_update->uin); } return FALSE; } old_timestamp_str = purple_buddy_icons_get_checksum_for_user(buddy); old_timestamp = old_timestamp_str ? g_ascii_strtoull( old_timestamp_str, NULL, 10) : 0; if (old_timestamp == pending_update->timestamp) { if (purple_debug_is_verbose()) { purple_debug_misc("gg", "ggp_avatar_buddy_update_next(%p): " "%u have up to date avatar with ts=%lu\n", gc, pending_update->uin, pending_update->timestamp); } return FALSE; } if (old_timestamp > pending_update->timestamp) { purple_debug_warning("gg", "ggp_avatar_buddy_update_next(%p): " "saved timestamp for %u is newer than received " "(%lu > %lu)\n", gc, pending_update->uin, old_timestamp, pending_update->timestamp); } purple_debug_info("gg", "ggp_avatar_buddy_update_next(%p): " "updating %u with ts=%lu...\n", gc, pending_update->uin, pending_update->timestamp); pending_update->gc = gc; avdata->current_update = pending_update; req = purple_http_request_new(NULL); purple_http_request_set_url_printf(req, GGP_AVATAR_BUDDY_URL, pending_update->uin); purple_http_request_header_set(req, "User-Agent", GGP_AVATAR_USERAGENT); purple_http_request_set_max_len(req, GGP_AVATAR_SIZE_MAX); pending_update->request = purple_http_request(gc, req, ggp_avatar_buddy_update_received, pending_update); purple_http_request_unref(req); return TRUE; }