Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision b7d3cc34f68dab7b8f7d0777711317b334fc2219)
+++ protocols/nogaim.c	(revision 99318adcb88fa3f1dd21882ec364e682fec96c5e)
@@ -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,28 +55,93 @@
 GSList *connections;
 
+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;
+}
 
 /* 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 );
+	GDir *dir;
+	GError *error = NULL;
+
 #ifdef WITH_MSN
-	msn_init( proto_prpl[PROTO_MSN] );
+	extern void msn_init();
+	msn_init();
 #endif
 
-	proto_prpl[PROTO_OSCAR] = g_new0( struct prpl, 1 );
 #ifdef WITH_OSCAR
-	oscar_init( proto_prpl[PROTO_OSCAR] );
+	extern void oscar_init();
+	oscar_init();
 #endif
 	
-	proto_prpl[PROTO_YAHOO] = g_new0( struct prpl, 1 );
 #ifdef WITH_YAHOO
-	byahoo_init( proto_prpl[PROTO_YAHOO] );
+	extern void byahoo_init();
+	byahoo_init();
 #endif
 	
-	proto_prpl[PROTO_JABBER] = g_new0( struct prpl, 1 );
 #ifdef WITH_JABBER
-	jabber_init( proto_prpl[PROTO_JABBER] );
+	extern void jabber_init();
+	jabber_init();
 #endif
+
+	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);
+	}
 }
 
@@ -122,5 +184,5 @@
 			gc->prpl->set_away( gc, s, away );
 			if( set_getint( gc->irc, "debug" ) )
-				irc_usermsg( gc->irc, "Setting away state for %s to %s", proto_name[gc->protocol], s );
+				irc_usermsg( gc->irc, "Setting away state for %s to %s", gc->prpl->name, s );
 		}
 		else
@@ -168,7 +230,7 @@
    way for now because I don't want to touch the Gaim code too much since
    it's not going to be here for too long anymore. */
-int handle_cmp( char *a, char *b, int protocol )
-{
-	if( protocol == PROTO_TOC || protocol == PROTO_ICQ )
+int handle_cmp( char *a, char *b, struct prpl *protocol )
+{
+	if( !strcmp(protocol->name, "oscar") )
 	{
 		/* AIM, being teh evil, thinks it's cool that users can put
@@ -210,6 +272,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,5 +315,5 @@
 void set_login_progress( struct gaim_connection *gc, int step, char *msg )
 {
-	irc_usermsg( gc->irc, "%s(%s) - Logging in: %s", proto_name[gc->protocol], gc->username, msg );
+	irc_usermsg( gc->irc, "%s(%s) - Logging in: %s", gc->prpl->name, gc->username, msg );
 }
 
@@ -260,5 +321,5 @@
 void hide_login_progress( struct gaim_connection *gc, char *msg )
 {
-	irc_usermsg( gc->irc, "%s(%s) - Login error: %s", proto_name[gc->protocol], gc->username, msg );
+	irc_usermsg( gc->irc, "%s(%s) - Login error: %s", gc->prpl->name, gc->username, msg );
 }
 
@@ -266,5 +327,5 @@
 void hide_login_progress_error( struct gaim_connection *gc, char *msg )
 {
-	irc_usermsg( gc->irc, "%s(%s) - Logged out: %s", proto_name[gc->protocol], gc->username, msg );
+	irc_usermsg( gc->irc, "%s(%s) - Logged out: %s", gc->prpl->name, gc->username, msg );
 }
 
@@ -289,5 +350,5 @@
 		strip_html( msg );
 	
-	irc_usermsg( gc->irc, "%s(%s) - %s", proto_name[gc->protocol], gc->username, msg );
+	irc_usermsg( gc->irc, "%s(%s) - %s", gc->prpl->name, gc->username, msg );
 }
 
@@ -314,5 +375,5 @@
 	u = user_find( gc->irc, gc->irc->nick );
 	
-	irc_usermsg( gc->irc, "%s(%s) - Logged in", proto_name[gc->protocol], gc->username );
+	irc_usermsg( gc->irc, "%s(%s) - Logged in", gc->prpl->name, gc->username );
 	
 	gc->keepalive = g_timeout_add( 60000, send_keepalive, gc );
@@ -321,5 +382,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 )
@@ -361,5 +422,5 @@
 	account_t *a;
 	
-	irc_usermsg( gc->irc, "%s(%s) - Signing off..", proto_name[gc->protocol], gc->username );
+	irc_usermsg( gc->irc, "%s(%s) - Signing off..", gc->prpl->name, gc->username );
 
 	gaim_input_remove( gc->keepalive );
@@ -393,5 +454,5 @@
 	{
 		int delay = set_getint( irc, "auto_reconnect_delay" );
-		irc_usermsg( gc->irc, "%s(%s) - Reconnecting in %d seconds..", proto_name[gc->protocol], gc->username, delay);
+		irc_usermsg( gc->irc, "%s(%s) - Reconnecting in %d seconds..", gc->prpl->name, gc->username, delay);
 		
 		a->reconnect = 1;
@@ -449,5 +510,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 );
@@ -473,5 +534,5 @@
 	else
 	{
-		u->host = g_strdup( proto_name[gc->user->protocol] );
+		u->host = g_strdup( gc->user->prpl->name );
 		u->user = g_strdup( handle );
 	}
@@ -567,5 +628,5 @@
 			if( set_getint( gc->irc, "debug" ) || g_strcasecmp( set_getstr( gc->irc, "handle_unknown" ), "ignore" ) != 0 )
 			{
-				irc_usermsg( gc->irc, "serv_got_update() for handle %s on connection %s(%s):", handle, proto_name[gc->protocol], gc->username );
+				irc_usermsg( gc->irc, "serv_got_update() for handle %s on connection %s(%s):", handle, gc->prpl->name, gc->username );
 				irc_usermsg( gc->irc, "loggedin = %d, type = %d", loggedin, type );
 			}
@@ -602,9 +663,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 )
@@ -648,5 +709,5 @@
 		{
 			if( set_getint( irc, "debug" ) )
-				irc_usermsg( irc, "Ignoring message from unknown handle %s on connection %s(%s)", handle, proto_name[gc->protocol], gc->username );
+				irc_usermsg( irc, "Ignoring message from unknown handle %s on connection %s(%s)", handle, gc->prpl->name, gc->username );
 			
 			return;
@@ -670,5 +731,5 @@
 		else
 		{
-			irc_usermsg( irc, "Message from unknown handle %s on connection %s(%s):", handle, proto_name[gc->protocol], gc->username );
+			irc_usermsg( irc, "Message from unknown handle %s on connection %s(%s):", handle, gc->prpl->name, gc->username );
 			u = user_find( irc, irc->mynick );
 		}
@@ -836,5 +897,5 @@
 	
 	/* It might be yourself! */
-	if( handle_cmp ( handle, b->gc->user->username, b->gc->protocol ) == 0 )
+	if( handle_cmp ( handle, b->gc->user->username, b->gc->prpl ) == 0 )
 	{
 		u = user_find( b->gc->irc, b->gc->irc->nick );
