source: conf.c @ 34b17d9

Last change on this file since 34b17d9 was 34b17d9, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-02-02T13:21:44Z

Added PID-file code.

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