source: conf.c @ 3355a82

Last change on this file since 3355a82 was c821e8a, checked in by ulim <a.sporto+bee@…>, at 2008-06-02T12:58:57Z

merged in upstream r384. No conflicts.

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