Пример #1
0
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);
}
Пример #2
0
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);
  }
}
Пример #3
0
//
// 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
	);
}
Пример #4
0
/**
 * 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 */
}
Пример #5
0
/**
 * 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);
}
Пример #6
0
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);
}
Пример #7
0
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);
		}
	}
}
Пример #8
0
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);
}
Пример #9
0
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);
	}
}
Пример #10
0
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;
        }
    }
}
Пример #11
0
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--;
}
Пример #12
0
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);
}
Пример #13
0
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);
}
Пример #14
0
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);
}
Пример #15
0
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);
}
Пример #16
0
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);
}
Пример #17
0
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);
    }

}
Пример #18
0
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);
}
Пример #19
0
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);
}
Пример #20
0
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);
}
Пример #21
0
/**
 * 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);
    }
}
Пример #22
0
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);
}
Пример #23
0
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);

	}

}
Пример #24
0
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, &timestamp)) {
			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, &timestamp)) {
			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, &timestamp)) {
			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, &timestamp)) {
			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);
	}
}
Пример #25
0
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);
}
Пример #26
0
/**
 * 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);
}
Пример #27
0
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++;
    }
  }
}