source: conf.c @ e9b755e

Last change on this file since e9b755e was e9b755e, checked in by Jelmer Vernooij <jelmer@…>, at 2007-10-18T16:44:25Z

Use standard functions for dealing with both IPv6 and IPv4.

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