]> the.earth.li Git - onak.git/blob - onak-conf.c
Fix compilation breakage introduced in last commit
[onak.git] / onak-conf.c
1 /*
2  * onak-conf.c - Routines related to runtime config.
3  *
4  * Copyright 2002,2012 Jonathan McDowell <noodles@earth.li>
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 51
17  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21
22 #include <ctype.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "ll.h"
28 #include "log.h"
29 #include "onak-conf.h"
30
31 extern struct onak_dbctx *DBINIT(struct onak_db_config *dbcfg, bool readonly);
32
33 /*
34  *      config - Runtime configuration for onak.
35  *
36  *      This is the default config; normally overridden with values from the
37  *      config file.
38  */
39 struct onak_config config = {
40         .maxkeys = 128,
41         .thissite = NULL,
42         .adminemail = NULL,
43         .mta = NULL,
44         .syncsites = NULL,
45         .logfile = NULL,
46
47         .use_keyd = false,
48         .sock_dir = ".",
49
50         .backends = NULL,
51         .backends_dir = NULL,
52
53         .dbinit = DBINIT,
54
55         .check_sighash = true,
56 };
57
58 bool parsebool(char *str, bool fallback)
59 {
60         if (!strcasecmp(str, "false") || !strcasecmp(str, "no") ||
61                         !strcasecmp(str, "0")) {
62                 return false;
63         } else if (!strcasecmp(str, "true") || !strcasecmp(str, "yes") ||
64                         !strcasecmp(str, "1")) {
65                 return true;
66         } else {
67                 logthing(LOGTHING_CRITICAL,
68                         "Couldn't parse %s as a boolean config variable, "
69                         "returning fallback of '%s'.",
70                         str,
71                         fallback ? "true" : "false");
72                 return fallback;
73         }
74 }
75
76 void readconfig(const char *configfile) {
77         FILE *conffile;
78         char  curline[1024];
79         int   i;
80         char *dir, *conf;
81         size_t len;
82         struct onak_db_config *backend;
83
84         curline[1023] = 0;
85         if (configfile == NULL) {
86                 conffile = NULL;
87                 if ((dir = getenv("XDG_CONFIG_HOME")) != NULL) {
88                         len = strlen(dir) + 1 + 9 + 1; /* dir + / + onak.conf + NUL */
89                         conf = malloc(len);
90                         snprintf(conf, len, "%s/onak.conf", dir);
91                         conffile = fopen(conf, "r");
92                         free(conf);
93                 } else if ((dir = getenv("HOME")) != NULL) {
94                         len = strlen(dir) + 18 + 1; /* dir + /.config/onak.conf + NUL */
95                         conf = malloc(len);
96                         snprintf(conf, len, "%s/.config/onak.conf", dir);
97                         conffile = fopen(conf, "r");
98                         free(conf);
99                 }
100                 if (conffile == NULL) {
101                         conffile = fopen(CONFIGFILE, "r");
102                 }
103         } else {
104                 conffile = fopen(configfile, "r");
105         }
106         if (conffile != NULL) {
107                 if (!fgets(curline, 1023, conffile)) {
108                         logthing(LOGTHING_CRITICAL,
109                                 "Problem reading configuration file.");
110                         fclose(conffile);
111                         return;
112                 }
113
114                 /* Add a single DB configuration */
115                 backend = calloc(1, sizeof(*backend));
116                 config.backend = backend;
117                 config.backends = lladd(NULL, backend);
118
119                 while (!feof(conffile)) {
120                         for (i = strlen(curline) - 1;
121                                         i >= 0 && isspace(curline[i]);
122                                         i--) {
123                                 curline[i] = 0;
124                         }
125
126                 if (curline[0] == '#' || curline[0] == 0) {
127                         /*
128                          * Comment line, ignore.
129                          */
130                 } else if (!strncmp("db_dir ", curline, 7)) {
131                         backend->location = strdup(&curline[7]);
132                 } else if (!strncmp("debug ", curline, 6)) {
133                         /*
134                          * Not supported yet; ignore for compatibility with
135                          * pksd.
136                          */
137                 } else if (!strncmp("default_language ", curline, 17)) {
138                         /*
139                          * Not supported yet; ignore for compatibility with
140                          * pksd.
141                          */
142                 } else if (!strncmp("mail_delivery_client ", curline, 21)) {
143                         config.mta = strdup(&curline[21]);
144                 } else if (!strncmp("maintainer_email ", curline, 17)) {
145                         config.adminemail = strdup(&curline[17]);
146                 } else if (!strncmp("mail_intro_file ", curline, 16)) {
147                         /*
148                          * Not supported yet; ignore for compatibility with
149                          * pksd.
150                          */
151                 } else if (!strncmp("help_dir ", curline, 9)) {
152                         /*
153                          * Not supported yet; ignore for compatibility with
154                          * pksd.
155                          */
156                 } else if (!strncmp("max_last ", curline, 9)) {
157                         /*
158                          * Not supported yet; ignore for compatibility with
159                          * pksd.
160                          */
161                 } else if (!strncmp("max_reply_keys ", curline, 15)) {
162                         config.maxkeys = atoi(&curline[15]);
163                 } else if (!strncmp("pg_dbhost ", curline, 10)) {
164                         backend->hostname = strdup(&curline[10]);
165                 } else if (!strncmp("pg_dbname ", curline, 10)) {
166                         backend->location = strdup(&curline[10]);
167                 } else if (!strncmp("pg_dbuser ", curline, 10)) {
168                         backend->username = strdup(&curline[10]);
169                 } else if (!strncmp("pg_dbpass ", curline, 10)) {
170                         backend->password = strdup(&curline[10]);
171                 } else if (!strncmp("syncsite ", curline, 9)) {
172                         config.syncsites =
173                                 lladd(config.syncsites, strdup(&curline[9]));
174                 } else if (!strncmp("logfile ", curline, 8)) {
175                         config.logfile = strdup(&curline[8]);
176                 } else if (!strncmp("loglevel ", curline, 9)) {
177                         setlogthreshold(atoi(&curline[9]));
178                 } else if (!strncmp("this_site ", curline, 10)) {
179                         config.thissite = strdup(&curline[10]);
180                 } else if (!strncmp("socket_name ", curline, 12) ||
181                                 !strncmp("pks_bin_dir ", curline, 12) ||
182                                 !strncmp("mail_dir ", curline, 9) ||
183                                 !strncmp("www_port ", curline, 9)) {
184                         /*
185                          * Not applicable; ignored for compatibility with pksd.
186                          */
187                 } else if (!strncmp("db_backend ", curline, 11)) {
188                         backend->type = strdup(&curline[11]);
189                         backend->name = strdup(&curline[11]);
190                         config.db_backend = strdup(&curline[11]);
191                 } else if (!strncmp("backends_dir ", curline, 13)) {
192                         config.backends_dir = strdup(&curline[13]);
193                 } else if (!strncmp("use_keyd ", curline, 9)) {
194                         config.use_keyd = parsebool(&curline[9],
195                                                 config.use_keyd);
196                 } else if (!strncmp("sock_dir ", curline, 9)) {
197                         config.sock_dir = strdup(&curline[9]);
198                 } else if (!strncmp("check_sighash ", curline, 9)) {
199                         config.check_sighash = parsebool(&curline[9],
200                                                 config.check_sighash);
201                 } else {
202                         logthing(LOGTHING_ERROR,
203                                 "Unknown config line: %s", curline);
204                 }
205
206                         if (!fgets(curline, 1023, conffile) &&
207                                         !feof(conffile)) {
208                                 logthing(LOGTHING_CRITICAL,
209                                         "Problem reading configuration file.");
210                                 break;
211                         }
212                 }
213                 fclose(conffile);
214         } else {
215                 logthing(LOGTHING_NOTICE,
216                                 "Couldn't open config file; using defaults.");
217         }
218 }
219
220 void cleanupdbconfig(void *object)
221 {
222         struct onak_db_config *dbconfig = (struct onak_db_config *) object;
223
224         if (dbconfig->name != NULL) {
225                 free(dbconfig->name);
226                 dbconfig->name = NULL;
227         }
228         if (dbconfig->type != NULL) {
229                 free(dbconfig->type);
230                 dbconfig->type = NULL;
231         }
232         if (dbconfig->location != NULL) {
233                 free(dbconfig->location);
234                 dbconfig->location = NULL;
235         }
236         if (dbconfig->hostname != NULL) {
237                 free(dbconfig->hostname);
238                 dbconfig->hostname = NULL;
239         }
240         if (dbconfig->username != NULL) {
241                 free(dbconfig->username);
242                 dbconfig->username = NULL;
243         }
244         if (dbconfig->password != NULL) {
245                 free(dbconfig->password);
246                 dbconfig->password = NULL;
247         }
248 }
249
250 void cleanupconfig(void) {
251         /* Free any defined DB backend configuration first */
252         llfree(config.backends, cleanupdbconfig);
253         config.backends = NULL;
254
255         if (config.thissite != NULL) {
256                 free(config.thissite);
257                 config.thissite = NULL;
258         }
259         if (config.adminemail != NULL) {
260                 free(config.adminemail);
261                 config.adminemail = NULL;
262         }
263         if (config.mta != NULL) {
264                 free(config.mta);
265                 config.mta = NULL;
266         }
267         if (config.syncsites != NULL) {
268                 llfree(config.syncsites, free);
269                 config.syncsites = NULL;
270         }
271         if (config.logfile != NULL) {
272                 free(config.logfile);
273                 config.logfile = NULL;
274         }
275         if (config.db_backend != NULL) {
276                 free(config.db_backend);
277                 config.db_backend = NULL;
278         }
279         if (config.backends_dir != NULL) {
280                 free(config.backends_dir);
281                 config.backends_dir = NULL;
282         }
283 }