source: conf.c @ 78b8401

Last change on this file since 78b8401 was 486ddb5, checked in by Wilmer van der Gaast <wilmer@…>, at 2011-12-19T14:50:58Z

Initial merge of tls_verify patch from AopicieR.

  • Property mode set to 100644
File size: 10.9 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->ft_max_size = SIZE_MAX;
66        conf->ft_max_kbps = G_MAXUINT;
67        conf->ft_listen = NULL;
68        conf->protocols = NULL;
69        conf->cafile = NULL;
70        proxytype = 0;
71       
72        i = conf_loadini( conf, global.conf_file );
73        if( i == 0 )
74        {
75                fprintf( stderr, "Error: Syntax error in configuration file `%s'.\n", global.conf_file );
76                return NULL;
77        }
78        else if( i == -1 )
79        {
80                config_missing ++;
81                /* Whine after parsing the options if there was no -c pointing
82                   at a *valid* configuration file. */
83        }
84       
85        while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hu:V" ) ) >= 0 )
86        /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
87        {
88                if( opt == 'i' )
89                {
90                        conf->iface_in = g_strdup( optarg );
91                }
92                else if( opt == 'p' )
93                {
94                        g_free( conf->port );
95                        conf->port = g_strdup( optarg );
96                }
97                else if( opt == 'P' )
98                {
99                        g_free( conf->pidfile );
100                        conf->pidfile = g_strdup( optarg );
101                }
102                else if( opt == 'n' )
103                        conf->nofork = 1;
104                else if( opt == 'v' )
105                        conf->verbose = 1;
106                else if( opt == 'I' )
107                        conf->runmode = RUNMODE_INETD;
108                else if( opt == 'D' )
109                        conf->runmode = RUNMODE_DAEMON;
110                else if( opt == 'F' )
111                        conf->runmode = RUNMODE_FORKDAEMON;
112                else if( opt == 'c' )
113                {
114                        if( strcmp( global.conf_file, optarg ) != 0 )
115                        {
116                                g_free( global.conf_file );
117                                global.conf_file = g_strdup( optarg );
118                                g_free( conf );
119                                /* Re-evaluate arguments. Don't use this option twice,
120                                   you'll end up in an infinite loop! Hope this trick
121                                   works with all libcs BTW.. */
122                                optind = 1;
123                                return conf_load( argc, argv );
124                        }
125                }
126                else if( opt == 'd' )
127                {
128                        g_free( conf->configdir );
129                        conf->configdir = g_strdup( optarg );
130                }
131                else if( opt == 'h' )
132                {
133                        printf( "Usage: bitlbee [-D/-F [-i <interface>] [-p <port>] [-n] [-v]] [-I]\n"
134                                "               [-c <file>] [-d <dir>] [-x] [-h]\n"
135                                "\n"
136                                "An IRC-to-other-chat-networks gateway\n"
137                                "\n"
138                                "  -I  Classic/InetD mode. (Default)\n"
139                                "  -D  Daemon mode. (one process serves all)\n"
140                                "  -F  Forking daemon. (one process per client)\n"
141                                "  -u  Run daemon as specified user.\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                                "  -x  Command-line interface to password encryption/hashing\n"
151                                "  -h  Show this help page.\n"
152                                "  -V  Show version info.\n" );
153                        return NULL;
154                }
155                else if( opt == 'V' )
156                {
157                        printf( "BitlBee %s\nAPI version %06x\n",
158                                BITLBEE_VERSION, BITLBEE_VERSION_CODE );
159                        return NULL;
160                }
161                else if( opt == 'u' )
162                {
163                        g_free( conf->user );
164                        conf->user = g_strdup( optarg );
165                }
166        }
167       
168        if( conf->configdir[strlen(conf->configdir)-1] != '/' )
169        {
170                char *s = g_new( char, strlen( conf->configdir ) + 2 );
171               
172                sprintf( s, "%s/", conf->configdir );
173                g_free( conf->configdir );
174                conf->configdir = s;
175        }
176       
177        if( config_missing )
178                fprintf( stderr, "Warning: Unable to read configuration file `%s'.\n", global.conf_file );
179       
180        return conf;
181}
182
183static int conf_loadini( conf_t *conf, char *file )
184{
185        ini_t *ini;
186        int i;
187       
188        ini = ini_open( file );
189        if( ini == NULL ) return -1;
190        while( ini_read( ini ) )
191        {
192                if( g_strcasecmp( ini->section, "settings" ) == 0 )
193                {
194                        if( g_strcasecmp( ini->key, "runmode" ) == 0 )
195                        {
196                                if( g_strcasecmp( ini->value, "daemon" ) == 0 )
197                                        conf->runmode = RUNMODE_DAEMON;
198                                else if( g_strcasecmp( ini->value, "forkdaemon" ) == 0 )
199                                        conf->runmode = RUNMODE_FORKDAEMON;
200                                else
201                                        conf->runmode = RUNMODE_INETD;
202                        }
203                        else if( g_strcasecmp( ini->key, "pidfile" ) == 0 )
204                        {
205                                g_free( conf->pidfile );
206                                conf->pidfile = g_strdup( ini->value );
207                        }
208                        else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
209                        {
210                                g_free( conf->iface_in );
211                                conf->iface_in = g_strdup( ini->value );
212                        }
213                        else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )
214                        {
215                                g_free( conf->port );
216                                conf->port = g_strdup( ini->value );
217                        }
218                        else if( g_strcasecmp( ini->key, "clientinterface" ) == 0 )
219                        {
220                                g_free( conf->iface_out );
221                                conf->iface_out = g_strdup( ini->value );
222                        }
223                        else if( g_strcasecmp( ini->key, "authmode" ) == 0 )
224                        {
225                                if( g_strcasecmp( ini->value, "registered" ) == 0 )
226                                        conf->authmode = AUTHMODE_REGISTERED;
227                                else if( g_strcasecmp( ini->value, "closed" ) == 0 )
228                                        conf->authmode = AUTHMODE_CLOSED;
229                                else
230                                        conf->authmode = AUTHMODE_OPEN;
231                        }
232                        else if( g_strcasecmp( ini->key, "authpassword" ) == 0 )
233                        {
234                                g_free( conf->auth_pass );
235                                conf->auth_pass = g_strdup( ini->value );
236                        }
237                        else if( g_strcasecmp( ini->key, "operpassword" ) == 0 )
238                        {
239                                g_free( conf->oper_pass );
240                                conf->oper_pass = g_strdup( ini->value );
241                        }
242                        else if( g_strcasecmp( ini->key, "hostname" ) == 0 )
243                        {
244                                g_free( conf->hostname );
245                                conf->hostname = g_strdup( ini->value );
246                        }
247                        else if( g_strcasecmp( ini->key, "configdir" ) == 0 )
248                        {
249                                g_free( conf->configdir );
250                                conf->configdir = g_strdup( ini->value );
251                        }
252                        else if( g_strcasecmp( ini->key, "motdfile" ) == 0 )
253                        {
254                                g_free( conf->motdfile );
255                                conf->motdfile = g_strdup( ini->value );
256                        }
257                        else if( g_strcasecmp( ini->key, "account_storage" ) == 0 )
258                        {
259                                g_free( conf->primary_storage );
260                                conf->primary_storage = g_strdup( ini->value );
261                        }
262                        else if( g_strcasecmp( ini->key, "account_storage_migrate" ) == 0 )
263                        {
264                                g_strfreev( conf->migrate_storage );
265                                conf->migrate_storage = g_strsplit_set( ini->value, " \t,;", -1 );
266                        }
267                        else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
268                        {
269                                if( sscanf( ini->value, "%d", &i ) != 1 )
270                                {
271                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
272                                        return 0;
273                                }
274                                conf->ping_interval = i;
275                        }
276                        else if( g_strcasecmp( ini->key, "pingtimeout" ) == 0 )
277                        {
278                                if( sscanf( ini->value, "%d", &i ) != 1 )
279                                {
280                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
281                                        return 0;
282                                }
283                                conf->ping_timeout = i;
284                        }
285                        else if( g_strcasecmp( ini->key, "proxy" ) == 0 )
286                        {
287                                url_t *url = g_new0( url_t, 1 );
288                               
289                                if( !url_set( url, ini->value ) )
290                                {
291                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
292                                        g_free( url );
293                                        return 0;
294                                }
295                               
296                                strncpy( proxyhost, url->host, sizeof( proxyhost ) );
297                                strncpy( proxyuser, url->user, sizeof( proxyuser ) );
298                                strncpy( proxypass, url->pass, sizeof( proxypass ) );
299                                proxyport = url->port;
300                                if( url->proto == PROTO_HTTP )
301                                        proxytype = PROXY_HTTP;
302                                else if( url->proto == PROTO_SOCKS4 )
303                                        proxytype = PROXY_SOCKS4;
304                                else if( url->proto == PROTO_SOCKS5 )
305                                        proxytype = PROXY_SOCKS5;
306                               
307                                g_free( url );
308                        }
309                        else if( g_strcasecmp( ini->key, "user" ) == 0 )
310                        {
311                                g_free( conf->user );
312                                conf->user = g_strdup( ini->value );
313                        }
314                        else if( g_strcasecmp( ini->key, "ft_max_size" ) == 0 )
315                        {
316                                size_t ft_max_size;
317                                if( sscanf( ini->value, "%zu", &ft_max_size ) != 1 )
318                                {
319                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
320                                        return 0;
321                                }
322                                conf->ft_max_size = ft_max_size;
323                        }
324                        else if( g_strcasecmp( ini->key, "ft_max_kbps" ) == 0 )
325                        {
326                                if( sscanf( ini->value, "%d", &i ) != 1 )
327                                {
328                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
329                                        return 0;
330                                }
331                                conf->ft_max_kbps = i;
332                        }
333                        else if( g_strcasecmp( ini->key, "ft_listen" ) == 0 )
334                        {
335                                g_free( conf->ft_listen );
336                                conf->ft_listen = g_strdup( ini->value );
337                        }
338                        else if( g_strcasecmp( ini->key, "protocols" ) == 0 )
339                        {
340                                g_strfreev( conf->protocols );
341                                conf->protocols = g_strsplit_set( ini->value, " \t,;", -1 );
342                        }
343                        else if( g_strcasecmp( ini->key, "cafile" ) == 0 )
344                        {
345                                g_free( conf->cafile );
346                                conf->cafile = g_strdup( ini->value );
347                        }
348                        else
349                        {
350                                fprintf( stderr, "Error: Unknown setting `%s` in configuration file (line %d).\n", ini->key, ini->line );
351                                return 0;
352                                /* For now just ignore unknown keys... */
353                        }
354                }
355                else if( g_strcasecmp( ini->section, "defaults" ) != 0 )
356                {
357                        fprintf( stderr, "Error: Unknown section [%s] in configuration file (line %d). "
358                                         "BitlBee configuration must be put in a [settings] section!\n", ini->section, ini->line );
359                        return 0;
360                }
361        }
362        ini_close( ini );
363       
364        return 1;
365}
366
367void conf_loaddefaults( irc_t *irc )
368{
369        ini_t *ini;
370       
371        ini = ini_open( global.conf_file );
372        if( ini == NULL ) return;
373        while( ini_read( ini ) )
374        {
375                if( g_strcasecmp( ini->section, "defaults" ) == 0 )
376                {
377                        set_t *s = set_find( &irc->b->set, ini->key );
378                       
379                        if( s )
380                        {
381                                if( s->def ) g_free( s->def );
382                                s->def = g_strdup( ini->value );
383                        }
384                }
385        }
386        ini_close( ini );
387}
Note: See TracBrowser for help on using the repository browser.