xref: /minix3/libexec/httpd/main.c (revision 03ac74ede908465cc64c671bbd209e761dc765dc)
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