/** * Callback function to process the buddy's get-info response. */ static gboolean buddy_get_info_cb(XmppStream *stream, xmlnode *root, XmppBuddy *buddy) { xmlnode *node; gchar *type; gchar *photo_bin; guchar *photo; gint photo_len; if (xmlnode_has_prop(root, "type")) { type = xmlnode_prop(root, "type"); if (g_strcmp0(type, "result") != 0) { hybrid_debug_error("xmpp", "get buddy info error."); g_free(type); return FALSE; } g_free(type); } if ((node = xmlnode_find(root, "PHOTO"))) { if ((node = xmlnode_find(root, "BINVAL"))) { photo_bin = xmlnode_content(node); /* decode the base64-encoded photo string. */ photo = hybrid_base64_decode(photo_bin, &photo_len); /* set icon for the buddy. */ hybrid_blist_set_buddy_icon(buddy->buddy, photo, photo_len, buddy->photo); g_free(photo_bin); g_free(photo); } } return TRUE; }
/** * Callback function to handle the portrait receive event. */ static gboolean portrait_recv_cb(gint sk, gpointer user_data) { gchar buf[BUF_LENGTH]; gint n; gchar *pos; HybridBuddy *imbuddy; portrait_trans *trans = (portrait_trans*)user_data; if ((n = recv(sk, buf, sizeof(buf), 0)) == -1) { hybrid_debug_error("fetion", "get portrait for \'%s\':%s", trans->buddy ? trans->buddy->sid : trans->ac->sid, strerror(errno)); return FALSE; } buf[n] = '\0'; if (n == 0) { if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) { imbuddy = hybrid_blist_find_buddy(trans->ac->account, trans->buddy->userid); } if (hybrid_get_http_code(trans->data) != 200) { /* * Note that we got no portrait, but we still need * to set buddy icon, just for the portrait checksum, we * set it default to "0" instead of leaving it NULL, * so that in the next login, we just check the changes * of the buddy's checksum to determine whether to fetch a * portrait from the server. */ if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) { hybrid_blist_set_buddy_icon(imbuddy, NULL, 0, trans->buddy->portrait_crc); } else { hybrid_account_set_icon(trans->ac->account, NULL, 0, trans->ac->portrait_crc); } goto pt_fin; } trans->data_len = hybrid_get_http_length(trans->data); if (!(pos = strstr(trans->data, "\r\n\r\n"))) { goto pt_fin; } pos += 4; if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) { /**< buddy portrait */ hybrid_blist_set_buddy_icon(imbuddy, (guchar*)pos, trans->data_len, trans->buddy->portrait_crc); } else { hybrid_account_set_icon(trans->ac->account, (guchar*)pos, trans->data_len, trans->ac->portrait_crc); } goto pt_fin; } else { trans->data = realloc(trans->data, trans->data_size + n); memcpy(trans->data + trans->data_size, buf, n); trans->data_size += n; } return TRUE; pt_fin: g_free(trans->data); g_free(trans); return FALSE; }