bin/xapian-tcpsrv.cc

Go to the documentation of this file.
00001 /* xapian-tcpsrv.cc: tcp daemon for use with Xapian's remote backend
00002  *
00003  * Copyright 1999,2000,2001 BrightStation PLC
00004  * Copyright 2001,2002 Ananova Ltd
00005  * Copyright 2002,2003,2004,2006,2007 Olly Betts
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License as
00009  * published by the Free Software Foundation; either version 2 of the
00010  * License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
00020  * USA
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; // Suppress "unused parameter" warning.
00041     // If you have defined your own weighting scheme, register it here
00042     // like so:
00043     // server.register_weighting_scheme(FooWeight());
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         // Try to open the database(s) so we report problems now instead of
00155         // waiting for the first connection.
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 }

Documentation for Xapian (version 1.0.10).
Generated on 24 Dec 2008 by Doxygen 1.5.2.