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 }