source: conf.c @ 29c1456

Last change on this file since 29c1456 was b79308b, checked in by ulim <a.sporto+bee@…>, at 2008-04-14T13:10:53Z

merged in upstream r379 (somewhere after 1.2-3).
Just one trivial conflict in the jabber Makefile, went smoothly.

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