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