static void request_own_user_display(MsnUser *user) { PurpleAccount *account; MsnSession *session; MsnObject *my_obj = NULL; gconstpointer data = NULL; const char *info = NULL; size_t len = 0; if (purple_debug_is_verbose()) purple_debug_info("msn", "Requesting our own user display\n"); session = user->userlist->session; account = session->account; my_obj = msn_user_get_object(user); if (my_obj != NULL) { PurpleStoredImage *img = msn_object_get_image(my_obj); data = purple_imgstore_get_data(img); len = purple_imgstore_get_size(img); info = msn_object_get_sha1(my_obj); } purple_buddy_icons_set_for_user(account, user->passport, g_memdup(data, len), len, info); /* Free one window slot */ session->userlist->buddy_icon_window++; if (purple_debug_is_verbose()) purple_debug_info("msn", "msn_request_user_display(): buddy_icon_window++ yields =%d\n", session->userlist->buddy_icon_window); msn_release_buddy_icon_request(session->userlist); }
static void tgp_info_load_photo_done (struct tgl_state *TLS, void *extra, int success, const char *filename) { tgl_peer_t *P = extra; g_return_if_fail(success); gchar *img = NULL; size_t len; GError *err = NULL; g_file_get_contents (filename, &img, &len, &err); if (err) { failure ("getting file contents for %s failed: %s", filename, err->message); return; } if (tgl_get_peer_type (P->id) == TGL_PEER_USER || tgl_get_peer_type (P->id) == TGL_PEER_ENCR_CHAT) { PurpleBuddy *B = tgp_blist_buddy_find (TLS, P->id); g_return_if_fail(B); purple_buddy_icons_set_for_user (tls_get_pa (TLS), purple_buddy_get_name (B), (guchar*) img, len, NULL); tgp_info_update_photo_id (&B->node, P->user.photo_big.local_id); } else { PurpleChat *C = tgp_blist_chat_find (TLS, P->id); g_return_if_fail(C); purple_buddy_icons_node_set_custom_icon (&C->node, (guchar*) img, len); tgp_info_update_photo_id (&C->node, P->user.photo_big.local_id); } }
// // Callback that's invoked each time that an user image has been downloaded. // // This function sets the buddy's icon based on the downloaded image, that is // assuming that the picture was successfully downloaded. // // This function always invokes a next iteration within the current worker. // static void budicons_got_image_response (SoupSession *session, SoupMessage *message, gpointer data) { PurpleBuddy *buddy = (PurpleBuddy *) data; char *url = soup_uri_to_string(soup_message_get_uri(message), FALSE); g_print("Soup: [%-3d] %s\n", message->status_code, url); g_free(url); if (! SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) { return; } const char *mime = soup_message_headers_get_content_type(message->response_headers, NULL); if (g_ascii_strncasecmp(mime, "image/", strlen("image/"))) { // Wrong mime-type, this isn't an image g_print("Soup: content-type '%s' doesn't correspond to an image\n", mime); return; } // Set the icon of the buddy const char *content = message->response_body->data; gsize length = (gsize) message->response_body->length; char *icon = g_memdup(content, length); purple_buddy_icons_set_for_user( buddy->account, buddy->name, icon, length, NULL ); }
/** * Callback for when a buddy icon finished being downloaded. */ static void msim_downloaded_buddy_icon(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { MsimUser *user; user = (MsimUser *)user_data; purple_debug_info("msim_downloaded_buddy_icon", "Downloaded %" G_GSIZE_FORMAT " bytes\n", len); if (!url_text) { purple_debug_info("msim_downloaded_buddy_icon", "failed to download icon for %s", user->buddy->name); return; } purple_buddy_icons_set_for_user(user->buddy->account, user->buddy->name, g_memdup((gchar *)url_text, len), len, /* Use URL itself as buddy icon "checksum" (TODO: ETag) */ user->image_url); /* checksum */ }
/** * We got the buddy icon data; deal with it */ void bonjour_buddy_got_buddy_icon(BonjourBuddy *buddy, gconstpointer data, gsize len) { /* Recalculate the hash instead of using the current phsh to make sure it is accurate for the icon. */ char *p, *hash; if (data == NULL || len == 0) return; /* Take advantage of the fact that we use a SHA-1 hash of the data as the filename. */ hash = purple_util_get_image_filename(data, len); /* Get rid of the extension */ if (!(p = strchr(hash, '.'))) { g_free(hash); return; } *p = '\0'; purple_debug_info("bonjour", "Got buddy icon for %s icon hash='%s' phsh='%s'.\n", buddy->name, hash, buddy->phsh ? buddy->phsh : "(null)"); purple_buddy_icons_set_for_user(buddy->account, buddy->name, g_memdup(data, len), len, hash); g_free(hash); }
static void on_userpic_loaded (struct tgl_state *TLS, void *extra, int success, char *filename) { if (!success) { struct download_desc *dld = extra; struct tgl_user *U = dld->data; warning ("Can not load userpic for user %s %s\n", U->first_name, U->last_name); } telegram_conn *conn = TLS->ev_base; gchar *data = NULL; size_t len; GError *err = NULL; g_file_get_contents (filename, &data, &len, &err); int imgStoreId = purple_imgstore_add_with_id (g_memdup(data, (guint)len), len, NULL); struct download_desc *dld = extra; struct tgl_user *U = dld->data; if (imgStoreId <= 0) { warning ("Can not load userpic for user %s %s\n", U->first_name, U->last_name); } char *who = g_strdup_printf ("%d", tgl_get_peer_id (U->id)); if (dld->type == 1) { PurpleNotifyUserInfo *info = create_user_notify_info(U); char *profile_image = profile_image = format_img_full(imgStoreId); purple_notify_user_info_add_pair (info, "Profile image", profile_image); purple_notify_userinfo (conn->gc, who, info, NULL, NULL); g_free (profile_image); } purple_buddy_icons_set_for_user(conn->pa, who, g_memdup(data, (guint)len), len, NULL); g_free(who); }
static void jabber_vcard_parse_avatar(JabberStream *js, const char *from, JabberIqType type, const char *id, xmlnode *packet, gpointer blah) { JabberBuddy *jb = NULL; xmlnode *vcard, *photo, *binval, *fn, *nick; char *text; if(!from) return; jb = jabber_buddy_find(js, from, TRUE); js->pending_avatar_requests = g_slist_remove(js->pending_avatar_requests, jb); if((vcard = xmlnode_get_child(packet, "vCard")) || (vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) { /* The logic here regarding the nickname and full name is copied from * buddy.c:jabber_vcard_parse. */ gchar *nickname = NULL; if ((fn = xmlnode_get_child(vcard, "FN"))) nickname = xmlnode_get_data(fn); if ((nick = xmlnode_get_child(vcard, "NICKNAME"))) { char *tmp = xmlnode_get_data(nick); char *bare_jid = jabber_get_bare_jid(from); if (tmp && strstr(bare_jid, tmp) == NULL) { g_free(nickname); nickname = tmp; } else if (tmp) g_free(tmp); g_free(bare_jid); } if (nickname) { serv_got_alias(js->gc, from, nickname); g_free(nickname); } if ((photo = xmlnode_get_child(vcard, "PHOTO")) && (binval = xmlnode_get_child(photo, "BINVAL")) && (text = xmlnode_get_data(binval))) { guchar *data; gsize size; data = purple_base64_decode(text, &size); if (data) { gchar *hash = jabber_calculate_data_hash(data, size, "sha1"); purple_buddy_icons_set_for_user(js->gc->account, from, data, size, hash); g_free(hash); } g_free(text); } } }
void ggp_avatar_buddy_remove(PurpleConnection *gc, uin_t uin) { if (purple_debug_is_verbose()) { purple_debug_misc("gg", "ggp_avatar_buddy_remove(%p, %u)\n", gc, uin); } purple_buddy_icons_set_for_user(purple_connection_get_account(gc), ggp_uin_to_str(uin), NULL, 0, NULL); }
static void query_icon(PurpleConnection *gc) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleAccount *acc = purple_connection_get_account(gc); char *who, *icon, *hash; int len; while (waAPI_queryicon(wconn->waAPI, &who, &icon, &len, &hash)) { purple_buddy_icons_set_for_user(acc, who, g_memdup(icon, len), len, hash); } }
static void flist_fetch_icon_cb(PurpleUtilFetchUrlData *url_data, gpointer data, const gchar *b, size_t len, const gchar *err) { FListFetchIcon *fli = data; FListAccount *fla = fli->fla; const gchar *character, *checksum; checksum = "0"; /* what the f**k is this checksum supposed to be?? */ character = fli->character; if(err) { if(fli->convo) { PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, fli->convo, fla->pa); if(convo) { purple_conv_custom_smiley_close(convo, fli->smiley); } } purple_debug_warning(FLIST_DEBUG, "Failed to fetch a character icon. (Character: %s) (Convo: %s) (Secure: %s) (Error Message: %s)\n", fli->character, fli->convo ? fli->convo : "none", fla->secure ? "yes" : "no", err); } else { purple_debug_info(FLIST_DEBUG, "Received character icon. (Character: %s) (Convo: %s) (Secure: %s)\n", fli->character, fli->convo ? fli->convo : "none", fla->secure ? "yes" : "no"); if(fli->convo) { PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, fli->convo, fla->pa); if(convo) { purple_debug_info(FLIST_DEBUG, "Writing character icon to convo... (Smiley: %s)\n", fli->smiley); purple_conv_custom_smiley_write(convo, fli->smiley, (const guchar *) b, len); purple_conv_custom_smiley_close(convo, fli->smiley); } } else { purple_buddy_icons_set_for_user(fla->pa, character, g_memdup(b, len), len, checksum); } } fla->icon_requests = g_slist_remove(fla->icon_requests, fli); if(fli->convo) g_free(fli->convo); if(fli->smiley) g_free(fli->smiley); g_free(fli->character); g_free(fli); gboolean done = FALSE; while(fla->icon_request_queue && !done) { FListFetchIcon *new_fli = fla->icon_request_queue->data; fla->icon_request_queue = g_slist_delete_link(fla->icon_request_queue, fla->icon_request_queue); if(new_fli->convo || purple_find_buddy(fla->pa, new_fli->character)) { flist_fetch_icon_real(fla, new_fli); done = TRUE; } } }
static void skypeweb_get_icon_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { PurpleBuddy *buddy = user_data; SkypeWebBuddy *sbuddy; if (!buddy || !purple_buddy_get_protocol_data(buddy)) return; sbuddy = purple_buddy_get_protocol_data(buddy); purple_buddy_icons_set_for_user(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy), g_memdup(url_text, len), len, sbuddy->avatar_url); active_icon_downloads--; }
static void ggp_avatar_buddy_update_received(PurpleHttpConnection *http_conn, PurpleHttpResponse *response, gpointer _pending_update) { ggp_avatar_buddy_update_req *pending_update = _pending_update; PurpleBuddy *buddy; PurpleAccount *account; PurpleConnection *gc = pending_update->gc; ggp_avatar_session_data *avdata; gchar timestamp_str[20]; const gchar *got_data; size_t got_len; PURPLE_ASSERT_CONNECTION_IS_VALID(gc); avdata = ggp_avatar_get_avdata(gc); g_assert(pending_update == avdata->current_update); avdata->current_update = NULL; if (!purple_http_response_is_successful(response)) { purple_debug_error("gg", "ggp_avatar_buddy_update_received: bad" " response while getting avatar for %u: %s\n", pending_update->uin, purple_http_response_get_error(response)); g_free(pending_update); return; } account = purple_connection_get_account(gc); buddy = purple_blist_find_buddy(account, ggp_uin_to_str(pending_update->uin)); if (!buddy) { purple_debug_warning("gg", "ggp_avatar_buddy_update_received: " "buddy %u disappeared\n", pending_update->uin); g_free(pending_update); return; } g_snprintf(timestamp_str, sizeof(timestamp_str), "%lu", pending_update->timestamp); got_data = purple_http_response_get_data(response, &got_len); purple_buddy_icons_set_for_user(account, purple_buddy_get_name(buddy), g_memdup(got_data, got_len), got_len, timestamp_str); purple_debug_info("gg", "ggp_avatar_buddy_update_received: " "got avatar for buddy %u [ts=%lu]\n", pending_update->uin, pending_update->timestamp); g_free(pending_update); }
static void skypeweb_get_icon_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { PurpleBuddy *buddy = user_data; SkypeWebBuddy *sbuddy = purple_buddy_get_protocol_data(buddy); SkypeWebAccount *sa = sbuddy->sa; sa->url_datas = g_slist_remove(sa->url_datas, url_data); active_icon_downloads--; if (!buddy) return; purple_buddy_icons_set_for_user(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy), g_memdup(url_text, len), len, url_data->url); }
void qq_update_buddy_icon(PurpleAccount *account, const gchar *who, gint face) { PurpleBuddy *buddy; const gchar *icon_name_prev = NULL; gchar *icon_name; gchar *icon_path; gchar *icon_file_content; gsize icon_file_size; g_return_if_fail(account != NULL && who != NULL); /* purple_debug_info("QQ", "Update %s icon to %d\n", who, face); */ icon_name = qq_get_icon_name(face); g_return_if_fail(icon_name != NULL); /* purple_debug_info("QQ", "icon file name is %s\n", icon_name); */ if ((buddy = purple_find_buddy(account, who))) { icon_name_prev = purple_buddy_icons_get_checksum_for_user(buddy); /* purple_debug_info("QQ", "Previous icon is %s\n", icon_name_prev != NULL ? icon_name_prev : "(NULL)"); */ } if (icon_name_prev != NULL && !strcmp(icon_name, icon_name_prev)) { /* purple_debug_info("QQ", "Icon is not changed\n"); */ g_free(icon_name); return; } icon_path = qq_get_icon_path(icon_name); if (icon_path == NULL) { g_free(icon_name); return; } if (!g_file_get_contents(icon_path, &icon_file_content, &icon_file_size, NULL)) { purple_debug_error("QQ", "Failed reading icon file %s\n", icon_path); } else { purple_debug_info("QQ", "Update %s icon to %d (%s)\n", who, face, icon_path); purple_buddy_icons_set_for_user(account, who, icon_file_content, icon_file_size, icon_name); } g_free(icon_name); g_free(icon_path); }
static void fetch_photo_cb(PurpleUtilFetchUrlData* url_data,gpointer user, const gchar* url_text,gsize len,const gchar* error_message) { FetchPhotoData* f = (FetchPhotoData*) user; if(!PURPLE_CONNECTION_IS_VALID(f->gc)) goto exit; PurpleAccount* account = purple_connection_get_account(f->gc); gpointer copied = g_memdup(url_text,len); purple_buddy_icons_set_for_user(account,f->user,copied, len,f->url); exit: g_free(f->user); g_free(f->url); g_free(f); }
static void got_user_display(MsnSlpCall *slpcall, const guchar *data, gsize size) { const char *info; PurpleAccount *account; g_return_if_fail(slpcall != NULL); info = slpcall->data_info; if (purple_debug_is_verbose()) purple_debug_info("msn", "Got User Display: %s\n", slpcall->slplink->remote_user); account = slpcall->slplink->session->account; purple_buddy_icons_set_for_user(account, slpcall->slplink->remote_user, g_memdup(data, size), size, info); }
static void spin_sync_photo(SpinData* spin,PurpleBuddy* buddy,const gchar* url) { PurpleAccount* account = purple_connection_get_account(spin->gc); const gchar* old_url = purple_buddy_icons_get_checksum_for_user(buddy); if(g_strcmp0(url,old_url) == 0) return; if(!url) purple_buddy_icons_set_for_user(account,purple_buddy_get_name(buddy), NULL,0,NULL); else { FetchPhotoData* user = g_new(FetchPhotoData,1); user->url = g_strdup(url); user->user = g_strdup(purple_buddy_get_name(buddy)); user->gc = spin->gc; spin_fetch_url_request(spin,url,fetch_photo_cb,user); } }
static void fetched_user_display(PurpleHttpConnection *http_conn, PurpleHttpResponse *response, gpointer _data) { MsnFetchUserDisplayData *data = _data; MsnSession *session = data->session; if (purple_http_response_is_successful(response)) { size_t len; const gchar *icon_data; icon_data = purple_http_response_get_data(response, &len); purple_buddy_icons_set_for_user(session->account, data->remote_user, g_memdup(icon_data, len), len, data->sha1); } end_user_display(NULL, session); g_free(data); }
static void buddy_icon_cb(FacebookAccount *fba, gchar *data, gsize data_len, gpointer user_data) { gchar *buddyname; PurpleBuddy *buddy; gpointer buddy_icon_data; buddyname = user_data; purple_debug_info("facebook", "buddy icon for buddy %s %" G_GSIZE_FORMAT "\n", buddyname, data_len); buddy = purple_find_buddy(fba->account, buddyname); g_free(buddyname); if (buddy == NULL) return; buddy_icon_data = g_memdup(data, data_len); purple_buddy_icons_set_for_user(fba->account, buddy->name, buddy_icon_data, data_len, NULL); }
static void yahoo_fetch_picture_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *pic_data, size_t len, const gchar *error_message) { struct yahoo_fetch_picture_data *d; YahooData *yd; d = user_data; yd = d->gc->proto_data; yd->url_datas = g_slist_remove(yd->url_datas, url_data); if (error_message != NULL) { purple_debug_error("yahoo", "Fetching buddy icon failed: %s\n", error_message); } else if (len == 0) { purple_debug_error("yahoo", "Fetched an icon with length 0. Strange.\n"); } else { char *checksum = g_strdup_printf("%i", d->checksum); purple_buddy_icons_set_for_user(purple_connection_get_account(d->gc), d->who, g_memdup(pic_data, len), len, checksum); g_free(checksum); } g_free(d->who); g_free(d); }
/** * Store a field of information about a buddy. * * @param key_str Key to store. * @param value_str Value string, either user takes ownership of this string * or it is freed if MsimUser doesn't store the string. * @param user User to store data in. Existing data will be replaced. */ static void msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user) { if (g_str_equal(key_str, "UserID") || g_str_equal(key_str, "ContactID")) { /* Save to buddy list, if it exists, for quick cached uid lookup with msim_uid2username_from_blist(). */ user->id = atol(value_str); g_free(value_str); if (user->buddy) { purple_debug_info("msim", "associating uid %s with username %s\n", key_str, user->buddy->name); purple_blist_node_set_int(&user->buddy->node, "UserID", user->id); } /* Need to store in MsimUser, too? What if not on blist? */ } else if (g_str_equal(key_str, "Age")) { user->age = atol(value_str); g_free(value_str); } else if (g_str_equal(key_str, "Gender")) { g_free(user->gender); user->gender = value_str; } else if (g_str_equal(key_str, "Location")) { g_free(user->location); user->location = value_str; } else if (g_str_equal(key_str, "TotalFriends")) { user->total_friends = atol(value_str); g_free(value_str); } else if (g_str_equal(key_str, "DisplayName")) { g_free(user->display_name); user->display_name = value_str; } else if (g_str_equal(key_str, "BandName")) { msim_set_artist_or_title(user, value_str, NULL); g_free(value_str); } else if (g_str_equal(key_str, "SongName")) { msim_set_artist_or_title(user, NULL, value_str); g_free(value_str); } else if (g_str_equal(key_str, "UserName") || g_str_equal(key_str, "IMName") || g_str_equal(key_str, "NickName")) { /* Ignore because PurpleBuddy knows this already */ g_free(value_str); } else if (g_str_equal(key_str, "ImageURL") || g_str_equal(key_str, "AvatarURL")) { const gchar *previous_url; if (user->temporary_user) { /* This user will be destroyed soon; don't try to look up its image or avatar, * since that won't return immediately and we will end up accessing freed data. */ g_free(value_str); return; } if (user->temporary_user) { /* This user will be destroyed soon; don't try to look up its image or avatar, * since that won't return immediately and we will end up accessing freed data. */ g_free(value_str); return; } g_free(user->image_url); user->image_url = value_str; /* Instead of showing 'no photo' picture, show nothing. */ if (g_str_equal(user->image_url, "http://x.myspace.com/images/no_pic.gif")) { purple_buddy_icons_set_for_user(user->buddy->account, user->buddy->name, NULL, 0, NULL); return; } /* TODO: use ETag for checksum */ previous_url = purple_buddy_icons_get_checksum_for_user(user->buddy); /* Only download if URL changed */ if (!previous_url || !g_str_equal(previous_url, user->image_url)) { purple_util_fetch_url(user->image_url, TRUE, NULL, TRUE, msim_downloaded_buddy_icon, (gpointer)user); } } else if (g_str_equal(key_str, "LastImageUpdated")) { /* TODO: use somewhere */ user->last_image_updated = atol(value_str); g_free(value_str); } else if (g_str_equal(key_str, "Headline")) { g_free(user->headline); user->headline = value_str; } else { /* TODO: other fields in MsimUser */ gchar *msg; msg = g_strdup_printf("msim_store_user_info_each: unknown field %s=%s", key_str, value_str); g_free(value_str); msim_unrecognized(NULL, NULL, msg); g_free(msg); } }
static void silcpurple_add_buddy_save(bool success, void *context) { SilcPurpleBuddyRes r = context; PurpleBuddy *b = r->b; SilcClient client = r->client; SilcClientEntry client_entry; SilcAttributePayload attr; SilcAttribute attribute; SilcVCardStruct vcard; SilcAttributeObjMime message, extension; #ifdef SILC_ATTRIBUTE_USER_ICON SilcAttributeObjMime usericon; #endif SilcAttributeObjPk serverpk, usersign, serversign; gboolean usign_success = TRUE, ssign_success = TRUE; char filename[512], filename2[512], *fingerprint = NULL, *tmp; SilcUInt32 len; int i; if (!success) { /* The user did not trust the public key. */ silcpurple_add_buddy_pk_no(r); silc_free(r); return; } if (r->offline) { /* User is offline. Associate the imported public key with this user. */ fingerprint = silc_hash_fingerprint(NULL, r->offline_pk, r->offline_pk_len); for (i = 0; i < strlen(fingerprint); i++) if (fingerprint[i] == ' ') fingerprint[i] = '_'; g_snprintf(filename, sizeof(filename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub", silcpurple_silcdir(), fingerprint); purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename); purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_OFFLINE, NULL); silc_free(fingerprint); silc_free(r->offline_pk); silc_free(r); return; } /* Get the client entry. */ client_entry = silc_client_get_client_by_id(r->client, r->conn, &r->client_id); if (!client_entry) { silc_free(r); return; } memset(&vcard, 0, sizeof(vcard)); memset(&message, 0, sizeof(message)); memset(&extension, 0, sizeof(extension)); #ifdef SILC_ATTRIBUTE_USER_ICON memset(&usericon, 0, sizeof(usericon)); #endif memset(&serverpk, 0, sizeof(serverpk)); memset(&usersign, 0, sizeof(usersign)); memset(&serversign, 0, sizeof(serversign)); /* Now that we have the public key and we trust it now we save the attributes of the buddy and update its status. */ if (client_entry->attrs) { silc_dlist_start(client_entry->attrs); while ((attr = silc_dlist_get(client_entry->attrs)) != SILC_LIST_END) { attribute = silc_attribute_get_attribute(attr); switch (attribute) { case SILC_ATTRIBUTE_USER_INFO: if (!silc_attribute_get_object(attr, (void *)&vcard, sizeof(vcard))) continue; break; case SILC_ATTRIBUTE_STATUS_MESSAGE: if (!silc_attribute_get_object(attr, (void *)&message, sizeof(message))) continue; break; case SILC_ATTRIBUTE_EXTENSION: if (!silc_attribute_get_object(attr, (void *)&extension, sizeof(extension))) continue; break; #ifdef SILC_ATTRIBUTE_USER_ICON case SILC_ATTRIBUTE_USER_ICON: if (!silc_attribute_get_object(attr, (void *)&usericon, sizeof(usericon))) continue; break; #endif case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY: if (serverpk.type) continue; if (!silc_attribute_get_object(attr, (void *)&serverpk, sizeof(serverpk))) continue; break; case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE: if (usersign.data) continue; if (!silc_attribute_get_object(attr, (void *)&usersign, sizeof(usersign))) continue; break; case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE: if (serversign.data) continue; if (!silc_attribute_get_object(attr, (void *)&serversign, sizeof(serversign))) continue; break; default: break; } } } /* Verify the attribute signatures */ if (usersign.data) { SilcPKCS pkcs; unsigned char *verifyd; SilcUInt32 verify_len; silc_pkcs_alloc((unsigned char*)"rsa", &pkcs); verifyd = silc_attribute_get_verify_data(client_entry->attrs, FALSE, &verify_len); if (verifyd && silc_pkcs_public_key_set(pkcs, client_entry->public_key)){ if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash, usersign.data, usersign.data_len, verifyd, verify_len)) usign_success = FALSE; } silc_free(verifyd); } if (serversign.data && purple_strequal(serverpk.type, "silc-rsa")) { SilcPublicKey public_key; SilcPKCS pkcs; unsigned char *verifyd; SilcUInt32 verify_len; if (silc_pkcs_public_key_decode(serverpk.data, serverpk.data_len, &public_key)) { silc_pkcs_alloc((unsigned char *)"rsa", &pkcs); verifyd = silc_attribute_get_verify_data(client_entry->attrs, TRUE, &verify_len); if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)) { if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash, serversign.data, serversign.data_len, verifyd, verify_len)) ssign_success = FALSE; } silc_pkcs_public_key_free(public_key); silc_free(verifyd); } } fingerprint = silc_fingerprint(client_entry->fingerprint, client_entry->fingerprint_len); for (i = 0; i < strlen(fingerprint); i++) if (fingerprint[i] == ' ') fingerprint[i] = '_'; if (usign_success || ssign_success) { struct passwd *pw; struct stat st; memset(filename2, 0, sizeof(filename2)); /* Filename for dir */ tmp = fingerprint + strlen(fingerprint) - 9; g_snprintf(filename, sizeof(filename) - 1, "%s" G_DIR_SEPARATOR_S "friends" G_DIR_SEPARATOR_S "%s", silcpurple_silcdir(), tmp); pw = getpwuid(getuid()); if (!pw) return; /* Create dir if it doesn't exist */ if ((g_stat(filename, &st)) == -1) { if (errno == ENOENT) { if (pw->pw_uid == geteuid()) { int ret = g_mkdir(filename, 0755); if (ret < 0) return; } } } /* Save VCard */ g_snprintf(filename2, sizeof(filename2) - 1, "%s" G_DIR_SEPARATOR_S "vcard", filename); if (vcard.full_name) { tmp = (char *)silc_vcard_encode(&vcard, &len); silc_file_writefile(filename2, tmp, len); silc_free(tmp); } /* Save status message */ if (message.mime) { memset(filename2, 0, sizeof(filename2)); g_snprintf(filename2, sizeof(filename2) - 1, "%s" G_DIR_SEPARATOR_S "status_message.mime", filename); silc_file_writefile(filename2, (char *)message.mime, message.mime_len); } /* Save extension data */ if (extension.mime) { memset(filename2, 0, sizeof(filename2)); g_snprintf(filename2, sizeof(filename2) - 1, "%s" G_DIR_SEPARATOR_S "extension.mime", filename); silc_file_writefile(filename2, (char *)extension.mime, extension.mime_len); } #ifdef SILC_ATTRIBUTE_USER_ICON /* Save user icon */ if (usericon.mime) { SilcMime m = silc_mime_decode(usericon.mime, usericon.mime_len); if (m) { const char *type = silc_mime_get_field(m, "Content-Type"); if (purple_strequal(type, "image/jpeg") || purple_strequal(type, "image/gif") || purple_strequal(type, "image/bmp") || purple_strequal(type, "image/png")) { const unsigned char *data; SilcUInt32 data_len; data = silc_mime_get_data(m, &data_len); if (data) { /* TODO: Check if SILC gives us something to use as the checksum instead */ purple_buddy_icons_set_for_user(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), g_memdup(data, data_len), data_len, NULL); } } silc_mime_free(m); } } #endif } /* Save the public key path to buddy properties, as it is used to identify the buddy in the network (and not the nickname). */ memset(filename, 0, sizeof(filename)); g_snprintf(filename, sizeof(filename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub", silcpurple_silcdir(), fingerprint); purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename); /* Update online status */ purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL); /* Finally, start watching this user so we receive its status changes from the server */ g_snprintf(filename2, sizeof(filename2) - 1, "+%s", filename); silc_client_command_call(r->client, r->conn, NULL, "WATCH", "-pubkey", filename2, NULL); silc_free(fingerprint); silc_free(r); }
void DownLoadPortrait(gpointer data, gint source, const gchar * error_message) { gchar buf[10240]; gchar *content_len, *cur, *pos; gchar *temp = NULL; gchar *header; gint len, rcv_len; struct fetion_account_data *sip; struct fetion_buddy *who = data; sip = who->sip; g_return_if_fail(who != NULL); purple_debug_info("fetion:", "DownLoadPortrait starting...\n"); rcv_len = read(source, buf, 10240); purple_debug_info("fetion:", "Received: %d...\n", rcv_len); if (rcv_len > 0) { cur = strstr(buf, "\r\n\r\n"); if (cur != NULL) { header = g_strndup(buf, cur-buf); purple_debug_info("fetion:", "Received headr: %s...\n", header); g_free(header); // If the stat is not 200 if (strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) { // If the stat is not 302, then assume no portrait is for him if (strncmp(buf, "HTTP/1.1 302 Found\r\n", 20) != 0) { who->icon_buf = NULL; return; } //fixme temp = get_token(buf, "Location: http://", "\r\n"); purple_debug_info("fetion:", "new URL: %s...\n", temp); if (temp != NULL && strlen(temp) > 7) GetPortrait(sip, who, temp); else { who->icon_buf = NULL; return; } purple_debug_info("fetion:", "DownLoadPortrait ip[%s][%s]\n", temp, who->name); purple_input_remove(who->inpa); return; } temp = get_token(buf, "Content-Length: ", "\r\n"); if (temp == NULL) return; content_len = g_strdup(temp); purple_debug_info("fetion:", "DownLoadPortrait Content-Length%s\n", content_len); if (content_len != NULL) who->icon_size = atoi(content_len); purple_debug_info("fetion:", "DownLoadPortrait Content-Length%d\n", who->icon_size); who->icon_rcv_len = 0; who->icon_buf = g_malloc0(who->icon_size); cur += 4; len = rcv_len - (cur - buf); memcpy(who->icon_buf, cur, len); who->icon_rcv_len = len; purple_debug_info("fetion:", "DownLoadPortrait Received Length: %d\n", len); while (who->icon_rcv_len < who->icon_size){ rcv_len = read(source, buf, 10240); if (rcv_len<=0) break; memcpy(who->icon_buf+who->icon_rcv_len, buf, rcv_len); who->icon_rcv_len += rcv_len; purple_debug_info("fetion:", "DownLoadPortrait Received Length: %d\n", rcv_len); } // purple_debug_info("fetion:", // "DownLoadPortrait begin[%s]\n", buf); } else if (who->icon_buf != NULL) { pos = (who->icon_buf) + (who->icon_rcv_len); memcpy(pos, buf, rcv_len); who->icon_rcv_len += rcv_len; } // purple_debug_info("fetion:", "DownLoadPortrait%d\n", rcv_len); } else { purple_input_remove(who->inpa); if (who->icon_rcv_len == who->icon_size) purple_buddy_icons_set_for_user(sip->account, who->name, who->icon_buf, who->icon_size, who->icon_crc); g_free(who->host); } }
static void waprpl_process_incoming_events(PurpleConnection * gc) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleAccount *acc = purple_connection_get_account(gc); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending authorization", 1, 4); break; case 2: purple_connection_update_progress(gc, "Awaiting response", 2, 4); break; case 3: purple_connection_update_progress(gc, "Connection established", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); if (!wconn->connected) waprpl_insert_contacts(gc); wconn->connected = 1; PurpleAccount *account = purple_connection_get_account(gc); PurpleStatus *status = purple_account_get_active_status(account); waprpl_set_status(account, status); break; default: break; }; char *msg, *who, *prev, *url, *author; int status; int size; double lat, lng; unsigned long timestamp; /* Incoming messages */ while (1) { int r = waAPI_querynext(wconn->waAPI); switch (r) { case 0: if (waAPI_querychat(wconn->waAPI, &who, &msg, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got chat message from %s: %s\n", who, msg); conv_add_message(gc, who, msg, author, timestamp); } break; case 1: if (waAPI_querychatimage(wconn->waAPI, &who, &prev, &size, &url, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got image from %s: %s\n", who, url); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); char *msg = g_strdup_printf("<a href=\"%s\"><img id=\"%u\"></a><br/><a href=\"%s\">%s</a>", url, imgid, url, url); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; case 2: if (waAPI_querychatlocation(wconn->waAPI, &who, &prev, &size, &lat, &lng, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got geomessage from: %s Coordinates (%f %f)\n", who, (float)lat, (float)lng); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); char *msg = g_strdup_printf("<a href=\"http://openstreetmap.org/?lat=%f&lon=%f&zoom=16\"><img src=\"%u\"></a>", lat, lng, imgid); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; case 3: if (waAPI_querychatsound(wconn->waAPI, &who, &url, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got chat sound from %s: %s\n", who, url); char *msg = g_strdup_printf("<a href=\"%s\">%s</a>", url, url); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; default: break; }; if (r < 0) break; } /* User status change */ while (waAPI_querystatus(wconn->waAPI, &who, &status)) { if (status == 1) { purple_prpl_got_user_status(acc, who, "available", "message", "", NULL); } else { purple_prpl_got_user_status(acc, who, "unavailable", "message", "", NULL); } } /* User typing info notify */ while (waAPI_querytyping(wconn->waAPI, &who, &status)) { if (status == 1) { purple_debug_info(WHATSAPP_ID, "%s is typing\n", who); serv_got_typing(gc, who, 0, PURPLE_TYPING); } else { purple_debug_info(WHATSAPP_ID, "%s is not typing\n", who); serv_got_typing(gc, who, 0, PURPLE_NOT_TYPING); serv_got_typing_stopped(gc, who); } } /* User profile picture */ char *icon, *hash; int len; while (waAPI_queryicon(wconn->waAPI, &who, &icon, &len, &hash)) { purple_buddy_icons_set_for_user(acc, who, g_memdup(icon, len), len, hash); } /* Groups update */ if (waAPI_getgroupsupdated(wconn->waAPI)) { /* Delete/update the chats that are in our list */ PurpleBlistNode *node; for (node = purple_blist_get_root(); node; node = purple_blist_node_next(node, FALSE)) { if (!PURPLE_BLIST_NODE_IS_CHAT(node)) continue; PurpleChat *ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) != acc) continue; GHashTable *hasht = purple_chat_get_components(ch); char *grid = g_hash_table_lookup(hasht, "id"); char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); if (str_array_find(gplist, grid) >= 0) { /* The group is in the system, update the fields */ char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, grid, &sub, &own, 0); g_hash_table_insert(hasht, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(hasht, g_strdup("owner"), g_strdup(own)); } else { /* The group was deleted */ PurpleChat *del = (PurpleChat *) node; node = purple_blist_node_next(node, FALSE); purple_blist_remove_chat(del); } g_strfreev(gplist); } /* Add new groups */ char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); gchar **p; for (p = gplist; *p; p++) { gchar *gpid = *p; PurpleChat *ch = blist_find_chat_by_id(gc, gpid); if (!ch) { char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, gpid, &sub, &own, 0); purple_debug_info("waprpl", "New group found %s %s\n", gpid, sub); GHashTable *htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(htable, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(htable, g_strdup("id"), g_strdup(gpid)); g_hash_table_insert(htable, g_strdup("owner"), g_strdup(own)); ch = purple_chat_new(acc, sub, htable); purple_blist_add_chat(ch, NULL, NULL); } /* Now update the open conversation that may exist */ char *id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation *conv = purple_find_chat(gc, prplid); char *subject, *owner, *part; if (conv && waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) conv_add_participants(conv, part, owner); } g_strfreev(gplist); } }
static void got_buddy_list_cb(FacebookAccount *fba, gchar *data, gsize data_len, gpointer userdata) { GSList *buddies_list; GSList *online_buddies_list = NULL; PurpleBuddy *buddy; FacebookBuddy *fbuddy; gchar *uid; gchar *name; gchar *status_text; gchar *status_time_text; gchar *buddy_icon_url; gboolean idle; guint32 error_number; gchar *search_start; gchar *search_tmp; gchar *tmp; gchar *largest_buddy_search_point = NULL; PurpleGroup *fb_group = NULL; gboolean current_buddy_online = FALSE; purple_debug_info("facebook", "parsing buddy list\n"); purple_debug_misc("facebook", "buddy list\n%s\n", data); if (fba == NULL) return; if (data == NULL) { purple_connection_error_reason(fba->pc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Could not retrieve buddy list")); return; } /* Check if the facebook group already exists (fixes #13) */ fb_group = purple_find_group("Facebook"); /* if logged out, this comes up */ /* for (;;);{"error":1357001,"errorSummary":"Not Logged In", "errorDescription":"You must be logged in to do that.", "payload":null,"bootload":[{"name":"js\/common.js.pkg.php", "type":"js","src":"http:\/\/static.ak.fbcdn.net\/rsrc.php\/pkg\/59\ /98561\/js\/common.js.pkg.php"}]} */ tmp = g_strstr_len(data, data_len, "\"error\":"); if (tmp != NULL) { tmp += 9; tmp = g_strndup(tmp, strchr(tmp, ',')-tmp); error_number = atoi(tmp); g_free(tmp); if (error_number) { /* error :( */ tmp = g_strstr_len(data, data_len, "\"errorDescription\":"); tmp += 20; tmp = g_strndup(tmp, strchr(tmp, '"')-tmp); /* TODO: Use purple_connection_error_reason() */ purple_connection_error(fba->pc, tmp); g_free(tmp); return; } } /* look for "userInfos":{ ... }, */ search_start = strstr(data, "\"userInfos\":{"); if (search_start == NULL) return; search_start += 13; while (*search_start != '}' && (search_start - data < data_len)) { tmp = strchr(search_start, ':'); uid = g_strndup(search_start+1, tmp-search_start-2); /* purple_debug_misc("facebook", "uid: %s\n", uid); */ search_start += strlen(uid) + 2; search_tmp = strstr(search_start, "\"name\":") + 8; if (search_tmp > largest_buddy_search_point) largest_buddy_search_point = search_tmp; search_tmp = g_strndup(search_tmp, strchr(search_tmp, '"')-search_tmp); name = fb_convert_unicode(search_tmp); g_free(search_tmp); /* purple_debug_misc("facebook", "name: %s\n", name); */ /* try updating the alias, just in case it was removed locally */ serv_got_alias(fba->pc, uid, name); /* look for "uid":{"i":_____} */ tmp = g_strdup_printf("\"%s\":{\"i\":", uid); search_tmp = g_strstr_len(data, data_len, tmp); if (search_tmp != NULL) { search_tmp += strlen(tmp); if (search_tmp > largest_buddy_search_point) largest_buddy_search_point = search_tmp; search_tmp = g_strndup(search_tmp, strchr(search_tmp, '}')-search_tmp); /* purple_debug_misc("facebook", "buddy idle: %s\n", search_tmp); */ buddy = purple_find_buddy(fba->account, uid); idle = g_str_equal(search_tmp, "true"); g_free(search_tmp); current_buddy_online = TRUE; } else { /* if we're here, the buddy's info has been sent, but they're not actually online */ current_buddy_online = FALSE; idle = FALSE; } g_free(tmp); /* Set the buddy status text and time */ search_tmp = strstr(search_start, "\"status\":"); if (search_tmp != NULL && *(search_tmp + 9) == '"') { search_tmp += 10; if (search_tmp > largest_buddy_search_point) largest_buddy_search_point = strstr(search_tmp, ",\"statusTime"); search_tmp = g_strndup(search_tmp, strstr(search_tmp, ",\"statusTime")-1-search_tmp); status_text = fb_convert_unicode(search_tmp); g_free(search_tmp); } else { status_text = NULL; } /* is this us? */ if (atoi(uid) == fba->uid) { purple_connection_set_display_name(fba->pc, name); /* set our last known status so that we don't re-set it */ if (status_text && !fba->last_status_message) fba->last_status_message = g_strdup(status_text); /* check that we don't want to show ourselves */ if (purple_account_get_bool(fba->account, "facebook_hide_self", TRUE)) { g_free(status_text); g_free(name); g_free(uid); /* Move pointer to the end of the buddy entry */ search_start = strchr(largest_buddy_search_point, '}') + 1; while (*search_start == ',' && (search_start - data < data_len)) search_start++; /* go on to the next buddy */ continue; } else { current_buddy_online = TRUE; } } /* Is this a new buddy? */ buddy = purple_find_buddy(fba->account, uid); if (buddy == NULL) { buddy = purple_buddy_new(fba->account, uid, NULL); if (fb_group == NULL) { fb_group = purple_group_new("Facebook"); purple_blist_add_group(fb_group, NULL); } purple_blist_add_buddy(buddy, NULL, fb_group, NULL); } serv_got_alias(fba->pc, uid, name); purple_presence_set_idle(purple_buddy_get_presence(buddy), idle, 0); /* Set the FacebookBuddy structure */ if (buddy->proto_data == NULL) { fbuddy = g_new0(FacebookBuddy, 1); fbuddy->buddy = buddy; fbuddy->fba = fba; fbuddy->uid = atoi(uid); fbuddy->name = g_strdup(name); /* load the old buddy icon from the account settings */ tmp = g_strdup_printf("buddy_icon_%d_cache", fbuddy->uid); fbuddy->thumb_url = g_strdup(purple_account_get_string(fba->account, tmp, "")); g_free(tmp); buddy->proto_data = fbuddy; } else { fbuddy = buddy->proto_data; } g_free(uid); g_free(name); if (status_text != NULL) { tmp = fb_strdup_withhtml(status_text); g_free(status_text); status_text = tmp; /* purple_debug_misc("facebook", "status: %s\n", status_text); */ search_tmp = strstr(search_start, "\"statusTimeRel\":") + 17; if (search_tmp > largest_buddy_search_point) largest_buddy_search_point = strchr(search_tmp, '"'); search_tmp = g_strndup(search_tmp, strchr(search_tmp, '"')-search_tmp); status_time_text = fb_convert_unicode(search_tmp); g_free(search_tmp); if (g_str_equal(status_time_text, "ull,")) { g_free(status_time_text); status_time_text = NULL; } g_free(fbuddy->status_rel_time); if (status_time_text != NULL) { fbuddy->status_rel_time = fb_strdup_withhtml(status_time_text); g_free(status_time_text); /* purple_debug_misc("facebook", "status time: %s\n", fbuddy->status_rel_time); */ } else { fbuddy->status_rel_time = NULL; } /* if the buddy status has changed, update the contact list */ if (fbuddy->status == NULL || !g_str_equal(fbuddy->status, status_text)) { tmp = fbuddy->status; fbuddy->status = status_text; g_free(tmp); if (current_buddy_online) purple_prpl_got_user_status(fba->account, buddy->name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL); } else { g_free(status_text); } } else { if (fbuddy->status != NULL) { g_free(fbuddy->status); fbuddy->status = NULL; if (current_buddy_online) { /* update the status in the contact list */ purple_prpl_got_user_status(fba->account, buddy->name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL); } } } /* Set the buddy icon (if it hasn't changed) */ search_tmp = strstr(search_start, "\"thumbSrc\":") + 12; if (search_tmp > largest_buddy_search_point) largest_buddy_search_point = search_tmp; buddy_icon_url = g_strndup(search_tmp, strchr(search_tmp, '"')-search_tmp); if (fbuddy->thumb_url == NULL || !g_str_equal(fbuddy->thumb_url, buddy_icon_url)) { g_free(fbuddy->thumb_url); fbuddy->thumb_url = g_strdup(buddy_icon_url); /* Save the buddy icon so that they don't all need to be reloaded at startup */ tmp = g_strdup_printf("buddy_icon_%d_cache", fbuddy->uid); purple_account_set_string(fba->account, tmp, buddy_icon_url); g_free(tmp); /* Turn the \/ into / */ tmp = g_strcompress(buddy_icon_url); /* small icon at http://profile.ak.facebook.com/profile6/1845/74/q800753867_2878.jpg */ /* bigger icon at http://profile.ak.facebook.com/profile6/1845/74/n800753867_2878.jpg */ search_tmp = strstr(tmp, "/q"); if (search_tmp) *(search_tmp + 1) = 'n'; if (g_str_equal(tmp, "http://static.ak.fbcdn.net/pics/q_silhouette.gif")) /* User has no icon */ purple_buddy_icons_set_for_user(fba->account, purple_buddy_get_name(buddy), NULL, 0, NULL); else /* Fetch their icon */ fb_post_or_get(fba, FB_METHOD_GET, "profile.ak.facebook.com", tmp + strlen("http://profile.ak.facebook.com"), NULL, buddy_icon_cb, g_strdup(purple_buddy_get_name(buddy)), FALSE); g_free(tmp); } g_free(buddy_icon_url); if (current_buddy_online) { /* Add buddy to the list of online buddies */ online_buddies_list = g_slist_append(online_buddies_list, buddy); /* Update the display of the buddy in the buddy list and make the user online */ if (!PURPLE_BUDDY_IS_ONLINE(buddy)) purple_prpl_got_user_status(fba->account, buddy->name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL); } /* Move pointer after any user configurable data */ search_start = search_tmp; /* Move pointer to the end of the buddy entry */ search_start = strchr(largest_buddy_search_point, '}') + 1; while (*search_start == ',' && (search_start - data < data_len)) search_start++; } buddies_list = purple_find_buddies(fba->account, NULL); if (buddies_list != NULL) { g_slist_foreach(buddies_list, (GFunc)set_buddies_offline, online_buddies_list); g_slist_free(buddies_list); } g_slist_free(online_buddies_list); }
/** * If the buddy does not yet exist, then create it and add it to * our buddy list. In either case we set the correct status for * the buddy. */ void bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy) { PurpleBuddy *buddy; PurpleGroup *group; PurpleAccount *account = bonjour_buddy->account; const char *status_id, *old_hash, *new_hash; /* Translate between the Bonjour status and the Purple status */ if (bonjour_buddy->status != NULL && g_ascii_strcasecmp("dnd", bonjour_buddy->status) == 0) status_id = BONJOUR_STATUS_ID_AWAY; else status_id = BONJOUR_STATUS_ID_AVAILABLE; /* * TODO: Figure out the idle time by getting the "away" * field from the DNS SD. */ /* Make sure the Bonjour group exists in our buddy list */ group = purple_find_group(BONJOUR_GROUP_NAME); /* Use the buddy's domain, instead? */ if (group == NULL) { group = purple_group_new(BONJOUR_GROUP_NAME); purple_blist_add_group(group, NULL); } /* Make sure the buddy exists in our buddy list */ buddy = purple_find_buddy(account, bonjour_buddy->name); if (buddy == NULL) { buddy = purple_buddy_new(account, bonjour_buddy->name, NULL); buddy->proto_data = bonjour_buddy; purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE); purple_blist_add_buddy(buddy, NULL, group, NULL); } /* Create the alias for the buddy using the first and the last name */ if (bonjour_buddy->nick) serv_got_alias(purple_account_get_connection(account), buddy->name, bonjour_buddy->nick); else { gchar *alias = NULL; const char *first, *last; first = bonjour_buddy->first; last = bonjour_buddy->last; if ((first && *first) || (last && *last)) alias = g_strdup_printf("%s%s%s", (first && *first ? first : ""), (first && *first && last && *last ? " " : ""), (last && *last ? last : "")); serv_got_alias(purple_account_get_connection(account), buddy->name, alias); g_free(alias); } /* Set the user's status */ if (bonjour_buddy->msg != NULL) purple_prpl_got_user_status(account, buddy->name, status_id, "message", bonjour_buddy->msg, NULL); else purple_prpl_got_user_status(account, buddy->name, status_id, NULL); purple_prpl_got_user_idle(account, buddy->name, FALSE, 0); /* TODO: Because we don't save Bonjour buddies in blist.xml, * we will always have to look up the buddy icon at login time. * I think we should figure out a way to do something about this. */ /* Deal with the buddy icon */ old_hash = purple_buddy_icons_get_checksum_for_user(buddy); new_hash = (bonjour_buddy->phsh && *(bonjour_buddy->phsh)) ? bonjour_buddy->phsh : NULL; if (new_hash && (!old_hash || strcmp(old_hash, new_hash) != 0)) { /* Look up the new icon data */ /* TODO: Make sure the hash assigned to the retrieved buddy icon is the same * as what we looked up. */ bonjour_dns_sd_retrieve_buddy_icon(bonjour_buddy); } else if (!new_hash) purple_buddy_icons_set_for_user(account, buddy->name, NULL, 0, NULL); }
static void waprpl_process_incoming_events(PurpleConnection *gc) { whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); PurpleAccount * acc = purple_connection_get_account(gc); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending auth", 1, 4); break; case 2: purple_connection_update_progress(gc, "Waiting response", 2, 4); break; case 3: purple_connection_update_progress(gc, "Connected", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); if (!wconn->connected) waprpl_insert_contacts(gc); wconn->connected = 1; break; default: break; }; char * msg, * who, * prev, * url, *author; int status; int size; double lat,lng; // Incoming messages while (waAPI_querychat(wconn->waAPI, &who, &msg, &author)) { purple_debug_info(WHATSAPP_ID, "Got chat message from %s: %s\n", who,msg); if (isgroup(who)) { // Search fot the combo PurpleBlistNode* node = purple_blist_get_root(); GHashTable* hasht = NULL; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { hasht = purple_chat_get_components(ch); if (strcmp(g_hash_table_lookup(hasht, "id"),who) == 0) { break; } } } node = purple_blist_node_next(node,FALSE); } int convo_id = chatid_to_convo(who); PurpleConversation *convo = purple_find_chat(gc, convo_id); // Create a window if it's not open yet if (!convo) waprpl_chat_join(gc,hasht); if (convo != NULL) { serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), author, PURPLE_MESSAGE_RECV, msg, time(NULL)); }else{ printf("Received group message but could not find the group! %s\n",msg); } }else{ // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, msg, PURPLE_MESSAGE_RECV, time(NULL)); } } while (waAPI_querychatimage(wconn->waAPI, &who, &prev, &size, &url)) { printf("Got chat image %s %s\n",who,url); purple_debug_info(WHATSAPP_ID, "Got image from %s: %s\n", who,url); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"%s\"><img id=\"%u\"></a>",url,imgid), PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, time(NULL)); } while (waAPI_querychatlocation(wconn->waAPI, &who, &prev, &size, &lat, &lng)) { purple_debug_info(WHATSAPP_ID, "Got geomessage from: %s Coordinates (%f %f)\n", who,(float)lat,(float)lng); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"http://openstreetmap.org/?lat=%f&lon=%f&zoom=16\"><img src=\"%u\"></a>",lat,lng,imgid), PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, time(NULL)); } while (waAPI_querychatsound(wconn->waAPI, &who, &url)) { purple_debug_info(WHATSAPP_ID, "Got chat sound from %s: %s\n", who,url); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"%s\">%s</a>",url,url), PURPLE_MESSAGE_RECV , time(NULL)); } // User status change while (waAPI_querystatus(wconn->waAPI, &who, &status)) { if (status == 1) { purple_prpl_got_user_status(acc, who, "available", "message","", NULL); } else { purple_prpl_got_user_status(acc, who, "unavailable", "message","", NULL); } } // User typing info notify while (waAPI_querytyping(wconn->waAPI, &who, &status)) { if (status == 1) { serv_got_typing(gc,who,0,PURPLE_TYPING); } else { serv_got_typing_stopped(gc,who); } } // User profile picture char * icon, * hash; int len; while (waAPI_queryicon(wconn->waAPI, &who, &icon, &len, &hash)) { purple_buddy_icons_set_for_user(acc,who, g_memdup(icon,len),len, hash); } // Groups update if (waAPI_getgroupsupdated(wconn->waAPI)) { // Delete/update the chats that are in our list PurpleBlistNode* node = purple_blist_get_root(); while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { int found = 0; GHashTable *hasht = purple_chat_get_components(ch); char * grid = g_hash_table_lookup(hasht, "id"); char * glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist,",",0); while (*gplist) { if (strcmp(*gplist,grid) == 0) { // The group is in the system, update the fields char *id,*sub,*own; waAPI_getgroupinfo(wconn->waAPI, *gplist, &sub, &own, 0); g_hash_table_insert(hasht, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(hasht, g_strdup("owner"), g_strdup(own)); found = 1; break; } gplist++; } // The group was deleted if (!found) { PurpleBlistNode* del = node; node = purple_blist_node_next(node,FALSE); purple_blist_remove_chat(del); } } } node = purple_blist_node_next(node,FALSE); } // Add new groups char * glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist,",",0); while (*gplist) { int found = 0; PurpleBlistNode* node = purple_blist_get_root(); PurpleChat * ch; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { char * grid = g_hash_table_lookup(purple_chat_get_components(ch), "id"); if (strcmp(*gplist,grid) == 0) { found = 1; break; } } } node = purple_blist_node_next(node,FALSE); } if (!found) { char *sub,*own; waAPI_getgroupinfo(wconn->waAPI, *gplist, &sub, &own, 0); purple_debug_info("waprpl", "New group found %s %s\n", *gplist,sub); GHashTable * htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(htable, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(htable, g_strdup("id"), g_strdup(*gplist)); g_hash_table_insert(htable, g_strdup("owner"), g_strdup(own)); ch = purple_chat_new(acc,sub,htable); purple_blist_add_chat(ch,NULL,NULL); } // Now update the open conversation that may exist char * id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation * conv = purple_find_chat(gc, prplid); if (conv) { char *subject, *owner, *part; if (!waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) return; purple_conv_chat_clear_users(purple_conversation_get_chat_data(conv)); gchar **plist = g_strsplit(part,",",0); while (*plist) { purple_conv_chat_add_user (purple_conversation_get_chat_data(conv), *plist,"",PURPLE_CBFLAGS_NONE | (!strcmp(owner,*plist) ? PURPLE_CBFLAGS_FOUNDER : 0),FALSE); plist++; } } gplist++; } } }