source: conf.c @ 57c4fc0

Last change on this file since 57c4fc0 was 54879ab, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-01-21T22:31:10Z

Added RESTART command (only for ForkDaemon mode) for easier upgrades.

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