improve behaviour under VPC, fixes from nicolas tittley.
[minix.git] / commands / httpd / httpd.c
blob5fc903afff8731e3759efcd68ac92451601aeeb5
1 /* httpd.c
3 * httpd A Server implementing the HTTP protocol.
5 * usage: tcpd http httpd &
7 * 02/17/1996 Michael Temari <Michael@TemWare.Com>
8 * 07/07/1996 Initial Release Michael Temari <Michael@TemWare.Com>
9 * 12/29/2002 Michael Temari <Michael@TemWare.Com>
10 * 07/04/2003 Al Woodhull <awoodhull@hampshire.edu>
14 #include <stdlib.h>
15 #include <sys/types.h>
16 #include <pwd.h>
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <string.h>
20 #include "http.h"
21 #include "utility.h"
22 #include "net.h"
23 #include "config.h"
25 FILE *stdlog = (FILE *)NULL;
26 FILE *dbglog = (FILE *)NULL;
28 char umsg[80];
30 _PROTOTYPE(int main, (int argc, char *argv[]));
32 struct http_request request;
33 struct http_reply reply;
35 int main(argc, argv)
36 int argc;
37 char *argv[];
39 char *prog;
40 int opt_t;
41 char *cfg = (char *)NULL;
42 struct passwd *pwd;
43 int s;
45 strcpy(umsg, "Usage: ");
46 strcat(umsg, argv[0]);
47 strcat(umsg, " [-t|v] [config_file]\n");
49 /* parse program name */
50 prog = strrchr(*argv, '/');
51 if(prog == (char *)NULL)
52 prog = *argv;
53 else
54 prog++;
55 argv++;
56 argc--;
58 /* Any options */
59 if(argc)
60 if(argv[0][0] == '-') {
61 switch (argv[0][1]) {
62 case 't' : opt_t = 1;
63 argv++;
64 argc--;
65 break;
66 case 'v' : fprintf(stderr, VERSION"\n");
67 exit(EXIT_SUCCESS);
68 break;
69 default : fprintf(stderr, VERSION"\n");
70 fprintf(stderr, umsg);
71 exit(EXIT_FAILURE);
75 /* Did they specify an alternate configuration file? */
76 if(argc) {
77 cfg = *argv++;
78 argc--;
81 /* Read the configuration settings */
82 if(readconfig(cfg, opt_t)) {
83 fprintf(stderr, "httpd: Error reading configuration file.\n");
84 return(-1);
87 /* Option t is to test configuration only */
88 if(opt_t)
89 return(0);
91 /* Open log file for append if it exists */
92 if(LogFile != NULL)
93 if((stdlog = fopen(LogFile, "r")) != (FILE *)NULL) {
94 fclose(stdlog);
95 stdlog = fopen(LogFile, "a");
98 /* Open debug log file for append if it exists */
99 if(DbgFile != NULL)
100 if((dbglog = fopen(DbgFile, "r")) != (FILE *)NULL) {
101 fclose(dbglog);
102 dbglog = fopen(DbgFile, "a");
105 #if 0
106 /* Get some network information */
107 GetNetInfo();
108 #endif
110 /* If user defined then prepare to secure as user given */
111 if(User != NULL)
112 if((pwd = getpwnam(User)) == (struct passwd *)NULL) {
113 fprintf(stderr, "httpd: unable to find user %s\n", User);
114 return(-1);
117 /* If Chroot defined then secure even more by doing a chroot */
118 if(Chroot != NULL) {
119 if(chroot(Chroot)) {
120 fprintf(stderr, "httpd: unable to chroot\n");
121 return(-1);
123 if(chdir("/")) {
124 fprintf(stderr, "httpd: unable to chroot\n");
125 return(-1);
129 /* If user defined then secure as user given */
130 if(User != NULL)
131 if(setgid(pwd->pw_gid) || setuid(pwd->pw_uid)) {
132 fprintf(stderr, "httpd: unable to set user\n");
133 return(-1);
136 #if DAEMON
137 /* Standalone? */
138 if (strncmp(prog, "in.", 3) != 0) {
139 /* Does not start with "in.", so not started from inetd/tcpd. */
140 /* XXX - Port name/number should be a config file option. */
141 daemonloop("http");
143 #endif
145 /* Get some network information */
146 GetNetInfo();
148 /* log a connection */
149 if(dbglog != (FILE *)NULL) {
150 fprintf(dbglog, "CONNECT: %d %s %s\n", getpid(),
151 rmthostname, logdate((time_t *)NULL));
152 fflush(dbglog);
155 /* loop getting, processing and replying to requests */
156 while(!(s = getrequest(&request))) {
157 if(processrequest(&request, &reply)) break;
158 if(stdlog != (FILE *)NULL) {
159 fprintf(stdlog, "%s %s %d %d %s\n",
160 logdate((time_t *)NULL), rmthostname,
161 request.method, reply.status, request.url);
162 fflush(stdlog);
164 if(sendreply(&reply, &request)) break;
165 if(!reply.keepopen) break;
167 if(s == 1 && stdlog != (FILE *)NULL) {
168 fprintf(stdlog, "%s %s %d %d %s\n",
169 logdate((time_t *)NULL), rmthostname,
170 request.method, 999, request.url);
171 fflush(stdlog);
174 return(0);