source: conf.c @ 666722e

Last change on this file since 666722e was 5ebff60, checked in by dequis <dx@…>, at 2015-02-20T22:50:54Z

Reindent everything to K&R style with tabs

Used uncrustify, with the configuration file in ./doc/uncrustify.cfg

Commit author set to "Indent <please@…>" so that it's easier to
skip while doing git blame.

  • Property mode set to 100644
File size: 10.7 KB
RevLine 
[5ebff60]1/********************************************************************\
[b7d3cc34]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;
[6f10697]22  if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
23  Fifth Floor, Boston, MA  02110-1301  USA
[b7d3cc34]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
[5ebff60]38static int conf_loadini(conf_t *conf, char *file);
[b7d3cc34]39
[5ebff60]40conf_t *conf_load(int argc, char *argv[])
[b7d3cc34]41{
42        conf_t *conf;
[eeb85a8]43        int opt, i, config_missing = 0;
[5ebff60]44
45        conf = g_new0(conf_t, 1);
46
[aefaac3a]47        conf->iface_in = NULL;
48        conf->iface_out = NULL;
[5ebff60]49        conf->port = g_strdup("6667");
[b7d3cc34]50        conf->nofork = 0;
51        conf->verbose = 0;
[5ebff60]52        conf->primary_storage = g_strdup("xml");
53        conf->migrate_storage = g_strsplit("text", ",", -1);
[b7d3cc34]54        conf->runmode = RUNMODE_INETD;
55        conf->authmode = AUTHMODE_OPEN;
[d25f6fc]56        conf->auth_pass = NULL;
57        conf->oper_pass = NULL;
[5ebff60]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");
[b7d3cc34]62        conf->ping_interval = 180;
63        conf->ping_timeout = 300;
[aaf92a9]64        conf->user = NULL;
[a02f34f]65        conf->ft_max_size = SIZE_MAX;
66        conf->ft_max_kbps = G_MAXUINT;
67        conf->ft_listen = NULL;
[90cd6c4]68        conf->protocols = NULL;
[486ddb5]69        conf->cafile = NULL;
[f4a5940]70        proxytype = 0;
[5ebff60]71
72        i = conf_loadini(conf, global.conf_file);
73        if (i == 0) {
74                fprintf(stderr, "Error: Syntax error in configuration file `%s'.\n", global.conf_file);
[eeb85a8]75                return NULL;
[5ebff60]76        } else if (i == -1) {
77                config_missing++;
[eeb85a8]78                /* Whine after parsing the options if there was no -c pointing
79                   at a *valid* configuration file. */
[b7d3cc34]80        }
[5ebff60]81
82        while (argc > 0 && (opt = getopt(argc, argv, "i:p:P:nvIDFc:d:hu:V")) >= 0) {
83                /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
84                if (opt == 'i') {
85                        conf->iface_in = g_strdup(optarg);
86                } else if (opt == 'p') {
87                        g_free(conf->port);
88                        conf->port = g_strdup(optarg);
89                } else if (opt == 'P') {
90                        g_free(conf->pidfile);
91                        conf->pidfile = g_strdup(optarg);
92                } else if (opt == 'n') {
[74c119d]93                        conf->nofork = 1;
[5ebff60]94                } else if (opt == 'v') {
[74c119d]95                        conf->verbose = 1;
[5ebff60]96                } else if (opt == 'I') {
[74c119d]97                        conf->runmode = RUNMODE_INETD;
[5ebff60]98                } else if (opt == 'D') {
[74c119d]99                        conf->runmode = RUNMODE_DAEMON;
[5ebff60]100                } else if (opt == 'F') {
[74c119d]101                        conf->runmode = RUNMODE_FORKDAEMON;
[5ebff60]102                } else if (opt == 'c') {
103                        if (strcmp(global.conf_file, optarg) != 0) {
104                                g_free(global.conf_file);
105                                global.conf_file = g_strdup(optarg);
106                                g_free(conf);
107                                /* Re-evaluate arguments. Don't use this option twice,
[f4a5940]108                                   you'll end up in an infinite loop! Hope this trick
109                                   works with all libcs BTW.. */
[74c119d]110                                optind = 1;
[5ebff60]111                                return conf_load(argc, argv);
[b7d3cc34]112                        }
[5ebff60]113                } else if (opt == 'd') {
114                        g_free(conf->configdir);
115                        conf->configdir = g_strdup(optarg);
116                } else if (opt == 'h') {
117                        printf("Usage: bitlbee [-D/-F [-i <interface>] [-p <port>] [-n] [-v]] [-I]\n"
118                               "               [-c <file>] [-d <dir>] [-x] [-h]\n"
119                               "\n"
120                               "An IRC-to-other-chat-networks gateway\n"
121                               "\n"
122                               "  -I  Classic/InetD mode. (Default)\n"
123                               "  -D  Daemon mode. (one process serves all)\n"
124                               "  -F  Forking daemon. (one process per client)\n"
125                               "  -u  Run daemon as specified user.\n"
126                               "  -P  Specify PID-file (not for inetd mode)\n"
127                               "  -i  Specify the interface (by IP address) to listen on.\n"
128                               "      (Default: 0.0.0.0 (any interface))\n"
129                               "  -p  Port number to listen on. (Default: 6667)\n"
130                               "  -n  Don't fork.\n"
131                               "  -v  Be verbose (only works in combination with -n)\n"
132                               "  -c  Load alternative configuration file\n"
133                               "  -d  Specify alternative user configuration directory\n"
134                               "  -x  Command-line interface to password encryption/hashing\n"
135                               "  -h  Show this help page.\n"
136                               "  -V  Show version info.\n");
[3d1481f]137                        return NULL;
[5ebff60]138                } else if (opt == 'V') {
139                        printf("BitlBee %s\nAPI version %06x\n",
140                               BITLBEE_VERSION, BITLBEE_VERSION_CODE);
[eeb85a8]141                        return NULL;
[5ebff60]142                } else if (opt == 'u') {
143                        g_free(conf->user);
144                        conf->user = g_strdup(optarg);
[aaf92a9]145                }
[b7d3cc34]146        }
[5ebff60]147
148        if (conf->configdir[strlen(conf->configdir) - 1] != '/') {
149                char *s = g_new(char, strlen(conf->configdir) + 2);
150
151                sprintf(s, "%s/", conf->configdir);
152                g_free(conf->configdir);
[b7d3cc34]153                conf->configdir = s;
154        }
[5ebff60]155
156        if (config_missing) {
157                fprintf(stderr, "Warning: Unable to read configuration file `%s'.\n", global.conf_file);
158        }
159
160        if (conf->cafile && access(conf->cafile, R_OK) != 0) {
[af5764e]161                /* Let's treat this as a serious problem so people won't think
162                   they're secure when in fact they're not. */
[5ebff60]163                fprintf(stderr, "Error: Could not read CA file %s: %s\n", conf->cafile, strerror(errno));
[af5764e]164                return NULL;
165        }
[5ebff60]166
[eeb85a8]167        return conf;
[b7d3cc34]168}
169
[5ebff60]170static int conf_loadini(conf_t *conf, char *file)
[b7d3cc34]171{
172        ini_t *ini;
173        int i;
[5ebff60]174
175        ini = ini_open(file);
176        if (ini == NULL) {
177                return -1;
178        }
179        while (ini_read(ini)) {
180                if (g_strcasecmp(ini->section, "settings") == 0) {
181                        if (g_strcasecmp(ini->key, "runmode") == 0) {
182                                if (g_strcasecmp(ini->value, "daemon") == 0) {
[b7d3cc34]183                                        conf->runmode = RUNMODE_DAEMON;
[5ebff60]184                                } else if (g_strcasecmp(ini->value, "forkdaemon") == 0) {
[d25f6fc]185                                        conf->runmode = RUNMODE_FORKDAEMON;
[5ebff60]186                                } else {
[b7d3cc34]187                                        conf->runmode = RUNMODE_INETD;
[5ebff60]188                                }
189                        } else if (g_strcasecmp(ini->key, "pidfile") == 0) {
190                                g_free(conf->pidfile);
191                                conf->pidfile = g_strdup(ini->value);
192                        } else if (g_strcasecmp(ini->key, "daemoninterface") == 0) {
193                                g_free(conf->iface_in);
194                                conf->iface_in = g_strdup(ini->value);
195                        } else if (g_strcasecmp(ini->key, "daemonport") == 0) {
196                                g_free(conf->port);
197                                conf->port = g_strdup(ini->value);
198                        } else if (g_strcasecmp(ini->key, "clientinterface") == 0) {
199                                g_free(conf->iface_out);
200                                conf->iface_out = g_strdup(ini->value);
201                        } else if (g_strcasecmp(ini->key, "authmode") == 0) {
202                                if (g_strcasecmp(ini->value, "registered") == 0) {
[b7d3cc34]203                                        conf->authmode = AUTHMODE_REGISTERED;
[5ebff60]204                                } else if (g_strcasecmp(ini->value, "closed") == 0) {
[b7d3cc34]205                                        conf->authmode = AUTHMODE_CLOSED;
[5ebff60]206                                } else {
[b7d3cc34]207                                        conf->authmode = AUTHMODE_OPEN;
[5ebff60]208                                }
209                        } else if (g_strcasecmp(ini->key, "authpassword") == 0) {
210                                g_free(conf->auth_pass);
211                                conf->auth_pass = g_strdup(ini->value);
212                        } else if (g_strcasecmp(ini->key, "operpassword") == 0) {
213                                g_free(conf->oper_pass);
214                                conf->oper_pass = g_strdup(ini->value);
215                        } else if (g_strcasecmp(ini->key, "hostname") == 0) {
216                                g_free(conf->hostname);
217                                conf->hostname = g_strdup(ini->value);
218                        } else if (g_strcasecmp(ini->key, "configdir") == 0) {
219                                g_free(conf->configdir);
220                                conf->configdir = g_strdup(ini->value);
221                        } else if (g_strcasecmp(ini->key, "motdfile") == 0) {
222                                g_free(conf->motdfile);
223                                conf->motdfile = g_strdup(ini->value);
224                        } else if (g_strcasecmp(ini->key, "account_storage") == 0) {
225                                g_free(conf->primary_storage);
226                                conf->primary_storage = g_strdup(ini->value);
227                        } else if (g_strcasecmp(ini->key, "account_storage_migrate") == 0) {
228                                g_strfreev(conf->migrate_storage);
229                                conf->migrate_storage = g_strsplit_set(ini->value, " \t,;", -1);
230                        } else if (g_strcasecmp(ini->key, "pinginterval") == 0) {
231                                if (sscanf(ini->value, "%d", &i) != 1) {
232                                        fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
[eeb85a8]233                                        return 0;
[b7d3cc34]234                                }
235                                conf->ping_interval = i;
[5ebff60]236                        } else if (g_strcasecmp(ini->key, "pingtimeout") == 0) {
237                                if (sscanf(ini->value, "%d", &i) != 1) {
238                                        fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
[eeb85a8]239                                        return 0;
[b7d3cc34]240                                }
241                                conf->ping_timeout = i;
[5ebff60]242                        } else if (g_strcasecmp(ini->key, "proxy") == 0) {
243                                url_t *url = g_new0(url_t, 1);
244
245                                if (!url_set(url, ini->value)) {
246                                        fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
247                                        g_free(url);
[eeb85a8]248                                        return 0;
[b7d3cc34]249                                }
[5ebff60]250
251                                strncpy(proxyhost, url->host, sizeof(proxyhost));
252                                strncpy(proxyuser, url->user, sizeof(proxyuser));
253                                strncpy(proxypass, url->pass, sizeof(proxypass));
[b7d3cc34]254                                proxyport = url->port;
[5ebff60]255                                if (url->proto == PROTO_HTTP) {
[b7d3cc34]256                                        proxytype = PROXY_HTTP;
[5ebff60]257                                } else if (url->proto == PROTO_SOCKS4) {
[b7d3cc34]258                                        proxytype = PROXY_SOCKS4;
[5ebff60]259                                } else if (url->proto == PROTO_SOCKS5) {
[b7d3cc34]260                                        proxytype = PROXY_SOCKS5;
[5ebff60]261                                }
262
263                                g_free(url);
264                        } else if (g_strcasecmp(ini->key, "user") == 0) {
265                                g_free(conf->user);
266                                conf->user = g_strdup(ini->value);
267                        } else if (g_strcasecmp(ini->key, "ft_max_size") == 0) {
[a02f34f]268                                size_t ft_max_size;
[5ebff60]269                                if (sscanf(ini->value, "%zu", &ft_max_size) != 1) {
270                                        fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
[a02f34f]271                                        return 0;
272                                }
273                                conf->ft_max_size = ft_max_size;
[5ebff60]274                        } else if (g_strcasecmp(ini->key, "ft_max_kbps") == 0) {
275                                if (sscanf(ini->value, "%d", &i) != 1) {
276                                        fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
[a02f34f]277                                        return 0;
278                                }
279                                conf->ft_max_kbps = i;
[5ebff60]280                        } else if (g_strcasecmp(ini->key, "ft_listen") == 0) {
281                                g_free(conf->ft_listen);
282                                conf->ft_listen = g_strdup(ini->value);
283                        } else if (g_strcasecmp(ini->key, "protocols") == 0) {
284                                g_strfreev(conf->protocols);
285                                conf->protocols = g_strsplit_set(ini->value, " \t,;", -1);
286                        } else if (g_strcasecmp(ini->key, "cafile") == 0) {
287                                g_free(conf->cafile);
288                                conf->cafile = g_strdup(ini->value);
289                        } else {
290                                fprintf(stderr, "Error: Unknown setting `%s` in configuration file (line %d).\n",
291                                        ini->key, ini->line);
[eeb85a8]292                                return 0;
[b7d3cc34]293                                /* For now just ignore unknown keys... */
294                        }
[5ebff60]295                } else if (g_strcasecmp(ini->section, "defaults") != 0) {
296                        fprintf(stderr, "Error: Unknown section [%s] in configuration file (line %d). "
297                                "BitlBee configuration must be put in a [settings] section!\n", ini->section,
298                                ini->line);
[eeb85a8]299                        return 0;
[b7d3cc34]300                }
301        }
[5ebff60]302        ini_close(ini);
303
[eeb85a8]304        return 1;
[b7d3cc34]305}
306
[5ebff60]307void conf_loaddefaults(irc_t *irc)
[b7d3cc34]308{
309        ini_t *ini;
[5ebff60]310
311        ini = ini_open(global.conf_file);
312        if (ini == NULL) {
313                return;
314        }
315        while (ini_read(ini)) {
316                if (g_strcasecmp(ini->section, "defaults") == 0) {
317                        set_t *s = set_find(&irc->b->set, ini->key);
318
319                        if (s) {
320                                if (s->def) {
321                                        g_free(s->def);
322                                }
323                                s->def = g_strdup(ini->value);
[b7d3cc34]324                        }
325                }
326        }
[5ebff60]327        ini_close(ini);
[b7d3cc34]328}
Note: See TracBrowser for help on using the repository browser.