Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision 11e090b246a86deb7b882217772b90fc52d7e4f6)
+++ protocols/jabber/jabber.c	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
@@ -155,9 +155,4 @@
 #define JCS_CLOSED  3	/* closed */
 
-
-static char *jabber_name()
-{
-	return "Jabber";
-}
 
 #define STATE_EVT(arg) if(gjc->on_state) { (gjc->on_state)(gjc, (arg) ); }
@@ -2368,11 +2363,11 @@
 }
 
-static struct prpl *my_protocol = NULL;
-
-void jabber_init(struct prpl *ret)
-{
+
+void jabber_init()
+{
+	struct prpl *ret = g_new0(struct prpl, 1);
+
 	/* the NULL's aren't required but they're nice to have */
-	ret->protocol = PROTO_JABBER;
-	ret->name = jabber_name;
+	ret->name = "jabber";
 	ret->away_states = jabber_away_states;
 	ret->actions = jabber_actions;
@@ -2398,4 +2393,4 @@
 	ret->cmp_buddynames = g_strcasecmp;
 
-	my_protocol = ret;
-}
+	register_protocol (ret);
+}
Index: protocols/msn/msn.c
===================================================================
--- protocols/msn/msn.c	(revision 11e090b246a86deb7b882217772b90fc52d7e4f6)
+++ protocols/msn/msn.c	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
@@ -26,6 +26,4 @@
 #include "nogaim.h"
 #include "msn.h"
-
-static struct prpl *my_protocol = NULL;
 
 static void msn_login( struct aim_user *acct )
@@ -375,7 +373,8 @@
 }
 
-void msn_init(struct prpl *ret)
-{
-	ret->protocol = PROTO_MSN;
+void msn_init()
+{
+	struct prpl *ret = g_new0(struct prpl, 1);
+	ret->name = "msn";
 	ret->login = msn_login;
 	ret->close = msn_close;
@@ -400,4 +399,4 @@
 	ret->cmp_buddynames = g_strcasecmp;
 
-	my_protocol = ret;
-}
+	register_protocol(ret);
+}
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision 11e090b246a86deb7b882217772b90fc52d7e4f6)
+++ protocols/nogaim.c	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
@@ -39,7 +39,4 @@
 #include <iconv.h>
 
-struct prpl *proto_prpl[PROTO_MAX];
-char proto_name[PROTO_MAX][8] = { "TOC", "OSCAR", "YAHOO", "ICQ", "MSN", "", "", "", "JABBER", "", "", "", "", "", "", "" };
-
 static char *proto_away_alias[7][5] =
 {
@@ -58,27 +55,102 @@
 GSList *connections;
 
+#ifdef WITH_PLUGINS
+gboolean load_plugin(char *path)
+{
+	void (*init_function) (void);
+	
+	GModule *mod = g_module_open(path, G_MODULE_BIND_LAZY);
+
+	if(!mod) {
+		log_message(LOGLVL_ERROR, "Can't find `%s', not loading", path);
+		return FALSE;
+	}
+
+	if(!g_module_symbol(mod,"init_plugin",(gpointer *) &init_function)) {
+		log_message(LOGLVL_WARNING, "Can't find function `init_plugin' in `%s'\n", path);
+		return FALSE;
+	}
+
+	init_function();
+
+	return TRUE;
+}
+
+void load_plugins(void)
+{
+	GDir *dir;
+	GError *error = NULL;
+
+	dir = g_dir_open(PLUGINDIR, 0, &error);
+
+	if (dir) {
+		const gchar *entry;
+		char *path;
+
+		while ((entry = g_dir_read_name(dir))) {
+			path = g_build_filename(PLUGINDIR, entry, NULL);
+			if(!path) {
+				log_message(LOGLVL_WARNING, "Can't build path for %s\n", entry);
+				continue;
+			}
+
+			load_plugin(path);
+
+			g_free(path);
+		}
+
+		g_dir_close(dir);
+	}
+}
+#endif
 
 /* nogaim.c */
 
+GList *protocols = NULL;
+  
+void register_protocol (struct prpl *p)
+{
+	protocols = g_list_append(protocols, p);
+}
+
+ 
+struct prpl *find_protocol(const char *name)
+{
+	GList *gl;
+	for (gl = protocols; gl; gl = gl->next) 
+ 	{
+ 		struct prpl *proto = gl->data;
+ 		if(!g_strcasecmp(proto->name, name)) 
+			return proto;
+ 	}
+ 	return NULL;
+}
+
+/* nogaim.c */
 void nogaim_init()
 {
-	proto_prpl[PROTO_MSN] = g_new0 ( struct prpl, 1 );
+	extern void msn_init();
+	extern void oscar_init();
+	extern void byahoo_init();
+	extern void jabber_init();
+
 #ifdef WITH_MSN
-	msn_init( proto_prpl[PROTO_MSN] );
+	msn_init();
 #endif
 
-	proto_prpl[PROTO_OSCAR] = g_new0( struct prpl, 1 );
 #ifdef WITH_OSCAR
-	oscar_init( proto_prpl[PROTO_OSCAR] );
+	oscar_init();
 #endif
 	
-	proto_prpl[PROTO_YAHOO] = g_new0( struct prpl, 1 );
 #ifdef WITH_YAHOO
-	byahoo_init( proto_prpl[PROTO_YAHOO] );
+	byahoo_init();
 #endif
 	
-	proto_prpl[PROTO_JABBER] = g_new0( struct prpl, 1 );
 #ifdef WITH_JABBER
-	jabber_init( proto_prpl[PROTO_JABBER] );
+	jabber_init();
+#endif
+
+#ifdef WITH_PLUGINS
+	load_plugins();
 #endif
 }
@@ -172,6 +244,5 @@
 	gc = g_new0( struct gaim_connection, 1 );
 	
-	gc->protocol = user->protocol;
-	gc->prpl = proto_prpl[gc->protocol];
+	gc->prpl = user->prpl;
 	g_snprintf( gc->username, sizeof( gc->username ), "%s", user->username );
 	g_snprintf( gc->password, sizeof( gc->password ), "%s", user->password );
@@ -254,12 +325,12 @@
 	/* Try to find a different connection on the same protocol. */
 	for( a = gc->irc->accounts; a; a = a->next )
-		if( proto_prpl[a->protocol] == gc->prpl && a->gc != gc )
+		if( a->prpl == gc->prpl && a->gc != gc )
 			break;
 	
 	/* If we found one, add the screenname to the acc_id. */
 	if( a )
-		g_snprintf( acc_id, 32, "%s(%s)", proto_name[gc->protocol], gc->username );
+		g_snprintf( acc_id, 32, "%s(%s)", gc->prpl->name, gc->username );
 	else
-		g_snprintf( acc_id, 32, "%s", proto_name[gc->protocol] );
+		g_snprintf( acc_id, 32, "%s", gc->prpl->name );
 	
 	irc_usermsg( gc->irc, "%s - %s", acc_id, msg );
@@ -295,5 +366,5 @@
 	if( u && u->away ) proto_away( gc, u->away );
 	
-	if( gc->protocol == PROTO_ICQ )
+ 	if( !strcmp(gc->prpl->name, "icq") )
 	{
 		for( u = gc->irc->users; u; u = u->next )
@@ -430,5 +501,5 @@
 	
 	memset( nick, 0, MAX_NICK_LENGTH + 1 );
-	strcpy( nick, nick_get( gc->irc, handle, gc->protocol, realname ) );
+	strcpy( nick, nick_get( gc->irc, handle, gc->prpl, realname ) );
 	
 	u = user_add( gc->irc, nick );
@@ -454,5 +525,5 @@
 	else
 	{
-		u->host = g_strdup( proto_name[gc->user->protocol] );
+		u->host = g_strdup( gc->user->prpl->name );
 		u->user = g_strdup( handle );
 	}
@@ -583,9 +654,9 @@
 	}
 	
-	if( ( type & UC_UNAVAILABLE ) && ( gc->protocol == PROTO_OSCAR || gc->protocol == PROTO_TOC ) )
+	if( ( type & UC_UNAVAILABLE ) && ( !strcmp(gc->prpl->name, "oscar") || !strcmp(gc->prpl->name, "icq")) )
 	{
 		u->away = g_strdup( "Away" );
 	}
-	else if( ( type & UC_UNAVAILABLE ) && ( gc->protocol == PROTO_JABBER ) )
+	else if( ( type & UC_UNAVAILABLE ) && ( !strcmp(gc->prpl->name, "jabber") ) )
 	{
 		if( type & UC_DND )
Index: protocols/nogaim.h
===================================================================
--- protocols/nogaim.h	(revision 11e090b246a86deb7b882217772b90fc52d7e4f6)
+++ protocols/nogaim.h	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
@@ -72,5 +72,4 @@
 	/* we need to do either oscar or TOC */
 	/* we make this as an int in case if we want to add more protocols later */
-	int protocol;
 	struct prpl *prpl;
 	guint32 flags;
@@ -152,5 +151,5 @@
 	char user_info[2048];
 	int options;
-	int protocol;
+	struct prpl *prpl;
 	/* prpls can use this to save information about the user,
 	 * like which server to connect to, etc */
@@ -162,7 +161,6 @@
 
 struct prpl {
-	int protocol;
 	int options;
-	char *(* name)();
+	const char *name;
 
 	/* for ICQ and Yahoo, who have off/on per-conversation options */
@@ -224,20 +222,4 @@
 };
 
-#define PROTO_TOC	0
-#define PROTO_OSCAR	1
-#define PROTO_YAHOO	2
-#define PROTO_ICQ	3
-#define PROTO_MSN	4
-#define PROTO_IRC	5
-#define PROTO_FTP	6
-#define PROTO_VGATE	7
-#define PROTO_JABBER	8
-#define PROTO_NAPSTER	9
-#define PROTO_ZEPHYR	10
-#define PROTO_GADUGADU	11
-#define PROTO_MAX	16
-
-extern char proto_name[PROTO_MAX][8];
-
 #define UC_UNAVAILABLE  1
 
@@ -249,5 +231,6 @@
 
 G_MODULE_EXPORT GSList *get_connections();
-extern struct prpl *proto_prpl[16];
+G_MODULE_EXPORT struct prpl *find_protocol(const char *name);
+G_MODULE_EXPORT void register_protocol(struct prpl *);
 
 /* nogaim.c */
@@ -319,24 +302,4 @@
 G_MODULE_EXPORT void info_string_append(GString *str, char *newline, char *name, char *value);
 
-#ifdef WITH_MSN
-/* msn.c */
-G_MODULE_EXPORT void msn_init( struct prpl *ret );
-#endif
-
-#ifdef WITH_OSCAR
-/* oscar.c */
-G_MODULE_EXPORT void oscar_init( struct prpl *ret );
-#endif
-
-#ifdef WITH_JABBER
-/* jabber.c */
-G_MODULE_EXPORT void jabber_init( struct prpl *ret );
-#endif
-
-#ifdef WITH_YAHOO
-/* yahoo.c */
-G_MODULE_EXPORT void byahoo_init( struct prpl *ret );
-#endif
-
 /* prefs.c */
 G_MODULE_EXPORT void build_block_list();
Index: protocols/oscar/oscar.c
===================================================================
--- protocols/oscar/oscar.c	(revision 11e090b246a86deb7b882217772b90fc52d7e4f6)
+++ protocols/oscar/oscar.c	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
@@ -357,8 +357,6 @@
 		odata->icq = TRUE;
 		/* this is odd but it's necessary for a proper do_import and do_export */
-		gc->protocol = PROTO_ICQ;
 		gc->password[8] = 0;
 	} else {
-		gc->protocol = PROTO_TOC;
 		gc->flags |= OPT_CONN_HTML;
 	}
@@ -2633,8 +2631,8 @@
 }
 
-static struct prpl *my_protocol = NULL;
-
-void oscar_init(struct prpl *ret) {
-	ret->protocol = PROTO_OSCAR;
+void oscar_init() 
+{
+	struct prpl *ret = g_new0(struct prpl, 1);
+	ret->name = "oscar";
 	ret->away_states = oscar_away_states;
 	ret->login = oscar_login;
@@ -2658,7 +2656,6 @@
 	ret->cmp_buddynames = aim_sncmp;
 	ret->get_status_string = oscar_get_status_string;
-
 	ret->send_typing = oscar_send_typing;
 
-	my_protocol = ret;
-}
+	register_protocol(ret);
+}
Index: protocols/yahoo/yahoo.c
===================================================================
--- protocols/yahoo/yahoo.c	(revision 11e090b246a86deb7b882217772b90fc52d7e4f6)
+++ protocols/yahoo/yahoo.c	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
@@ -64,10 +64,4 @@
 };
 
-static char *yahoo_name()
-{
-	return "Yahoo";
-}
-
-static struct prpl *my_protocol = NULL;
 static GSList *byahoo_inputs = NULL;
 static int byahoo_chat_id = 0;
@@ -396,13 +390,12 @@
 }
 
-void byahoo_init( struct prpl *ret )
-{
-	ret->protocol = PROTO_YAHOO;
-	ret->name = yahoo_name;
+void byahoo_init( )
+{
+	struct prpl *ret = g_new0(struct prpl, 1);
+	ret->name = "yahoo";
 	
 	ret->login = byahoo_login;
 	ret->close = byahoo_close;
 	ret->send_im = byahoo_send_im;
-	ret->send_typing = byahoo_send_typing;
 	ret->get_info = byahoo_get_info;
 	ret->away_states = byahoo_away_states;
@@ -412,4 +405,5 @@
 	ret->remove_buddy = byahoo_remove_buddy;
 	ret->get_status_string = byahoo_get_status_string;
+	ret->send_typing = byahoo_send_typing;
 	
 	ret->chat_send = byahoo_chat_send;
@@ -419,5 +413,5 @@
 	ret->cmp_buddynames = g_strcasecmp;
 	
-	my_protocol = ret;
+	register_protocol(ret);
 }
 
@@ -433,5 +427,5 @@
 		yd = gc->proto_data;
 		
-		if( gc->protocol == PROTO_YAHOO && yd->y2_id == id )
+		if( !strcmp(gc->prpl->name, "yahoo") && yd->y2_id == id )
 			return( gc );
 	}
