예제 #1
0
PurpleStoredImage *
purple_buddy_icons_set_account_icon(PurpleAccount *account,
                                    guchar *icon_data, size_t icon_len)
{
	PurpleStoredImage *old_img;
	PurpleStoredImage *img = NULL;
	char *old_icon;

	if (icon_data != NULL && icon_len > 0)
	{
		img = purple_buddy_icon_data_new(icon_data, icon_len, NULL);
	}

	old_icon = g_strdup(purple_account_get_string(account, "buddy_icon", NULL));
	if (img && purple_buddy_icons_is_caching())
	{
		const char *filename = purple_imgstore_get_filename(img);
		purple_account_set_string(account, "buddy_icon", filename);
		purple_account_set_int(account, "buddy_icon_timestamp", time(NULL));
		ref_filename(filename);
	}
	else
	{
		purple_account_set_string(account, "buddy_icon", NULL);
		purple_account_set_int(account, "buddy_icon_timestamp", 0);
	}
	unref_filename(old_icon);

	old_img = g_hash_table_lookup(pointer_icon_cache, account);

	if (img)
		g_hash_table_insert(pointer_icon_cache, account, img);
	else
		g_hash_table_remove(pointer_icon_cache, account);

	if (purple_account_is_connected(account))
	{
		PurpleConnection *gc;
		PurplePluginProtocolInfo *prpl_info;

		gc = purple_account_get_connection(account);
		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));

		if (prpl_info && prpl_info->set_buddy_icon)
			prpl_info->set_buddy_icon(gc, img);
	}

	if (old_img)
		purple_imgstore_unref(old_img);
	else if (old_icon)
	{
		/* The old icon may not have been loaded into memory.  In that
		 * case, we'll need to uncache the filename.  The filenames
		 * are ref-counted, so this is safe. */
		purple_buddy_icon_data_uncache_file(old_icon);
	}
	g_free(old_icon);

	return img;
}
예제 #2
0
static void
purple_buddy_icon_data_cache(PurpleStoredImage *img)
{
	const char *dirname;
	char *path;

	g_return_if_fail(img != NULL);

	if (!purple_buddy_icons_is_caching())
		return;

	dirname  = purple_buddy_icons_get_cache_dir();
	path = g_build_filename(dirname, purple_imgstore_get_filename(img), NULL);

	if (!g_file_test(dirname, G_FILE_TEST_IS_DIR))
	{
		purple_debug_info("buddyicon", "Creating icon cache directory.\n");

		if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0)
		{
			purple_debug_error("buddyicon",
			                   "Unable to create directory %s: %s\n",
			                   dirname, g_strerror(errno));
		}
	}

	purple_util_write_data_to_file_absolute(path, purple_imgstore_get_data(img),
											purple_imgstore_get_size(img));
	g_free(path);
}
예제 #3
0
char *purple_smiley_get_full_path(PurpleSmiley *smiley)
{
	g_return_val_if_fail(smiley != NULL, NULL);

	if (smiley->img == NULL)
		return NULL;

	return get_file_full_path(purple_imgstore_get_filename(smiley->img));
}
예제 #4
0
파일: smiley.c 프로젝트: Distrotech/pidgin
char *purple_smiley_get_full_path(PurpleSmiley *smiley)
{
	PurpleSmileyPrivate *priv = NULL;

	g_return_val_if_fail(smiley != NULL, NULL);

	priv = PURPLE_SMILEY_GET_PRIVATE(smiley);

	if (priv->img == NULL)
		return NULL;

	return get_file_full_path(purple_imgstore_get_filename(priv->img));
}
예제 #5
0
static void
purple_smiley_data_store(PurpleStoredImage *stored_img)
{
	const char *dirname;
	char *path;
	FILE *file = NULL;

	g_return_if_fail(stored_img != NULL);

	if (!smileys_loaded)
		return;

	dirname  = purple_smileys_get_storing_dir();
	path = g_build_filename(dirname, purple_imgstore_get_filename(stored_img), NULL);

	if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) {
		purple_debug_info(SMILEYS_LOG_ID, "Creating smileys directory.\n");

		if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) {
			purple_debug_error(SMILEYS_LOG_ID,
			                   "Unable to create directory %s: %s\n",
			                   dirname, g_strerror(errno));
		}
	}

	if ((file = g_fopen(path, "wb")) != NULL) {
		if (!fwrite(purple_imgstore_get_data(stored_img),
				purple_imgstore_get_size(stored_img), 1, file)) {
			purple_debug_error(SMILEYS_LOG_ID, "Error writing %s: %s\n",
			                   path, g_strerror(errno));
		} else {
			purple_debug_info(SMILEYS_LOG_ID, "Wrote cache file: %s\n", path);
		}

		fclose(file);
	} else {
		purple_debug_error(SMILEYS_LOG_ID, "Unable to create file %s: %s\n",
		                   path, g_strerror(errno));
		g_free(path);

		return;
	}

	g_free(path);
}
예제 #6
0
char *purple_buddy_icon_get_full_path(PurpleBuddyIcon *icon)
{
	char *path;

	g_return_val_if_fail(icon != NULL, NULL);

	if (icon->img == NULL)
		return NULL;

	path = g_build_filename(purple_buddy_icons_get_cache_dir(),
	                        purple_imgstore_get_filename(icon->img), NULL);
	if (!g_file_test(path, G_FILE_TEST_EXISTS))
	{
		g_free(path);
		return NULL;
	}
	return path;
}
예제 #7
0
static void
image_deleting_cb(const PurpleStoredImage *img, gpointer data)
{
	const char *filename = purple_imgstore_get_filename(img);

	/* If there's no filename, it can't be one of our images. */
	if (filename == NULL)
		return;

	if (img == g_hash_table_lookup(icon_data_cache, filename))
	{
		purple_buddy_icon_data_uncache_file(filename);
		g_hash_table_remove(icon_data_cache, filename);

		/* We could make this O(1) by using another hash table, but
		 * this is probably good enough. */
		g_hash_table_foreach_remove(pointer_icon_cache, value_equals, (gpointer)img);
	}
}
예제 #8
0
void bonjour_dns_sd_update_buddy_icon(BonjourDnsSd *data) {
	PurpleStoredImage *img;

	if ((img = purple_buddy_icons_find_account_icon(data->account))) {
		gconstpointer avatar_data;
		gsize avatar_len;

		avatar_data = purple_imgstore_get_data(img);
		avatar_len = purple_imgstore_get_size(img);

		if (_mdns_set_buddy_icon_data(data, avatar_data, avatar_len)) {
			/* The filename is a SHA-1 hash of the data (conveniently what we need) */
			const char *p, *filename = purple_imgstore_get_filename(img);

			g_free(data->phsh);
			data->phsh = NULL;

			/* Get rid of the extension */
			p = strchr(filename, '.');
			if (p)
				data->phsh = g_strndup(filename, p - filename);
			else
				purple_debug_error("bonjour", "account buddy icon returned unexpected filename (%s)"
								"; unable to extract hash. Clearing buddy icon\n", filename);

			/* Update our TXT record */
			publish_presence(data, PUBLISH_UPDATE);
		}

		purple_imgstore_unref(img);
	} else {
		/* We need to do this regardless of whether data->phsh is set so that we
		 * cancel any icons that are currently in the process of being set */
		_mdns_set_buddy_icon_data(data, NULL, 0);
		if (data->phsh != NULL) {
			/* Clear the buddy icon */
			g_free(data->phsh);
			data->phsh = NULL;
			/* Update our TXT record */
			publish_presence(data, PUBLISH_UPDATE);
		}
	}
}
예제 #9
0
static void
purple_smiley_finalize(GObject *obj)
{
	PurpleSmiley *smiley = PURPLE_SMILEY(obj);

	if (g_hash_table_lookup(smiley_shortcut_index, smiley->shortcut)) {
		g_hash_table_remove(smiley_shortcut_index, smiley->shortcut);
		g_hash_table_remove(smiley_checksum_index, smiley->checksum);
	}

	g_free(smiley->shortcut);
	g_free(smiley->checksum);
	if (smiley->img)
		purple_smiley_data_unstore(purple_imgstore_get_filename(smiley->img));
	purple_imgstore_unref(smiley->img);

	PURPLE_DBUS_UNREGISTER_POINTER(smiley);

	purple_smileys_save();
}
예제 #10
0
static xmlnode *
smiley_to_xmlnode(PurpleSmiley *smiley)
{
	xmlnode *smiley_node = NULL;

	smiley_node = xmlnode_new(XML_SMILEY_TAG);

	if (!smiley_node)
		return NULL;

	xmlnode_set_attrib(smiley_node, XML_SHORTCUT_ATTRIB_TAG,
			smiley->shortcut);

	xmlnode_set_attrib(smiley_node, XML_CHECKSUM_ATRIB_TAG,
			smiley->checksum);

	xmlnode_set_attrib(smiley_node, XML_FILENAME_ATRIB_TAG,
			purple_imgstore_get_filename(smiley->img));

	return smiley_node;
}
예제 #11
0
파일: smiley.c 프로젝트: Distrotech/pidgin
static PurpleXmlNode *
smiley_to_xmlnode(PurpleSmiley *smiley)
{
	PurpleSmileyPrivate *priv = NULL;
	PurpleXmlNode *smiley_node = NULL;

	smiley_node = purple_xmlnode_new(XML_SMILEY_TAG);

	if (!smiley_node)
		return NULL;

	priv = PURPLE_SMILEY_GET_PRIVATE(smiley);

	purple_xmlnode_set_attrib(smiley_node, XML_SHORTCUT_ATTRIB_TAG,
			priv->shortcut);

	purple_xmlnode_set_attrib(smiley_node, XML_CHECKSUM_ATRIB_TAG,
			priv->checksum);

	purple_xmlnode_set_attrib(smiley_node, XML_FILENAME_ATRIB_TAG,
			purple_imgstore_get_filename(priv->img));

	return smiley_node;
}
예제 #12
0
int tgp_msg_send (struct tgl_state *TLS, const char *message, tgl_peer_id_t to) {
  // search for outgoing embedded image tags and send them
  gchar *img = NULL;
  gchar *stripped = NULL;
  if ((img = g_strrstr (message, "<IMG")) || (img = g_strrstr (message, "<img"))) {
    if (tgl_get_peer_type(to) == TGL_PEER_ENCR_CHAT) {
      tgp_msg_err_out (TLS, "Sorry, sending documents to encrypted chats not yet supported.", to);
      return 0;
    }
    
    debug ("img found: %s", img);
    gchar *id;
    if ((id = g_strrstr (img, "ID=\"")) || (id = g_strrstr (img, "id=\""))) {
      id += 4;
      debug ("id found: %s", id);
      int imgid = atoi (id);
      if (imgid > 0) {
        PurpleStoredImage *psi = purple_imgstore_find_by_id (imgid);
        gchar *tmp = g_build_filename(g_get_tmp_dir(), purple_imgstore_get_filename (psi), NULL) ;
        GError *err = NULL;
        gconstpointer data = purple_imgstore_get_data (psi);
        g_file_set_contents (tmp, data, purple_imgstore_get_size (psi), &err);
        if (! err) {
          stripped = purple_markup_strip_html (message);
          tgl_do_send_document (TLS, to, tmp, stripped, (int)strlen (stripped), TGL_SEND_MSG_FLAG_DOCUMENT_AUTO, tgp_msg_send_done, NULL);
          g_free (stripped);
          return 1;
        } else {
          failure ("Cannot store image, temp directory not available: %s\n", err->message);
          g_error_free (err);
          return 0;
        }
      }
    }
    // no image id found in image
    return 0;
  }
  
#ifndef __ADIUM_
  /*
    Adium won't escape any HTML markup and just pass any user-input through,
    while Pidgin will replace special chars with the escape chars and also add 
    additional markup for RTL languages and such.

    First, we remove any HTML markup added by Pidgin, since Telegram won't handle it properly.
    User-entered HTML is still escaped and therefore won't be harmed.
   */
  stripped = purple_markup_strip_html (message);
  
  /* 
    now unescape the markup, so that html special chars will still show
    up properly in Telegram
   */
  gchar *unescaped = purple_unescape_text (stripped);
  int ret = tgp_msg_send_split (TLS, stripped, to);
  
  g_free (unescaped);
  g_free (stripped);
  return ret;
#endif
  
  return tgp_msg_send_split (TLS, message, to);
}
예제 #13
0
파일: util.c 프로젝트: Draghtnod/pidgin
SilcDList silcpurple_image_message(const char *msg, SilcMessageFlags *mflags)
{
	SilcMime mime = NULL, p;
	SilcDList list, parts = NULL;
	const char *start, *end, *last;
	GData *attribs;
	char *type;
	gboolean images = FALSE;

	last = msg;
	while (last && *last && purple_markup_find_tag("img", last, &start,
						     &end, &attribs)) {
		PurpleStoredImage *image = NULL;
		const char *id;

		/* Check if there is text before image */
		if (start - last) {
			char *text, *tmp;
			p = silc_mime_alloc();

			/* Add content type */
			silc_mime_add_field(p, "Content-Type",
					    "text/plain; charset=utf-8");

			tmp = g_strndup(last, start - last);
			text = purple_unescape_html(tmp);
			g_free(tmp);

			/* Add text */
			silc_mime_add_data(p, (const unsigned char *)text, strlen(text));
			g_free(text);

			if (!parts)
				parts = silc_dlist_init();
			silc_dlist_add(parts, p);
		}

		id = g_datalist_get_data(&attribs, "id");
		if (id && (image = purple_imgstore_find_by_id(atoi(id)))) {
			unsigned long imglen = purple_imgstore_get_size(image);
			gconstpointer img = purple_imgstore_get_data(image);

			p = silc_mime_alloc();

			/* Add content type */
			type = silcpurple_file2mime(purple_imgstore_get_filename(image));
			if (!type) {
				g_datalist_clear(&attribs);
				last = end + 1;
				continue;
			}
			silc_mime_add_field(p, "Content-Type", type);
			g_free(type);

			/* Add content transfer encoding */
			silc_mime_add_field(p, "Content-Transfer-Encoding", "binary");

			/* Add image data */
			silc_mime_add_data(p, img, imglen);

			if (!parts)
				parts = silc_dlist_init();
			silc_dlist_add(parts, p);
			images = TRUE;
		}

		g_datalist_clear(&attribs);

		/* Continue after tag */
		last = end + 1;
	}

	/* Check for text after the image(s) */
	if (images && last && *last) {
		char *tmp = purple_unescape_html(last);
		p = silc_mime_alloc();

		/* Add content type */
		silc_mime_add_field(p, "Content-Type",
				    "text/plain; charset=utf-8");

		/* Add text */
		silc_mime_add_data(p, (const unsigned char *)tmp, strlen(tmp));
		g_free(tmp);

		if (!parts)
			parts = silc_dlist_init();
		silc_dlist_add(parts, p);
	}

	/* If there weren't any images, don't return anything. */
	if (!images) {
		if (parts)
			silc_dlist_uninit(parts);
		return NULL;
	}

	if (silc_dlist_count(parts) > 1) {
		/* Multipart MIME message */
		char b[32];
		mime = silc_mime_alloc();
		silc_mime_add_field(mime, "MIME-Version", "1.0");
		g_snprintf(b, sizeof(b), "b%4X%4X",
			   (unsigned int)time(NULL),
			   silc_dlist_count(parts));
		silc_mime_set_multipart(mime, "mixed", b);
		silc_dlist_start(parts);
		while ((p = silc_dlist_get(parts)) != SILC_LIST_END)
			silc_mime_add_multipart(mime, p);
	} else {
		/* Simple MIME message */
		silc_dlist_start(parts);
		mime = silc_dlist_get(parts);
		silc_mime_add_field(mime, "MIME-Version", "1.0");
	}

	*mflags &= ~SILC_MESSAGE_FLAG_UTF8;
	*mflags |= SILC_MESSAGE_FLAG_DATA;

	/* Encode message. Fragment if it is too large */
	list = silc_mime_encode_partial(mime, 0xfc00);

	silc_dlist_uninit(parts);

	/* Added multiparts gets freed here */
	silc_mime_free(mime);

	return list;
}
예제 #14
0
PurpleStoredImage *
purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node,
                                        guchar *icon_data, size_t icon_len)
{
	char *old_icon;
	PurpleStoredImage *old_img;
	PurpleStoredImage *img = NULL;

	g_return_val_if_fail(node != NULL, NULL);

	if (!PURPLE_BLIST_NODE_IS_CONTACT(node) &&
	    !PURPLE_BLIST_NODE_IS_CHAT(node) &&
	    !PURPLE_BLIST_NODE_IS_GROUP(node)) {
		return NULL;
	}

	old_img = g_hash_table_lookup(pointer_icon_cache, node);

	if (icon_data != NULL && icon_len > 0) {
		img = purple_buddy_icon_data_new(icon_data, icon_len, NULL);
	}

	old_icon = g_strdup(purple_blist_node_get_string(node,
	                                                 "custom_buddy_icon"));
	if (img && purple_buddy_icons_is_caching()) {
		const char *filename = purple_imgstore_get_filename(img);
		purple_blist_node_set_string(node, "custom_buddy_icon",
		                             filename);
		ref_filename(filename);
	} else {
		purple_blist_node_remove_setting(node, "custom_buddy_icon");
	}
	unref_filename(old_icon);

	if (img)
		g_hash_table_insert(pointer_icon_cache, node, img);
	else
		g_hash_table_remove(pointer_icon_cache, node);

	if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
		PurpleBlistNode *child;
		for (child = purple_blist_node_get_first_child(node);
		     child;
			 child = purple_blist_node_get_sibling_next(child))
		{
			PurpleBuddy *buddy;
			PurpleConversation *conv;

			if (!PURPLE_BLIST_NODE_IS_BUDDY(child))
				continue;

			buddy = (PurpleBuddy *)child;

			conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
			if (conv)
				purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON);

			/* Is this call necessary anymore? Can the buddies
			 * themselves need updating when the custom buddy
			 * icon changes? */
			purple_blist_update_node_icon((PurpleBlistNode*)buddy);
		}
	} else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
		PurpleConversation *conv = NULL;

		conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, purple_chat_get_name((PurpleChat*)node), purple_chat_get_account((PurpleChat*)node));
		if (conv) {
			purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON);
		}
	}

	purple_blist_update_node_icon(node);

	if (old_img) {
		purple_imgstore_unref(old_img);
	} else if (old_icon) {
		/* The old icon may not have been loaded into memory.  In that
		 * case, we'll need to uncache the filename.  The filenames
		 * are ref-counted, so this is safe. */
		purple_buddy_icon_data_uncache_file(old_icon);
	}
	g_free(old_icon);

	return img;
}
예제 #15
0
void
purple_buddy_icon_update(PurpleBuddyIcon *icon)
{
	PurpleConversation *conv;
	PurpleAccount *account;
	const char *username;
	PurpleBuddyIcon *icon_to_set;
	GSList *buddies;

	g_return_if_fail(icon != NULL);

	account  = purple_buddy_icon_get_account(icon);
	username = purple_buddy_icon_get_username(icon);

	/* If no data exists (icon->img == NULL), then call the functions below
	 * with NULL to unset the icon.  They will then unref the icon and it should
	 * be destroyed.  The only way it wouldn't be destroyed is if someone
	 * else is holding a reference to it, in which case they can kill
	 * the icon when they realize it has no data. */
	icon_to_set = icon->img ? icon : NULL;

	/* Ensure that icon remains valid throughout */
	purple_buddy_icon_ref(icon);

	buddies = purple_find_buddies(account, username);
	while (buddies != NULL)
	{
		PurpleBuddy *buddy = (PurpleBuddy *)buddies->data;
		char *old_icon;

		purple_buddy_set_icon(buddy, icon_to_set);
		old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)buddy,
		                                                 "buddy_icon"));
		if (icon->img && purple_buddy_icons_is_caching())
		{
			const char *filename = purple_imgstore_get_filename(icon->img);
			purple_blist_node_set_string((PurpleBlistNode *)buddy,
			                             "buddy_icon",
			                             filename);

			if (icon->checksum && *icon->checksum)
			{
				purple_blist_node_set_string((PurpleBlistNode *)buddy,
				                             "icon_checksum",
				                             icon->checksum);
			}
			else
			{
				purple_blist_node_remove_setting((PurpleBlistNode *)buddy,
				                                 "icon_checksum");
			}
			ref_filename(filename);
		}
		else if (!icon->img)
		{
			purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "buddy_icon");
			purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "icon_checksum");
		}
		unref_filename(old_icon);
		g_free(old_icon);

		buddies = g_slist_delete_link(buddies, buddies);
	}

	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, username, account);

	if (conv != NULL)
		purple_conv_im_set_icon(PURPLE_CONV_IM(conv), icon_to_set);

	/* icon's refcount was incremented above */
	purple_buddy_icon_unref(icon);
}
예제 #16
0
static void nullprpl_set_buddy_icon(PurpleConnection *gc,
                                    PurpleStoredImage *img) {
 purple_debug_info("nullprpl", "setting %s's buddy icon to %s\n",
                   purple_account_get_username(purple_connection_get_account(gc)),
                   img ? purple_imgstore_get_filename(img) : "(null)");
}