crossroads

Git mirror of https://crossroads.e-tunity.com/
git clone git://git.finwo.net/app/crossroads
Log | Files | Refs | LICENSE

parsecmdline.cc (8823B)


      1 #include "config"
      2 #include "../build/usage.h"
      3 
      4 using namespace std;
      5 
      6 void Config::parsecmdline (int ac, char **av) {
      7     // Remember original argv.
      8     org_argv = av;
      9     
     10     // Prepare invoking command line.
     11     string cmdline;
     12     for (int i = 0; i < ac; i++) {
     13 	if (i)
     14 	    cmdline += ' ';
     15 	cmdline += av[i];
     16     }
     17     // Not a single argument? Usage.
     18     if (ac == 1)
     19 	throw Error("Bad command line '" + cmdline + "'\n" + USAGE);
     20 
     21 #   define OPTSTRING "?a:A:B:b:c:CDd:E:e:fF:Gg:hH:Ij:l:" \
     22 	             "m:M:np:PQ:r:R:Ss:t:T:u:U:vVW:w:xXy:Y:z:Z:"
     23 #   ifdef HAVE_GETOPT_LONG
     24     static struct option longopts[] = {
     25 	{ "allow-from",		   required_argument, 0, 'a' },
     26 	{ "deny-from",		   required_argument, 0, 'A' },
     27 	{ "backend", 	 	   required_argument, 0, 'b' },
     28 	{ "buffer-size",  	   required_argument, 0, 'B' },
     29 	{ "checkup-interval",  	   required_argument, 0, 'c' },
     30 	{ "close-sockets-fast",    no_argument,	      0, 'C' },
     31 	{ "debug", 	 	   no_argument,       0, 'D' },
     32 	{ "dispatch-mode", 	   required_argument, 0, 'd' },
     33 	{ "hard-maxconn-excess",   required_argument, 0, 'E' },
     34 	{ "soft-maxconn-excess",   required_argument, 0, 'e' },
     35 	{ "dns-cache-timeout",	   required_argument, 0, 'F' },
     36 	{ "foreground", 	   no_argument,       0, 'f' },
     37 	{ "remove-reservations",   no_argument,	      0, 'G' },
     38 	{ "backend-check",	   required_argument, 0, 'g' },
     39 	{ "help", 		   no_argument,       0, 'h' },
     40 	{ "add-server-header",     required_argument, 0, 'H' },
     41 	{ "replace-host-header",   no_argument,       0, 'I' },
     42 	{ "url-match",		   required_argument, 0, 'j' },
     43 	{ "log-traffic-dir",	   required_argument, 0, 'l' },
     44 	{ "max-connections", 	   required_argument, 0, 'm' },
     45 	{ "host-match",		   required_argument, 0, 'M' },
     46 	{ "tryout",		   no_argument,	      0, 'n' },
     47 	{ "pidfile",		   required_argument, 0, 'p' },
     48 	{ "prefix-timestamp",	   no_argument,       0, 'P' },
     49 	{ "soft-maxconnrate",	   required_argument, 0, 'r' },
     50 	{ "quit-after",		   required_argument, 0, 'Q' },
     51 	{ "hard-maxconnrate",	   required_argument, 0, 'R' },
     52 	{ "server", 		   required_argument, 0, 's' },
     53 	{ "sticky-http", 	   no_argument,       0, 'S' },
     54 	{ "backend-timeout", 	   required_argument, 0, 't' },
     55 	{ "client-timeout", 	   required_argument, 0, 'T' },
     56 	{ "time-interval",	   required_argument, 0, 'u' },
     57 	{ "defer-time",		   required_argument, 0, 'U' },
     58 	{ "verbose", 		   no_argument,       0, 'v' },
     59 	{ "version", 		   no_argument,       0, 'V' },
     60 	{ "wakeup-interval",	   required_argument, 0, 'w' },
     61 	{ "web-interface",	   required_argument, 0, 'W' },
     62 	{ "web-interface-auth",    required_argument, 0, 'Y' },
     63 	{ "add-xr-version", 	   no_argument,       0, 'X' },
     64 	{ "add-x-forwarded-for",   no_argument,       0, 'x' },
     65 	{ "onfail",		   required_argument, 0, 'y' },
     66 	{ "onstart",		   required_argument, 0, 'z' },
     67 	{ "onend", 		   required_argument, 0, 'Z' },
     68 	{ 0, 			   0, 		      0, 0 }
     69     };
     70 #   endif
     71 
     72     int opt;
     73     bool backend_set = false;
     74     bool tryout = false, wakeup_used = false;
     75     string current_hostmatch = "";
     76     string current_urlmatch = "";
     77     BackendCheck current_backendcheck;
     78     vector<string> parts;
     79 
     80 #   ifdef HAVE_GETOPT_LONG
     81     while ( (opt = getopt_long (ac, av, OPTSTRING, longopts, 0)) > 0)
     82 #else
     83     while ( (opt = getopt (ac, av, OPTSTRING)) > 0 )
     84 #endif
     85     {
     86 	switch (opt) {
     87 	case 'a':
     88 	    addallow (optarg);
     89 	    break;
     90 	case 'A':
     91 	    adddeny (optarg);
     92 	    break;
     93 	case 'b':
     94 	    setbackend (optarg, current_hostmatch, current_urlmatch,
     95 			current_backendcheck);
     96 	    backend_set = true;
     97 	    break;
     98 	case 'B':
     99 	    bufsize = (unsigned)setinteger (optarg);
    100 	    break;
    101 	case 'c':
    102 	    checkup = setinteger (optarg);
    103 	    break;
    104 	case 'C':
    105 	    fast_close = true;
    106 	    break;
    107 	case 'D':
    108 	    verbose_flag = true;
    109 	    debug_flag = true;
    110 	    break;
    111 	case 'd':
    112 	    setdispatchmode (optarg);
    113 	    break;
    114 	case 'E':
    115 	    hard_maxconn_excess_prog = optarg;
    116 	    break;
    117 	case 'e':
    118 	    soft_maxconn_excess_prog = optarg;
    119 	    break;
    120 	case 'F':
    121 	    dns_cache_timeout = (unsigned)setinteger(optarg);
    122 	    break;
    123 	case 'f':
    124 	    foreground_mode = true;
    125 	    break;
    126 	case 'G':
    127 	    removereservations(true);
    128 	    break;
    129 	case 'g':
    130 	    current_backendcheck.parse(optarg);
    131 	    break;
    132 	case 'h':
    133 	case '?':
    134 	    throw Error(USAGE);
    135 	    break;
    136 	case 'H':
    137 	    addserverheader (optarg);
    138 	    break;
    139 	case 'I':
    140 	    replacehostheader(true);
    141 	    break;
    142 	case 'j':
    143 	    current_urlmatch = optarg;
    144 	    break;
    145 	case 'l':
    146 	    dumpdir (optarg);
    147 	    break;
    148 	case 'M':
    149 	    current_hostmatch = optarg;
    150 	    break;
    151 	case 'm':
    152 	    max_conn = (unsigned)setinteger (optarg);
    153 	    break;
    154 	case 'n':
    155 	    tryout = true;
    156 	    break;
    157 	case 'P':
    158 	    prefix_timestamp = true;
    159 	    break;
    160 	case 'p':
    161 	    pidfile(optarg);
    162 	    break;
    163 	case 'Q':
    164 	    quit_after = (unsigned) setinteger(optarg);
    165 	    break;
    166 	case 'r':
    167 	    soft_maxconnrate = (unsigned) setinteger (optarg);
    168 	    break;
    169 	case 'R':
    170 	    hard_maxconnrate = (unsigned) setinteger (optarg);
    171 	    break;
    172 	case 's':
    173 	    setserver (optarg);
    174 	    break;
    175 	case 'S':
    176 	    sticky_http = true;
    177 	    break;
    178 	case 't':
    179 	    parts = str2parts(optarg, ':');
    180 	    if (parts.size() == 1) {
    181 		backend_read_timeout(atoi(parts[0].c_str()));
    182 		backend_write_timeout(atoi(parts[0].c_str()));
    183 	    } else if (parts.size() == 2) {
    184 		backend_read_timeout(atoi(parts[0].c_str()));
    185 		backend_write_timeout(atoi(parts[1].c_str()));
    186 	    } else
    187 		throw Error("Bad backend timeout specifier, "
    188 			    "expected SEC or RSEC:WSEC");
    189 	    break;
    190 	case 'T':
    191 	    parts = str2parts(optarg, ':');
    192 	    if (parts.size() == 1) {
    193 		client_read_timeout(atoi(parts[0].c_str()));
    194 		client_write_timeout(atoi(parts[0].c_str()));
    195 	    } else if (parts.size() == 2) {
    196 		client_read_timeout(atoi(parts[0].c_str()));
    197 		client_write_timeout(atoi(parts[1].c_str()));
    198 	    } else
    199 		throw Error("Bad backend timeout specifier, "
    200 			    "expected SEC or RSEC:WSEC");
    201 	    break;
    202 	case 'U':
    203 	    defer_time = (unsigned) setinteger(optarg);
    204 	    break;
    205 	case 'u':
    206 	    connrate_timeinterval = (unsigned) setinteger (optarg);
    207 	    break;
    208 	case 'v':
    209 	    verbose_flag = true;
    210 	    break;
    211 	case 'V':
    212 	    cout << "XR version    : " << VER << "\n"
    213 		 << "Written by    : " << AUTHOR << "\n"
    214 		 << "Maintained by : " << MAINTAINER << "\n"
    215 		 << "Primary site  : " << DISTSITE << "\n"
    216 		 << "Compiled with : " << CONF_CC << "\n"
    217 		 << "Optimization  : " << CONF_OPTFLAGS << "\n"
    218 		 << "System        : " << SYS << "\n"
    219 		 << "Libraries     : " << CONF_LIB << "\n"
    220 		 << "Type sizes    : ssize_t=" << sizeof(ssize_t)
    221 		 << 		    ", int=" << sizeof(int)
    222 		 << 		    ", long=" << sizeof(long)
    223 		 << 		    ", double=" << sizeof(double)
    224 		 << 		    ", ptr=" << sizeof(char*) << "\n"
    225 		;
    226 #	    ifdef HAVE_GETOPT_H
    227 	    cout << "getopt.h      : present\n";
    228 #	    else
    229 	    cout << "getopt.h      : absent\n";
    230 #	    endif
    231 #	    ifdef HAVE_INADDR_NONE
    232 	    cout << "INADDR_NONE   : present\n";
    233 #	    else
    234 	    cout << "INADDR_NONE   : absent, defined to " << INADDR_NONE
    235 		 << "\n";
    236 #	    endif
    237 #	    ifdef HAVE_GETOPT_LONG
    238 	    cout << "getopt_long() : present\n";
    239 #	    else
    240 	    cout << "getopt_long() : absent (only short flags will work)\n";
    241 #	    endif
    242 #	    ifdef HAVE_INET_ATON
    243 	    cout << "inet_aton()   : present\n";
    244 #	    else	    	
    245 	    cout << "inet_aton()   : absent\n";
    246 #	    endif	    
    247 #	    ifdef HAVE_STRNSTR
    248 	    cout << "strnstr()     : present\n";
    249 #	    else	    	
    250 	    cout << "strnstr()     : absent\n";
    251 #	    endif	    
    252 	    exit (0);
    253 	case 'W':
    254 	    setwebinterface(optarg);
    255 	    break;
    256 	case 'w':
    257 	    wakeup = setinteger (optarg);
    258 	    wakeup_used = true;
    259 	    break;
    260 	case 'X':
    261 	    add_xr_version = true;
    262 	    break;
    263 	case 'x':
    264 	    add_x_forwarded_for = true;
    265 	    break;
    266 	case 'y':
    267 	    onfail(optarg);
    268 	    break;
    269 	case 'Y':
    270 	    webinterface_auth(optarg);
    271 	    break;
    272 	case 'z':
    273 	    onstart(optarg);
    274 	    break;
    275 	case 'Z':
    276 	    onend(optarg);
    277 	    break;
    278 	default:
    279 	    throw Error("Unknown flag, try 'xr -h' for usage");
    280 	    break;
    281 	}
    282     }
    283 
    284     // Sanity checks.
    285     if (ac != optind)
    286 	throw Error("Bad command line '" + cmdline + "'\n" + USAGE);
    287 
    288     if (!backend_set)
    289 	throw Error("No backend defined, use '-b...' at least once, "
    290 		    "or try 'xr -h' for usage");
    291     if (checkup && wakeup) {
    292 	if (!wakeup_used)
    293 	    wakeup = 0;
    294 	else
    295 	    throw Error("Use either --checkup-interval or --wakeup-interval, "
    296 			"but not both");
    297     }
    298 
    299     // In tryout mode, stop now.
    300     if (tryout)
    301 	exit (0);
    302 
    303     msg ("+--------------------------------------------+\n");
    304     msg ("| Welcome to xr V" VER "                        |\n");
    305     msg ("| Copyright (c) Karel Kubat <karel@kubat.nl> |\n");
    306     msg ("| Distributed under GPLV3.                   |\n");
    307     msg ("+--------------------------------------------+\n");
    308 
    309     msg ("Invoking command line: '" + cmdline + "'\n");
    310 }