LCOV - code coverage report
Current view: top level - bin - xapian-tcpsrv.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 954b5873a738 Lines: 55 96 57.3 %
Date: 2019-06-30 05:20:33 Functions: 4 5 80.0 %
Branches: 58 170 34.1 %

           Branch data     Line data    Source code
       1                 :            : /** @file xapian-tcpsrv.cc
       2                 :            :  * @brief tcp daemon for use with Xapian's remote backend
       3                 :            :  */
       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 "parseint.h"
      36                 :            : #include "net/remotetcpserver.h"
      37                 :            : #include "net/remoteserver.h"
      38                 :            : #include "stringutils.h"
      39                 :            : 
      40                 :            : using namespace std;
      41                 :            : 
      42                 :        383 : static void register_user_weighting_schemes(RemoteTcpServer &server) {
      43         [ +  - ]:        383 :     Xapian::Registry reg;
      44                 :            :     // If you have defined your own weighting scheme, register it here
      45                 :            :     // like so:
      46                 :            :     // reg.register_weighting_scheme(FooWeight());
      47         [ +  - ]:        383 :     server.set_registry(reg);
      48                 :        383 : }
      49                 :            : 
      50                 :            : const int MSECS_IDLE_TIMEOUT_DEFAULT = 60000;
      51                 :            : const int MSECS_ACTIVE_TIMEOUT_DEFAULT = 15000;
      52                 :            : 
      53                 :            : #define PROG_NAME "xapian-tcpsrv"
      54                 :            : #define PROG_DESC "TCP daemon for use with Xapian's remote backend"
      55                 :            : 
      56                 :            : #define OPT_HELP 1
      57                 :            : #define OPT_VERSION 2
      58                 :            : 
      59                 :            : static const char * opts = "I:p:a:i:t:oqw";
      60                 :            : static const struct option long_opts[] = {
      61                 :            :     {"interface",     required_argument,      0, 'I'},
      62                 :            :     {"port",          required_argument,      0, 'p'},
      63                 :            :     {"active-timeout",        required_argument,      0, 'a'},
      64                 :            :     {"idle-timeout",  required_argument,      0, 'i'},
      65                 :            :     {"timeout",               required_argument,      0, 't'},
      66                 :            :     {"one-shot",      no_argument,            0, 'o'},
      67                 :            :     {"quiet",         no_argument,            0, 'q'},
      68                 :            :     {"writable",      no_argument,            0, 'w'},
      69                 :            :     {"help",          no_argument,            0, OPT_HELP},
      70                 :            :     {"version",               no_argument,            0, OPT_VERSION},
      71                 :            :     {NULL, 0, 0, 0}
      72                 :            : };
      73                 :            : 
      74                 :          0 : static void show_usage() {
      75                 :            :     cout << "Usage: " PROG_NAME " [OPTIONS] DATABASE_DIRECTORY...\n\n"
      76                 :            : "Options:\n"
      77                 :            : "  --port PORTNUM          listen on port PORTNUM for connections (no default)\n"
      78                 :            : "  --interface ADDRESS     listen on the interface associated with name or\n"
      79                 :            : "                          address ADDRESS (default is all interfaces)\n"
      80                 :            : "  --idle-timeout MSECS    set timeout for idle connections (default " STRINGIZE(MSECS_IDLE_TIMEOUT_DEFAULT) "ms)\n"
      81                 :            : "  --active-timeout MSECS  set timeout for active connections (default " STRINGIZE(MSECS_ACTIVE_TIMEOUT_DEFAULT) "ms)\n"
      82                 :            : "  --timeout MSECS         set both timeout values\n"
      83                 :            : "  --one-shot              serve a single connection and exit\n"
      84                 :            : "  --quiet                 disable information messages to stdout\n"
      85                 :            : "  --writable              allow updates (only one database directory allowed)\n"
      86                 :            : "  --help                  display this help and exit\n"
      87                 :          0 : "  --version               output version information and exit" << endl;
      88                 :          0 : }
      89                 :            : 
      90                 :        423 : int main(int argc, char **argv) {
      91         [ +  - ]:        423 :     string host;
      92                 :        423 :     int port = 0;
      93                 :        423 :     double active_timeout = MSECS_ACTIVE_TIMEOUT_DEFAULT * 1e-3;
      94                 :        423 :     double idle_timeout   = MSECS_IDLE_TIMEOUT_DEFAULT * 1e-3;
      95                 :            : 
      96                 :        423 :     bool one_shot = false;
      97                 :        423 :     bool verbose = true;
      98                 :        423 :     bool writable = false;
      99                 :        423 :     bool syntax_error = false;
     100                 :            : 
     101                 :            :     int c;
     102         [ +  + ]:       2202 :     while ((c = gnu_getopt_long(argc, argv, opts, long_opts, NULL)) != -1) {
     103   [ -  -  +  +  :       1779 :         switch (c) {
          -  -  +  +  -  
                   +  - ]
     104                 :            :             case OPT_HELP:
     105         [ #  # ]:          0 :                 cout << PROG_NAME " - " PROG_DESC "\n\n";
     106         [ #  # ]:          0 :                 show_usage();
     107                 :          0 :                 exit(0);
     108                 :            :             case OPT_VERSION:
     109 [ #  # ][ #  # ]:          0 :                 cout << PROG_NAME " - " PACKAGE_STRING << endl;
     110                 :          0 :                 exit(0);
     111                 :            :             case 'I':
     112         [ +  - ]:        423 :                 host.assign(optarg);
     113                 :        423 :                 break;
     114                 :            :             case 'p':
     115 [ +  - ][ +  - ]:        846 :                 if (!parse_signed(optarg, port) ||
         [ +  - ][ -  + ]
     116         [ -  + ]:        423 :                     (port < 1 || port > 65535)) {
     117                 :            :                     cerr << "Error: must specify a valid port number "
     118 [ #  # ][ #  # ]:          0 :                             "(between 1 and 65535). " << endl;
     119                 :          0 :                     exit(1);
     120                 :            :                 }
     121                 :        423 :                 break;
     122                 :            :             case 'a': {
     123                 :            :                 unsigned int active;
     124 [ #  # ][ #  # ]:          0 :                 if (!parse_unsigned(optarg, active)) {
     125 [ #  # ][ #  # ]:          0 :                     cerr << "Active timeout must be >= 0" << endl;
     126                 :          0 :                     exit(1);
     127                 :            :                 }
     128                 :          0 :                 active_timeout = active * 1e-3;
     129                 :          0 :                 break;
     130                 :            :             }
     131                 :            :             case 'i': {
     132                 :            :                 unsigned int idle;
     133 [ #  # ][ #  # ]:          0 :                 if (!parse_unsigned(optarg, idle)) {
     134 [ #  # ][ #  # ]:          0 :                     cerr << "Idle timeout must be >= 0" << endl;
     135                 :          0 :                     exit(1);
     136                 :            :                 }
     137                 :          0 :                 idle_timeout = idle * 1e-3;
     138                 :          0 :                 break;
     139                 :            :             }
     140                 :            :             case 't': {
     141                 :            :                 unsigned int timeout;
     142 [ +  - ][ -  + ]:        423 :                 if (!parse_unsigned(optarg, timeout)) {
     143 [ #  # ][ #  # ]:          0 :                     cerr << "timeout must be >= 0" << endl;
     144                 :          0 :                     exit(1);
     145                 :            :                 }
     146                 :        423 :                 active_timeout = idle_timeout = timeout * 1e-3;
     147                 :        423 :                 break;
     148                 :            :             }
     149                 :            :             case 'o':
     150                 :        423 :                 one_shot = true;
     151                 :        423 :                 break;
     152                 :            :             case 'q':
     153                 :          0 :                 verbose = false;
     154                 :          0 :                 break;
     155                 :            :             case 'w':
     156                 :         87 :                 writable = true;
     157                 :         87 :                 break;
     158                 :            :             default:
     159                 :          0 :                 syntax_error = true;
     160                 :            :         }
     161                 :            :     }
     162                 :            : 
     163 [ +  - ][ -  + ]:        423 :     if (syntax_error || argv[optind] == NULL) {
     164         [ #  # ]:          0 :         show_usage();
     165                 :          0 :         exit(1);
     166                 :            :     }
     167                 :            : 
     168         [ -  + ]:        423 :     if (port == 0) {
     169 [ #  # ][ #  # ]:          0 :         cerr << "Error: You must specify a port with --port" << endl;
     170                 :          0 :         exit(1);
     171                 :            :     }
     172                 :            : 
     173 [ +  + ][ -  + ]:        423 :     if (writable && (argc - optind) != 1) {
     174 [ #  # ][ #  # ]:          0 :         cerr << "Error: only one database directory allowed with '--writable'." << endl;
     175                 :          0 :         exit(1);
     176                 :            :     }
     177                 :            : 
     178                 :            :     try {
     179                 :        423 :         vector<string> dbnames;
     180                 :            :         // Try to open the database(s) so we report problems now instead of
     181                 :            :         // waiting for the first connection.
     182         [ +  + ]:        423 :         if (writable) {
     183 [ +  - ][ +  - ]:         87 :             Xapian::WritableDatabase db(argv[optind], Xapian::DB_CREATE_OR_OPEN);
     184 [ +  - ][ +  - ]:         87 :             dbnames.push_back(argv[optind]);
     185                 :            :         } else {
     186         [ +  + ]:        672 :             while (argv[optind]) {
     187 [ +  - ][ +  - ]:        336 :                 dbnames.push_back(argv[optind]);
     188 [ +  - ][ +  - ]:        336 :                 Xapian::Database db(argv[optind++]);
     189                 :        336 :             }
     190                 :            :         }
     191                 :            : 
     192         [ +  - ]:        423 :         if (verbose) {
     193         [ +  - ]:        423 :             cout << "Starting";
     194         [ +  + ]:        423 :             if (writable)
     195         [ +  - ]:         87 :                 cout << " writable";
     196         [ +  - ]:        423 :             cout << " server on";
     197         [ +  - ]:        423 :             if (!host.empty())
     198 [ +  - ][ +  - ]:        423 :                 cout << " host " << host << ",";
                 [ +  - ]
     199 [ +  - ][ +  - ]:        423 :             cout << " port " << port << endl;
                 [ +  - ]
     200                 :            :         }
     201                 :            : 
     202                 :            :         RemoteTcpServer server(dbnames, host, port, active_timeout,
     203         [ +  - ]:        806 :                                idle_timeout, writable, verbose);
     204                 :            : 
     205         [ +  - ]:        383 :         if (verbose)
     206 [ +  - ][ +  - ]:        383 :             cout << "Listening..." << endl;
     207                 :            : 
     208         [ +  - ]:        383 :         register_user_weighting_schemes(server);
     209                 :            : 
     210         [ +  - ]:        383 :         if (one_shot) {
     211         [ +  - ]:        383 :             server.run_once();
     212                 :            :         } else {
     213         [ #  # ]:          0 :             server.run();
     214                 :        383 :         }
     215                 :          0 :     } catch (const Xapian::Error &e) {
     216   [ #  #  #  #  :          0 :         cerr << e.get_description() << endl;
                   #  # ]
     217                 :          0 :         exit(1);
     218                 :          0 :     } catch (const exception &e) {
     219   [ #  #  #  #  :          0 :         cerr << "Caught standard exception: " << e.what() << endl;
                   #  # ]
     220                 :          0 :         exit(1);
     221      [ #  #  # ]:          0 :     } catch (...) {
     222   [ #  #  #  # ]:          0 :         cerr << "Caught unknown exception" << endl;
     223                 :          0 :         exit(1);
     224                 :        383 :     }
     225 [ +  - ][ +  - ]:       2075 : }

Generated by: LCOV version 1.11