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