source: conf.c @ 7adc657

Last change on this file since 7adc657 was aaf92a9, checked in by Wilmer van der Gaast <wilmer@…>, at 2007-12-02T23:18:25Z

Imported setuid() patch from Simo Leone <simo@archlinux...> with some
modifications. Also adding some missing g_free()s to conf.c.

  • Property mode set to 100644
File size: 9.4 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
[df1694b]36#include "proxy.h"
[b7d3cc34]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       
[e9b755e]49        conf->iface = NULL;
[d75597b]50        conf->port = g_strdup( "6667" );
[b7d3cc34]51        conf->nofork = 0;
52        conf->verbose = 0;
[d75597b]53        conf->primary_storage = g_strdup( "xml" );
[00ab350]54        conf->migrate_storage = g_strsplit( "text", ",", -1 );
[b7d3cc34]55        conf->runmode = RUNMODE_INETD;
56        conf->authmode = AUTHMODE_OPEN;
[d25f6fc]57        conf->auth_pass = NULL;
58        conf->oper_pass = NULL;
[b7d3cc34]59        conf->configdir = g_strdup( CONFIG );
[4bfca70]60        conf->plugindir = g_strdup( PLUGINDIR );
[7e0af53]61        conf->pidfile = g_strdup( PIDFILE );
[b7d3cc34]62        conf->motdfile = g_strdup( ETCDIR "/motd.txt" );
63        conf->ping_interval = 180;
64        conf->ping_timeout = 300;
[aaf92a9]65        conf->user = NULL;
[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       
[aaf92a9]79        while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:" ) ) >= 0 )
[f4a5940]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                {
[e9b755e]88                        g_free( conf->port );
89                        conf->port = g_strdup( optarg );
[b7d3cc34]90                }
[dd89a55]91                else if( opt == 'P' )
[34b17d9]92                {
93                        g_free( conf->pidfile );
94                        conf->pidfile = g_strdup( optarg );
95                }
[b7d3cc34]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                {
[d4589cb]127                        printf( "Usage: bitlbee [-D/-F [-i <interface>] [-p <port>] [-n] [-v]] [-I]\n"
[b7d3cc34]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"
[aaf92a9]135                                "  -u  Run daemon as specified user.\n"
[7cf85e7]136                                "  -P  Specify PID-file (not for inetd mode)\n"
[b7d3cc34]137                                "  -i  Specify the interface (by IP address) to listen on.\n"
138                                "      (Default: 0.0.0.0 (any interface))\n"
139                                "  -p  Port number to listen on. (Default: 6667)\n"
140                                "  -n  Don't fork.\n"
141                                "  -v  Be verbose (only works in combination with -n)\n"
142                                "  -c  Load alternative configuration file\n"
143                                "  -d  Specify alternative user configuration directory\n"
144                                "  -h  Show this help page.\n" );
145                        return( NULL );
146                }
[54879ab]147                else if( opt == 'R' )
148                {
149                        /* We can't load the statefile yet (and should make very sure we do this
150                           only once), so set the filename here and load the state information
151                           when initializing ForkDaemon. (This option only makes sense in that
152                           mode anyway!) */
153                        ipc_master_set_statefile( optarg );
154                }
[aaf92a9]155                else if( opt == 'u' )
156                {
157                        g_free( conf->user );
158                        conf->user = g_strdup( optarg );
159                }
[b7d3cc34]160        }
161       
162        if( conf->configdir[strlen(conf->configdir)-1] != '/' )
163        {
164                char *s = g_new( char, strlen( conf->configdir ) + 2 );
165               
166                sprintf( s, "%s/", conf->configdir );
167                g_free( conf->configdir );
168                conf->configdir = s;
169        }
170       
171        return( conf );
172}
173
174static int conf_loadini( conf_t *conf, char *file )
175{
176        ini_t *ini;
177        int i;
178       
179        ini = ini_open( file );
180        if( ini == NULL ) return( -1 );
181        while( ini_read( ini ) )
182        {
183                if( g_strcasecmp( ini->section, "settings" ) == 0 )
184                {
185                        if( g_strcasecmp( ini->key, "runmode" ) == 0 )
186                        {
187                                if( g_strcasecmp( ini->value, "daemon" ) == 0 )
188                                        conf->runmode = RUNMODE_DAEMON;
[d25f6fc]189                                else if( g_strcasecmp( ini->value, "forkdaemon" ) == 0 )
190                                        conf->runmode = RUNMODE_FORKDAEMON;
[b7d3cc34]191                                else
192                                        conf->runmode = RUNMODE_INETD;
193                        }
[34b17d9]194                        else if( g_strcasecmp( ini->key, "pidfile" ) == 0 )
195                        {
196                                g_free( conf->pidfile );
197                                conf->pidfile = g_strdup( ini->value );
198                        }
[b7d3cc34]199                        else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
200                        {
[aaf92a9]201                                g_free( conf->iface );
[b7d3cc34]202                                conf->iface = g_strdup( ini->value );
203                        }
204                        else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )
205                        {
[aaf92a9]206                                g_free( conf->port );
[e9b755e]207                                conf->port = g_strdup( ini->value );
[b7d3cc34]208                        }
209                        else if( g_strcasecmp( ini->key, "authmode" ) == 0 )
210                        {
211                                if( g_strcasecmp( ini->value, "registered" ) == 0 )
212                                        conf->authmode = AUTHMODE_REGISTERED;
213                                else if( g_strcasecmp( ini->value, "closed" ) == 0 )
214                                        conf->authmode = AUTHMODE_CLOSED;
215                                else
216                                        conf->authmode = AUTHMODE_OPEN;
217                        }
218                        else if( g_strcasecmp( ini->key, "authpassword" ) == 0 )
219                        {
[aaf92a9]220                                g_free( conf->auth_pass );
[d25f6fc]221                                conf->auth_pass = g_strdup( ini->value );
222                        }
223                        else if( g_strcasecmp( ini->key, "operpassword" ) == 0 )
224                        {
[aaf92a9]225                                g_free( conf->oper_pass );
[d25f6fc]226                                conf->oper_pass = g_strdup( ini->value );
[b7d3cc34]227                        }
228                        else if( g_strcasecmp( ini->key, "hostname" ) == 0 )
229                        {
[aaf92a9]230                                g_free( conf->hostname );
[b7d3cc34]231                                conf->hostname = g_strdup( ini->value );
232                        }
233                        else if( g_strcasecmp( ini->key, "configdir" ) == 0 )
234                        {
235                                g_free( conf->configdir );
236                                conf->configdir = g_strdup( ini->value );
237                        }
238                        else if( g_strcasecmp( ini->key, "motdfile" ) == 0 )
239                        {
240                                g_free( conf->motdfile );
241                                conf->motdfile = g_strdup( ini->value );
[1ee6c18]242                        }
[b73ac9c]243                        else if( g_strcasecmp( ini->key, "account_storage" ) == 0 )
[1ee6c18]244                        {
[b73ac9c]245                                g_free( conf->primary_storage );
246                                conf->primary_storage = g_strdup( ini->value );
247                        }
248                        else if( g_strcasecmp( ini->key, "account_storage_migrate" ) == 0 )
249                        {
250                                g_strfreev( conf->migrate_storage );
251                                conf->migrate_storage = g_strsplit( ini->value, " \t,;", -1 );
[b7d3cc34]252                        }
253                        else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
254                        {
255                                if( sscanf( ini->value, "%d", &i ) != 1 )
256                                {
257                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
258                                        return( 0 );
259                                }
260                                conf->ping_interval = i;
261                        }
262                        else if( g_strcasecmp( ini->key, "pingtimeout" ) == 0 )
263                        {
264                                if( sscanf( ini->value, "%d", &i ) != 1 )
265                                {
266                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
267                                        return( 0 );
268                                }
269                                conf->ping_timeout = i;
270                        }
271                        else if( g_strcasecmp( ini->key, "proxy" ) == 0 )
272                        {
273                                url_t *url = g_new0( url_t, 1 );
274                               
275                                if( !url_set( url, ini->value ) )
276                                {
277                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
278                                        g_free( url );
279                                        return( 0 );
280                                }
281                               
282                                strncpy( proxyhost, url->host, sizeof( proxyhost ) );
283                                strncpy( proxyuser, url->user, sizeof( proxyuser ) );
284                                strncpy( proxypass, url->pass, sizeof( proxypass ) );
285                                proxyport = url->port;
286                                if( url->proto == PROTO_HTTP )
287                                        proxytype = PROXY_HTTP;
288                                else if( url->proto == PROTO_SOCKS4 )
289                                        proxytype = PROXY_SOCKS4;
290                                else if( url->proto == PROTO_SOCKS5 )
291                                        proxytype = PROXY_SOCKS5;
292                               
293                                g_free( url );
294                        }
[aaf92a9]295                        else if( g_strcasecmp( ini->key, "user" ) == 0 )
296                        {
297                                g_free( conf->user );
298                                conf->user = g_strdup( ini->value );
299                        }
[b7d3cc34]300                        else
301                        {
302                                fprintf( stderr, "Error: Unknown setting `%s` in configuration file.\n", ini->key );
303                                return( 0 );
304                                /* For now just ignore unknown keys... */
305                        }
306                }
307                else if( g_strcasecmp( ini->section, "defaults" ) != 0 )
308                {
309                        fprintf( stderr, "Error: Unknown section [%s] in configuration file. "
310                                         "BitlBee configuration must be put in a [settings] section!\n", ini->section );
311                        return( 0 );
312                }
313        }
314        ini_close( ini );
315       
316        return( 1 );
317}
318
319void conf_loaddefaults( irc_t *irc )
320{
321        ini_t *ini;
322       
323        ini = ini_open( CONF_FILE );
324        if( ini == NULL ) return;
325        while( ini_read( ini ) )
326        {
327                if( g_strcasecmp( ini->section, "defaults" ) == 0 )
328                {
[5c9512f]329                        set_t *s = set_find( &irc->set, ini->key );
[b7d3cc34]330                       
331                        if( s )
332                        {
333                                if( s->def ) g_free( s->def );
334                                s->def = g_strdup( ini->value );
335                        }
336                }
337        }
338        ini_close( ini );
339}
Note: See TracBrowser for help on using the repository browser.