1 /* $NetBSD: main.c,v 1.8 2014/07/16 07:41:43 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-2014 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 bozo_warn(httpd, "usage: %s [options] slashdir [virtualhostname]", 62 progname); 63 bozo_warn(httpd, "options:"); 64 #ifndef NO_DEBUG 65 bozo_warn(httpd, " -d\t\t\tenable debug support"); 66 #endif 67 bozo_warn(httpd, " -s\t\t\talways log to stderr"); 68 #ifndef NO_USER_SUPPORT 69 bozo_warn(httpd, " -u\t\t\tenable ~user/public_html support"); 70 bozo_warn(httpd, " -p dir\t\tchange `public_html' directory name]"); 71 #endif 72 #ifndef NO_DYNAMIC_CONTENT 73 bozo_warn(httpd, " -M arg t c c11\tadd this mime extenstion"); 74 #endif 75 #ifndef NO_CGIBIN_SUPPORT 76 #ifndef NO_DYNAMIC_CONTENT 77 bozo_warn(httpd, " -C arg prog\t\tadd this CGI handler"); 78 #endif 79 bozo_warn(httpd, 80 " -c cgibin\t\tenable cgi-bin support in this directory"); 81 #endif 82 #ifndef NO_LUA_SUPPORT 83 bozo_warn(httpd, " -L arg script\tadd this Lua script"); 84 #endif 85 bozo_warn(httpd, " -I port\t\tbind or use on this port"); 86 #ifndef NO_DAEMON_MODE 87 bozo_warn(httpd, " -b\t\t\tbackground and go into daemon mode"); 88 bozo_warn(httpd, " -f\t\t\tkeep daemon mode in the foreground"); 89 bozo_warn(httpd, 90 " -i address\t\tbind on this address (daemon mode only)"); 91 bozo_warn(httpd, " -P pidfile\t\tpath to the pid file to create"); 92 #endif 93 bozo_warn(httpd, " -S version\t\tset server version string"); 94 bozo_warn(httpd, " -t dir\t\tchroot to `dir'"); 95 bozo_warn(httpd, " -U username\t\tchange user to `user'"); 96 bozo_warn(httpd, 97 " -e\t\t\tdon't clean the environment (-t and -U only)"); 98 bozo_warn(httpd, 99 " -v virtualroot\tenable virtual host support " 100 "in this directory"); 101 bozo_warn(httpd, 102 " -r\t\t\tmake sure sub-pages come from " 103 "this host via referrer"); 104 #ifndef NO_DIRINDEX_SUPPORT 105 bozo_warn(httpd, 106 " -X\t\t\tenable automatic directory index support"); 107 bozo_warn(httpd, 108 " -H\t\t\thide files starting with a period (.)" 109 " in index mode"); 110 #endif 111 bozo_warn(httpd, 112 " -x index\t\tchange default `index.html' file name"); 113 #ifndef NO_SSL_SUPPORT 114 bozo_warn(httpd, 115 " -Z cert privkey\tspecify path to server certificate" 116 " and private key file\n" 117 "\t\t\tin pem format and enable bozohttpd in SSL mode"); 118 #endif /* NO_SSL_SUPPORT */ 119 bozo_err(httpd, 1, "%s failed to start", progname); 120 } 121 122 int 123 main(int argc, char **argv) 124 { 125 bozo_httpreq_t *request; 126 bozohttpd_t httpd; 127 bozoprefs_t prefs; 128 char *progname; 129 int c; 130 131 (void) memset(&httpd, 0x0, sizeof(httpd)); 132 (void) memset(&prefs, 0x0, sizeof(prefs)); 133 134 if ((progname = strrchr(argv[0], '/')) == NULL) 135 progname = argv[0]; 136 else 137 progname++; 138 139 openlog(progname, LOG_PID|LOG_NDELAY, LOG_FTP); 140 141 bozo_set_defaults(&httpd, &prefs); 142 143 while ((c = getopt(argc, argv, 144 "C:HI:L:M:P:S:U:VXZ:bc:defhi:np:rst:uv:x:z:")) != -1) { 145 switch(c) { 146 147 case 'L': 148 #ifdef NO_LUA_SUPPORT 149 bozo_err(&httpd, 1, 150 "Lua support is not enabled"); 151 /* NOTREACHED */ 152 #else 153 /* make sure there's two argument */ 154 if (argc - optind < 1) 155 usage(&httpd, progname); 156 bozo_add_lua_map(&httpd, optarg, argv[optind]); 157 optind++; 158 break; 159 #endif /* NO_LUA_SUPPORT */ 160 case 'M': 161 #ifdef NO_DYNAMIC_CONTENT 162 bozo_err(&httpd, 1, 163 "dynamic mime content support is not enabled"); 164 /* NOTREACHED */ 165 #else 166 /* make sure there's four arguments */ 167 if (argc - optind < 3) 168 usage(&httpd, progname); 169 bozo_add_content_map_mime(&httpd, optarg, argv[optind], 170 argv[optind+1], argv[optind+2]); 171 optind += 3; 172 break; 173 #endif /* NO_DYNAMIC_CONTENT */ 174 175 case 'n': 176 bozo_set_pref(&prefs, "numeric", "true"); 177 break; 178 179 case 'r': 180 bozo_set_pref(&prefs, "trusted referal", "true"); 181 break; 182 183 case 's': 184 bozo_set_pref(&prefs, "log to stderr", "true"); 185 break; 186 187 case 'S': 188 bozo_set_pref(&prefs, "server software", optarg); 189 break; 190 case 'Z': 191 #ifdef NO_SSL_SUPPORT 192 bozo_err(&httpd, 1, "ssl support is not enabled"); 193 /* NOT REACHED */ 194 #else 195 /* make sure there's two arguments */ 196 if (argc - optind < 1) 197 usage(&httpd, progname); 198 bozo_ssl_set_opts(&httpd, optarg, argv[optind++]); 199 break; 200 #endif /* NO_SSL_SUPPORT */ 201 case 'U': 202 bozo_set_pref(&prefs, "username", optarg); 203 break; 204 205 case 'V': 206 bozo_set_pref(&prefs, "unknown slash", "true"); 207 break; 208 209 case 'v': 210 bozo_set_pref(&prefs, "virtual base", optarg); 211 break; 212 213 case 'x': 214 bozo_set_pref(&prefs, "index.html", optarg); 215 break; 216 217 case 'I': 218 bozo_set_pref(&prefs, "port number", optarg); 219 break; 220 221 #ifdef NO_DAEMON_MODE 222 case 'b': 223 case 'e': 224 case 'f': 225 case 'i': 226 case 'P': 227 bozo_err(&httpd, 1, "Daemon mode is not enabled"); 228 /* NOTREACHED */ 229 #else 230 case 'b': 231 /* 232 * test suite support - undocumented 233 * background == 2 (aka, -b -b) means to 234 * only process 1 per kid 235 */ 236 if (bozo_get_pref(&prefs, "background") == NULL) { 237 bozo_set_pref(&prefs, "background", "1"); 238 } else { 239 bozo_set_pref(&prefs, "background", "2"); 240 } 241 break; 242 243 case 'e': 244 bozo_set_pref(&prefs, "dirty environment", "true"); 245 break; 246 247 case 'f': 248 bozo_set_pref(&prefs, "foreground", "true"); 249 break; 250 251 case 'i': 252 bozo_set_pref(&prefs, "bind address", optarg); 253 break; 254 255 case 'P': 256 bozo_set_pref(&prefs, "pid file", optarg); 257 break; 258 #endif /* NO_DAEMON_MODE */ 259 260 #ifdef NO_CGIBIN_SUPPORT 261 case 'c': 262 case 'C': 263 bozo_err(&httpd, 1, "CGI is not enabled"); 264 /* NOTREACHED */ 265 #else 266 case 'c': 267 bozo_cgi_setbin(&httpd, optarg); 268 break; 269 270 case 'C': 271 # ifdef NO_DYNAMIC_CONTENT 272 bozo_err(&httpd, 1, 273 "dynamic CGI handler support is not enabled"); 274 /* NOTREACHED */ 275 # else 276 /* make sure there's two arguments */ 277 if (argc - optind < 1) 278 usage(&httpd, progname); 279 bozo_add_content_map_cgi(&httpd, optarg, 280 argv[optind++]); 281 break; 282 # endif /* NO_DYNAMIC_CONTENT */ 283 #endif /* NO_CGIBIN_SUPPORT */ 284 285 case 'd': 286 httpd.debug++; 287 #ifdef NO_DEBUG 288 if (httpd.debug == 1) 289 bozo_warn(&httpd, "Debugging is not enabled"); 290 #endif /* NO_DEBUG */ 291 break; 292 293 case 't': 294 bozo_set_pref(&prefs, "chroot dir", optarg); 295 break; 296 297 #ifdef NO_USER_SUPPORT 298 case 'p': 299 case 'u': 300 bozo_err(&httpd, 1, "User support is not enabled"); 301 /* NOTREACHED */ 302 #else 303 case 'p': 304 bozo_set_pref(&prefs, "public_html", optarg); 305 break; 306 307 case 'u': 308 bozo_set_pref(&prefs, "enable users", "true"); 309 break; 310 #endif /* NO_USER_SUPPORT */ 311 312 #ifdef NO_DIRINDEX_SUPPORT 313 case 'H': 314 case 'X': 315 bozo_err(&httpd, 1, 316 "directory indexing is not enabled"); 317 /* NOTREACHED */ 318 #else 319 case 'H': 320 bozo_set_pref(&prefs, "hide dots", "true"); 321 break; 322 323 case 'X': 324 bozo_set_pref(&prefs, "directory indexing", "true"); 325 break; 326 327 #endif /* NO_DIRINDEX_SUPPORT */ 328 329 default: 330 usage(&httpd, progname); 331 /* NOTREACHED */ 332 } 333 } 334 335 argc -= optind; 336 argv += optind; 337 338 if (argc == 0 || argc > 2) { 339 usage(&httpd, progname); 340 } 341 342 /* virtual host, and root of tree to serve */ 343 bozo_setup(&httpd, &prefs, argv[1], argv[0]); 344 345 /* 346 * read and process the HTTP request. 347 */ 348 do { 349 if ((request = bozo_read_request(&httpd)) != NULL) { 350 bozo_process_request(request); 351 bozo_clean_request(request); 352 } 353 } while (httpd.background); 354 355 return (0); 356 } 357