source: conf.c @ ddcf491f

Last change on this file since ddcf491f was eeb85a8, checked in by Wilmer van der Gaast <wilmer@…>, at 2008-02-11T12:35:01Z

Got rid of some noise at startup: complaining when the default configuration
file couldn't be found while the user specified an alternative location with
the -c option, and double complaints about /var/lib/bitlbee/ permissions.

  • Property mode set to 100644
File size: 9.6 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       
[e9b755e]47        conf->iface = NULL;
[d75597b]48        conf->port = g_strdup( "6667" );
[b7d3cc34]49        conf->nofork = 0;
50        conf->verbose = 0;
[d75597b]51        conf->primary_storage = g_strdup( "xml" );
[00ab350]52        conf->migrate_storage = g_strsplit( "text", ",", -1 );
[b7d3cc34]53        conf->runmode = RUNMODE_INETD;
54        conf->authmode = AUTHMODE_OPEN;
[d25f6fc]55        conf->auth_pass = NULL;
56        conf->oper_pass = NULL;
[b7d3cc34]57        conf->configdir = g_strdup( CONFIG );
[4bfca70]58        conf->plugindir = g_strdup( PLUGINDIR );
[7e0af53]59        conf->pidfile = g_strdup( PIDFILE );
[b7d3cc34]60        conf->motdfile = g_strdup( ETCDIR "/motd.txt" );
61        conf->ping_interval = 180;
62        conf->ping_timeout = 300;
[aaf92a9]63        conf->user = NULL;
[f4a5940]64        proxytype = 0;
[b7d3cc34]65       
[eeb85a8]66        i = conf_loadini( conf, global.conf_file );
[b7d3cc34]67        if( i == 0 )
68        {
[eeb85a8]69                fprintf( stderr, "Error: Syntax error in configuration file `%s'.\n", global.conf_file );
70                return NULL;
[b7d3cc34]71        }
72        else if( i == -1 )
73        {
[eeb85a8]74                config_missing ++;
75                /* Whine after parsing the options if there was no -c pointing
76                   at a *valid* configuration file. */
[b7d3cc34]77        }
78       
[aaf92a9]79        while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:" ) ) >= 0 )
[f4a5940]80        /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
[b7d3cc34]81        {
82                if( opt == 'i' )
83                {
84                        conf->iface = g_strdup( optarg );
85                }
86                else if( opt == 'p' )
87                {
[e9b755e]88                        g_free( conf->port );
89                        conf->port = g_strdup( optarg );
[b7d3cc34]90                }
[dd89a55]91                else if( opt == 'P' )
[34b17d9]92                {
93                        g_free( conf->pidfile );
94                        conf->pidfile = g_strdup( optarg );
95                }
[b7d3cc34]96                else if( opt == 'n' )
[74c119d]97                        conf->nofork = 1;
[b7d3cc34]98                else if( opt == 'v' )
[74c119d]99                        conf->verbose = 1;
[b7d3cc34]100                else if( opt == 'I' )
[74c119d]101                        conf->runmode = RUNMODE_INETD;
[b7d3cc34]102                else if( opt == 'D' )
[74c119d]103                        conf->runmode = RUNMODE_DAEMON;
[d25f6fc]104                else if( opt == 'F' )
[74c119d]105                        conf->runmode = RUNMODE_FORKDAEMON;
[b7d3cc34]106                else if( opt == 'c' )
107                {
[eeb85a8]108                        if( strcmp( global.conf_file, optarg ) != 0 )
[b7d3cc34]109                        {
[eeb85a8]110                                g_free( global.conf_file );
111                                global.conf_file = g_strdup( optarg );
[b7d3cc34]112                                g_free( conf );
[f4a5940]113                                /* Re-evaluate arguments. Don't use this option twice,
114                                   you'll end up in an infinite loop! Hope this trick
115                                   works with all libcs BTW.. */
[74c119d]116                                optind = 1;
[eeb85a8]117                                return conf_load( argc, argv );
[b7d3cc34]118                        }
119                }
120                else if( opt == 'd' )
121                {
122                        g_free( conf->configdir );
123                        conf->configdir = g_strdup( optarg );
124                }
125                else if( opt == 'h' )
126                {
[d4589cb]127                        printf( "Usage: bitlbee [-D/-F [-i <interface>] [-p <port>] [-n] [-v]] [-I]\n"
[b7d3cc34]128                                "               [-c <file>] [-d <dir>] [-h]\n"
129                                "\n"
130                                "An IRC-to-other-chat-networks gateway\n"
131                                "\n"
132                                "  -I  Classic/InetD mode. (Default)\n"
133                                "  -D  Daemon mode. (Still EXPERIMENTAL!)\n"
[d25f6fc]134                                "  -F  Forking daemon. (one process per client)\n"
[aaf92a9]135                                "  -u  Run daemon as specified user.\n"
[7cf85e7]136                                "  -P  Specify PID-file (not for inetd mode)\n"
[b7d3cc34]137                                "  -i  Specify the interface (by IP address) to listen on.\n"
138                                "      (Default: 0.0.0.0 (any interface))\n"
139                                "  -p  Port number to listen on. (Default: 6667)\n"
140                                "  -n  Don't fork.\n"
141                                "  -v  Be verbose (only works in combination with -n)\n"
142                                "  -c  Load alternative configuration file\n"
143                                "  -d  Specify alternative user configuration directory\n"
144                                "  -h  Show this help page.\n" );
[eeb85a8]145                        return NULL;
[b7d3cc34]146                }
[54879ab]147                else if( opt == 'R' )
148                {
149                        /* We can't load the statefile yet (and should make very sure we do this
150                           only once), so set the filename here and load the state information
151                           when initializing ForkDaemon. (This option only makes sense in that
152                           mode anyway!) */
153                        ipc_master_set_statefile( optarg );
154                }
[aaf92a9]155                else if( opt == 'u' )
156                {
157                        g_free( conf->user );
158                        conf->user = g_strdup( optarg );
159                }
[b7d3cc34]160        }
161       
162        if( conf->configdir[strlen(conf->configdir)-1] != '/' )
163        {
164                char *s = g_new( char, strlen( conf->configdir ) + 2 );
165               
166                sprintf( s, "%s/", conf->configdir );
167                g_free( conf->configdir );
168                conf->configdir = s;
169        }
170       
[eeb85a8]171        if( config_missing )
172                fprintf( stderr, "Warning: Unable to read configuration file `%s'.\n", global.conf_file );
173       
174        return conf;
[b7d3cc34]175}
176
177static int conf_loadini( conf_t *conf, char *file )
178{
179        ini_t *ini;
180        int i;
181       
182        ini = ini_open( file );
[eeb85a8]183        if( ini == NULL ) return -1;
[b7d3cc34]184        while( ini_read( ini ) )
185        {
186                if( g_strcasecmp( ini->section, "settings" ) == 0 )
187                {
188                        if( g_strcasecmp( ini->key, "runmode" ) == 0 )
189                        {
190                                if( g_strcasecmp( ini->value, "daemon" ) == 0 )
191                                        conf->runmode = RUNMODE_DAEMON;
[d25f6fc]192                                else if( g_strcasecmp( ini->value, "forkdaemon" ) == 0 )
193                                        conf->runmode = RUNMODE_FORKDAEMON;
[b7d3cc34]194                                else
195                                        conf->runmode = RUNMODE_INETD;
196                        }
[34b17d9]197                        else if( g_strcasecmp( ini->key, "pidfile" ) == 0 )
198                        {
199                                g_free( conf->pidfile );
200                                conf->pidfile = g_strdup( ini->value );
201                        }
[b7d3cc34]202                        else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
203                        {
[aaf92a9]204                                g_free( conf->iface );
[b7d3cc34]205                                conf->iface = g_strdup( ini->value );
206                        }
207                        else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )
208                        {
[aaf92a9]209                                g_free( conf->port );
[e9b755e]210                                conf->port = g_strdup( ini->value );
[b7d3cc34]211                        }
212                        else if( g_strcasecmp( ini->key, "authmode" ) == 0 )
213                        {
214                                if( g_strcasecmp( ini->value, "registered" ) == 0 )
215                                        conf->authmode = AUTHMODE_REGISTERED;
216                                else if( g_strcasecmp( ini->value, "closed" ) == 0 )
217                                        conf->authmode = AUTHMODE_CLOSED;
218                                else
219                                        conf->authmode = AUTHMODE_OPEN;
220                        }
221                        else if( g_strcasecmp( ini->key, "authpassword" ) == 0 )
222                        {
[aaf92a9]223                                g_free( conf->auth_pass );
[d25f6fc]224                                conf->auth_pass = g_strdup( ini->value );
225                        }
226                        else if( g_strcasecmp( ini->key, "operpassword" ) == 0 )
227                        {
[aaf92a9]228                                g_free( conf->oper_pass );
[d25f6fc]229                                conf->oper_pass = g_strdup( ini->value );
[b7d3cc34]230                        }
231                        else if( g_strcasecmp( ini->key, "hostname" ) == 0 )
232                        {
[aaf92a9]233                                g_free( conf->hostname );
[b7d3cc34]234                                conf->hostname = g_strdup( ini->value );
235                        }
236                        else if( g_strcasecmp( ini->key, "configdir" ) == 0 )
237                        {
238                                g_free( conf->configdir );
239                                conf->configdir = g_strdup( ini->value );
240                        }
241                        else if( g_strcasecmp( ini->key, "motdfile" ) == 0 )
242                        {
243                                g_free( conf->motdfile );
244                                conf->motdfile = g_strdup( ini->value );
[1ee6c18]245                        }
[b73ac9c]246                        else if( g_strcasecmp( ini->key, "account_storage" ) == 0 )
[1ee6c18]247                        {
[b73ac9c]248                                g_free( conf->primary_storage );
249                                conf->primary_storage = g_strdup( ini->value );
250                        }
251                        else if( g_strcasecmp( ini->key, "account_storage_migrate" ) == 0 )
252                        {
253                                g_strfreev( conf->migrate_storage );
254                                conf->migrate_storage = g_strsplit( ini->value, " \t,;", -1 );
[b7d3cc34]255                        }
256                        else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
257                        {
258                                if( sscanf( ini->value, "%d", &i ) != 1 )
259                                {
260                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
[eeb85a8]261                                        return 0;
[b7d3cc34]262                                }
263                                conf->ping_interval = i;
264                        }
265                        else if( g_strcasecmp( ini->key, "pingtimeout" ) == 0 )
266                        {
267                                if( sscanf( ini->value, "%d", &i ) != 1 )
268                                {
269                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
[eeb85a8]270                                        return 0;
[b7d3cc34]271                                }
272                                conf->ping_timeout = i;
273                        }
274                        else if( g_strcasecmp( ini->key, "proxy" ) == 0 )
275                        {
276                                url_t *url = g_new0( url_t, 1 );
277                               
278                                if( !url_set( url, ini->value ) )
279                                {
280                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
281                                        g_free( url );
[eeb85a8]282                                        return 0;
[b7d3cc34]283                                }
284                               
285                                strncpy( proxyhost, url->host, sizeof( proxyhost ) );
286                                strncpy( proxyuser, url->user, sizeof( proxyuser ) );
287                                strncpy( proxypass, url->pass, sizeof( proxypass ) );
288                                proxyport = url->port;
289                                if( url->proto == PROTO_HTTP )
290                                        proxytype = PROXY_HTTP;
291                                else if( url->proto == PROTO_SOCKS4 )
292                                        proxytype = PROXY_SOCKS4;
293                                else if( url->proto == PROTO_SOCKS5 )
294                                        proxytype = PROXY_SOCKS5;
295                               
296                                g_free( url );
297                        }
[aaf92a9]298                        else if( g_strcasecmp( ini->key, "user" ) == 0 )
299                        {
300                                g_free( conf->user );
301                                conf->user = g_strdup( ini->value );
302                        }
[b7d3cc34]303                        else
304                        {
305                                fprintf( stderr, "Error: Unknown setting `%s` in configuration file.\n", ini->key );
[eeb85a8]306                                return 0;
[b7d3cc34]307                                /* For now just ignore unknown keys... */
308                        }
309                }
310                else if( g_strcasecmp( ini->section, "defaults" ) != 0 )
311                {
312                        fprintf( stderr, "Error: Unknown section [%s] in configuration file. "
313                                         "BitlBee configuration must be put in a [settings] section!\n", ini->section );
[eeb85a8]314                        return 0;
[b7d3cc34]315                }
316        }
317        ini_close( ini );
318       
[eeb85a8]319        return 1;
[b7d3cc34]320}
321
322void conf_loaddefaults( irc_t *irc )
323{
324        ini_t *ini;
325       
[eeb85a8]326        ini = ini_open( global.conf_file );
[b7d3cc34]327        if( ini == NULL ) return;
328        while( ini_read( ini ) )
329        {
330                if( g_strcasecmp( ini->section, "defaults" ) == 0 )
331                {
[5c9512f]332                        set_t *s = set_find( &irc->set, ini->key );
[b7d3cc34]333                       
334                        if( s )
335                        {
336                                if( s->def ) g_free( s->def );
337                                s->def = g_strdup( ini->value );
338                        }
339                }
340        }
341        ini_close( ini );
342}
Note: See TracBrowser for help on using the repository browser.