source: conf.c @ 87f525e

Last change on this file since 87f525e was 87f525e, checked in by ulim <a.sporto+bee@…>, at 2008-08-10T10:42:52Z

Merged in upstream r416 which includes my msn_write_msg patch. w00t! ;)

  • Property mode set to 100644
File size: 9.8 KB
RevLine 
[b7d3cc34]1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
[c92e6801]4  * Copyright 2002-2005 Wilmer van der Gaast and others                *
[b7d3cc34]5  \********************************************************************/
6
7/* Configuration reading code                                           */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23  Suite 330, Boston, MA  02111-1307  USA
24*/
25
26#include "bitlbee.h"
27
28#include <stdio.h>
29#include <string.h>
30#include <stdlib.h>
31#include "conf.h"
32#include "ini.h"
33#include "url.h"
[54879ab]34#include "ipc.h"
[b7d3cc34]35
[df1694b]36#include "proxy.h"
[b7d3cc34]37
38static int conf_loadini( conf_t *conf, char *file );
39
40conf_t *conf_load( int argc, char *argv[] )
41{
42        conf_t *conf;
[eeb85a8]43        int opt, i, config_missing = 0;
[b7d3cc34]44       
45        conf = g_new0( conf_t, 1 );
46       
[aefaac3a]47        conf->iface_in = NULL;
48        conf->iface_out = NULL;
[d75597b]49        conf->port = g_strdup( "6667" );
[b7d3cc34]50        conf->nofork = 0;
51        conf->verbose = 0;
[d75597b]52        conf->primary_storage = g_strdup( "xml" );
[00ab350]53        conf->migrate_storage = g_strsplit( "text", ",", -1 );
[b7d3cc34]54        conf->runmode = RUNMODE_INETD;
55        conf->authmode = AUTHMODE_OPEN;
[d25f6fc]56        conf->auth_pass = NULL;
57        conf->oper_pass = NULL;
[b7d3cc34]58        conf->configdir = g_strdup( CONFIG );
[4bfca70]59        conf->plugindir = g_strdup( PLUGINDIR );
[7e0af53]60        conf->pidfile = g_strdup( PIDFILE );
[b7d3cc34]61        conf->motdfile = g_strdup( ETCDIR "/motd.txt" );
62        conf->ping_interval = 180;
63        conf->ping_timeout = 300;
[aaf92a9]64        conf->user = NULL;
[2c2df7d]65        conf->max_filetransfer_size = G_MAXUINT;
[f4a5940]66        proxytype = 0;
[b7d3cc34]67       
[eeb85a8]68        i = conf_loadini( conf, global.conf_file );
[b7d3cc34]69        if( i == 0 )
70        {
[eeb85a8]71                fprintf( stderr, "Error: Syntax error in configuration file `%s'.\n", global.conf_file );
72                return NULL;
[b7d3cc34]73        }
74        else if( i == -1 )
75        {
[eeb85a8]76                config_missing ++;
77                /* Whine after parsing the options if there was no -c pointing
78                   at a *valid* configuration file. */
[b7d3cc34]79        }
80       
[e0798cc]81        while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:" ) ) >= 0 )
[f4a5940]82        /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
[b7d3cc34]83        {
84                if( opt == 'i' )
85                {
[aefaac3a]86                        conf->iface_in = g_strdup( optarg );
[b7d3cc34]87                }
88                else if( opt == 'p' )
89                {
[e9b755e]90                        g_free( conf->port );
91                        conf->port = g_strdup( optarg );
[b7d3cc34]92                }
[dd89a55]93                else if( opt == 'P' )
[34b17d9]94                {
95                        g_free( conf->pidfile );
96                        conf->pidfile = g_strdup( optarg );
97                }
[b7d3cc34]98                else if( opt == 'n' )
[74c119d]99                        conf->nofork = 1;
[b7d3cc34]100                else if( opt == 'v' )
[74c119d]101                        conf->verbose = 1;
[b7d3cc34]102                else if( opt == 'I' )
[74c119d]103                        conf->runmode = RUNMODE_INETD;
[b7d3cc34]104                else if( opt == 'D' )
[74c119d]105                        conf->runmode = RUNMODE_DAEMON;
[d25f6fc]106                else if( opt == 'F' )
[74c119d]107                        conf->runmode = RUNMODE_FORKDAEMON;
[b7d3cc34]108                else if( opt == 'c' )
109                {
[eeb85a8]110                        if( strcmp( global.conf_file, optarg ) != 0 )
[b7d3cc34]111                        {
[eeb85a8]112                                g_free( global.conf_file );
113                                global.conf_file = g_strdup( optarg );
[b7d3cc34]114                                g_free( conf );
[f4a5940]115                                /* Re-evaluate arguments. Don't use this option twice,
116                                   you'll end up in an infinite loop! Hope this trick
117                                   works with all libcs BTW.. */
[74c119d]118                                optind = 1;
[eeb85a8]119                                return conf_load( argc, argv );
[b7d3cc34]120                        }
121                }
122                else if( opt == 'd' )
123                {
124                        g_free( conf->configdir );
125                        conf->configdir = g_strdup( optarg );
126                }
127                else if( opt == 'h' )
128                {
[d4589cb]129                        printf( "Usage: bitlbee [-D/-F [-i <interface>] [-p <port>] [-n] [-v]] [-I]\n"
[b7d3cc34]130                                "               [-c <file>] [-d <dir>] [-h]\n"
131                                "\n"
132                                "An IRC-to-other-chat-networks gateway\n"
133                                "\n"
134                                "  -I  Classic/InetD mode. (Default)\n"
[de8e584]135                                "  -D  Daemon mode. (one process serves all)\n"
[d25f6fc]136                                "  -F  Forking daemon. (one process per client)\n"
[aaf92a9]137                                "  -u  Run daemon as specified user.\n"
[7cf85e7]138                                "  -P  Specify PID-file (not for inetd mode)\n"
[b7d3cc34]139                                "  -i  Specify the interface (by IP address) to listen on.\n"
140                                "      (Default: 0.0.0.0 (any interface))\n"
141                                "  -p  Port number to listen on. (Default: 6667)\n"
142                                "  -n  Don't fork.\n"
143                                "  -v  Be verbose (only works in combination with -n)\n"
144                                "  -c  Load alternative configuration file\n"
145                                "  -d  Specify alternative user configuration directory\n"
146                                "  -h  Show this help page.\n" );
[eeb85a8]147                        return NULL;
[b7d3cc34]148                }
[e0798cc]149                else if( opt == 'R' )
150                {
151                        /* Backward compatibility; older BitlBees passed this
152                           info using a command-line flag. Allow people to
153                           upgrade from such a version for now. */
154                        setenv( "_BITLBEE_RESTART_STATE", optarg, 0 );
155                }
[aaf92a9]156                else if( opt == 'u' )
157                {
158                        g_free( conf->user );
159                        conf->user = g_strdup( optarg );
160                }
[b7d3cc34]161        }
162       
163        if( conf->configdir[strlen(conf->configdir)-1] != '/' )
164        {
165                char *s = g_new( char, strlen( conf->configdir ) + 2 );
166               
167                sprintf( s, "%s/", conf->configdir );
168                g_free( conf->configdir );
169                conf->configdir = s;
170        }
171       
[eeb85a8]172        if( config_missing )
173                fprintf( stderr, "Warning: Unable to read configuration file `%s'.\n", global.conf_file );
174       
175        return conf;
[b7d3cc34]176}
177
178static int conf_loadini( conf_t *conf, char *file )
179{
180        ini_t *ini;
181        int i;
182       
183        ini = ini_open( file );
[eeb85a8]184        if( ini == NULL ) return -1;
[b7d3cc34]185        while( ini_read( ini ) )
186        {
187                if( g_strcasecmp( ini->section, "settings" ) == 0 )
188                {
189                        if( g_strcasecmp( ini->key, "runmode" ) == 0 )
190                        {
191                                if( g_strcasecmp( ini->value, "daemon" ) == 0 )
192                                        conf->runmode = RUNMODE_DAEMON;
[d25f6fc]193                                else if( g_strcasecmp( ini->value, "forkdaemon" ) == 0 )
194                                        conf->runmode = RUNMODE_FORKDAEMON;
[b7d3cc34]195                                else
196                                        conf->runmode = RUNMODE_INETD;
197                        }
[34b17d9]198                        else if( g_strcasecmp( ini->key, "pidfile" ) == 0 )
199                        {
200                                g_free( conf->pidfile );
201                                conf->pidfile = g_strdup( ini->value );
202                        }
[b7d3cc34]203                        else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
204                        {
[aefaac3a]205                                g_free( conf->iface_in );
206                                conf->iface_in = g_strdup( ini->value );
[b7d3cc34]207                        }
208                        else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )
209                        {
[aaf92a9]210                                g_free( conf->port );
[e9b755e]211                                conf->port = g_strdup( ini->value );
[b7d3cc34]212                        }
[aefaac3a]213                        else if( g_strcasecmp( ini->key, "clientinterface" ) == 0 )
214                        {
215                                g_free( conf->iface_out );
216                                conf->iface_out = g_strdup( ini->value );
217                        }
[b7d3cc34]218                        else if( g_strcasecmp( ini->key, "authmode" ) == 0 )
219                        {
220                                if( g_strcasecmp( ini->value, "registered" ) == 0 )
221                                        conf->authmode = AUTHMODE_REGISTERED;
222                                else if( g_strcasecmp( ini->value, "closed" ) == 0 )
223                                        conf->authmode = AUTHMODE_CLOSED;
224                                else
225                                        conf->authmode = AUTHMODE_OPEN;
226                        }
227                        else if( g_strcasecmp( ini->key, "authpassword" ) == 0 )
228                        {
[aaf92a9]229                                g_free( conf->auth_pass );
[d25f6fc]230                                conf->auth_pass = g_strdup( ini->value );
231                        }
232                        else if( g_strcasecmp( ini->key, "operpassword" ) == 0 )
233                        {
[aaf92a9]234                                g_free( conf->oper_pass );
[d25f6fc]235                                conf->oper_pass = g_strdup( ini->value );
[b7d3cc34]236                        }
237                        else if( g_strcasecmp( ini->key, "hostname" ) == 0 )
238                        {
[aaf92a9]239                                g_free( conf->hostname );
[b7d3cc34]240                                conf->hostname = g_strdup( ini->value );
241                        }
242                        else if( g_strcasecmp( ini->key, "configdir" ) == 0 )
243                        {
244                                g_free( conf->configdir );
245                                conf->configdir = g_strdup( ini->value );
246                        }
247                        else if( g_strcasecmp( ini->key, "motdfile" ) == 0 )
248                        {
249                                g_free( conf->motdfile );
250                                conf->motdfile = g_strdup( ini->value );
[1ee6c18]251                        }
[b73ac9c]252                        else if( g_strcasecmp( ini->key, "account_storage" ) == 0 )
[1ee6c18]253                        {
[b73ac9c]254                                g_free( conf->primary_storage );
255                                conf->primary_storage = g_strdup( ini->value );
256                        }
257                        else if( g_strcasecmp( ini->key, "account_storage_migrate" ) == 0 )
258                        {
259                                g_strfreev( conf->migrate_storage );
[dd14ecc]260                                conf->migrate_storage = g_strsplit_set( ini->value, " \t,;", -1 );
[b7d3cc34]261                        }
262                        else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
263                        {
264                                if( sscanf( ini->value, "%d", &i ) != 1 )
265                                {
266                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
[eeb85a8]267                                        return 0;
[b7d3cc34]268                                }
269                                conf->ping_interval = i;
270                        }
271                        else if( g_strcasecmp( ini->key, "pingtimeout" ) == 0 )
272                        {
273                                if( sscanf( ini->value, "%d", &i ) != 1 )
274                                {
275                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
[eeb85a8]276                                        return 0;
[b7d3cc34]277                                }
278                                conf->ping_timeout = i;
279                        }
280                        else if( g_strcasecmp( ini->key, "proxy" ) == 0 )
281                        {
282                                url_t *url = g_new0( url_t, 1 );
283                               
284                                if( !url_set( url, ini->value ) )
285                                {
286                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
287                                        g_free( url );
[eeb85a8]288                                        return 0;
[b7d3cc34]289                                }
290                               
291                                strncpy( proxyhost, url->host, sizeof( proxyhost ) );
292                                strncpy( proxyuser, url->user, sizeof( proxyuser ) );
293                                strncpy( proxypass, url->pass, sizeof( proxypass ) );
294                                proxyport = url->port;
295                                if( url->proto == PROTO_HTTP )
296                                        proxytype = PROXY_HTTP;
297                                else if( url->proto == PROTO_SOCKS4 )
298                                        proxytype = PROXY_SOCKS4;
299                                else if( url->proto == PROTO_SOCKS5 )
300                                        proxytype = PROXY_SOCKS5;
301                               
302                                g_free( url );
303                        }
[aaf92a9]304                        else if( g_strcasecmp( ini->key, "user" ) == 0 )
305                        {
306                                g_free( conf->user );
307                                conf->user = g_strdup( ini->value );
308                        }
[b7d3cc34]309                        else
310                        {
311                                fprintf( stderr, "Error: Unknown setting `%s` in configuration file.\n", ini->key );
[eeb85a8]312                                return 0;
[b7d3cc34]313                                /* For now just ignore unknown keys... */
314                        }
315                }
316                else if( g_strcasecmp( ini->section, "defaults" ) != 0 )
317                {
318                        fprintf( stderr, "Error: Unknown section [%s] in configuration file. "
319                                         "BitlBee configuration must be put in a [settings] section!\n", ini->section );
[eeb85a8]320                        return 0;
[b7d3cc34]321                }
322        }
323        ini_close( ini );
324       
[eeb85a8]325        return 1;
[b7d3cc34]326}
327
328void conf_loaddefaults( irc_t *irc )
329{
330        ini_t *ini;
331       
[eeb85a8]332        ini = ini_open( global.conf_file );
[b7d3cc34]333        if( ini == NULL ) return;
334        while( ini_read( ini ) )
335        {
336                if( g_strcasecmp( ini->section, "defaults" ) == 0 )
337                {
[5c9512f]338                        set_t *s = set_find( &irc->set, ini->key );
[b7d3cc34]339                       
340                        if( s )
341                        {
342                                if( s->def ) g_free( s->def );
343                                s->def = g_strdup( ini->value );
344                        }
345                }
346        }
347        ini_close( ini );
348}
Note: See TracBrowser for help on using the repository browser.