Fix bug in PL2+ implementation
[xapian.git] / xapian-applications / omega / configfile.cc
blob7c0bdd22e7e7a73d091e20e6d3b6c2c49cd46521
1 /** @file
2 * @brief Read a config file for omega.
3 */
4 /* Copyright 2001 Lemur Consulting Ltd.
5 * Copyright 2002 Ananova Ltd
6 * Copyright 2003,2005,2007,2010,2015 Olly Betts
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21 * USA
24 #include <config.h>
26 #include <fstream>
28 #include <sys/types.h>
29 #include "safesysstat.h"
30 #include "safeunistd.h"
31 #include <cstdlib>
32 #include "stringutils.h"
34 #include "configfile.h"
36 using namespace std;
38 static const char configfile_local[] = "omega.conf";
39 static const char configfile_system[] = CONFIGFILE_SYSTEM;
40 static const char configfile_envvar[] = "OMEGA_CONFIG_FILE";
42 string database_dir = "/var/lib/omega/data/";
43 string template_dir = "/var/lib/omega/templates/";
44 string default_template = "query";
45 string default_db = "default";
46 string log_dir = "/var/log/omega/";
47 string cdb_dir = "/var/lib/omega/cdb/";
49 /** Return true if the file fname exists.
51 static bool
52 file_exists(const char * fname)
54 struct stat sbuf;
55 // exists && is a regular file or symlink
56 return stat(fname, &sbuf) >= 0 && !S_ISDIR(sbuf.st_mode);
59 static bool
60 try_read_config_file(const char * cfile)
62 ifstream in(cfile);
63 if (!in) {
64 if (file_exists(cfile))
65 throw string("Can't open configuration file '") + cfile + "'";
66 return false;
69 while (in) {
70 char line[1024];
71 in.getline(line, sizeof(line));
73 char *p = line;
74 while (C_isspace(*p)) ++p;
75 if (!*p || *p == '#') continue; // Ignore blank line and comments
77 char *q = p;
78 while (*q && !C_isspace(*q)) ++q;
79 string name(p, q - p);
81 p = q;
82 while (C_isspace(*p)) ++p;
83 q = p;
84 while (*q && !C_isspace(*q)) ++q;
85 string value(p, q - p);
87 while (*q && C_isspace(*q)) ++q;
88 if (value.empty() || *q) {
89 throw string("Bad line in configuration file '") + cfile + "'";
92 if (endswith(name, "_dir") && *value.rbegin() != '/')
93 value += '/';
95 if (name == "database_dir") {
96 swap(database_dir, value);
97 } else if (name == "template_dir") {
98 swap(template_dir, value);
99 } else if (name == "default_template") {
100 swap(default_template, value);
101 } else if (name == "default_db") {
102 swap(default_db, value);
103 } else if (name == "log_dir") {
104 swap(log_dir, value);
105 } else if (name == "cdb_dir") {
106 swap(cdb_dir, value);
110 return true;
113 void
114 read_config_file()
116 // Tries to find the config file in various ways. If a config file
117 // is found in a particular location but is not readable, an error
118 // is thrown. If a config file isn't found in a particular location,
119 // the next candidate is tried.
121 // First check if a location is specified in the environment variable.
122 const char * cfile = getenv(configfile_envvar);
123 if (cfile != NULL && cfile[0] != '\0') {
124 if (try_read_config_file(cfile)) return;
127 // Next, try reading the local config file.
128 if (try_read_config_file(configfile_local)) return;
130 // Finally read the system config file.
131 if (try_read_config_file(configfile_system)) return;
133 // Just use the default configuration.
134 return;