2 * onak-conf.c - Routines related to runtime config.
4 * Copyright 2002,2012 Jonathan McDowell <noodles@earth.li>
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.
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
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.
29 #include "onak-conf.h"
31 extern struct onak_dbctx *DBINIT(struct onak_db_config *dbcfg, bool readonly);
34 * config - Runtime configuration for onak.
36 * This is the default config; normally overridden with values from the
39 struct onak_config config = {
55 .check_sighash = true,
61 bool parsebool(char *str, bool fallback)
63 if (!strcasecmp(str, "false") || !strcasecmp(str, "no") ||
64 !strcasecmp(str, "0")) {
66 } else if (!strcasecmp(str, "true") || !strcasecmp(str, "yes") ||
67 !strcasecmp(str, "1")) {
70 logthing(LOGTHING_CRITICAL,
71 "Couldn't parse %s as a boolean config variable, "
72 "returning fallback of '%s'.",
74 fallback ? "true" : "false");
79 static bool parseconfigline(char *line)
81 if (line[0] == '#' || line[0] == 0) {
83 * Comment line, ignore.
85 } else if (!strncmp("db_dir ", line, 7)) {
86 config.backend->location = strdup(&line[7]);
87 } else if (!strncmp("debug ", line, 6)) {
89 * Not supported yet; ignore for compatibility with
92 } else if (!strncmp("default_language ", line, 17)) {
94 * Not supported yet; ignore for compatibility with
97 } else if (!strncmp("mail_delivery_client ", line, 21)) {
98 config.mta = strdup(&line[21]);
99 } else if (!strncmp("maintainer_email ", line, 17)) {
100 config.adminemail = strdup(&line[17]);
101 } else if (!strncmp("mail_intro_file ", line, 16)) {
103 * Not supported yet; ignore for compatibility with
106 } else if (!strncmp("help_dir ", line, 9)) {
108 * Not supported yet; ignore for compatibility with
111 } else if (!strncmp("max_last ", line, 9)) {
113 * Not supported yet; ignore for compatibility with
116 } else if (!strncmp("max_reply_keys ", line, 15)) {
117 config.maxkeys = atoi(&line[15]);
118 } else if (!strncmp("pg_dbhost ", line, 10)) {
119 config.backend->hostname = strdup(&line[10]);
120 } else if (!strncmp("pg_dbname ", line, 10)) {
121 config.backend->location = strdup(&line[10]);
122 } else if (!strncmp("pg_dbuser ", line, 10)) {
123 config.backend->username = strdup(&line[10]);
124 } else if (!strncmp("pg_dbpass ", line, 10)) {
125 config.backend->password = strdup(&line[10]);
126 } else if (!strncmp("syncsite ", line, 9)) {
128 lladd(config.syncsites, strdup(&line[9]));
129 } else if (!strncmp("logfile ", line, 8)) {
130 config.logfile = strdup(&line[8]);
131 } else if (!strncmp("loglevel ", line, 9)) {
132 setlogthreshold(atoi(&line[9]));
133 } else if (!strncmp("this_site ", line, 10)) {
134 config.thissite = strdup(&line[10]);
135 } else if (!strncmp("socket_name ", line, 12) ||
136 !strncmp("www_port ", line, 9)) {
138 * Not applicable; ignored for compatibility with pksd.
140 } else if (!strncmp("pks_bin_dir ", line, 12)) {
141 config.bin_dir = strdup(&line[12]);
142 } else if (!strncmp("mail_dir ", line, 9)) {
143 config.mail_dir = strdup(&line[9]);
144 } else if (!strncmp("db_backend ", line, 11)) {
145 config.backend->type = strdup(&line[11]);
146 config.backend->name = strdup(&line[11]);
147 config.db_backend = strdup(&line[11]);
148 } else if (!strncmp("backends_dir ", line, 13)) {
149 config.backends_dir = strdup(&line[13]);
150 } else if (!strncmp("use_keyd ", line, 9)) {
151 config.use_keyd = parsebool(&line[9],
153 } else if (!strncmp("sock_dir ", line, 9)) {
154 config.sock_dir = strdup(&line[9]);
155 } else if (!strncmp("check_sighash ", line, 9)) {
156 config.check_sighash = parsebool(&line[9],
157 config.check_sighash);
165 void readconfig(const char *configfile) {
171 struct onak_db_config *backend;
174 if (configfile == NULL) {
176 if ((dir = getenv("XDG_CONFIG_HOME")) != NULL) {
177 len = strlen(dir) + 1 + 9 + 1; /* dir + / + onak.conf + NUL */
179 snprintf(conf, len, "%s/onak.conf", dir);
180 conffile = fopen(conf, "r");
182 } else if ((dir = getenv("HOME")) != NULL) {
183 len = strlen(dir) + 18 + 1; /* dir + /.config/onak.conf + NUL */
185 snprintf(conf, len, "%s/.config/onak.conf", dir);
186 conffile = fopen(conf, "r");
189 if (conffile == NULL) {
190 conffile = fopen(CONFIGFILE, "r");
193 conffile = fopen(configfile, "r");
195 if (conffile != NULL) {
196 if (!fgets(curline, 1023, conffile)) {
197 logthing(LOGTHING_CRITICAL,
198 "Problem reading configuration file.");
203 /* Add a single DB configuration */
204 backend = calloc(1, sizeof(*backend));
205 config.backend = backend;
206 config.backends = lladd(NULL, backend);
208 while (!feof(conffile)) {
209 /* Strip any trailing white space */
210 for (i = strlen(curline) - 1;
211 i >= 0 && isspace(curline[i]);
216 /* Strip any leading white space */
218 while (curline[i] != 0 && isspace(curline[i])) {
222 if (!parseconfigline(&curline[i])) {
223 logthing(LOGTHING_ERROR,
224 "Unknown config line: %s", curline);
227 if (!fgets(curline, 1023, conffile) &&
229 logthing(LOGTHING_CRITICAL,
230 "Problem reading configuration file.");
236 logthing(LOGTHING_NOTICE,
237 "Couldn't open config file; using defaults.");
241 void cleanupdbconfig(void *object)
243 struct onak_db_config *dbconfig = (struct onak_db_config *) object;
245 if (dbconfig->name != NULL) {
246 free(dbconfig->name);
247 dbconfig->name = NULL;
249 if (dbconfig->type != NULL) {
250 free(dbconfig->type);
251 dbconfig->type = NULL;
253 if (dbconfig->location != NULL) {
254 free(dbconfig->location);
255 dbconfig->location = NULL;
257 if (dbconfig->hostname != NULL) {
258 free(dbconfig->hostname);
259 dbconfig->hostname = NULL;
261 if (dbconfig->username != NULL) {
262 free(dbconfig->username);
263 dbconfig->username = NULL;
265 if (dbconfig->password != NULL) {
266 free(dbconfig->password);
267 dbconfig->password = NULL;
273 void cleanupconfig(void) {
274 /* Free any defined DB backend configuration first */
275 llfree(config.backends, cleanupdbconfig);
276 config.backends = NULL;
278 if (config.thissite != NULL) {
279 free(config.thissite);
280 config.thissite = NULL;
282 if (config.adminemail != NULL) {
283 free(config.adminemail);
284 config.adminemail = NULL;
286 if (config.mta != NULL) {
290 if (config.syncsites != NULL) {
291 llfree(config.syncsites, free);
292 config.syncsites = NULL;
294 if (config.logfile != NULL) {
295 free(config.logfile);
296 config.logfile = NULL;
298 if (config.db_backend != NULL) {
299 free(config.db_backend);
300 config.db_backend = NULL;
302 if (config.backends_dir != NULL) {
303 free(config.backends_dir);
304 config.backends_dir = NULL;
306 if (config.sock_dir != NULL) {
307 free(config.sock_dir);
308 config.sock_dir = NULL;
310 if (config.bin_dir != NULL) {
311 free(config.bin_dir);
312 config.bin_dir = NULL;
314 if (config.mail_dir != NULL) {
315 free(config.mail_dir);
316 config.mail_dir = NULL;