static void stress_close(PurpleConnection *pc) { GList *l = NULL; PurpleGroup *g = NULL; for(l = buddies; l; l = l->next) { StressBuddy *sb = l->data; purple_blist_remove_buddy(sb->buddy); } g_list_free(buddies); g = purple_find_group("prpl-stress"); purple_blist_remove_group(g); buddies = NULL; }
void BuddyListGroup::GroupContextMenu::removeResponseHandler( CppConsUI::MessageDialog& /*activator*/, CppConsUI::AbstractDialog::ResponseType response) { if (response != CppConsUI::AbstractDialog::RESPONSE_OK) return; // based on gtkdialogs.c:pidgin_dialogs_remove_group_cb() PurpleGroup *group = parent_group->getPurpleGroup(); PurpleBlistNode *cnode = purple_blist_node_get_first_child( PURPLE_BLIST_NODE(group)); while (cnode) { if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) { PurpleBlistNode *bnode = purple_blist_node_get_first_child(cnode); cnode = purple_blist_node_get_sibling_next(cnode); while (bnode) if (PURPLE_BLIST_NODE_IS_BUDDY(bnode)) { PurpleBuddy *buddy = PURPLE_BUDDY(bnode); PurpleAccount *account = purple_buddy_get_account(buddy); bnode = purple_blist_node_get_sibling_next(bnode); if (purple_account_is_connected(account)) { purple_account_remove_buddy(account, buddy, group); purple_blist_remove_buddy(buddy); } } else bnode = purple_blist_node_get_sibling_next(bnode); } else if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) { PurpleChat *chat = PURPLE_CHAT(cnode); cnode = purple_blist_node_get_sibling_next(cnode); purple_blist_remove_chat(chat); } else cnode = purple_blist_node_get_sibling_next(cnode); } /* Close the context menu before the group is deleted because its deletion * can lead to destruction of this object. */ close(); purple_blist_remove_group(group); }
bool PurpleIMContactList::removeGroupCbk(void * dataIn) { Mutex::ScopedLock lock(PurpleIMContactList::_mutex); PurpleIMContactListCallbackData* cbData = (PurpleIMContactListCallbackData*)dataIn; PurpleGroup *gGroup = purple_find_group( cbData->getGroupName().c_str() ); if (gGroup) { purple_blist_remove_group(gGroup); } timeoutRemove( cbData ); delete cbData; return TRUE; }
xmlnode * _h_elim_remove_buddy ( const char *name , const char *id , SEXP_VALUE *args , gpointer data ) { ASSERT_ALISTP( args, id, name ); fprintf( stderr, "(elim-remove-buddy)\n" ); elim_ping(); const char *aname = ALIST_VAL_STR( args, "account-name" ); const char *proto = ALIST_VAL_STR( args, "im-protocol" ); gpointer auid = ALIST_VAL_PTR( args, "account-uid" ); PurpleAccount *acct = NULL; gpointer b_uid = ALIST_VAL_PTR( args, "bnode-uid" ); const char *b_arg = NULL; const char *bname = NULL; const char *gname = NULL; PurpleGroup *group = NULL; PurpleBuddy *buddy = NULL; gboolean gone = FALSE; if( b_uid ) { PurpleBlistNodeType type = PURPLE_BLIST_OTHER_NODE; PurpleBlistNode *node = find_blist_node_by_uid( b_uid , TRUE ); if( !node ) { sexp_val_free( args ); return response_error( EINVAL, id, name, "rogue buddy pointer" ); } type = purple_blist_node_get_type( node ); // =========================================================== // groups, contacts and chats can safely be removed here: // buddies should instead be noted for removal in the next // block of code as they require client<->server interaction: switch( type ) { case PURPLE_BLIST_GROUP_NODE : purple_blist_remove_group ( (PurpleGroup *)node ); gone = TRUE; break; case PURPLE_BLIST_CONTACT_NODE: purple_blist_remove_contact( (PurpleContact *)node ); gone = TRUE; break; case PURPLE_BLIST_CHAT_NODE : FIND_ACCOUNT( args, id, name, acct, auid, aname, proto ); BNODE_ACCOUNT_CHECK(chat,(PurpleChat *)node, acct, args, id, name); purple_blist_remove_chat ( (PurpleChat *)node ); gone = TRUE; break; case PURPLE_BLIST_BUDDY_NODE : buddy = (PurpleBuddy *)node; FIND_ACCOUNT( args, id, name, acct, auid, aname, proto ); BNODE_ACCOUNT_CHECK( buddy, buddy, acct, args, id, name ); b_arg = purple_buddy_get_name( buddy ); bname = purple_normalize( acct, b_arg ); break; default: sexp_val_free( args ); return response_error( EINVAL, id, name, "Unknown buddy list node type" ); } if( gone ) { xmlnode *rval = xnode_new( "alist" ); if( acct ) { AL_STR( rval, "account-name", aname ); AL_STR( rval, "im-protocol" , proto ); AL_PTR( rval, "account-uid" , acct ); } AL_PTR ( rval, "bnode-uid" , buddy ); AL_ENUM( rval, "bnode-type", type , ":blist-node-type" ); sexp_val_free( args ); return response_value( 0, id, name, rval ); } } else { b_arg = ALIST_VAL_STRING( args, "bnode-name" ); FIND_ACCOUNT( args, id, name, acct, auid, aname, proto ); if( b_arg ) { bname = purple_normalize( acct, b_arg ); gname = ALIST_VAL_STRING( args, "group" ); group = ( gname && *gname ) ? purple_find_group( gname ) : NULL; buddy = ( group ? purple_find_buddy_in_group( acct, bname, group ) : purple_find_buddy ( acct, bname ) ); } } if( !b_arg || !*b_arg ) { sexp_val_free( args ); return response_error( EINVAL, id, name, "buddy not specified" ); } // buddy must be in our local list or libpurple won't remove it from the // server list ( determined empirically, confirmed by inspecting code ): if( !buddy ) { buddy = purple_buddy_new( acct, bname, bname ); purple_blist_add_buddy ( buddy, NULL, NULL, NULL ); } if( buddy ) { // the order of the remove operations is important: it has to be // this way round, as noted above: account buddy removal won't // happen if the buddy is not in the blist when we try: if( !group ) group = purple_buddy_get_group( buddy ); // is this correct? what if we have more than one copy of said buddy? // potentially confusing. dunno what the right thing to do is here. purple_account_remove_buddy( acct, buddy, group ); purple_blist_remove_buddy( buddy ); } else { sexp_val_free( args ); return response_error( ENXIO, id, name, "no such buddy" ); } xmlnode *rval = xnode_new( "alist" ); AL_STR ( rval, "account-name", purple_account_get_username ( acct ) ); AL_STR ( rval, "im-protocol" , purple_account_get_protocol_id( acct ) ); AL_PTR ( rval, "account-uid" , acct ); AL_PTR ( rval, "bnode-uid" , buddy ); AL_ENUM( rval, "bnode-type", PURPLE_BLIST_BUDDY_NODE, ":blist-node-type" ); sexp_val_free( args ); return response_value( 0, id, name, rval ); }
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); }