Index: conf.c
===================================================================
--- conf.c	(revision 210d1d9cf4366d9933c02383300175e4b573be61)
+++ conf.c	(revision b7d3cc34f68dab7b8f7d0777711317b334fc2219)
@@ -1,6 +1,6 @@
-/********************************************************************\
+  /********************************************************************\
   * BitlBee -- An IRC to other IM-networks gateway                     *
   *                                                                    *
-  * Copyright 2002-2005 Wilmer van der Gaast and others                *
+  * Copyright 2002-2004 Wilmer van der Gaast and others                *
   \********************************************************************/
 
@@ -20,6 +20,6 @@
   You should have received a copy of the GNU General Public License with
   the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
-  Fifth Floor, Boston, MA  02110-1301  USA
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
 */
 
@@ -32,363 +32,250 @@
 #include "ini.h"
 #include "url.h"
-#include "ipc.h"
-
-#include "proxy.h"
-
-static int conf_loadini(conf_t *conf, char *file);
-static void conf_free(conf_t *conf);
-
-conf_t *conf_load(int argc, char *argv[])
+
+#include "protocols/proxy.h"
+
+char *CONF_FILE;
+
+static int conf_loadini( conf_t *conf, char *file );
+
+conf_t *conf_load( int argc, char *argv[] )
 {
 	conf_t *conf;
-	int opt, i, config_missing = 0;
-	int version_happened = 0;
-
-	conf = g_new0(conf_t, 1);
-
-	conf->iface_in = NULL;
-	conf->iface_out = NULL;
-	conf->port = g_strdup("6667");
+	int opt, i;
+	
+	conf = g_new0( conf_t, 1 );
+	
+	conf->iface = "0.0.0.0";
+	conf->port = 6667;
 	conf->nofork = 0;
 	conf->verbose = 0;
-	conf->primary_storage = g_strdup("xml");
-	conf->migrate_storage = g_strsplit("text", ",", -1);
 	conf->runmode = RUNMODE_INETD;
 	conf->authmode = AUTHMODE_OPEN;
-	conf->auth_backend = NULL;
-	conf->auth_pass = NULL;
-	conf->oper_pass = NULL;
-	conf->allow_account_add = 1;
-	conf->configdir = g_strdup(CONFIG);
-	conf->plugindir = g_strdup(PLUGINDIR);
-	conf->pidfile = g_strdup(PIDFILE);
-	conf->motdfile = g_strdup(ETCDIR "/motd.txt");
+	conf->password = NULL;
+	conf->configdir = g_strdup( CONFIG );
+	conf->motdfile = g_strdup( ETCDIR "/motd.txt" );
 	conf->ping_interval = 180;
 	conf->ping_timeout = 300;
-	conf->user = NULL;
-	conf->ft_max_size = SIZE_MAX;
-	conf->ft_max_kbps = G_MAXUINT;
-	conf->ft_listen = NULL;
-	conf->protocols = NULL;
-	conf->cafile = NULL;
-	proxytype = 0;
-
-	i = conf_loadini(conf, global.conf_file);
-	if (i == 0) {
-		fprintf(stderr, "Error: Syntax error in configuration file `%s'.\n", global.conf_file);
-		conf_free(conf);
-		return NULL;
-	} else if (i == -1) {
-		config_missing++;
-		/* Whine after parsing the options if there was no -c pointing
-		   at a *valid* configuration file. */
-	}
-
-	while (argc > 0 && (opt = getopt(argc, argv, "i:p:P:nvIDFc:d:hu:V")) >= 0) {
-		/*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
-		if (opt == 'i') {
-			conf->iface_in = g_strdup(optarg);
-		} else if (opt == 'p') {
-			g_free(conf->port);
-			conf->port = g_strdup(optarg);
-		} else if (opt == 'P') {
-			g_free(conf->pidfile);
-			conf->pidfile = g_strdup(optarg);
-		} else if (opt == 'n') {
-			conf->nofork = 1;
-		} else if (opt == 'v') {
-			conf->verbose = 1;
-		} else if (opt == 'I') {
-			conf->runmode = RUNMODE_INETD;
-		} else if (opt == 'D') {
-			conf->runmode = RUNMODE_DAEMON;
-		} else if (opt == 'F') {
-			conf->runmode = RUNMODE_FORKDAEMON;
-		} else if (opt == 'c') {
-			if (strcmp(global.conf_file, optarg) != 0) {
-				g_free(global.conf_file);
-				global.conf_file = g_strdup(optarg);
-				conf_free(conf);
-				/* Re-evaluate arguments. Don't use this option twice,
-				   you'll end up in an infinite loop! Hope this trick
-				   works with all libcs BTW.. */
-				optind = 1;
-				return conf_load(argc, argv);
-			}
-		} else if (opt == 'd') {
-			g_free(conf->configdir);
-			conf->configdir = g_strdup(optarg);
-		} else if (opt == 'h') {
-			printf("Usage: bitlbee [-D/-F [-i <interface>] [-p <port>] [-n] [-v]] [-I]\n"
-			       "               [-c <file>] [-d <dir>] [-x] [-h]\n"
-			       "\n"
-			       "An IRC-to-other-chat-networks gateway\n"
-			       "\n"
-			       "  -I  Classic/InetD mode. (Default)\n"
-			       "  -D  Daemon mode. (one process serves all)\n"
-			       "  -F  Forking daemon. (one process per client)\n"
-			       "  -u  Run daemon as specified user.\n"
-			       "  -P  Specify PID-file (not for inetd mode)\n"
-			       "  -i  Specify the interface (by IP address) to listen on.\n"
-			       "      (Default: 0.0.0.0 (any interface))\n"
-			       "  -p  Port number to listen on. (Default: 6667)\n"
-			       "  -n  Don't fork.\n"
-			       "  -v  Be verbose (only works in combination with -n)\n"
-			       "  -c  Load alternative configuration file\n"
-			       "  -d  Specify alternative user configuration directory\n"
-			       "  -x  Command-line interface to password encryption/hashing\n"
-			       "  -h  Show this help page.\n"
-			       "  -V  Show version info.\n");
-			conf_free(conf);
-			return NULL;
-		} else if (opt == 'V') {
-			printf("BitlBee %s\n", BITLBEE_VERSION);
-			/* the rest of the version string is displayed below, for ld -vvv compatibility*/
-			version_happened = TRUE;
-		} else if (opt == 'u') {
-			g_free(conf->user);
-			conf->user = g_strdup(optarg);
-		}
-	}
-
-	if (version_happened) {
-		printf("API version %06x\nConfigure args: %s\n",
-		       BITLBEE_VERSION_CODE, BITLBEE_CONFIGURE_ARGS);
-		conf_free(conf);
-		return NULL;
-	}
-
-	if (conf->configdir[strlen(conf->configdir) - 1] != '/') {
-		char *s = g_new(char, strlen(conf->configdir) + 2);
-
-		sprintf(s, "%s/", conf->configdir);
-		g_free(conf->configdir);
+	
+	i = conf_loadini( conf, CONF_FILE );
+	if( i == 0 )
+	{
+		fprintf( stderr, "Error: Syntax error in configuration file `%s'.\n", CONF_FILE );
+		return( NULL );
+	}
+	else if( i == -1 )
+	{
+		fprintf( stderr, "Warning: Unable to read configuration file `%s'.\n", CONF_FILE );
+	}
+	
+	while( ( opt = getopt( argc, argv, "i:p:nvIDc:d:h" ) ) >= 0 )
+	{
+		if( opt == 'i' )
+		{
+			conf->iface = g_strdup( optarg );
+		}
+		else if( opt == 'p' )
+		{
+			if( ( sscanf( optarg, "%d", &i ) != 1 ) || ( i <= 0 ) || ( i > 65535 ) )
+			{
+				fprintf( stderr, "Invalid port number: %s\n", optarg );
+				return( NULL );
+			}
+			conf->port = i;
+		}
+		else if( opt == 'n' )
+			conf->nofork=1;
+		else if( opt == 'v' )
+			conf->verbose=1;
+		else if( opt == 'I' )
+			conf->runmode=RUNMODE_INETD;
+		else if( opt == 'D' )
+			conf->runmode=RUNMODE_DAEMON;
+		else if( opt == 'c' )
+		{
+			if( strcmp( CONF_FILE, optarg ) != 0 )
+			{
+				g_free( CONF_FILE );
+				CONF_FILE = g_strdup( optarg );
+				g_free( conf );
+				return( conf_load( argc, argv ) );
+			}
+		}
+		else if( opt == 'd' )
+		{
+			g_free( conf->configdir );
+			conf->configdir = g_strdup( optarg );
+		}
+		else if( opt == 'h' )
+		{
+			printf( "Usage: bitlbee [-D [-i <interface>] [-p <port>] [-n] [-v]] [-I]\n"
+			        "               [-c <file>] [-d <dir>] [-h]\n"
+			        "\n"
+			        "An IRC-to-other-chat-networks gateway\n"
+			        "\n"
+			        "  -I  Classic/InetD mode. (Default)\n"
+			        "  -D  Daemon mode. (Still EXPERIMENTAL!)\n"
+			        "  -i  Specify the interface (by IP address) to listen on.\n"
+			        "      (Default: 0.0.0.0 (any interface))\n"
+			        "  -p  Port number to listen on. (Default: 6667)\n"
+			        "  -n  Don't fork.\n"
+			        "  -v  Be verbose (only works in combination with -n)\n"
+			        "  -c  Load alternative configuration file\n"
+			        "  -d  Specify alternative user configuration directory\n"
+			        "  -h  Show this help page.\n" );
+			return( NULL );
+		}
+	}
+	
+	if( conf->configdir[strlen(conf->configdir)-1] != '/' )
+	{
+		char *s = g_new( char, strlen( conf->configdir ) + 2 );
+		
+		sprintf( s, "%s/", conf->configdir );
+		g_free( conf->configdir );
 		conf->configdir = s;
 	}
-
-	if (config_missing) {
-		fprintf(stderr, "Warning: Unable to read configuration file `%s'.\n", global.conf_file);
-	}
-
-	if (conf->cafile && access(conf->cafile, R_OK) != 0) {
-		/* Let's treat this as a serious problem so people won't think
-		   they're secure when in fact they're not. */
-		fprintf(stderr, "Error: Could not read CA file %s: %s\n", conf->cafile, strerror(errno));
-		conf_free(conf);
-		return NULL;
-	}
-
-	return conf;
+	
+	return( conf );
 }
 
-static void conf_free(conf_t *conf)
-{
-	/* Free software means users have the four essential freedoms:
-	   0. to run the program,
-	   2. to study and change the program in source code form,
-	   2. to redistribute exact copies, and
-	   3. to distribute modified versions
-	*/
-	g_free(conf->auth_pass);
-	g_free(conf->cafile);
-	g_free(conf->configdir);
-	g_free(conf->ft_listen);
-	g_free(conf->hostname);
-	g_free(conf->iface_in);
-	g_free(conf->iface_out);
-	g_free(conf->motdfile);
-	g_free(conf->oper_pass);
-	g_free(conf->pidfile);
-	g_free(conf->plugindir);
-	g_free(conf->port);
-	g_free(conf->primary_storage);
-	g_free(conf->user);
-	g_strfreev(conf->migrate_storage);
-	g_strfreev(conf->protocols);
-	g_free(conf);
-
-}
-
-static int conf_loadini(conf_t *conf, char *file)
+static int conf_loadini( conf_t *conf, char *file )
 {
 	ini_t *ini;
 	int i;
-
-	ini = ini_open(file);
-	if (ini == NULL) {
-		return -1;
-	}
-	while (ini_read(ini)) {
-		if (g_strcasecmp(ini->section, "settings") == 0) {
-			if (g_strcasecmp(ini->key, "runmode") == 0) {
-				if (g_strcasecmp(ini->value, "daemon") == 0) {
+	
+	ini = ini_open( file );
+	if( ini == NULL ) return( -1 );
+	while( ini_read( ini ) )
+	{
+		if( g_strcasecmp( ini->section, "settings" ) == 0 )
+		{
+			if( g_strcasecmp( ini->key, "runmode" ) == 0 )
+			{
+				if( g_strcasecmp( ini->value, "daemon" ) == 0 )
 					conf->runmode = RUNMODE_DAEMON;
-				} else if (g_strcasecmp(ini->value, "forkdaemon") == 0) {
-					conf->runmode = RUNMODE_FORKDAEMON;
-				} else {
+				else
 					conf->runmode = RUNMODE_INETD;
-				}
-			} else if (g_strcasecmp(ini->key, "pidfile") == 0) {
-				g_free(conf->pidfile);
-				conf->pidfile = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "daemoninterface") == 0) {
-				g_free(conf->iface_in);
-				conf->iface_in = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "daemonport") == 0) {
-				g_free(conf->port);
-				conf->port = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "clientinterface") == 0) {
-				g_free(conf->iface_out);
-				conf->iface_out = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "authmode") == 0) {
-				if (g_strcasecmp(ini->value, "registered") == 0) {
+			}
+			else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
+			{
+				conf->iface = g_strdup( ini->value );
+			}
+			else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )
+			{
+				if( ( sscanf( ini->value, "%d", &i ) != 1 ) || ( i <= 0 ) || ( i > 65535 ) )
+				{
+					fprintf( stderr, "Invalid port number: %s\n", ini->value );
+					return( 0 );
+				}
+				conf->port = i;
+			}
+			else if( g_strcasecmp( ini->key, "authmode" ) == 0 )
+			{
+				if( g_strcasecmp( ini->value, "registered" ) == 0 )
 					conf->authmode = AUTHMODE_REGISTERED;
-				} else if (g_strcasecmp(ini->value, "closed") == 0) {
+				else if( g_strcasecmp( ini->value, "closed" ) == 0 )
 					conf->authmode = AUTHMODE_CLOSED;
-				} else {
+				else
 					conf->authmode = AUTHMODE_OPEN;
-				}
-			} else if (g_strcasecmp(ini->key, "authbackend") == 0) {
-				if (g_strcasecmp(ini->value, "storage") == 0) {
-					conf->auth_backend = NULL;
-				} else if (g_strcasecmp(ini->value, "pam") == 0 ||
-				         g_strcasecmp(ini->value, "ldap") == 0) {
-					g_free(conf->auth_backend);
-					conf->auth_backend = g_strdup(ini->value);
-				} else {
-					fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
-					return 0;
-				}
-			} else if (g_strcasecmp(ini->key, "authpassword") == 0) {
-				g_free(conf->auth_pass);
-				conf->auth_pass = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "operpassword") == 0) {
-				g_free(conf->oper_pass);
-				conf->oper_pass = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "allowaccountadd") == 0) {
-				if (!is_bool(ini->value)) {
-					fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
-					return 0;
-				}
-				conf->allow_account_add = bool2int(ini->value);
-			} else if (g_strcasecmp(ini->key, "hostname") == 0) {
-				g_free(conf->hostname);
-				conf->hostname = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "configdir") == 0) {
-				g_free(conf->configdir);
-				conf->configdir = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "plugindir") == 0) {
-				g_free(conf->plugindir);
-				conf->plugindir = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "motdfile") == 0) {
-				g_free(conf->motdfile);
-				conf->motdfile = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "accountstorage") == 0 ||
-				   g_strcasecmp(ini->key, "account_storage") == 0) {
-				g_free(conf->primary_storage);
-				conf->primary_storage = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "accountstoragemigrate") == 0 ||
-				   g_strcasecmp(ini->key, "account_storage_migrate") == 0) {
-				g_strfreev(conf->migrate_storage);
-				conf->migrate_storage = g_strsplit_set(ini->value, " \t,;", -1);
-			} else if (g_strcasecmp(ini->key, "pinginterval") == 0) {
-				if (sscanf(ini->value, "%d", &i) != 1) {
-					fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
-					return 0;
+			}
+			else if( g_strcasecmp( ini->key, "authpassword" ) == 0 )
+			{
+				conf->password = g_strdup( ini->value );
+			}
+			else if( g_strcasecmp( ini->key, "hostname" ) == 0 )
+			{
+				conf->hostname = g_strdup( ini->value );
+			}
+			else if( g_strcasecmp( ini->key, "configdir" ) == 0 )
+			{
+				g_free( conf->configdir );
+				conf->configdir = g_strdup( ini->value );
+			}
+			else if( g_strcasecmp( ini->key, "motdfile" ) == 0 )
+			{
+				g_free( conf->motdfile );
+				conf->motdfile = g_strdup( ini->value );
+			}
+			else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
+			{
+				if( sscanf( ini->value, "%d", &i ) != 1 )
+				{
+					fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
+					return( 0 );
 				}
 				conf->ping_interval = i;
-			} else if (g_strcasecmp(ini->key, "pingtimeout") == 0) {
-				if (sscanf(ini->value, "%d", &i) != 1) {
-					fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
-					return 0;
+			}
+			else if( g_strcasecmp( ini->key, "pingtimeout" ) == 0 )
+			{
+				if( sscanf( ini->value, "%d", &i ) != 1 )
+				{
+					fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
+					return( 0 );
 				}
 				conf->ping_timeout = i;
-			} else if (g_strcasecmp(ini->key, "proxy") == 0) {
-				url_t *url = g_new0(url_t, 1);
-
-				if (!url_set(url, ini->value)) {
-					fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
-					g_free(url);
-					return 0;
-				}
-
-				strncpy(proxyhost, url->host, sizeof(proxyhost));
-				strncpy(proxyuser, url->user, sizeof(proxyuser));
-				strncpy(proxypass, url->pass, sizeof(proxypass));
+			}
+			else if( g_strcasecmp( ini->key, "proxy" ) == 0 )
+			{
+				url_t *url = g_new0( url_t, 1 );
+				
+				if( !url_set( url, ini->value ) )
+				{
+					fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
+					g_free( url );
+					return( 0 );
+				}
+				
+				strncpy( proxyhost, url->host, sizeof( proxyhost ) );
+				strncpy( proxyuser, url->user, sizeof( proxyuser ) );
+				strncpy( proxypass, url->pass, sizeof( proxypass ) );
 				proxyport = url->port;
-				if (url->proto == PROTO_HTTP) {
+				if( url->proto == PROTO_HTTP )
 					proxytype = PROXY_HTTP;
-				} else if (url->proto == PROTO_SOCKS4) {
+				else if( url->proto == PROTO_SOCKS4 )
 					proxytype = PROXY_SOCKS4;
-				} else if (url->proto == PROTO_SOCKS5) {
+				else if( url->proto == PROTO_SOCKS5 )
 					proxytype = PROXY_SOCKS5;
-				} else if (url->proto == PROTO_SOCKS4A) {
-					proxytype = PROXY_SOCKS4A;
-				}
-
-				g_free(url);
-			} else if (g_strcasecmp(ini->key, "user") == 0) {
-				g_free(conf->user);
-				conf->user = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "ft_max_size") == 0) {
-				size_t ft_max_size;
-				if (sscanf(ini->value, "%zu", &ft_max_size) != 1) {
-					fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
-					return 0;
-				}
-				conf->ft_max_size = ft_max_size;
-			} else if (g_strcasecmp(ini->key, "ft_max_kbps") == 0) {
-				if (sscanf(ini->value, "%d", &i) != 1) {
-					fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
-					return 0;
-				}
-				conf->ft_max_kbps = i;
-			} else if (g_strcasecmp(ini->key, "ft_listen") == 0) {
-				g_free(conf->ft_listen);
-				conf->ft_listen = g_strdup(ini->value);
-			} else if (g_strcasecmp(ini->key, "protocols") == 0) {
-				g_strfreev(conf->protocols);
-				conf->protocols = g_strsplit_set(ini->value, " \t,;", -1);
-			} else if (g_strcasecmp(ini->key, "cafile") == 0) {
-				g_free(conf->cafile);
-				conf->cafile = g_strdup(ini->value);
-			} else {
-				fprintf(stderr, "Error: Unknown setting `%s` in configuration file (line %d).\n",
-				        ini->key, ini->line);
-				return 0;
+				
+				g_free( url );
+			}
+			else
+			{
+				fprintf( stderr, "Error: Unknown setting `%s` in configuration file.\n", ini->key );
+				return( 0 );
 				/* For now just ignore unknown keys... */
 			}
-		} else if (g_strcasecmp(ini->section, "defaults") != 0) {
-			fprintf(stderr, "Error: Unknown section [%s] in configuration file (line %d). "
-			        "BitlBee configuration must be put in a [settings] section!\n", ini->section,
-			        ini->line);
-			return 0;
-		}
-	}
-	ini_close(ini);
-
-	return 1;
+		}
+		else if( g_strcasecmp( ini->section, "defaults" ) != 0 )
+		{
+			fprintf( stderr, "Error: Unknown section [%s] in configuration file. "
+			                 "BitlBee configuration must be put in a [settings] section!\n", ini->section );
+			return( 0 );
+		}
+	}
+	ini_close( ini );
+	
+	return( 1 );
 }
 
-void conf_loaddefaults(irc_t *irc)
+void conf_loaddefaults( irc_t *irc )
 {
 	ini_t *ini;
-
-	ini = ini_open(global.conf_file);
-	if (ini == NULL) {
-		return;
-	}
-	while (ini_read(ini)) {
-		if (g_strcasecmp(ini->section, "defaults") == 0) {
-			set_t *s = set_find(&irc->b->set, ini->key);
-
-			if (s) {
-				if (s->def) {
-					g_free(s->def);
-				}
-				s->def = g_strdup(ini->value);
-			}
-		}
-	}
-	ini_close(ini);
+	
+	ini = ini_open( CONF_FILE );
+	if( ini == NULL ) return;
+	while( ini_read( ini ) )
+	{
+		if( g_strcasecmp( ini->section, "defaults" ) == 0 )
+		{
+			set_t *s = set_find( irc, ini->key );
+			
+			if( s )
+			{
+				if( s->def ) g_free( s->def );
+				s->def = g_strdup( ini->value );
+			}
+		}
+	}
+	ini_close( ini );
 }
