xapian-core  1.4.27
databasehelpers.h
Go to the documentation of this file.
1 
4 /* Copyright 2002-2019 Olly Betts
5  * Copyright 2008 Lemur Consulting Ltd
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20  * USA
21  */
22 
23 #ifndef XAPIAN_INCLUDED_DATABASEHELPERS_H
24 #define XAPIAN_INCLUDED_DATABASEHELPERS_H
25 
26 #include <cerrno>
27 #include <cstdlib>
28 #include <fstream>
29 #include <string>
30 
31 #include "fileutils.h"
32 #include "safesysstat.h"
33 #include "safeunistd.h"
34 #include "str.h"
35 #include "xapian/error.h"
36 
48 int
49 test_if_single_file_db(const struct stat& sb,
50  const std::string& path,
51  int* fd_ptr);
52 
57 template<typename A1,
58  typename A2,
59  typename A3,
60  typename A4,
61  typename A5,
62  typename A6>
63 void
64 read_stub_file(const std::string& file,
65  A1 action_auto,
66  A2 action_chert,
67  A3 action_glass,
68  A4 action_remote_prog,
69  A5 action_remote_tcp,
70  A6 action_inmemory)
71 {
72  // A stub database is a text file with one or more lines of this format:
73  // <dbtype> <serialised db object>
74  //
75  // Lines which start with a "#" character are ignored.
76  //
77  // Any paths specified in stub database files which are relative will be
78  // considered to be relative to the directory containing the stub database.
79  std::ifstream stub(file.c_str());
80  if (!stub) {
81  std::string msg = "Couldn't open stub database file: ";
82  msg += file;
83  throw Xapian::DatabaseNotFoundError(msg, errno);
84  }
85  std::string line;
86  unsigned int line_no = 0;
87  while (std::getline(stub, line)) {
88  ++line_no;
89  if (line.empty() || line[0] == '#')
90  continue;
91  std::string::size_type space = line.find(' ');
92  if (space == std::string::npos) space = line.size();
93 
94  std::string type(line, 0, space);
95  line.erase(0, space + 1);
96 
97  if (type == "auto") {
98  resolve_relative_path(line, file);
99  action_auto(line);
100  continue;
101  }
102 
103  if (type == "chert") {
104 #ifdef XAPIAN_HAS_CHERT_BACKEND
105  resolve_relative_path(line, file);
106  action_chert(line);
107  continue;
108 #else
109  (void)action_chert;
110  throw Xapian::FeatureUnavailableError("Chert backend disabled");
111 #endif
112  }
113 
114  if (type == "glass") {
115 #ifdef XAPIAN_HAS_GLASS_BACKEND
116  resolve_relative_path(line, file);
117  action_glass(line);
118  continue;
119 #else
120  (void)action_glass;
121  throw Xapian::FeatureUnavailableError("Glass backend disabled");
122 #endif
123  }
124 
125  if (type == "remote" && !line.empty()) {
126 #ifdef XAPIAN_HAS_REMOTE_BACKEND
127  if (line[0] == ':') {
128  // prog
129  // FIXME: timeouts
130  // Is it a security risk?
131  space = line.find(' ');
132  std::string args;
133  if (space != std::string::npos) {
134  args.assign(line, space + 1, std::string::npos);
135  line.assign(line, 1, space - 1);
136  } else {
137  line.erase(0, 1);
138  }
139  action_remote_prog(line, args);
140  continue;
141  }
142  std::string::size_type colon = line.rfind(':');
143  if (colon != std::string::npos) {
144  // tcp
145  // FIXME: timeouts
146  // Avoid misparsing an IPv6 address without a port number. The
147  // port number is required, so just leave that case to the
148  // error handling further below.
149  if (!(line[0] == '[' && line.back() == ']')) {
150  unsigned int port = std::atoi(line.c_str() + colon + 1);
151  line.erase(colon);
152  if (line[0] == '[' && line.back() == ']') {
153  line.erase(line.size() - 1, 1);
154  line.erase(0, 1);
155  }
156  action_remote_tcp(line, port);
157  continue;
158  }
159  }
160 #else
161  (void)action_remote_prog;
162  (void)action_remote_tcp;
163  throw Xapian::FeatureUnavailableError("Remote backend disabled");
164 #endif
165  }
166 
167  if (type == "inmemory" && line.empty()) {
168 #ifdef XAPIAN_HAS_INMEMORY_BACKEND
169  action_inmemory();
170  continue;
171 #else
172  (void)action_inmemory;
173  throw Xapian::FeatureUnavailableError("Inmemory backend disabled");
174 #endif
175  }
176 
177  if (type == "flint") {
178  auto msg = "Flint backend no longer supported";
180  }
181 
182  // Don't include the line itself - that might help an attacker
183  // by revealing part of a sensitive file's contents if they can
184  // arrange for it to be read as a stub database via infelicities in
185  // an application which uses Xapian. The line number is enough
186  // information to identify the problem line.
187  std::string msg = file;
188  msg += ':';
189  msg += str(line_no);
190  msg += ": Bad line";
191  throw Xapian::DatabaseOpeningError(msg);
192  }
193 }
194 
195 #endif
DatabaseOpeningError indicates failure to open a database.
Definition: error.h:581
Convert types to std::string.
include <sys/stat.h> with portability enhancements
int test_if_single_file_db(const struct stat &sb, const std::string &path, int *fd_ptr)
Probe if a path is a single-file database.
Hierarchy of classes which Xapian can throw as exceptions.
Indicates an attempt to use a feature which is unavailable.
Definition: error.h:719
string str(int value)
Convert int to std::string.
Definition: str.cc:90
Indicates an attempt to access a database not present.
Definition: error.h:1055
void read_stub_file(const std::string &file, A1 action_auto, A2 action_chert, A3 action_glass, A4 action_remote_prog, A5 action_remote_tcp, A6 action_inmemory)
Open, read and process a stub database file.
void resolve_relative_path(string &path, const string &base)
Resolve path relative to base.
Definition: fileutils.cc:105
<unistd.h>, but with compat.
File and path manipulation routines.