xapian-core  1.4.21
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 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 const int MSECS_IDLE_TIMEOUT_DEFAULT = 60000;
50 const int 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_DIRECTORY...\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 " STRINGIZE(MSECS_IDLE_TIMEOUT_DEFAULT) "ms)\n"
80 " --active-timeout MSECS set timeout for active connections (default " STRINGIZE(MSECS_ACTIVE_TIMEOUT_DEFAULT) "ms)\n"
81 " --timeout MSECS set both timeout values\n"
82 " --one-shot serve a single connection and exit\n"
83 " --quiet disable information messages to stdout\n"
84 " --writable allow updates (only one database directory allowed)\n"
85 " --help display this help and exit\n"
86 " --version output version information and exit" << endl;
87 }
88 
89 int main(int argc, char **argv) {
90  string host;
91  int port = 0;
92  double active_timeout = MSECS_ACTIVE_TIMEOUT_DEFAULT * 1e-3;
93  double idle_timeout = MSECS_IDLE_TIMEOUT_DEFAULT * 1e-3;
94 
95  bool one_shot = false;
96  bool verbose = true;
97  bool writable = false;
98  bool syntax_error = false;
99 
100  int c;
101  while ((c = gnu_getopt_long(argc, argv, opts, long_opts, NULL)) != -1) {
102  switch (c) {
103  case OPT_HELP:
104  cout << PROG_NAME " - " PROG_DESC "\n\n";
105  show_usage();
106  exit(0);
107  case OPT_VERSION:
108  cout << PROG_NAME " - " PACKAGE_STRING << endl;
109  exit(0);
110  case 'I':
111  host.assign(optarg);
112  break;
113  case 'p':
114  port = atoi(optarg);
115  if (port <= 0 || port >= 65536) {
116  cerr << "Error: must specify a valid port number "
117  "(between 1 and 65535). "
118  "We actually got " << port << endl;
119  exit(1);
120  }
121  break;
122  case 'a':
123  active_timeout = atoi(optarg) * 1e-3;
124  break;
125  case 'i':
126  idle_timeout = atoi(optarg) * 1e-3;
127  break;
128  case 't':
129  active_timeout = idle_timeout = atoi(optarg) * 1e-3;
130  break;
131  case 'o':
132  one_shot = true;
133  break;
134  case 'q':
135  verbose = false;
136  break;
137  case 'w':
138  writable = true;
139  break;
140  default:
141  syntax_error = true;
142  }
143  }
144 
145  if (syntax_error || argv[optind] == NULL) {
146  show_usage();
147  exit(1);
148  }
149 
150  if (port == 0) {
151  cerr << "Error: You must specify a port with --port" << endl;
152  exit(1);
153  }
154 
155  if (writable && (argc - optind) != 1) {
156  cerr << "Error: only one database directory allowed with '--writable'." << endl;
157  exit(1);
158  }
159 
160  try {
161  vector<string> dbnames;
162  // Try to open the database(s) so we report problems now instead of
163  // waiting for the first connection.
164  if (writable) {
166  dbnames.push_back(argv[optind]);
167  } else {
168  while (argv[optind]) {
169  dbnames.push_back(argv[optind]);
170  Xapian::Database db(argv[optind++]);
171  }
172  }
173 
174  if (verbose) {
175  cout << "Starting";
176  if (writable)
177  cout << " writable";
178  cout << " server on";
179  if (!host.empty())
180  cout << " host " << host << ",";
181  cout << " port " << port << endl;
182  }
183 
184  RemoteTcpServer server(dbnames, host, port, active_timeout,
185  idle_timeout, writable, verbose);
186 
187  if (verbose)
188  cout << "Listening..." << endl;
189 
191 
192  if (one_shot) {
193  server.run_once();
194  } else {
195  server.run();
196  }
197  } catch (const Xapian::Error &e) {
198  cerr << e.get_description() << endl;
199  exit(1);
200  } catch (const exception &e) {
201  cerr << "Caught standard exception: " << e.what() << endl;
202  exit(1);
203  } catch (...) {
204  cerr << "Caught unknown exception" << endl;
205  exit(1);
206  }
207 }
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:785
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 PROG_NAME
All exceptions thrown by Xapian are subclasses of Xapian::Error.
Definition: error.h:43
const int MSECS_ACTIVE_TIMEOUT_DEFAULT
Various handy helpers which std::string really should provide.
#define PACKAGE_STRING
Definition: config.h:337
const int MSECS_IDLE_TIMEOUT_DEFAULT
static void show_usage()