Ejemplo n.º 1
0
/* char *ggp_buddylist_dump(PurpleAccount *account) {{{ */
char *ggp_buddylist_dump(PurpleAccount *account)
{
	GSList *buddies;
	GString *buddylist = g_string_sized_new(1024);
	char *ptr;

	for (buddies = purple_blist_find_buddies(account, NULL); buddies;
		buddies = g_slist_delete_link(buddies, buddies))
	{
		PurpleBuddy *buddy = buddies->data;
		PurpleGroup *group = purple_buddy_get_group(buddy);
		const char *bname = purple_buddy_get_name(buddy);
		const char *gname = purple_group_get_name(group);
		const char *alias = purple_buddy_get_alias(buddy);

		if (alias == NULL)
			alias = bname;

		g_string_append_printf(buddylist,
				"%s;%s;%s;%s;%s;%s;%s;%s%s\r\n",
				alias, alias, alias, alias,
				"", gname, bname, "", "");
	}

	ptr = ggp_convert_to_cp1250(buddylist->str);
	g_string_free(buddylist, TRUE);
	return ptr;
}
Ejemplo n.º 2
0
static void
msn_session_sync_users(MsnSession *session)
{
	PurpleConnection *gc = purple_account_get_connection(session->account);
	GList *to_remove = NULL;
	GSList *buddies;

	g_return_if_fail(gc != NULL);

	/* The core used to use msn_add_buddy to add all buddies before
	 * being logged in. This no longer happens, so we manually iterate
	 * over the whole buddy list to identify sync issues.
	 */
	for (buddies = purple_blist_find_buddies(session->account, NULL); buddies;
			buddies = g_slist_delete_link(buddies, buddies)) {
		PurpleBuddy *buddy = buddies->data;
		const gchar *buddy_name = purple_buddy_get_name(buddy);
		const gchar *group_name = purple_group_get_name(purple_buddy_get_group(buddy));
		MsnUser *remote_user;
		gboolean found = FALSE;

		remote_user = msn_userlist_find_user(session->userlist, buddy_name);
		if (remote_user && remote_user->list_op & MSN_LIST_FL_OP) {
			GList *l;
			for (l = remote_user->group_ids; l; l = l->next) {
				const char *name = msn_userlist_find_group_name(remote_user->userlist, l->data);
				if (name && !g_ascii_strcasecmp(group_name, name)) {
					found = TRUE;
					break;
				}
			}

			/* We don't care if they're in a different group, as long as they're on the
			 * list somewhere. If we check for the group, we cause pain, agony and
			 * suffering for people who decide to re-arrange their buddy list elsewhere.
			 */
			if (!found) {
				if ((remote_user == NULL) || !(remote_user->list_op & MSN_LIST_FL_OP)) {
					/* The user is not on the server list */
					msn_error_sync_issue(session, buddy_name, group_name);
				} else {
					/* The user is not in that group on the server list */
					to_remove = g_list_prepend(to_remove, buddy);
				}
			}
		}
	}

	if (to_remove != NULL) {
		g_list_foreach(to_remove, (GFunc)purple_blist_remove_buddy, NULL);
		g_list_free(to_remove);
	}
}
Ejemplo n.º 3
0
PurpleBuddy *
fb_util_account_find_buddy(PurpleAccount *acct, PurpleChatConversation *chat,
                           const gchar *search, GError **error)
{
	const gchar *alias;
	const gchar *name;
	GSList *buddies;
	GSList *l;
	guint retc;
	PurpleBuddy *ret = NULL;

	g_return_val_if_fail(PURPLE_IS_ACCOUNT(acct), NULL);
	g_return_val_if_fail(search != NULL, NULL);

	buddies = purple_blist_find_buddies(acct, NULL);

	for (retc = 0, l = buddies; l != NULL; l = l->next) {
		name = purple_buddy_get_name(l->data);
		alias = purple_buddy_get_alias(l->data);

		if ((chat != NULL) &&
		    !purple_chat_conversation_has_user(chat, name))
		{
			continue;
		}

		if (g_ascii_strcasecmp(name, search) == 0) {
			ret = l->data;
			retc++;
		}

		if (g_ascii_strcasecmp(alias, search) == 0) {
			ret = l->data;
			retc++;
		}
	}

	if (retc == 0) {
		g_set_error(error, FB_UTIL_ERROR, FB_UTIL_ERROR_GENERAL,
		            _("Buddy %s not found"), search);
	} else if (retc > 1) {
		g_set_error(error, FB_UTIL_ERROR, FB_UTIL_ERROR_GENERAL,
		            _("Buddy name %s is ambiguous"), search);
		ret = NULL;
	}

	g_slist_free(buddies);
	return ret;
}
Ejemplo n.º 4
0
/* this is for for notify purposes, not synchronizing buddy list */
void ggp_buddylist_send(PurpleConnection *gc)
{
	GGPInfo *info = purple_connection_get_protocol_data(gc);
	PurpleAccount *account = purple_connection_get_account(gc);
	GSList *buddies;
	uin_t *userlist;
	gchar *types;
	int i = 0, ret = 0;
	int size;

	buddies = purple_blist_find_buddies(account, NULL);

	size = g_slist_length(buddies);
	userlist = g_new(uin_t, size);
	types    = g_new(gchar, size);

	for (buddies = purple_blist_find_buddies(account, NULL); buddies;
			buddies = g_slist_delete_link(buddies, buddies), ++i)
	{
		PurpleBuddy *buddy = buddies->data;
		const gchar *name = purple_buddy_get_name(buddy);

		userlist[i] = ggp_str_to_uin(name);
		types[i]    = GG_USER_NORMAL;
		purple_debug_info("gg", "ggp_buddylist_send: adding %d\n",
			userlist[i]);
	}

	ret = gg_notify_ex(info->session, userlist, types, size);
	purple_debug_info("gg", "send: ret=%d; size=%d\n", ret, size);

	if (userlist) {
		g_free(userlist);
		g_free(types);
	}
}
Ejemplo n.º 5
0
static void historize(PurpleConversation *c)
{
	PurpleAccount *account = purple_conversation_get_account(c);
	const char *name = purple_conversation_get_name(c);
	GList *logs = NULL;
	const char *alias = name;
	guint flags;
	char *history;
	PidginConversation *gtkconv;
#if 0
	/* FIXME: WebView has no options */
	GtkIMHtmlOptions options = GTK_IMHTML_NO_COLOURS;
#endif
	char *header;
#if 0
	/* FIXME: WebView has no protocol setting */
	char *protocol;
#endif
	char *escaped_alias;
	const char *header_date;

	gtkconv = PIDGIN_CONVERSATION(c);
	g_return_if_fail(gtkconv != NULL);

	/* An IM which is the first active conversation. */
	g_return_if_fail(gtkconv->convs != NULL);
	if (PURPLE_IS_IM_CONVERSATION(c) && !gtkconv->convs->next)
	{
		GSList *buddies;
		GSList *cur;

		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_ims"))
			return;

		/* Find buddies for this conversation. */
		buddies = purple_blist_find_buddies(account, name);

		/* If we found at least one buddy, save the first buddy's alias. */
		if (buddies != NULL)
			alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(buddies->data));

		for (cur = buddies; cur != NULL; cur = cur->next)
		{
			PurpleBlistNode *node = cur->data;
			PurpleBlistNode *prev = purple_blist_node_get_sibling_prev(node);
			PurpleBlistNode *next = purple_blist_node_get_sibling_next(node);
			if ((node != NULL) && ((prev != NULL) || (next != NULL)))
			{
				PurpleBlistNode *node2;
				PurpleBlistNode *parent = purple_blist_node_get_parent(node);
				PurpleBlistNode *child = purple_blist_node_get_first_child(parent);

				alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(node));

				/* We've found a buddy that matches this conversation.  It's part of a
				 * PurpleContact with more than one PurpleBuddy.  Loop through the PurpleBuddies
				 * in the contact and get all the logs. */
				for (node2 = child ; node2 != NULL ; node2 = purple_blist_node_get_sibling_next(node2))
				{
					logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM,
							purple_buddy_get_name(PURPLE_BUDDY(node2)),
							purple_buddy_get_account(PURPLE_BUDDY(node2))),
							logs);
				}
				break;
			}
		}
		g_slist_free(buddies);

		if (logs == NULL)
			logs = purple_log_get_logs(PURPLE_LOG_IM, name, account);
		else
			logs = g_list_sort(logs, purple_log_compare);
	}
	else if (PURPLE_IS_CHAT_CONVERSATION(c))
	{
		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_chats"))
			return;

		logs = purple_log_get_logs(PURPLE_LOG_CHAT, name, account);
	}

	if (logs == NULL)
		return;

	history = purple_log_read((PurpleLog*)logs->data, &flags);
	gtkconv = PIDGIN_CONVERSATION(c);
#if 0
	/* FIXME: WebView has no options */
	if (flags & PURPLE_LOG_READ_NO_NEWLINE)
		options |= GTK_IMHTML_NO_NEWLINE;
#endif

#if 0
	/* FIXME: WebView has no protocol setting */
	protocol = g_strdup(gtk_imhtml_get_protocol_name(GTK_IMHTML(gtkconv->imhtml)));
	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml),
			purple_account_get_protocol_name(((PurpleLog*)logs->data)->account));
#endif

#if 0
	/* TODO WebKit: Do this properly... */
	if (!pidgin_webview_is_empty(PIDGIN_WEBVIEW(gtkconv->webview)))
		pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), "<BR>");
#endif

	escaped_alias = g_markup_escape_text(alias, -1);

	if (((PurpleLog *)logs->data)->tm)
		header_date = purple_date_format_full(((PurpleLog *)logs->data)->tm);
	else
		header_date = purple_date_format_full(localtime(&((PurpleLog *)logs->data)->time));

	header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), escaped_alias, header_date);
	pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), header);
	g_free(header);
	g_free(escaped_alias);

	g_strchomp(history);
	pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), history);
	g_free(history);

	pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), "<hr>");

#if 0
	/* FIXME: WebView has no protocol setting */
	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol);
	g_free(protocol);
#endif

	g_object_ref(G_OBJECT(gtkconv->webview));
	g_idle_add(_scroll_webview_to_end, gtkconv->webview);

	g_list_foreach(logs, (GFunc)purple_log_free, NULL);
	g_list_free(logs);
}
Ejemplo n.º 6
0
gpointer
fb_util_request_buddy(PurpleConnection *gc, const gchar *title,
                      const gchar *primary, const gchar *secondary,
                      GSList *select, gboolean multi, GCallback ok_cb,
		      GCallback cancel_cb, gpointer data)
{
	const gchar *alias;
	const gchar *name;
	gchar *str;
	GList *items = NULL;
	gpointer *mata;
	GSList *buddies;
	GSList *l;
	PurpleAccount *acct;
	PurpleRequestCommonParameters *cpar;
	PurpleRequestField *field;
	PurpleRequestFieldGroup *group;
	PurpleRequestFields *fields;

	mata = g_new0(gpointer, 3);
	mata[0] = ok_cb;
	mata[1] = cancel_cb;
	mata[2] = data;

	acct = purple_connection_get_account(gc);
	buddies = purple_blist_find_buddies(acct, NULL);
	buddies = g_slist_sort(buddies, (GCompareFunc) g_ascii_strcasecmp);

	fields = purple_request_fields_new();
	group = purple_request_field_group_new(NULL);
	purple_request_fields_add_group(fields, group);

	field = purple_request_field_list_new("buddy", NULL);
	purple_request_field_list_set_multi_select(field, multi);
	purple_request_field_set_required(field, TRUE);
	purple_request_field_group_add_field(group, field);

	for (l = buddies; l != NULL; l = l->next) {
		name = purple_buddy_get_name(l->data);
		alias = purple_buddy_get_alias(l->data);
		str = g_strdup_printf("%s (%s)", alias, name);
		purple_request_field_list_add_icon(field, str, NULL, l->data);
		g_free(str);
	}

	for (l = select; l != NULL; l = l->next) {
		name = purple_buddy_get_name(l->data);
		alias = purple_buddy_get_alias(l->data);
		str = g_strdup_printf("%s (%s)", alias, name);
		items = g_list_append(items, str);
	}

	purple_request_field_list_set_selected(field, items);
	g_slist_free(buddies);
	g_list_free_full(items, g_free);

	cpar = purple_request_cpar_from_connection(gc);
	return purple_request_fields(gc, title, primary, secondary, fields,
	                             _("Ok"),
	                             G_CALLBACK(fb_util_request_buddy_ok),
				     _("Cancel"),
	                             G_CALLBACK(fb_util_request_buddy_cancel),
				     cpar, mata);
}
Ejemplo n.º 7
0
static void ggp_roster_reply_list(PurpleConnection *gc, uint32_t version,
	const char *data)
{
	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
	PurpleXmlNode *xml, *xml_it;
	PurpleAccount *account;
	GSList *local_buddies;
	GHashTable *remove_buddies;
	GList *update_buddies = NULL, *local_groups, *it, *table_values;
	ggp_roster_content *content;

	g_return_if_fail(gc != NULL);
	g_return_if_fail(data != NULL);

	account = purple_connection_get_account(gc);

	purple_debug_info("gg", "ggp_roster_reply_list: got list, version=%u\n",
		version);

	xml = purple_xmlnode_from_str(data, -1);
	if (xml == NULL) {
		purple_debug_warning("gg", "ggp_roster_reply_list: "
			"invalid xml\n");
		return;
	}

	ggp_roster_content_free(rdata->content);
	rdata->content = NULL;
	rdata->is_updating = TRUE;
	content = g_new0(ggp_roster_content, 1);
	content->version = version;
	content->xml = xml;
	content->contact_nodes = g_hash_table_new(NULL, NULL);
	content->group_nodes = g_hash_table_new_full(
		g_str_hash, g_str_equal, g_free, NULL);
	content->group_ids = g_hash_table_new_full(
		g_str_hash, g_str_equal, g_free, g_free);
	content->group_names = g_hash_table_new_full(
		g_str_hash, g_str_equal, g_free, g_free);

#if GGP_ROSTER_DEBUG
	ggp_roster_dump(content);
#endif

	/* reading groups */
	content->groups_node = purple_xmlnode_get_child(xml, "Groups");
	if (content->groups_node == NULL) {
		ggp_roster_content_free(content);
		g_return_if_reached();
	}
	xml_it = purple_xmlnode_get_child(content->groups_node, "Group");
	while (xml_it != NULL) {
		if (!ggp_roster_reply_list_read_group(xml_it, content)) {
			ggp_roster_content_free(content);
			g_return_if_reached();
		}

		xml_it = purple_xmlnode_get_next_twin(xml_it);
	}

	/* dumping current group list */
	local_groups = ggp_purplew_account_get_groups(account, TRUE);

	/* dumping current buddy list
	 * we will:
	 * - remove synchronized ones, if not found in list at server
	 * - upload not synchronized ones
	 */
	local_buddies = purple_blist_find_buddies(account, NULL);
	remove_buddies = g_hash_table_new(g_direct_hash, g_direct_equal);
	while (local_buddies) {
		PurpleBuddy *buddy = local_buddies->data;
		uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy));
		local_buddies =
			g_slist_delete_link(local_buddies, local_buddies);

		if (!uin)
			continue;

		if (ggp_roster_is_synchronized(buddy))
			g_hash_table_insert(remove_buddies,
				GINT_TO_POINTER(uin), buddy);
		else
			update_buddies = g_list_append(update_buddies, buddy);
	}

	/* reading buddies */
	content->contacts_node = purple_xmlnode_get_child(xml, "Contacts");
	if (content->contacts_node == NULL) {
		g_hash_table_destroy(remove_buddies);
		g_list_free(update_buddies);
		ggp_roster_content_free(content);
		g_return_if_reached();
	}
	xml_it = purple_xmlnode_get_child(content->contacts_node, "Contact");
	while (xml_it != NULL) {
		if (!ggp_roster_reply_list_read_buddy(gc, xml_it, content,
			remove_buddies))
		{
			g_hash_table_destroy(remove_buddies);
			g_list_free(update_buddies);
			ggp_roster_content_free(content);
			g_return_if_reached();
		}

		xml_it = purple_xmlnode_get_next_twin(xml_it);
	}

	/* removing buddies, which are not present in roster */
	table_values = g_hash_table_get_values(remove_buddies);
	it = g_list_first(table_values);
	while (it) {
		PurpleBuddy *buddy = it->data;
		it = g_list_next(it);
		if (!ggp_roster_is_synchronized(buddy))
			continue;
		purple_debug_info("gg", "ggp_roster_reply_list: "
			"removing %s from buddy list\n",
			purple_buddy_get_name(buddy));
		purple_blist_remove_buddy(buddy);
	}
	g_list_free(table_values);
	g_hash_table_destroy(remove_buddies);

	/* remove groups, which are empty, but had contacts before
	 * synchronization
	 */
	it = g_list_first(local_groups);
	while (it) {
		PurpleGroup *group = it->data;
		it = g_list_next(it);
		if (purple_counting_node_get_total_size(PURPLE_COUNTING_NODE(group)) != 0)
			continue;
		purple_debug_info("gg", "ggp_roster_reply_list: "
			"removing group %s\n", purple_group_get_name(group));
		purple_blist_remove_group(group);
	}
	g_list_free(local_groups);

	/* adding not synchronized buddies */
	it = g_list_first(update_buddies);
	while (it) {
		PurpleBuddy *buddy = it->data;
		uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy));
		ggp_roster_change *change;

		it = g_list_next(it);
		g_assert(uin > 0);

		purple_debug_misc("gg", "ggp_roster_reply_list: "
			"adding change of %u for roster\n", uin);
		change = g_new0(ggp_roster_change, 1);
		change->type = GGP_ROSTER_CHANGE_CONTACT_UPDATE;
		change->data.uin = uin;
		rdata->pending_updates =
			g_list_append(rdata->pending_updates, change);
	}
	g_list_free(update_buddies);

	rdata->content = content;
	rdata->is_updating = FALSE;
	purple_debug_info("gg", "ggp_roster_reply_list: "
		"import done, version=%u\n", version);
}