source: conf.c @ 793cc25

Last change on this file since 793cc25 was 08135df, checked in by ulim <a.sporto+bee@…>, at 2007-12-04T01:08:43Z

Merged in current devel

Wilmer van der Gaast 2007-12-02 Imported setuid() patch from Simo Leone <simo@archlinux...> with some

Wilmer van der Gaast 2007-12-02 Forgot to return something in jabber_chat_join_failed().
Wilmer van der Gaast 2007-12-02 Merging a change I should've pulled before committing three other changes.
Wilmer van der Gaast 2007-12-02 Added charset checks on incoming msgs (from the IRC side) to prevent possible
Wilmer van der Gaast 2007-12-02 Handling of presence-error packets (only useful for groupchats now), moved
Wilmer van der Gaast 2007-12-02 Defining DEBUG via CFLAGS so that it'll always be there, even when a file
Wilmer van der Gaast 2007-12-02 Removed retarded printf() (ARGH) and moved the event handling handling of
Wilmer van der Gaast 2007-11-29 printf() in daemons considered harmful.
Wilmer van der Gaast 2007-11-28 Fixed the epoll+ForkDaemon combination. The libevent event handling

  • 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
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       
49        conf->iface = NULL;
50        conf->port = g_strdup( "6667" );
51        conf->nofork = 0;
52        conf->verbose = 0;
53        conf->primary_storage = g_strdup( "xml" );
54        conf->migrate_storage = g_strsplit( "text", ",", -1 );
55        conf->runmode = RUNMODE_INETD;
56        conf->authmode = AUTHMODE_OPEN;
57        conf->auth_pass = NULL;
58        conf->oper_pass = NULL;
59        conf->configdir = g_strdup( CONFIG );
60        conf->plugindir = g_strdup( PLUGINDIR );
61        conf->pidfile = g_strdup( PIDFILE );
62        conf->motdfile = g_strdup( ETCDIR "/motd.txt" );
63        conf->ping_interval = 180;
64        conf->ping_timeout = 300;
65        conf->user = NULL;
66        conf->max_filetransfer_size = G_MAXUINT;
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:hR:u:" ) ) >= 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                        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( CONF_FILE, optarg ) != 0 )
110                        {
111                                g_free( CONF_FILE );
112                                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. (Still EXPERIMENTAL!)\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 == 'R' )
149                {
150                        /* We can't load the statefile yet (and should make very sure we do this
151                           only once), so set the filename here and load the state information
152                           when initializing ForkDaemon. (This option only makes sense in that
153                           mode anyway!) */
154                        ipc_master_set_statefile( optarg );
155                }
156                else if( opt == 'u' )
157                {
158                        g_free( conf->user );
159                        conf->user = g_strdup( optarg );
160                }
161        }
162       
163        if( conf->configdir[strlen(conf->configdir)-1] != '/' )
164        {
165                char *s = g_new( char, strlen( conf->configdir ) + 2 );
166               
167                sprintf( s, "%s/", conf->configdir );
168                g_free( conf->configdir );
169                conf->configdir = s;
170        }
171       
172        return( conf );
173}
174
175static int conf_loadini( conf_t *conf, char *file )
176{
177        ini_t *ini;
178        int i;
179       
180        ini = ini_open( file );
181        if( ini == NULL ) return( -1 );
182        while( ini_read( ini ) )
183        {
184                if( g_strcasecmp( ini->section, "settings" ) == 0 )
185                {
186                        if( g_strcasecmp( ini->key, "runmode" ) == 0 )
187                        {
188                                if( g_strcasecmp( ini->value, "daemon" ) == 0 )
189                                        conf->runmode = RUNMODE_DAEMON;
190                                else if( g_strcasecmp( ini->value, "forkdaemon" ) == 0 )
191                                        conf->runmode = RUNMODE_FORKDAEMON;
192                                else
193                                        conf->runmode = RUNMODE_INETD;
194                        }
195                        else if( g_strcasecmp( ini->key, "pidfile" ) == 0 )
196                        {
197                                g_free( conf->pidfile );
198                                conf->pidfile = g_strdup( ini->value );
199                        }
200                        else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
201                        {
202                                g_free( conf->iface );
203                                conf->iface = g_strdup( ini->value );
204                        }
205                        else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )
206                        {
207                                g_free( conf->port );
208                                conf->port = 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( 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( 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.