1 /* $NetBSD: main.c,v 1.16 2016/10/04 18:33:00 mrg Exp $ */ 2 3 /* $eterna: main.c,v 1.6 2011/11/18 09:21:15 mrg Exp $ */ 4 /* from: eterna: bozohttpd.c,v 1.159 2009/05/23 02:14:30 mrg Exp */ 5 6 /* 7 * Copyright (c) 1997-2016 Matthew R. Green 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer and 17 * dedication in the documentation and/or other materials provided 18 * with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 */ 33 34 /* this program is dedicated to the Great God of Processed Cheese */ 35 36 /* 37 * main.c: C front end to bozohttpd 38 */ 39 40 #include <sys/types.h> 41 #include <sys/param.h> 42 43 #include <errno.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <syslog.h> 47 #include <time.h> 48 #include <unistd.h> 49 50 #include "bozohttpd.h" 51 52 /* variables and functions */ 53 #ifndef LOG_FTP 54 #define LOG_FTP LOG_DAEMON 55 #endif 56 57 /* print a usage message, and then exit */ 58 BOZO_DEAD static void 59 usage(bozohttpd_t *httpd, char *progname) 60 { 61 bozowarn(httpd, "usage: %s [options] slashdir [virtualhostname]", 62 progname); 63 bozowarn(httpd, "options:"); 64 #ifndef NO_DEBUG 65 bozowarn(httpd, " -d\t\t\tenable debug support"); 66 #endif 67 bozowarn(httpd, " -s\t\t\talways log to stderr"); 68 #ifndef NO_DYNAMIC_CONTENT 69 bozowarn(httpd, " -M arg t c c11\tadd this mime extenstion"); 70 #endif 71 #ifndef NO_USER_SUPPORT 72 bozowarn(httpd, " -u\t\t\tenable ~user/public_html support"); 73 bozowarn(httpd, " -p dir\t\tchange `public_html' directory name"); 74 #ifndef NO_CGIBIN_SUPPORT 75 bozowarn(httpd, " -E\t\t\tenable CGI support for user dirs"); 76 #endif 77 #endif 78 #ifndef NO_CGIBIN_SUPPORT 79 #ifndef NO_DYNAMIC_CONTENT 80 bozowarn(httpd, " -C arg prog\t\tadd this CGI handler"); 81 #endif 82 bozowarn(httpd, 83 " -c cgibin\t\tenable cgi-bin support in this directory"); 84 #endif 85 #ifndef NO_LUA_SUPPORT 86 bozowarn(httpd, " -L arg script\tadd this Lua script"); 87 #endif 88 bozowarn(httpd, " -I port\t\tbind or use on this port"); 89 #ifndef NO_DAEMON_MODE 90 bozowarn(httpd, " -b\t\t\tbackground and go into daemon mode"); 91 bozowarn(httpd, " -f\t\t\tkeep daemon mode in the foreground"); 92 bozowarn(httpd, 93 " -i address\t\tbind on this address (daemon mode only)"); 94 bozowarn(httpd, " -P pidfile\t\tpath to the pid file to create"); 95 #endif 96 bozowarn(httpd, " -S version\t\tset server version string"); 97 bozowarn(httpd, " -t dir\t\tchroot to `dir'"); 98 bozowarn(httpd, " -U username\t\tchange user to `user'"); 99 bozowarn(httpd, 100 " -e\t\t\tdon't clean the environment (-t and -U only)"); 101 bozowarn(httpd, 102 " -v virtualroot\tenable virtual host support " 103 "in this directory"); 104 bozowarn(httpd, " -V\t\tUnknown virtual hosts go to `slashdir'"); 105 #ifndef NO_DIRINDEX_SUPPORT 106 bozowarn(httpd, 107 " -X\t\t\tenable automatic directory index support"); 108 bozowarn(httpd, 109 " -H\t\t\thide files starting with a period (.)" 110 " in index mode"); 111 #endif 112 bozowarn(httpd, 113 " -x index\t\tchange default `index.html' file name"); 114 #ifndef NO_SSL_SUPPORT 115 bozowarn(httpd, 116 " -z ciphers\t\tspecify SSL ciphers"); 117 bozowarn(httpd, 118 " -Z cert privkey\tspecify path to server certificate" 119 " and private key file\n" 120 "\t\t\tin pem format and enable bozohttpd in SSL mode"); 121 #endif /* NO_SSL_SUPPORT */ 122 bozowarn(httpd, " -G print version number and exit"); 123 bozoerr(httpd, 1, "%s failed to start", progname); 124 } 125 126 int 127 main(int argc, char **argv) 128 { 129 bozo_httpreq_t *request; 130 bozohttpd_t httpd; 131 bozoprefs_t prefs; 132 char *progname; 133 const char *val; 134 int c; 135 136 (void) memset(&httpd, 0x0, sizeof(httpd)); 137 (void) memset(&prefs, 0x0, sizeof(prefs)); 138 139 if ((progname = strrchr(argv[0], '/')) == NULL) 140 progname = argv[0]; 141 else 142 progname++; 143 144 openlog(progname, LOG_PID|LOG_NDELAY, LOG_FTP); 145 146 bozo_set_defaults(&httpd, &prefs); 147 148 /* 149 * -r option was removed, do not reuse it for a while 150 */ 151 152 while ((c = getopt(argc, argv, 153 "C:EGHI:L:M:P:S:U:VXZ:bc:defhi:np:st:uv:x:z:")) != -1) { 154 switch (c) { 155 156 case 'L': 157 #ifdef NO_LUA_SUPPORT 158 bozoerr(&httpd, 1, 159 "Lua support is not enabled"); 160 /* NOTREACHED */ 161 #else 162 /* make sure there's two argument */ 163 if (argc - optind < 1) 164 usage(&httpd, progname); 165 bozo_add_lua_map(&httpd, optarg, argv[optind]); 166 optind++; 167 break; 168 #endif /* NO_LUA_SUPPORT */ 169 case 'M': 170 #ifdef NO_DYNAMIC_CONTENT 171 bozoerr(&httpd, 1, 172 "dynamic mime content support is not enabled"); 173 /* NOTREACHED */ 174 #else 175 /* make sure there's four arguments */ 176 if (argc - optind < 3) 177 usage(&httpd, progname); 178 bozo_add_content_map_mime(&httpd, optarg, argv[optind], 179 argv[optind+1], argv[optind+2]); 180 optind += 3; 181 break; 182 #endif /* NO_DYNAMIC_CONTENT */ 183 184 case 'n': 185 bozo_set_pref(&httpd, &prefs, "numeric", "true"); 186 break; 187 188 case 's': 189 bozo_set_pref(&httpd, &prefs, "log to stderr", "true"); 190 break; 191 192 case 'S': 193 bozo_set_pref(&httpd, &prefs, "server software", 194 optarg); 195 break; 196 case 'Z': 197 #ifdef NO_SSL_SUPPORT 198 bozoerr(&httpd, 1, "ssl support is not enabled"); 199 /* NOT REACHED */ 200 #else 201 /* make sure there's two arguments */ 202 if (argc - optind < 1) 203 usage(&httpd, progname); 204 bozo_ssl_set_opts(&httpd, optarg, argv[optind++]); 205 break; 206 #endif /* NO_SSL_SUPPORT */ 207 208 case 'z': 209 #ifdef NO_SSL_SUPPORT 210 bozoerr(&httpd, 1, "ssl support is not enabled"); 211 /* NOT REACHED */ 212 #else 213 bozo_ssl_set_ciphers(&httpd, optarg); 214 break; 215 #endif /* NO_SSL_SUPPORT */ 216 217 case 'U': 218 bozo_set_pref(&httpd, &prefs, "username", optarg); 219 break; 220 221 case 'V': 222 bozo_set_pref(&httpd, &prefs, "unknown slash", "true"); 223 break; 224 225 case 'v': 226 bozo_set_pref(&httpd, &prefs, "virtual base", optarg); 227 break; 228 229 case 'x': 230 bozo_set_pref(&httpd, &prefs, "index.html", optarg); 231 break; 232 233 case 'I': 234 bozo_set_pref(&httpd, &prefs, "port number", optarg); 235 break; 236 237 #ifdef NO_DAEMON_MODE 238 case 'b': 239 case 'e': 240 case 'f': 241 case 'i': 242 case 'P': 243 bozoerr(&httpd, 1, "Daemon mode is not enabled"); 244 /* NOTREACHED */ 245 #else 246 case 'b': 247 /* 248 * test suite support - undocumented 249 * background == 2 (aka, -b -b) means to 250 * only process 1 per kid 251 */ 252 val = bozo_get_pref(&prefs, "background") == NULL ? 253 "1" : "2"; 254 bozo_set_pref(&httpd, &prefs, "background", val); 255 break; 256 257 case 'e': 258 bozo_set_pref(&httpd, &prefs, "dirty environment", 259 "true"); 260 break; 261 262 case 'f': 263 bozo_set_pref(&httpd, &prefs, "foreground", "true"); 264 break; 265 266 case 'i': 267 bozo_set_pref(&httpd, &prefs, "bind address", optarg); 268 break; 269 270 case 'P': 271 bozo_set_pref(&httpd, &prefs, "pid file", optarg); 272 break; 273 #endif /* NO_DAEMON_MODE */ 274 275 #ifdef NO_CGIBIN_SUPPORT 276 case 'c': 277 case 'C': 278 bozoerr(&httpd, 1, "CGI is not enabled"); 279 /* NOTREACHED */ 280 #else 281 case 'c': 282 bozo_cgi_setbin(&httpd, optarg); 283 break; 284 285 case 'C': 286 # ifdef NO_DYNAMIC_CONTENT 287 bozoerr(&httpd, 1, 288 "dynamic CGI handler support is not enabled"); 289 /* NOTREACHED */ 290 # else 291 /* make sure there's two arguments */ 292 if (argc - optind < 1) 293 usage(&httpd, progname); 294 bozo_add_content_map_cgi(&httpd, optarg, 295 argv[optind++]); 296 break; 297 # endif /* NO_DYNAMIC_CONTENT */ 298 #endif /* NO_CGIBIN_SUPPORT */ 299 300 case 'd': 301 httpd.debug++; 302 #ifdef NO_DEBUG 303 if (httpd.debug == 1) 304 bozowarn(&httpd, "Debugging is not enabled"); 305 #endif /* NO_DEBUG */ 306 break; 307 308 case 't': 309 bozo_set_pref(&httpd, &prefs, "chroot dir", optarg); 310 break; 311 312 #ifdef NO_USER_SUPPORT 313 case 'p': 314 case 'u': 315 case 'E': 316 bozoerr(&httpd, 1, "User support is not enabled"); 317 /* NOTREACHED */ 318 #else 319 case 'p': 320 bozo_set_pref(&httpd, &prefs, "public_html", optarg); 321 break; 322 323 case 'u': 324 bozo_set_pref(&httpd, &prefs, "enable users", "true"); 325 break; 326 #ifndef NO_CGIBIN_SUPPORT 327 case 'E': 328 bozo_set_pref(&httpd, &prefs, "enable user cgibin", 329 "true"); 330 break; 331 #else 332 case 'E': 333 bozoerr(&httpd, 1, "CGI is not enabled"); 334 /* NOTREACHED */ 335 #endif /* NO_CGIBIN_SPPORT */ 336 #endif /* NO_USER_SUPPORT */ 337 338 #ifdef NO_DIRINDEX_SUPPORT 339 case 'H': 340 case 'X': 341 bozoerr(&httpd, 1, 342 "directory indexing is not enabled"); 343 /* NOTREACHED */ 344 #else 345 case 'H': 346 bozo_set_pref(&httpd, &prefs, "hide dots", "true"); 347 break; 348 349 case 'X': 350 bozo_set_pref(&httpd, &prefs, "directory indexing", 351 "true"); 352 break; 353 354 #endif /* NO_DIRINDEX_SUPPORT */ 355 356 case 'G': 357 { 358 char version[128]; 359 360 bozo_get_version(version, sizeof(version)); 361 printf("bozohttpd version %s\n", version); 362 } 363 return 0; 364 365 default: 366 usage(&httpd, progname); 367 /* NOTREACHED */ 368 } 369 } 370 371 argc -= optind; 372 argv += optind; 373 374 if (argc == 0 || argc > 2) { 375 usage(&httpd, progname); 376 } 377 378 /* virtual host, and root of tree to serve */ 379 bozo_setup(&httpd, &prefs, argv[1], argv[0]); 380 381 /* 382 * read and process the HTTP request. 383 */ 384 do { 385 if ((request = bozo_read_request(&httpd)) != NULL) { 386 bozo_process_request(request); 387 bozo_clean_request(request); 388 } 389 } while (httpd.background); 390 391 return (0); 392 } 393