source: conf.c @ f4a5940

Last change on this file since f4a5940 was f4a5940, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-01-15T20:31:59Z

Added REHASH command, IPC emulation in daemon (non-forked) mode.

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