xapian-core  1.4.26
xapian-tcpsrv.cc
Go to the documentation of this file.
1 
4 /* Copyright 1999,2000,2001 BrightStation PLC
5  * Copyright 2001,2002 Ananova Ltd
6  * Copyright 2002,2003,2004,2006,2007,2008,2009,2010,2011,2013,2015,2023 Olly Betts
7  *
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.
12  *
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.
17  *
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
22  */
23 
24 #include <config.h>
25 
26 #include <cstdlib>
27 
28 #include <iostream>
29 #include <string>
30 
31 #include "gnu_getopt.h"
32 
33 #include "xapian/constants.h"
34 #include "xapian/error.h"
35 #include "net/remotetcpserver.h"
36 #include "net/remoteserver.h"
37 #include "stringutils.h"
38 
39 using namespace std;
40 
42  Xapian::Registry reg;
43  // If you have defined your own weighting scheme, register it here
44  // like so:
45  // reg.register_weighting_scheme(FooWeight());
46  server.set_registry(reg);
47 }
48 
49 #define MSECS_IDLE_TIMEOUT_DEFAULT 60000
50 #define MSECS_ACTIVE_TIMEOUT_DEFAULT 15000
51 
52 #define PROG_NAME "xapian-tcpsrv"
53 #define PROG_DESC "TCP daemon for use with Xapian's remote backend"
54 
55 #define OPT_HELP 1
56 #define OPT_VERSION 2
57 
58 static const char * opts = "I:p:a:i:t:oqw";
59 static const struct option long_opts[] = {
60  {"interface", required_argument, 0, 'I'},
61  {"port", required_argument, 0, 'p'},
62  {"active-timeout", required_argument, 0, 'a'},
63  {"idle-timeout", required_argument, 0, 'i'},
64  {"timeout", required_argument, 0, 't'},
65  {"one-shot", no_argument, 0, 'o'},
66  {"quiet", no_argument, 0, 'q'},
67  {"writable", no_argument, 0, 'w'},
68  {"help", no_argument, 0, OPT_HELP},
69  {"version", no_argument, 0, OPT_VERSION},
70  {NULL, 0, 0, 0}
71 };
72 
73 static void show_usage() {
74  cout << "Usage: " PROG_NAME " [OPTIONS] DATABASE_PATH...\n\n"
75 "Options:\n"
76 " --port PORTNUM listen on port PORTNUM for connections (no default)\n"
77 " --interface ADDRESS listen on the interface associated with name or\n"
78 " address ADDRESS (default is all interfaces)\n"
79 " --idle-timeout MSECS set timeout for idle connections (default: "
81 " --active-timeout MSECS set timeout for active connections (default: "
83 " --timeout MSECS set both timeout values\n"
84 " --one-shot serve a single connection and exit\n"
85 " --quiet disable information messages to stdout\n"
86 " --writable allow updates\n"
87 " --help display this help and exit\n"
88 " --version output version information and exit\n";
89 }
90 
91 int main(int argc, char **argv) {
92  string host;
93  int port = 0;
94  double active_timeout = MSECS_ACTIVE_TIMEOUT_DEFAULT * 1e-3;
95  double idle_timeout = MSECS_IDLE_TIMEOUT_DEFAULT * 1e-3;
96 
97  bool one_shot = false;
98  bool verbose = true;
99  bool writable = false;
100  bool syntax_error = false;
101 
102  int c;
103  while ((c = gnu_getopt_long(argc, argv, opts, long_opts, NULL)) != -1) {
104  switch (c) {
105  case OPT_HELP:
106  cout << PROG_NAME " - " PROG_DESC "\n\n";
107  show_usage();
108  exit(0);
109  case OPT_VERSION:
110  cout << PROG_NAME " - " PACKAGE_STRING "\n";
111  exit(0);
112  case 'I':
113  host.assign(optarg);
114  break;
115  case 'p':
116  port = atoi(optarg);
117  if (port <= 0 || port >= 65536) {
118  cerr << "Error: must specify a valid port number "
119  "(between 1 and 65535). "
120  "We actually got " << port << '\n';
121  exit(1);
122  }
123  break;
124  case 'a':
125  active_timeout = atoi(optarg) * 1e-3;
126  break;
127  case 'i':
128  idle_timeout = atoi(optarg) * 1e-3;
129  break;
130  case 't':
131  active_timeout = idle_timeout = atoi(optarg) * 1e-3;
132  break;
133  case 'o':
134  one_shot = true;
135  break;
136  case 'q':
137  verbose = false;
138  break;
139  case 'w':
140  writable = true;
141  break;
142  default:
143  syntax_error = true;
144  }
145  }
146 
147  if (syntax_error || argv[optind] == NULL) {
148  show_usage();
149  exit(1);
150  }
151 
152  if (port == 0) {
153  cerr << "Error: You must specify a port with --port\n";
154  exit(1);
155  }
156 
157  vector<string> dbnames(argv + optind, argv + argc);
158  try {
159  if (!one_shot) {
160  // Try to open the database(s) so we report problems now instead of
161  // waiting for the first connection.
162  for (auto& dbname : dbnames) {
163  if (writable) {
164  Xapian::WritableDatabase db(dbname,
166  } else {
167  Xapian::Database db(dbname);
168  }
169  }
170  }
171 
172  if (verbose) {
173  cout << "Starting";
174  if (writable)
175  cout << " writable";
176  cout << " server on";
177  if (!host.empty())
178  cout << " host " << host << ",";
179  cout << " port " << port << '\n';
180  }
181 
182  RemoteTcpServer server(dbnames, host, port, active_timeout,
183  idle_timeout, writable, verbose);
184 
185  if (verbose)
186  cout << "Listening...\n" << flush;
187 
189 
190  if (one_shot) {
191  server.run_once();
192  } else {
193  server.run();
194  }
195  } catch (const Xapian::Error &e) {
196  cerr << e.get_description() << '\n';
197  exit(1);
198  } catch (const exception &e) {
199  cerr << "Caught standard exception: " << e.what() << '\n';
200  exit(1);
201  } catch (...) {
202  cerr << "Caught unknown exception\n";
203  exit(1);
204  }
205 }
Wrappers to allow GNU getopt to be used cleanly from C++ code.
#define OPT_HELP
static void register_user_weighting_schemes(RemoteTcpServer &server)
int optind
Definition: getopt.cc:94
This class is used to access a database, or a group of databases.
Definition: database.h:68
int gnu_getopt_long(int argc_, char *const *argv_, const char *shortopts_, const struct option *longopts_, int *optind_)
Definition: gnu_getopt.h:97
Constants in the Xapian namespace.
#define STRINGIZE(X)
The STRINGIZE macro converts its parameter into a string constant.
Definition: stringutils.h:36
static const char * dbnames
STL namespace.
const int DB_CREATE_OR_OPEN
Create database if it doesn&#39;t already exist.
Definition: constants.h:35
static const struct option long_opts[]
static const char * opts
#define no_argument
Definition: gnu_getopt.h:79
#define PROG_DESC
TCP/IP socket based server for RemoteDatabase.
Hierarchy of classes which Xapian can throw as exceptions.
int main(int argc, char **argv)
#define OPT_VERSION
static int verbose
Definition: xapian-delve.cc:47
TCP/IP socket based server for RemoteDatabase.
This class provides read/write access to a database.
Definition: database.h:789
void set_registry(const Xapian::Registry &reg_)
Set the registry used for (un)serialisation.
Registry for user subclasses.
Definition: registry.h:47
char * optarg
Definition: getopt.cc:79
Xapian remote backend server base class.
#define required_argument
Definition: gnu_getopt.h:80
std::string get_description() const
Return a string describing this object.
Definition: error.cc:93
#define MSECS_IDLE_TIMEOUT_DEFAULT
#define MSECS_ACTIVE_TIMEOUT_DEFAULT
#define PROG_NAME
All exceptions thrown by Xapian are subclasses of Xapian::Error.
Definition: error.h:43
Various handy helpers which std::string really should provide.
#define PACKAGE_STRING
Definition: config.h:337
static void show_usage()