source: conf.c @ 8961950

Last change on this file since 8961950 was 8961950, checked in by Sven Moritz Hallberg <sm@…>, at 2008-02-16T16:25:24Z

read root's welcome message from a file (like tho MOTD)

  • Property mode set to 100644
File size: 9.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"
[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" );
[8961950]63        conf->welcomefile = g_strdup( ETCDIR "/welcome.txt" );
[b7d3cc34]64        conf->ping_interval = 180;
65        conf->ping_timeout = 300;
[aaf92a9]66        conf->user = NULL;
[f4a5940]67        proxytype = 0;
[b7d3cc34]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       
[aaf92a9]80        while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:" ) ) >= 0 )
[f4a5940]81        /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
[b7d3cc34]82        {
83                if( opt == 'i' )
84                {
85                        conf->iface = g_strdup( optarg );
86                }
87                else if( opt == 'p' )
88                {
[e9b755e]89                        g_free( conf->port );
90                        conf->port = g_strdup( optarg );
[b7d3cc34]91                }
[dd89a55]92                else if( opt == 'P' )
[34b17d9]93                {
94                        g_free( conf->pidfile );
95                        conf->pidfile = g_strdup( optarg );
96                }
[b7d3cc34]97                else if( opt == 'n' )
[74c119d]98                        conf->nofork = 1;
[b7d3cc34]99                else if( opt == 'v' )
[74c119d]100                        conf->verbose = 1;
[b7d3cc34]101                else if( opt == 'I' )
[74c119d]102                        conf->runmode = RUNMODE_INETD;
[b7d3cc34]103                else if( opt == 'D' )
[74c119d]104                        conf->runmode = RUNMODE_DAEMON;
[d25f6fc]105                else if( opt == 'F' )
[74c119d]106                        conf->runmode = RUNMODE_FORKDAEMON;
[b7d3cc34]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 );
[f4a5940]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.. */
[74c119d]117                                optind = 1;
[b7d3cc34]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                {
[d4589cb]128                        printf( "Usage: bitlbee [-D/-F [-i <interface>] [-p <port>] [-n] [-v]] [-I]\n"
[b7d3cc34]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"
[d25f6fc]135                                "  -F  Forking daemon. (one process per client)\n"
[aaf92a9]136                                "  -u  Run daemon as specified user.\n"
[7cf85e7]137                                "  -P  Specify PID-file (not for inetd mode)\n"
[b7d3cc34]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                }
[54879ab]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                }
[aaf92a9]156                else if( opt == 'u' )
157                {
158                        g_free( conf->user );
159                        conf->user = g_strdup( optarg );
160                }
[b7d3cc34]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;
[d25f6fc]190                                else if( g_strcasecmp( ini->value, "forkdaemon" ) == 0 )
191                                        conf->runmode = RUNMODE_FORKDAEMON;
[b7d3cc34]192                                else
193                                        conf->runmode = RUNMODE_INETD;
194                        }
[34b17d9]195                        else if( g_strcasecmp( ini->key, "pidfile" ) == 0 )
196                        {
197                                g_free( conf->pidfile );
198                                conf->pidfile = g_strdup( ini->value );
199                        }
[b7d3cc34]200                        else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
201                        {
[aaf92a9]202                                g_free( conf->iface );
[b7d3cc34]203                                conf->iface = g_strdup( ini->value );
204                        }
205                        else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )
206                        {
[aaf92a9]207                                g_free( conf->port );
[e9b755e]208                                conf->port = g_strdup( ini->value );
[b7d3cc34]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                        {
[aaf92a9]221                                g_free( conf->auth_pass );
[d25f6fc]222                                conf->auth_pass = g_strdup( ini->value );
223                        }
224                        else if( g_strcasecmp( ini->key, "operpassword" ) == 0 )
225                        {
[aaf92a9]226                                g_free( conf->oper_pass );
[d25f6fc]227                                conf->oper_pass = g_strdup( ini->value );
[b7d3cc34]228                        }
229                        else if( g_strcasecmp( ini->key, "hostname" ) == 0 )
230                        {
[aaf92a9]231                                g_free( conf->hostname );
[b7d3cc34]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 );
[1ee6c18]243                        }
[8961950]244                        else if( g_strcasecmp( ini->key, "welcomefile" ) == 0 )
245                        {
246                                g_free( conf->welcomefile );
247                                conf->welcomefile = g_strdup( ini->value );
248                        }
[b73ac9c]249                        else if( g_strcasecmp( ini->key, "account_storage" ) == 0 )
[1ee6c18]250                        {
[b73ac9c]251                                g_free( conf->primary_storage );
252                                conf->primary_storage = g_strdup( ini->value );
253                        }
254                        else if( g_strcasecmp( ini->key, "account_storage_migrate" ) == 0 )
255                        {
256                                g_strfreev( conf->migrate_storage );
257                                conf->migrate_storage = g_strsplit( ini->value, " \t,;", -1 );
[b7d3cc34]258                        }
259                        else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
260                        {
261                                if( sscanf( ini->value, "%d", &i ) != 1 )
262                                {
263                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
264                                        return( 0 );
265                                }
266                                conf->ping_interval = i;
267                        }
268                        else if( g_strcasecmp( ini->key, "pingtimeout" ) == 0 )
269                        {
270                                if( sscanf( ini->value, "%d", &i ) != 1 )
271                                {
272                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
273                                        return( 0 );
274                                }
275                                conf->ping_timeout = i;
276                        }
277                        else if( g_strcasecmp( ini->key, "proxy" ) == 0 )
278                        {
279                                url_t *url = g_new0( url_t, 1 );
280                               
281                                if( !url_set( url, ini->value ) )
282                                {
283                                        fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
284                                        g_free( url );
285                                        return( 0 );
286                                }
287                               
288                                strncpy( proxyhost, url->host, sizeof( proxyhost ) );
289                                strncpy( proxyuser, url->user, sizeof( proxyuser ) );
290                                strncpy( proxypass, url->pass, sizeof( proxypass ) );
291                                proxyport = url->port;
292                                if( url->proto == PROTO_HTTP )
293                                        proxytype = PROXY_HTTP;
294                                else if( url->proto == PROTO_SOCKS4 )
295                                        proxytype = PROXY_SOCKS4;
296                                else if( url->proto == PROTO_SOCKS5 )
297                                        proxytype = PROXY_SOCKS5;
298                               
299                                g_free( url );
300                        }
[aaf92a9]301                        else if( g_strcasecmp( ini->key, "user" ) == 0 )
302                        {
303                                g_free( conf->user );
304                                conf->user = g_strdup( ini->value );
305                        }
[b7d3cc34]306                        else
307                        {
308                                fprintf( stderr, "Error: Unknown setting `%s` in configuration file.\n", ini->key );
309                                return( 0 );
310                                /* For now just ignore unknown keys... */
311                        }
312                }
313                else if( g_strcasecmp( ini->section, "defaults" ) != 0 )
314                {
315                        fprintf( stderr, "Error: Unknown section [%s] in configuration file. "
316                                         "BitlBee configuration must be put in a [settings] section!\n", ini->section );
317                        return( 0 );
318                }
319        }
320        ini_close( ini );
321       
322        return( 1 );
323}
324
325void conf_loaddefaults( irc_t *irc )
326{
327        ini_t *ini;
328       
329        ini = ini_open( CONF_FILE );
330        if( ini == NULL ) return;
331        while( ini_read( ini ) )
332        {
333                if( g_strcasecmp( ini->section, "defaults" ) == 0 )
334                {
[5c9512f]335                        set_t *s = set_find( &irc->set, ini->key );
[b7d3cc34]336                       
337                        if( s )
338                        {
339                                if( s->def ) g_free( s->def );
340                                s->def = g_strdup( ini->value );
341                        }
342                }
343        }
344        ini_close( ini );
345}
Note: See TracBrowser for help on using the repository browser.