source: conf.c @ 2befb95

Last change on this file since 2befb95 was 2befb95, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-06-20T21:37:16Z

Added migration storage defaults.

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