source: conf.c @ deff040

Last change on this file since deff040 was 5c9512f, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-06-30T09:17:18Z

Made set.c API more generic so it's not specific to irc_t structures anymore,
but can be used for account_t structures too, for example.

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