/* 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; }
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); } }
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; }
/* 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); } }
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); }
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); }
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); }