Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision 93e09014ec54e94cd4b08250d1dc1c86711c97c3)
+++ protocols/nogaim.c	(revision a852b2b5d74a6fb3b440447d540ccb41424a0825)
@@ -312,10 +312,11 @@
 	}
 
-	if (ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS) {
+	if ((ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS) &&
+	    !(ic->flags & OPT_LOCAL_CONTACTS_SENT)) {
 		GHashTableIter nicks;
-		gpointer k, v;
+		gpointer handle;
 		g_hash_table_iter_init(&nicks, ic->acc->nicks);
-		while (g_hash_table_iter_next(&nicks, &k, &v)) {
-			ic->acc->prpl->add_buddy(ic, (char *) k, NULL);
+		while (g_hash_table_iter_next(&nicks, &handle, NULL)) {
+			ic->acc->prpl->add_buddy(ic, (char *) handle, NULL);
 		}
 	}
@@ -495,4 +496,26 @@
 		bee->ui->user_nick_hint(bee, bu, nick);
 	}
+}
+
+/* Returns the local contacts for an IM account (based on assigned nicks).
+   Linked list should be freed, the strings themselves not! So look at it
+   like a GSList<const char*> I guess? Empty list means NULL retval (as
+   always with GSList). */
+GSList *imcb_get_local_contacts(struct im_connection *ic)
+{
+ 	GHashTableIter nicks;
+	GSList *ret = NULL;
+	
+	g_hash_table_iter_init(&nicks, ic->acc->nicks);
+	gpointer handle;
+	while (g_hash_table_iter_next(&nicks, &handle, NULL)) {
+		ret = g_slist_prepend(ret, (char *) handle);
+	}
+	
+	/* If the protocol asked for the list, assume we won't have to send it
+	   anymore in imcb_connected(). */
+	ic->flags |= OPT_LOCAL_CONTACTS_SENT;
+	
+	return ret;
 }
 
Index: protocols/nogaim.h
===================================================================
--- protocols/nogaim.h	(revision 93e09014ec54e94cd4b08250d1dc1c86711c97c3)
+++ protocols/nogaim.h	(revision a852b2b5d74a6fb3b440447d540ccb41424a0825)
@@ -57,5 +57,10 @@
 
 /* Sharing flags between all kinds of things. I just hope I won't hit any
-   limits before 32-bit machines become extinct. ;-) */
+   limits before 32-bit machines become extinct. ;-)
+   
+   Argh! This needs to be renamed to be more clear which field they're used
+   for. As said it's currently mixed which is nonsense. Some are for the
+   im_connection flags field, some for imcb_buddy_status(), some for typing
+   notifications, and who knows what else... */
 #define OPT_LOGGED_IN   0x00000001
 #define OPT_LOGGING_OUT 0x00000002
@@ -70,4 +75,5 @@
 #define OPT_PONGS       0x00010000 /* Service sends us keep-alives */
 #define OPT_PONGED      0x00020000 /* Received a keep-alive during last interval */
+#define OPT_LOCAL_CONTACTS_SENT 0x00040000 /* Protocol already requested local contact list, so don't send it after finishing login. */
 
 /* ok. now the fun begins. first we create a connection structure */
@@ -324,4 +330,5 @@
 G_MODULE_EXPORT void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick);
 G_MODULE_EXPORT void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data);
+G_MODULE_EXPORT GSList *imcb_get_local_contacts(struct im_connection *ic);
 
 G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags);
Index: protocols/rpc/rpc.c
===================================================================
--- protocols/rpc/rpc.c	(revision 93e09014ec54e94cd4b08250d1dc1c86711c97c3)
+++ protocols/rpc/rpc.c	(revision a852b2b5d74a6fb3b440447d540ccb41424a0825)
@@ -605,4 +605,17 @@
 }
 
+static JSON_Value *rpc_imcb_get_local_contacts(struct im_connection *ic, void *func_, JSON_Array *params) {
+	JSON_Value *resp = json_value_init_object();
+	JSON_Value *arr = json_value_init_array();
+	GSList *contacts = imcb_get_local_contacts(ic);
+	GSList *c;
+	for (c = contacts; c; c = c->next) {
+		json_array_append_string(json_array(arr), (const char*) c->data);
+	}
+	g_slist_free(contacts);
+	json_object_set_value(json_object(resp), "result", arr);
+	return resp;
+}
+
 static JSON_Value *rpc_imcb_chat_new(struct im_connection *ic, void *func_, JSON_Array *params) {
 	struct rpc_groupchat *rc = rpc_groupchat_new(ic, json_array_get_string(params, 0));
@@ -719,4 +732,5 @@
 	{ "imcb_buddy_msg", imcb_buddy_msg, rpc_imcb_buddy_msg, "ssii" },
 	{ "imcb_buddy_typing", imcb_buddy_typing, rpc_imcb_buddy_typing, "si" },
+	{ "imcb_get_local_contacts", NULL, rpc_imcb_get_local_contacts, "" },
 	{ "imcb_chat_new", NULL, rpc_imcb_chat_new, "s" },
 	
