00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024
00025 #include <stdlib.h>
00026
00027 #include "safeerrno.h"
00028
00029 #include <iostream>
00030 #include <string>
00031
00032 #include "gnu_getopt.h"
00033
00034 #include <xapian/error.h>
00035 #include "tcpserver.h"
00036
00037 using namespace std;
00038
00039 static void register_user_weighting_schemes(TcpServer &server) {
00040 (void)server;
00041
00042
00043
00044 }
00045
00046 const int MSECS_IDLE_TIMEOUT_DEFAULT = 60000;
00047 const int MSECS_ACTIVE_TIMEOUT_DEFAULT = 15000;
00048
00049 #define PROG_NAME "xapian-tcpsrv"
00050 #define PROG_DESC "TCP daemon for use with Xapian's remote backend"
00051
00052 #define OPT_HELP 1
00053 #define OPT_VERSION 2
00054
00055 static const char * opts = "I:p:a:i:t:oqw";
00056 static const struct option long_opts[] = {
00057 {"interface", required_argument, 0, 'I'},
00058 {"port", required_argument, 0, 'p'},
00059 {"active-timeout", required_argument, 0, 'a'},
00060 {"idle-timeout", required_argument, 0, 'i'},
00061 {"timeout", required_argument, 0, 't'},
00062 {"one-shot", no_argument, 0, 'o'},
00063 {"quiet", no_argument, 0, 'q'},
00064 {"writable", no_argument, 0, 'w'},
00065 {"help", no_argument, 0, OPT_HELP},
00066 {"version", no_argument, 0, OPT_VERSION},
00067 {NULL, 0, 0, 0}
00068 };
00069
00070 static void show_usage() {
00071 cout << "Usage: "PROG_NAME" [OPTIONS] DATABASE_DIRECTORY...\n\n"
00072 "Options:\n"
00073 " --port PORTNUM listen on port PORTNUM for connections (no default)\n"
00074 " --interface ADDRESS listen on the interface associated with name or\n"
00075 " address ADDRESS (default is all interfaces)\n"
00076 " --idle-timeout MSECS set timeout for idle connections (default " << MSECS_IDLE_TIMEOUT_DEFAULT << "ms)\n"
00077 " --active-timeout MSECS set timeout for active connections (default " << MSECS_ACTIVE_TIMEOUT_DEFAULT << "ms)\n"
00078 " --timeout MSECS set both timeout values\n"
00079 " --one-shot serve a single connection and exit\n"
00080 " --quiet disable information messages to stdout\n"
00081 " --writable allow updates (only one database directory allowed)\n"
00082 " --help display this help and exit\n"
00083 " --version output version information and exit" << endl;
00084 }
00085
00086 int main(int argc, char **argv) {
00087 string host;
00088 int port = 0;
00089 int msecs_active_timeout = MSECS_ACTIVE_TIMEOUT_DEFAULT;
00090 int msecs_idle_timeout = MSECS_IDLE_TIMEOUT_DEFAULT;
00091
00092 bool one_shot = false;
00093 bool verbose = true;
00094 bool writable = false;
00095 bool syntax_error = false;
00096
00097 int c;
00098 while ((c = gnu_getopt_long(argc, argv, opts, long_opts, NULL)) != -1) {
00099 switch (c) {
00100 case OPT_HELP:
00101 cout << PROG_NAME" - "PROG_DESC"\n\n";
00102 show_usage();
00103 exit(0);
00104 case OPT_VERSION:
00105 cout << PROG_NAME" - "PACKAGE_STRING << endl;
00106 exit(0);
00107 case 'I':
00108 host.assign(optarg);
00109 break;
00110 case 'p':
00111 port = atoi(optarg);
00112 break;
00113 case 'a':
00114 msecs_active_timeout = atoi(optarg);
00115 break;
00116 case 'i':
00117 msecs_idle_timeout = atoi(optarg);
00118 break;
00119 case 't':
00120 msecs_active_timeout = msecs_idle_timeout = atoi(optarg);
00121 break;
00122 case 'o':
00123 one_shot = true;
00124 break;
00125 case 'q':
00126 verbose = false;
00127 break;
00128 case 'w':
00129 writable = true;
00130 break;
00131 default:
00132 syntax_error = true;
00133 }
00134 }
00135
00136 if (syntax_error || argv[optind] == NULL) {
00137 show_usage();
00138 exit(1);
00139 }
00140
00141 if (port <= 0 || port >= 65536) {
00142 cerr << "Error: must specify a valid port number (between 1 and 65535)."
00143 " We actually got " << port << endl;
00144 exit(1);
00145 }
00146
00147 if (writable && (argc - optind) != 1) {
00148 cerr << "Error: only one database directory allowed with '--writable'." << endl;
00149 exit(1);
00150 }
00151
00152 try {
00153 vector<string> dbnames;
00154
00155
00156 if (writable) {
00157 Xapian::WritableDatabase db(argv[optind], Xapian::DB_CREATE_OR_OPEN);
00158 dbnames.push_back(argv[optind]);
00159 } else {
00160 while (argv[optind]) {
00161 dbnames.push_back(argv[optind]);
00162 Xapian::Database db(argv[optind++]);
00163 }
00164 }
00165
00166 if (verbose) {
00167 cout << "Starting";
00168 if (writable)
00169 cout << " writable";
00170 cout << " server on";
00171 if (!host.empty())
00172 cout << " host " << host << ",";
00173 cout << " port " << port << endl;
00174 }
00175
00176 TcpServer server(dbnames, host, port, msecs_active_timeout,
00177 msecs_idle_timeout, writable, verbose);
00178
00179 if (verbose)
00180 cout << "Listening..." << endl;
00181
00182 register_user_weighting_schemes(server);
00183
00184 if (one_shot) {
00185 server.run_once();
00186 } else {
00187 server.run();
00188 }
00189 } catch (const Xapian::Error &e) {
00190 cerr << e.get_description() << endl;
00191 exit(1);
00192 } catch (const exception &e) {
00193 cerr << "Caught standard exception: " << e.what() << endl;
00194 exit(1);
00195 } catch (...) {
00196 cerr << "Caught unknown exception" << endl;
00197 exit(1);
00198 }
00199 }