source: conf.c @ cd63d58

Last change on this file since cd63d58 was cd63d58, checked in by Wilmer van der Gaast <wilmer@…>, at 2008-06-29T12:47:39Z

Now using an environment variable instead of a flag to pass state info when
restarting the ForkDaemon. Preparing for a proper fallback when execv()
fails. (Bug #425)

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