Line 0
Link Here
|
|
|
1 |
*** 1.1 1995/07/11 17:09:01 |
2 |
--- Library/Implementation/HTAAServ.c 1995/07/12 20:54:32 |
3 |
*************** |
4 |
*** 571,576 **** |
5 |
--- 571,588 ---- |
6 |
*/ |
7 |
StrAllocCopy(untranslated, HTReqArgPath); |
8 |
|
9 |
+ if (sc.virtualize) { /* JPH003 */ |
10 |
+ char * vpath; /* JPH003 */ |
11 |
+ /* JPH003 */ |
12 |
+ vpath = (char *)malloc(1 + strlen(HTVirtualHost) + /* JPH003 */ |
13 |
+ strlen(HTReqArgPath) + 1); /* JPH003 */ |
14 |
+ sprintf(vpath, "/%s%s", HTVirtualHost, HTReqArgPath); /* JPH003 */ |
15 |
+ CTRACE(stderr, "Virtualize.. %s -> %s\n", /* JPH003 */ |
16 |
+ HTReqArgPath, vpath); /* JPH003 */ |
17 |
+ StrAllocCopy(HTReqArgPath, vpath); /* JPH003 */ |
18 |
+ free(vpath); /* JPH003 */ |
19 |
+ } /* JPH003 */ |
20 |
+ |
21 |
/* |
22 |
** Translate into absolute pathname, and |
23 |
** get protection by "protect" and "defprot" rules. |
24 |
*************** |
25 |
*** 618,623 **** |
26 |
--- 630,646 ---- |
27 |
StrAllocCat(welcome, "/"); |
28 |
physical = HTMulti(req, welcome, &stat_info2); |
29 |
free(welcome); |
30 |
+ |
31 |
+ if (physical && /* JPH003 */ |
32 |
+ !S_ISDIR(stat_info2.st_mode) && /* JPH003 */ |
33 |
+ sc.virtualize) { /* JPH003 */ |
34 |
+ CTRACE(stderr, /* JPH003 */ |
35 |
+ "UnVirtualize %s -> %s\n", /* JPH003 */ |
36 |
+ HTReqArgPath, /* JPH003 */ |
37 |
+ untranslated); /* JPH003 */ |
38 |
+ strcpy(HTReqArgPath, /* JPH003 */ |
39 |
+ untranslated); /* JPH003 */ |
40 |
+ } /* JPH003 */ |
41 |
|
42 |
if (physical && !S_ISDIR(stat_info2.st_mode)) { |
43 |
char * escaped = HTEscape(HTReqArgPath, |
44 |
*** 1.1 1995/07/14 15:49:18 |
45 |
--- Library/Implementation/HTConfig.c 1995/07/14 15:56:01 |
46 |
*************** |
47 |
*** 111,116 **** |
48 |
--- 111,118 ---- |
49 |
*/ |
50 |
PUBLIC void HTDefaultConfig NOARGS |
51 |
{ |
52 |
+ sc.virtualize = NO; /* JPH003 */ |
53 |
+ sc.workers = 0; /* JPH004 */ |
54 |
sc.input_timeout = DEFAULT_INPUT_TIMEOUT; |
55 |
sc.output_timeout = DEFAULT_OUTPUT_TIMEOUT; |
56 |
sc.script_timeout = DEFAULT_SCRIPT_TIMEOUT; |
57 |
*************** |
58 |
*** 1233,1238 **** |
59 |
--- 1235,1255 ---- |
60 |
} else if (strstr(vec[0],"icon")) { /* All *Icon* directives */ |
61 |
icon_config(vec,c); |
62 |
|
63 |
+ } else if (strstr(vec[0], "virtualize")) { /* JPH003 */ |
64 |
+ sc.virtualize = positive(vec[1]); /* JPH003 */ |
65 |
+ CTRACE(stderr, "Virtualize.. %s\n", /* JPH003 */ |
66 |
+ sc.virtualize ? "On" : "Off"); /* JPH003 */ |
67 |
+ /* JPH003 */ |
68 |
+ } else if (strstr(vec[0], "workers")) { /* JPH004 */ |
69 |
+ sc.workers = atoi(vec[1]); /* JPH004 */ |
70 |
+ if (sc.workers) { /* JPH004 */ |
71 |
+ CTRACE(stderr, /* JPH004 */ |
72 |
+ "PreForking.. On, %d workers\n", /* JPH004 */ |
73 |
+ sc.workers); /* JPH004 */ |
74 |
+ } else { /* JPH004 */ |
75 |
+ CTRACE(stderr, "PreForking.. Off\n"); /* JPH004 */ |
76 |
+ } /* JPH004 */ |
77 |
+ /* JPH004 */ |
78 |
} else if (!strncmp(vec[0], "serverroot", 10)) { |
79 |
sc.server_root = tilde_to_home(vec[1]); |
80 |
HTSaveLocallyDir = sc.server_root; /* Henrik Aug 31, 94 */ |
81 |
*** 1.1 1995/07/11 17:09:06 |
82 |
--- Library/Implementation/HTConfig.h 1995/07/12 21:50:59 |
83 |
*************** |
84 |
*** 47,52 **** |
85 |
--- 47,54 ---- |
86 |
int port; /* Default port number string */ |
87 |
BOOL no_bg; /* Don't auto-go background */ |
88 |
BOOL standalone; /* Am I standalone? */ |
89 |
+ BOOL virtualize; /* multi-home mode? */ /* JPH003 */ |
90 |
+ int workers; /* preforking mode? */ /* JPH004 */ |
91 |
char * server_root; /* Server's "home directory" */ |
92 |
int security_level; /* 0 = normal, 1 = high */ |
93 |
char * errormsg_path; /* URL for error messages */ |
94 |
*** 1.1 1995/07/11 17:09:07 |
95 |
--- Library/Implementation/HTDaemon.c 1995/10/11 16:56:00 |
96 |
*************** |
97 |
*** 161,166 **** |
98 |
--- 161,168 ---- |
99 |
#include <signal.h> |
100 |
#include <sys/param.h> |
101 |
#include <errno.h> |
102 |
+ #include <sys/uio.h> /* JPH004 */ |
103 |
+ #include <setjmp.h> /* JPH007 */ |
104 |
|
105 |
#ifndef SIGCLD |
106 |
#ifdef SIGCHLD |
107 |
*************** |
108 |
*** 251,256 **** |
109 |
--- 253,260 ---- |
110 |
/* Server environment when handling requests |
111 |
** ----------------------------------------- |
112 |
*/ |
113 |
+ PUBLIC jmp_buf HTJumpEnv; /* JPH007 */ |
114 |
+ PUBLIC char * HTVirtualHost = NULL; /* JPH003 */ |
115 |
PUBLIC char * HTReasonLine = NULL; |
116 |
PUBLIC int HTSoc = 0; |
117 |
PUBLIC char * HTReqLine = NULL; |
118 |
*************** |
119 |
*** 532,543 **** |
120 |
--- 536,556 ---- |
121 |
{ |
122 |
if (sc.standalone) { |
123 |
#if defined(__svr4__) || defined(_POSIX_SOURCE) || defined(__hpux) |
124 |
+ if (kill(-pgrp, SIGTERM) == 0) { /* JPH001 */ |
125 |
+ kill(-pgrp, SIGCONT); /* JPH001 */ |
126 |
+ sleep(5); /* JPH001 */ |
127 |
+ } /* JPH001 */ |
128 |
kill(-pgrp, SIGKILL); |
129 |
#else |
130 |
+ if (killpg(pgrp, SIGTERM) == 0) { /* JPH001 */ |
131 |
+ killpg(pgrp, SIGCONT); /* JPH001 */ |
132 |
+ sleep(5); /* JPH001 */ |
133 |
+ } /* JPH001 */ |
134 |
killpg(pgrp, SIGKILL); |
135 |
#endif |
136 |
shutdown(master_soc, 2); |
137 |
close(master_soc); |
138 |
+ exit(1); /* JPH001 */ |
139 |
} |
140 |
} |
141 |
|
142 |
*************** |
143 |
*** 580,585 **** |
144 |
--- 593,600 ---- |
145 |
|
146 |
PRIVATE void sig_pipe NOARGS |
147 |
{ |
148 |
+ PRIVATE void clean_exit NOARGS; /* JPH007 */ |
149 |
+ |
150 |
if (!sigpipe_caught) { |
151 |
if (HTReqLine) |
152 |
HTLog_error2("Connection interrupted [SIGPIPE], req:",HTReqLine); |
153 |
*************** |
154 |
*** 587,592 **** |
155 |
--- 602,614 ---- |
156 |
HTLog_error("Connection interrupted [SIGPIPE]"); |
157 |
} |
158 |
|
159 |
+ if (sc.workers) { /* JPH004 */ |
160 |
+ CTRACE(stderr, "SIGPIPE..... ignored (pre-forking)\n"); /* JPH004 */ |
161 |
+ sigpipe_caught = YES; /* JPH004 */ |
162 |
+ set_signals(); /* JPH004 */ |
163 |
+ return; /* JPH004 */ |
164 |
+ } /* JPH004 */ |
165 |
+ |
166 |
if (ignore_sigpipes) { |
167 |
CTRACE(stderr, "SIGPIPE..... ignored (writing to cache)\n"); |
168 |
sigpipe_caught = YES; |
169 |
*************** |
170 |
*** 595,605 **** |
171 |
else { |
172 |
timeout_off(); /* So timeouts don't go to parent */ |
173 |
CTRACE(stderr, "SIGPIPE..... caught, exiting...\n"); |
174 |
! if (com_soc > 0) { |
175 |
! shutdown(com_soc, 2); |
176 |
! NETCLOSE(com_soc); |
177 |
! } |
178 |
! exit(0); |
179 |
} |
180 |
} |
181 |
|
182 |
--- 617,623 ---- |
183 |
else { |
184 |
timeout_off(); /* So timeouts don't go to parent */ |
185 |
CTRACE(stderr, "SIGPIPE..... caught, exiting...\n"); |
186 |
! clean_exit(); /* JPH007 */ |
187 |
} |
188 |
} |
189 |
|
190 |
*************** |
191 |
*** 1444,1449 **** |
192 |
--- 1462,1471 ---- |
193 |
shutdown(com_soc, 2); |
194 |
NETCLOSE(com_soc); |
195 |
} |
196 |
+ if (sc.workers) { /* JPH007 */ |
197 |
+ longjmp(HTJumpEnv, 1); /* JPH007 */ |
198 |
+ HTLog_error("Worker failed to long-jump back"); /* JPH007 */ |
199 |
+ } /* JPH007 */ |
200 |
exit(0); |
201 |
} |
202 |
|
203 |
*************** |
204 |
*** 1625,1630 **** |
205 |
--- 1647,1666 ---- |
206 |
HTVMS_enableSysPrv(); |
207 |
#endif /* VMS */ |
208 |
|
209 |
+ if (sc.virtualize) { /* JPH003 */ |
210 |
+ SockA vaddr; /* JPH003 */ |
211 |
+ int vlen = sizeof(vaddr); /* JPH003 */ |
212 |
+ /* JPH003 */ |
213 |
+ memset((char*)&vaddr, 0, sizeof(vaddr)); /* JPH003 */ |
214 |
+ getsockname(com_soc, (struct sockaddr*)&vaddr, &vlen); /* JPH003 */ |
215 |
+ StrAllocCopy(HTVirtualHost, HTInetString(&vaddr)); /* JPH003 */ |
216 |
+ if (!HTVirtualHost || !*HTVirtualHost) { /* JPH003 */ |
217 |
+ StrAllocCopy(HTVirtualHost, "0.0.0.0"); /* JPH003 */ |
218 |
+ } /* JPH003 */ |
219 |
+ CTRACE(stderr, "Connection... via address %s\n", /* JPH003 */ |
220 |
+ HTVirtualHost); /* JPH003 */ |
221 |
+ } /* JPH003 */ |
222 |
+ |
223 |
out.status_code = HTAA_checkAuthorization(req); |
224 |
CTRACE(stderr, "AA.......... check returned %d\n", out.status_code); |
225 |
CTRACE(stderr, "Translated.. \"%s\"\n", |
226 |
*************** |
227 |
*** 2063,2069 **** |
228 |
} |
229 |
#endif /* not VMS */ |
230 |
|
231 |
! |
232 |
|
233 |
/* standalone_server_loop() |
234 |
* New server_loop() for Unixes in standalone mode |
235 |
--- 2099,2413 ---- |
236 |
} |
237 |
#endif /* not VMS */ |
238 |
|
239 |
! #if !defined(VMS) && defined(FORKING) /* JPH004 */ |
240 |
! PRIVATE int wait_for_work ARGS1(int, fd) /* JPH004 */ |
241 |
! { /* JPH004 */ |
242 |
! struct iovec iov[1]; /* JPH004 */ |
243 |
! struct msghdr msg; /* JPH004 */ |
244 |
! int passedfd = -1; /* just in case */ /* JPH004 */ |
245 |
! char dummy; /* JPH004 */ |
246 |
! /* JPH004 */ |
247 |
! iov[0].iov_base = &dummy; /* JPH004 */ |
248 |
! iov[0].iov_len = 1; /* JPH004 */ |
249 |
! msg.msg_name = NULL; /* JPH004 */ |
250 |
! msg.msg_namelen = 0; /* JPH004 */ |
251 |
! msg.msg_iov = iov; /* JPH004 */ |
252 |
! msg.msg_iovlen = 1; /* JPH004 */ |
253 |
! msg.msg_accrights = (caddr_t)&passedfd; /* JPH004 */ |
254 |
! msg.msg_accrightslen = sizeof(passedfd); /* JPH004 */ |
255 |
! while (recvmsg(fd, &msg, 0) == -1) { /* JPH007 */ |
256 |
! if (errno != EINTR) { /* JPH007 */ |
257 |
! HTLog_error("Failed to recvmsg in worker\n"); /* JPH004 */ |
258 |
! _exit(1); /* JPH004 */ |
259 |
! } /* JPH007 */ |
260 |
! } /* JPH004 */ |
261 |
! return passedfd; /* JPH004 */ |
262 |
! } /* JPH004 */ |
263 |
! /* JPH004 */ |
264 |
! PRIVATE int work_completed ARGS1(HTWorkerStruct *, wp) /* JPH004 */ |
265 |
! { /* JPH004 */ |
266 |
! return send(wp->fd, &wp->index, sizeof(wp->index), 0); /* JPH004 */ |
267 |
! } /* JPH004 */ |
268 |
! /* JPH004 */ |
269 |
! PRIVATE int do_work ARGS1(HTWorkerStruct *, wp) /* JPH004 */ |
270 |
! { /* JPH004 */ |
271 |
! int tcp_status; /* JPH004 */ |
272 |
! static struct linger sl = {1, 600}; /* JPH004 */ |
273 |
! SockA addr; /* JPH004 */ |
274 |
! int alen = sizeof(addr); /* JPH004 */ |
275 |
! char * host; /* JPH004 */ |
276 |
! int fd; /* JPH008 */ |
277 |
! int closemask = 0; /* JPH008 */ |
278 |
! /* JPH004 */ |
279 |
! for (fd = 0; fd < 32; ++fd) { /* JPH008 */ |
280 |
! closemask |= (!~fcntl(fd, F_GETFD, 0) << fd); /* JPH008 */ |
281 |
! } /* JPH008 */ |
282 |
! for (;;) { /* JPH004 */ |
283 |
! com_soc = wait_for_work(wp->fd); /* JPH004 */ |
284 |
! time(&cur_time); /* JPH004 */ |
285 |
! child_serial++; /* JPH004 */ |
286 |
! CTRACE(stderr, "Worker...... I'm awake\n"); /* JPH004 */ |
287 |
! if (sc.do_linger) { /* JPH004 */ |
288 |
! setsockopt(com_soc, SOL_SOCKET, SO_LINGER, /* JPH004 */ |
289 |
! (char*)&sl, sizeof(sl)); /* JPH004 */ |
290 |
! } /* JPH004 */ |
291 |
! memset((char*)&addr, 0, sizeof(addr)); /* JPH004 */ |
292 |
! getpeername(com_soc, (struct sockaddr*)&addr, &alen); /* JPH004 */ |
293 |
! host = HTInetString(&addr); /* JPH004 */ |
294 |
! if (!host || !*host) host = "0.0.0.0"; /* JPH004 */ |
295 |
! StrAllocCopy(HTClientHost, host); /* JPH004 */ |
296 |
! FREE(HTClientHostName); /* JPH004 */ |
297 |
! if (sc.do_dns_lookup) { /* JPH004 */ |
298 |
! HTClientHostName = HTGetHostBySock(com_soc); /* JPH004 */ |
299 |
! } /* JPH004 */ |
300 |
! CTRACE(stderr, "Reading..... socket %d from host %s\n", /* JPH004 */ |
301 |
! com_soc, HTClientHost); /* JPH004 */ |
302 |
! remote_ident = NULL; /* JPH004 */ |
303 |
! if (sc.do_rfc931) { /* ...broken?... */ } /* JPH004 */ |
304 |
! sigpipe_caught = NO; /* JPH004 */ |
305 |
! if (setjmp(HTJumpEnv) == 0) { /* JPH007 */ |
306 |
! tcp_status = HTHandle(com_soc); /* JPH004 */ |
307 |
! } /* JPH007 */ |
308 |
! if (TRACE) { /* JPH004 */ |
309 |
! if (tcp_status < 0) { /* JPH004 */ |
310 |
! fprintf(stderr, /* JPH004 */ |
311 |
! "ERROR....... %d handling msg (errno=%d).\n", /* JPH004 */ |
312 |
! tcp_status, errno); /* JPH004 */ |
313 |
! } else if (tcp_status == 0) { /* JPH004 */ |
314 |
! fprintf(stderr, /* JPH004 */ |
315 |
! "Socket...... %d disconnected by peer\n", /* JPH004 */ |
316 |
! com_soc); /* JPH004 */ |
317 |
! } /* JPH004 */ |
318 |
! } /* JPH004 */ |
319 |
! shutdown(com_soc, 2); /* JPH004 */ |
320 |
! NETCLOSE(com_soc); /* JPH004 */ |
321 |
! for (fd = 0; fd < 32; ++fd) { /* JPH008 */ |
322 |
! if (closemask & (1 << fd)) close(fd); /* JPH008 */ |
323 |
! } /* JPH008 */ |
324 |
! work_completed(wp); /* JPH004 */ |
325 |
! } /* JPH004 */ |
326 |
! /*NOTREACHED*/ /* JPH004 */ |
327 |
! } /* JPH004 */ |
328 |
! /* JPH004 */ |
329 |
! PRIVATE int getlocaldgram ARGS2(struct sockaddr_un *, sunp, /* JPH004 */ |
330 |
! int *, alenp) /* JPH004 */ |
331 |
! { /* JPH004 */ |
332 |
! int sockfd; /* JPH004 */ |
333 |
! /* JPH004 */ |
334 |
! if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) { /* JPH004 */ |
335 |
! HTLog_error("Failed to create UNIX/DGRAM socket\n"); /* JPH004 */ |
336 |
! return -1; /* JPH004 */ |
337 |
! } /* JPH004 */ |
338 |
! sunp->sun_family = AF_UNIX; /* JPH004 */ |
339 |
! strcpy(sunp->sun_path, tempnam(NULL, "wwwSS")); /* JPH004 */ |
340 |
! *alenp = sizeof(sunp->sun_family) + strlen(sunp->sun_path); /* JPH004 */ |
341 |
! if (bind(sockfd, sunp, *alenp) == -1) { /* JPH004 */ |
342 |
! HTLog_error2("Failed to bind UNIX/DGRAM socket to %s", /* JPH004 */ |
343 |
! sunp->sun_path); /* JPH004 */ |
344 |
! return -1; /* JPH004 */ |
345 |
! } /* JPH004 */ |
346 |
! return sockfd; /* JPH004 */ |
347 |
! } /* JPH004 */ |
348 |
! /* JPH004 */ |
349 |
! PRIVATE int make_worker ARGS3(HTWorkerStruct *, wp, /* JPH004 */ |
350 |
! struct sockaddr_un *, bossp, /* JPH004 */ |
351 |
! int, bosslen) /* JPH004 */ |
352 |
! { /* JPH004 */ |
353 |
! wp->fd = getlocaldgram(&wp->addr, &wp->addrlen); /* JPH004 */ |
354 |
! if (wp->fd == -1) { /* JPH004 */ |
355 |
! HTLog_error("Failed to make worker process\n"); /* JPH004 */ |
356 |
! return -1; /* JPH004 */ |
357 |
! } /* JPH004 */ |
358 |
! if (connect(wp->fd, bossp, bosslen) == -1) { /* JPH004 */ |
359 |
! HTLog_error("Failed to connect worker process\n"); /* JPH004 */ |
360 |
! return -1; /* JPH004 */ |
361 |
! } /* JPH004 */ |
362 |
! if ((wp->pid = fork()) == 0) do_work(wp); /* JPH004 */ |
363 |
! if (wp->pid == -1) { /* JPH004 */ |
364 |
! HTLog_error("Failed to fork worker process\n"); /* JPH004 */ |
365 |
! } /* JPH004 */ |
366 |
! close(wp->fd); /* JPH004 */ |
367 |
! wp->fd = -1; /* JPH004 */ |
368 |
! return (wp->pid); /* JPH004 */ |
369 |
! } /* JPH004 */ |
370 |
! /* JPH004 */ |
371 |
! PRIVATE int assign_work ARGS3(int, workerfd, /* JPH004 */ |
372 |
! int, clientfd, /* JPH004 */ |
373 |
! HTWorkerStruct *, wp) /* JPH004 */ |
374 |
! { /* JPH004 */ |
375 |
! struct iovec iov[1]; /* JPH004 */ |
376 |
! struct msghdr msg; /* JPH004 */ |
377 |
! /* JPH004 */ |
378 |
! iov[0].iov_base = "?"; /* any old byte */ /* JPH004 */ |
379 |
! iov[0].iov_len = 1; /* JPH004 */ |
380 |
! msg.msg_name = (caddr_t)&wp->addr; /* JPH004 */ |
381 |
! msg.msg_namelen = wp->addrlen; /* JPH004 */ |
382 |
! msg.msg_iov = iov; /* JPH004 */ |
383 |
! msg.msg_iovlen = 1; /* JPH004 */ |
384 |
! msg.msg_accrights = (caddr_t)&clientfd; /* JPH004 */ |
385 |
! msg.msg_accrightslen = sizeof(clientfd); /* JPH004 */ |
386 |
! if (sendmsg(workerfd, &msg, 0) == -1) { /* JPH004 */ |
387 |
! HTLog_error("Failed to sendmsg to worker\n"); /* JPH004 */ |
388 |
! return -1; /* JPH004 */ |
389 |
! } /* JPH004 */ |
390 |
! return 0; /* JPH004 */ |
391 |
! } /* JPH004 */ |
392 |
! /* JPH004 */ |
393 |
! PRIVATE int worker_done ARGS1(int, fd) /* JPH004 */ |
394 |
! { /* JPH004 */ |
395 |
! int index = -1; /* just in case */ /* JPH004 */ |
396 |
! /* JPH004 */ |
397 |
! (void)recv(fd, &index, sizeof(index)); /* JPH004 */ |
398 |
! return index; /* JPH004 */ |
399 |
! } /* JPH004 */ |
400 |
! /* JPH004 */ |
401 |
! /* JPH004 */ |
402 |
! /* New server_loop() for Unixes in preforking mode */ /* JPH004 */ |
403 |
! /* JPH004 */ |
404 |
! PRIVATE int preforking_server_loop NOARGS /* JPH004 */ |
405 |
! { /* JPH004 */ |
406 |
! int soc_addr_len = sizeof(client_soc_addr); /* JPH004 */ |
407 |
! int timeout; /* JPH004 */ |
408 |
! int worker_soc = -1; /* JPH004 */ |
409 |
! struct sockaddr_un boss; /* JPH004 */ |
410 |
! int blen; /* JPH004 */ |
411 |
! int nw = 0; /* JPH004 */ |
412 |
! HTWorkerStruct * worker = NULL; /* JPH004 */ |
413 |
! int * roster = NULL; /* JPH004 */ |
414 |
! int nIdle; /* JPH004 */ |
415 |
! int idle_index; /* index in worker of just completed */ /* JPH004 */ |
416 |
! int idle_slot; /* and its slot in roster table */ /* JPH004 */ |
417 |
! fd_set read_chans; /* JPH004 */ |
418 |
! struct timeval max_wait; /* JPH004 */ |
419 |
! int nfound; /* JPH004 */ |
420 |
! /* JPH004 */ |
421 |
! CTRACE(stderr, "ServerLoop.. Unix preforking\n"); /* JPH004 */ |
422 |
! /* JPH004 */ |
423 |
! worker_soc = getlocaldgram(&boss, &blen); /* JPH004 */ |
424 |
! if (worker_soc == -1) goto fallback; /* JPH004 */ |
425 |
! worker = (HTWorkerStruct *) /* JPH004 */ |
426 |
! malloc(sc.workers * sizeof(HTWorkerStruct)); /* JPH004 */ |
427 |
! if (worker == NULL) { /* JPH004 */ |
428 |
! HTLog_error("Worker alloc failed\n"); /* JPH004 */ |
429 |
! goto fallback; /* JPH004 */ |
430 |
! } /* JPH004 */ |
431 |
! roster = (int *)malloc(sc.workers * sizeof(int)); /* JPH004 */ |
432 |
! if (roster == NULL) { /* JPH004 */ |
433 |
! HTLog_error("Worker roster alloc failed\n"); /* JPH004 */ |
434 |
! goto fallback; /* JPH004 */ |
435 |
! } /* JPH004 */ |
436 |
! for (nIdle = 0; nIdle < sc.workers; ++nIdle) { /* JPH004 */ |
437 |
! roster[nIdle] = nIdle; /* JPH004 */ |
438 |
! } /* JPH004 */ |
439 |
! for (nw = 0; nw < sc.workers; ++nw) { /* JPH004 */ |
440 |
! worker[nw].index = nw; /* JPH004 */ |
441 |
! worker[nw].slot = nw; /* JPH004 */ |
442 |
! if (make_worker(worker + nw, &boss, blen) == -1) break; /* JPH004 */ |
443 |
! } /* JPH004 */ |
444 |
! if (nw == 0) { /* JPH004 */ |
445 |
! HTLog_error("Unable to create any worker processes\n"); /* JPH004 */ |
446 |
! goto fallback; /* JPH004 */ |
447 |
! } /* JPH004 */ |
448 |
! if (nw != sc.workers) { /* JPH004 */ |
449 |
! HTLog_errorN("Worker processes reduced to", nw); /* JPH004 */ |
450 |
! sc.workers = nw; /* JPH004 */ |
451 |
! } /* JPH004 */ |
452 |
! /* JPH004 */ |
453 |
! FD_ZERO(&open_sockets); /* JPH004 */ |
454 |
! FD_SET(worker_soc, &open_sockets); /* JPH004 */ |
455 |
! FD_SET(master_soc, &open_sockets); /* JPH004 */ |
456 |
! num_sockets = 1 + /* JPH004 */ |
457 |
! ((worker_soc > master_soc) ? worker_soc : master_soc); /* JPH004 */ |
458 |
! for (;;) { /* JPH004 */ |
459 |
! if (nIdle == 0) { /* JPH004 */ |
460 |
! HTLog_error("All workers busy, not accepting\n"); /* JPH004 */ |
461 |
! FD_CLR(master_soc, &open_sockets); /* JPH004 */ |
462 |
! } /* JPH004 */ |
463 |
! read_chans = open_sockets; /* JPH004 */ |
464 |
! timeout = get_next_timeout(); /* JPH004 */ |
465 |
! max_wait.tv_sec = timeout/100; /* JPH004 */ |
466 |
! max_wait.tv_usec = (timeout%100)*10000; /* JPH004 */ |
467 |
! timeout /= 100; /* JPH004 */ |
468 |
! if (TRACE) { /* JPH004 */ |
469 |
! fprintf(stderr, /* JPH004 */ |
470 |
! "Next timeout after %d hours %d mins %d secs\n", /* JPH004 */ |
471 |
! timeout/3600, (timeout/60)%60, timeout%60); /* JPH004 */ |
472 |
! fprintf(stderr, /* JPH004 */ |
473 |
! "Daemon...... %s (Mask=%x hex, max=%x hex).\n", /* JPH004 */ |
474 |
! "Waiting for connection", /* JPH004 */ |
475 |
! *(unsigned int *)(&read_chans), /* JPH004 */ |
476 |
! (unsigned int)num_sockets); /* JPH004 */ |
477 |
! } /* JPH004 */ |
478 |
! #ifdef __hpux /* JPH004 */ |
479 |
! nfound = select(num_sockets, /* JPH004 */ |
480 |
! (int *)&read_chans, NULL, NULL, /* JPH004 */ |
481 |
! timeout > 0 ? &max_wait : NULL); /* JPH004 */ |
482 |
! #else /* JPH004 */ |
483 |
! nfound = select(num_sockets, /* JPH004 */ |
484 |
! &read_chans, NULL, NULL, /* JPH004 */ |
485 |
! timeout > 0 ? &max_wait : NULL); /* JPH004 */ |
486 |
! #endif /* JPH004 */ |
487 |
! if (nfound < 0) { /* Interrupted */ /* JPH004 */ |
488 |
! if (errno != EINTR) (void)HTInetStatus("select"); /* JPH004 */ |
489 |
! continue; /* JPH004 */ |
490 |
! } /* JPH004 */ |
491 |
! if (nfound == 0) { /* Timeout */ /* JPH004 */ |
492 |
! CTRACE(stderr, /* JPH004 */ |
493 |
! "Time to do.. daily garbage collection\n"); /* JPH004 */ |
494 |
! gc_pid = fork(); /* JPH004 */ |
495 |
! if (!gc_pid) gc_and_exit(1,0); /* JPH004 */ |
496 |
! else continue; /* JPH004 */ |
497 |
! } /* JPH004 */ |
498 |
! if (FD_ISSET(worker_soc, &read_chans)) { /* JPH004 */ |
499 |
! idle_index = worker_done(worker_soc); /* JPH004 */ |
500 |
! if (idle_index != -1) { /* JPH004 */ |
501 |
! idle_slot = worker[idle_index].slot; /* JPH004 */ |
502 |
! roster[idle_slot] = roster[nIdle]; /* JPH004 */ |
503 |
! worker[roster[nIdle]].slot = idle_slot; /* JPH004 */ |
504 |
! roster[nIdle] = idle_index; /* JPH004 */ |
505 |
! worker[idle_index].slot = nIdle; /* JPH004 */ |
506 |
! if (nIdle++ == 0) { /* JPH004 */ |
507 |
! HTLog_error( /* JPH004 */ |
508 |
! "A worker is now available\n"); /* JPH004 */ |
509 |
! FD_SET(master_soc, &open_sockets); /* JPH004 */ |
510 |
! } /* JPH004 */ |
511 |
! } /* JPH004 */ |
512 |
! } /* JPH004 */ |
513 |
! if (FD_ISSET(master_soc, &read_chans)) { /* JPH004 */ |
514 |
! CTRACE(stderr, /* JPH004 */ |
515 |
! "Daemon...... accepting connection...\n"); /* JPH004 */ |
516 |
! com_soc = accept(master_soc, /* JPH004 */ |
517 |
! (struct sockaddr *)&client_soc_addr, /* JPH004 */ |
518 |
! &soc_addr_len); /* JPH004 */ |
519 |
! if (com_soc < 0) { /* JPH004 */ |
520 |
! if (errno != EINTR) HTInetStatus("accept"); /* JPH004 */ |
521 |
! continue; /* JPH004 */ |
522 |
! } /* JPH004 */ |
523 |
! --nIdle; /* JPH004 */ |
524 |
! CTRACE(stderr, /* JPH004 */ |
525 |
! "Accepted.... socket %d, worker %d slot %d\n", /* JPH004 */ |
526 |
! com_soc, roster[nIdle], nIdle); /* JPH004 */ |
527 |
! assign_work(worker_soc, com_soc, /* JPH004 */ |
528 |
! worker + roster[nIdle]); /* JPH004 */ |
529 |
! NETCLOSE(com_soc); /* JPH004 */ |
530 |
! #ifdef SIGTSTP /* BSD */ /* JPH004 */ |
531 |
! sig_child(); /* ??? redundant ??? */ /* JPH004 */ |
532 |
! #endif /* JPH004 */ |
533 |
! } /* JPH004 */ |
534 |
! } /* for loop */ /* JPH004 */ |
535 |
! /* JPH004 */ |
536 |
! fallback: /* JPH004 */ |
537 |
! if (worker_soc != -1) { /* JPH004 */ |
538 |
! close(worker_soc); /* JPH004 */ |
539 |
! unlink(boss.sun_path); /* JPH004 */ |
540 |
! } /* JPH004 */ |
541 |
! if (roster != NULL) free(roster); /* JPH004 */ |
542 |
! if (worker != NULL) free(worker); /* JPH004 */ |
543 |
! sc.workers = 0; /* JPH004 */ |
544 |
! HTLog_error("Falling back to non-preforking mode\n"); /* JPH004 */ |
545 |
! return 1; /* JPH004 */ |
546 |
! } /* JPH004 */ |
547 |
! #endif /* JPH004 */ |
548 |
|
549 |
/* standalone_server_loop() |
550 |
* New server_loop() for Unixes in standalone mode |
551 |
*************** |
552 |
*** 2300,2305 **** |
553 |
--- 2644,2652 ---- |
554 |
/* |
555 |
* Use new server loop, old one is a mess. |
556 |
*/ |
557 |
+ if ((role == master) && (sc.workers)) { /* JPH004 */ |
558 |
+ preforking_server_loop(); /* JPH004 */ |
559 |
+ } /* JPH004 */ |
560 |
if (role == master) standalone_server_loop(); |
561 |
#endif |
562 |
|
563 |
*************** |
564 |
*** 2674,2685 **** |
565 |
#if defined(__svr4__) || defined(_POSIX_SOURCE) || defined(__hpux) |
566 |
pgrp = setsid(); |
567 |
#else |
568 |
! pgrp = setpgrp(0, getpid()); |
569 |
|
570 |
if ((fd = open("/dev/tty", O_RDWR)) >= 0) { |
571 |
ioctl(fd, TIOCNOTTY, (char*)NULL); /* Lose controlling tty */ |
572 |
close(fd); |
573 |
} |
574 |
#endif |
575 |
if (pgrp == -1) |
576 |
HTLog_error("Can't change process group"); |
577 |
--- 3021,3038 ---- |
578 |
#if defined(__svr4__) || defined(_POSIX_SOURCE) || defined(__hpux) |
579 |
pgrp = setsid(); |
580 |
#else |
581 |
! pgrp = (setpgrp(0, getpid()) == -1) ? -1 : getpgrp(0); /* JPH002 */ |
582 |
|
583 |
if ((fd = open("/dev/tty", O_RDWR)) >= 0) { |
584 |
ioctl(fd, TIOCNOTTY, (char*)NULL); /* Lose controlling tty */ |
585 |
close(fd); |
586 |
} |
587 |
+ |
588 |
+ /* TIOCNOTTY can reset pgrp to zero! */ /* JPH002 */ |
589 |
+ /* JPH002 */ |
590 |
+ if (getpgrp(0) == 0) { /* JPH002 */ |
591 |
+ pgrp = (setpgrp(0, getpid()) == -1) ? -1 : getpgrp(0); /* JPH002 */ |
592 |
+ } /* JPH002 */ |
593 |
#endif |
594 |
if (pgrp == -1) |
595 |
HTLog_error("Can't change process group"); |
596 |
*** 1.1 1995/07/11 17:09:08 |
597 |
--- Library/Implementation/HTDaemon.h 1995/07/13 02:57:04 |
598 |
*************** |
599 |
*** 14,19 **** |
600 |
--- 14,20 ---- |
601 |
extern BOOL ignore_sigpipes; /* Should we catch and ignore SIGPIPE */ |
602 |
extern BOOL sigpipe_caught; /* If so, have we caught a SIGPIPE */ |
603 |
|
604 |
+ extern char * HTVirtualHost; /* JPH003 */ |
605 |
extern char * HTClientProtocol; |
606 |
extern int HTServerPort; |
607 |
|
608 |
*************** |
609 |
*** 53,58 **** |
610 |
--- 54,71 ---- |
611 |
extern BOOL trace_all; |
612 |
#define VTRACE if(trace_all)fprintf |
613 |
|
614 |
+ #ifdef FORKING /* JPH004 */ |
615 |
+ #include <sys/un.h> /* JPH004 */ |
616 |
+ /* JPH004 */ |
617 |
+ typedef struct _HTWorkerStruct { /* JPH004 */ |
618 |
+ struct sockaddr_un addr; /* JPH004 */ |
619 |
+ int addrlen; /* JPH004 */ |
620 |
+ int index; /* into worker table */ /* JPH004 */ |
621 |
+ int slot; /* into roster table */ /* JPH004 */ |
622 |
+ int pid; /* JPH004 */ |
623 |
+ int fd; /* valid in workers only */ /* JPH004 */ |
624 |
+ } HTWorkerStruct; /* JPH004 */ |
625 |
+ #endif /* JPH004 */ |
626 |
|
627 |
typedef struct _HTInStruct { |
628 |
BOOL no_cache_pragma; |
629 |
*** 1.1 1995/07/11 17:09:11 |
630 |
--- Library/Implementation/HTLog.c 1995/07/14 00:08:39 |
631 |
*************** |
632 |
*** 62,68 **** |
633 |
|
634 |
/* If we have a date format to paste on the file names. Else use default */ |
635 |
time(&t); |
636 |
! gmt = gmtime(&t); |
637 |
result = malloc(strlen(filename)+DATE_EXT_LEN+2); |
638 |
if (sc.log_file_date_ext) { |
639 |
|
640 |
--- 62,68 ---- |
641 |
|
642 |
/* If we have a date format to paste on the file names. Else use default */ |
643 |
time(&t); |
644 |
! gmt = sc.use_gmt ? gmtime(&t) : localtime(&t); /* JPH005 */ |
645 |
result = malloc(strlen(filename)+DATE_EXT_LEN+2); |
646 |
if (sc.log_file_date_ext) { |
647 |
|
648 |
*************** |
649 |
*** 300,305 **** |
650 |
--- 300,312 ---- |
651 |
} |
652 |
else strcpy(buf, "- -"); |
653 |
|
654 |
+ if (sc.virtualize) { /* JPH003 */ |
655 |
+ fprintf(log, "%s %s %s %s [%s] \"%s\" %s\n", /* JPH003 */ |
656 |
+ HTVirtualHost, /* JPH003 */ |
657 |
+ n_pick(HTClientHostName,HTClientHost), /* JPH003 */ |
658 |
+ r_ident, authuser, log_time(), /* JPH003 */ |
659 |
+ n_noth(HTReqLine), buf); /* JPH003 */ |
660 |
+ } else /* JPH003 */ |
661 |
fprintf(log, "%s %s %s [%s] \"%s\" %s\n", |
662 |
n_pick(HTClientHostName,HTClientHost), |
663 |
r_ident, authuser, log_time(), n_noth(HTReqLine), buf); |
664 |
*** 1.1 1995/07/11 17:09:15 |
665 |
--- Library/Implementation/HTScript.c 1995/07/15 01:24:04 |
666 |
*************** |
667 |
*** 833,838 **** |
668 |
--- 833,839 ---- |
669 |
char ** argv = NULL; |
670 |
char ** envp = NULL; |
671 |
BOOL nph_script = NO; |
672 |
+ int fd; /* JPH006 */ |
673 |
|
674 |
FREE(msg); /* From previous call */ |
675 |
|
676 |
*************** |
677 |
*** 939,944 **** |
678 |
--- 940,948 ---- |
679 |
pid = fork(); |
680 |
if (pid < 0) { /* fork() failed */ |
681 |
char msg[100]; |
682 |
+ |
683 |
+ close(pin[0]),close(pin[1]); /* JPH006 */ |
684 |
+ close(pout[0]),close(pout[1]); /* JPH006 */ |
685 |
sprintf(msg, "Internal error: fork() failed with %s script", |
686 |
(nph_script ? "NPH-" : HTMethod_name(req->method))); |
687 |
return HTLoadError(req, 500, msg); |
688 |
*************** |
689 |
*** 954,959 **** |
690 |
--- 958,964 ---- |
691 |
** Standalone server, redirect socket to stdin/stdout. |
692 |
*/ |
693 |
CTRACE(stderr, "Child....... doing IO redirections\n"); |
694 |
+ close(0); /* JPH006 */ |
695 |
if (req->content_length > 0) { /* Need to give stdin */ |
696 |
if (pin[0] != 0) { |
697 |
CTRACE(stderr, "Child....... stdin from input pipe\n"); |
698 |
*************** |
699 |
*** 981,986 **** |
700 |
--- 986,992 ---- |
701 |
"Child....... Standalone specific IO redirections done.\n"); |
702 |
CTRACE(stderr, "Child....... redirecting stderr to stdout, and then doing execve()\n"); |
703 |
dup2(1, 2); /* Redirect stderr to stdout */ |
704 |
+ for (fd = 3; fd < pout[1]; ++fd) close(fd); /* JPH006 */ |
705 |
if (-1 == execve(HTReqScript, argv, envp)) { |
706 |
CTRACE(stderr, "ERROR....... execve() failed\n"); |
707 |
HTLoadError(req, 500, "Internal error: execve() failed"); |