source: conf.c @ d16e951

Last change on this file since d16e951 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
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., 51 Franklin St.,
23  Fifth Floor, Boston, MA  02110-1301  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
38static int conf_loadini(conf_t *conf, char *file);
39
40conf_t *conf_load(int argc, char *argv[])
41{
42        conf_t *conf;
43        int opt, i, config_missing = 0;
44
45        conf = g_new0(conf_t, 1);
46
47        conf->iface_in = NULL;
48        conf->iface_out = NULL;
49        conf->port = g_strdup("6667");
50        conf->nofork = 0;
51        conf->verbose = 0;
52        conf->primary_storage = g_strdup("xml");
53        conf->migrate_storage = g_strsplit("text", ",", -1);
54        conf->runmode = RUNMODE_INETD;
55        conf->authmode = AUTHMODE_OPEN;
56        conf->auth_pass = NULL;
57        conf->oper_pass = NULL;
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");
62        conf->ping_interval = 180;
63        conf->ping_timeout = 300;
64        conf->user = NULL;
65        conf->ft_max_size = SIZE_MAX;
66        conf->ft_max_kbps = G_MAXUINT;
67        conf->ft_listen = NULL;
68        conf->protocols = NULL;
69        conf->cafile = NULL;
70        proxytype = 0;
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);
75                return NULL;
76        } else if (i == -1) {
77                config_missing++;
78                /* Whine after parsing the options if there was no -c pointing
79                   at a *valid* configuration file. */
80        }
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') {
93                        conf->nofork = 1;
94                } else if (opt == 'v') {
95                        conf->verbose = 1;
96                } else if (opt == 'I') {
97                        conf->runmode = RUNMODE_INETD;
98                } else if (opt == 'D') {
99                        conf->runmode = RUNMODE_DAEMON;
100                } else if (opt == 'F') {
101                        conf->runmode = RUNMODE_FORKDAEMON;
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,
108                                   you'll end up in an infinite loop! Hope this trick
109                                   works with all libcs BTW.. */
110                                optind = 1;
111                                return conf_load(argc, argv);
112                        }
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");
137                        return NULL;
138                } else if (opt == 'V') {
139                        printf("BitlBee %s\nAPI version %06x\n",
140                               BITLBEE_VERSION, BITLBEE_VERSION_CODE);
141                        return NULL;
142                } else if (opt == 'u') {
143                        g_free(conf->user);
144                        conf->user = g_strdup(optarg);
145                }
146        }
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);
153                conf->configdir = s;
154        }
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) {
161                /* Let's treat this as a serious problem so people won't think
162                   they're secure when in fact they're not. */
163                fprintf(stderr, "Error: Could not read CA file %s: %s\n", conf->cafile, strerror(errno));
164                return NULL;
165        }
166
167        return conf;
168}
169
170static int conf_loadini(conf_t *conf, char *file)
171{
172        ini_t *ini;
173        int i;
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) {
183                                        conf->runmode = RUNMODE_DAEMON;
184                                } else if (g_strcasecmp(ini->value, "forkdaemon") == 0) {
185                                        conf->runmode = RUNMODE_FORKDAEMON;
186                                } else {
187                                        conf->runmode = RUNMODE_INETD;
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) {
203                                        conf->authmode = AUTHMODE_REGISTERED;
204                                } else if (g_strcasecmp(ini->value, "closed") == 0) {
205                                        conf->authmode = AUTHMODE_CLOSED;
206                                } else {
207                                        conf->authmode = AUTHMODE_OPEN;
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);
233                                        return 0;
234                                }
235                                conf->ping_interval = i;
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);
239                                        return 0;
240                                }
241                                conf->ping_timeout = i;
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);
248                                        return 0;
249                                }
250
251                                strncpy(proxyhost, url->host, sizeof(proxyhost));
252                                strncpy(proxyuser, url->user, sizeof(proxyuser));
253                                strncpy(proxypass, url->pass, sizeof(proxypass));
254                                proxyport = url->port;
255                                if (url->proto == PROTO_HTTP) {
256                                        proxytype = PROXY_HTTP;
257                                } else if (url->proto == PROTO_SOCKS4) {
258                                        proxytype = PROXY_SOCKS4;
259                                } else if (url->proto == PROTO_SOCKS5) {
260                                        proxytype = PROXY_SOCKS5;
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) {
268                                size_t ft_max_size;
269                                if (sscanf(ini->value, "%zu", &ft_max_size) != 1) {
270                                        fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
271                                        return 0;
272                                }
273                                conf->ft_max_size = ft_max_size;
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);
277                                        return 0;
278                                }
279                                conf->ft_max_kbps = i;
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);
292                                return 0;
293                                /* For now just ignore unknown keys... */
294                        }
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);
299                        return 0;
300                }
301        }
302        ini_close(ini);
303
304        return 1;
305}
306
307void conf_loaddefaults(irc_t *irc)
308{
309        ini_t *ini;
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);
324                        }
325                }
326        }
327        ini_close(ini);
328}
Note: See TracBrowser for help on using the repository browser.