Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 Jun 1998 21:09:20 -0700 (PDT)
From:      giffunip@asme.org
To:        freebsd-gnats-submit@FreeBSD.ORG
Subject:   ports/6935: Update to the w3c-httpd port
Message-ID:  <199806130409.VAA22755@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         6935
>Category:       ports
>Synopsis:       Update to the w3c-httpd port
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jun 12 21:10:01 PDT 1998
>Last-Modified:
>Originator:     Pedro F. Giffuni
>Organization:
U. Nacional de Colombia
>Release:        2.2.5-R
>Environment:
>Description:
Brian Waters has been collecting patches for the original w3c-server. He
politely sent me a URL (http://www.bbin.com/~jbw/httpd.html) for his 
own updated version and I got some of his patches and integrated them
to the port. Brian is a NetBSD user, but as soon as he is ready he will
maintain our port.
>How-To-Repeat:
Lot's of bug fixes and features from many sources coming in....
>Fix:
diff -rNu /cdrom/ports/www/w3c-httpd/patches/CacheCheckSize.patch w3c-httpd/patches/CacheCheckSize.patch
--- /cdrom/ports/www/w3c-httpd/patches/CacheCheckSize.patch	Wed Dec 31 19:00:00 1969
+++ w3c-httpd/patches/CacheCheckSize.patch	Fri Jun 12 19:07:38 1998
@@ -0,0 +1,147 @@
+*** /dev/null	Tue Feb  6 11:05:04 1996
+--- WWW/README-CACHE_CHECK_SIZE	Tue Feb  6 13:27:32 1996
+***************
+*** 0 ****
+--- 1,11 ----
++ Patch to avoid serving truncated files from the cache.
++ 
++ Apply the patch, modify WWW/All/<model>/Makefile.include (for your model
++ system) and add '-DCACHE_CHECK_SIZE' to CFLAGS.
++ 
++ With the patch, the server checks the size of a file in the cache before
++ returning it to the user; if the size is incorrect, the server will
++ refresh the file in the cache.
++ 
++ -- 
++ -- 19960205, Gertjan van Oosten, gertjan@West.NL, West Consulting bv
+*** WWW/Daemon/Implementation/HTCache.c.orig	Fri Aug 12 12:36:11 1994
+--- WWW/Daemon/Implementation/HTCache.c	Mon Feb  5 14:02:11 1996
+***************
+*** 382,387 ****
+--- 382,437 ----
+  }
+  
+  
++ #ifdef CACHE_CHECK_SIZE
++ /*
++ **	Check whether cache file has correct size
++ **
++ ** On exit:
++ **	return YES
++ **		if size is good
++ **	return NO
++ **		if size is too small or too large
++ **
++ */
++ PRIVATE BOOL cache_check_size ARGS2(char *, cfn,
++                                     struct stat *, stat_info)
++ {
++     char buf[BUF_SIZE+2];
++     FILE *cf;
++     long cl = 0, pos, size, actual;
++ 
++     if (!cfn)
++ 	return NO;
++ 
++     cf = fopen(cfn, "r");
++     if (!cf)
++ 	return NO;
++ 
++     while (fgets(buf, sizeof(buf), cf)) {
++ 	if (!buf[0]
++ 	    || (buf[0] == '\n' && !buf[1])
++ 	    || (buf[0] == '\r' && buf[1] == '\n' && !buf[2]))
++ 	    break;
++ 
++         if (!strncasecomp(buf, "content-length:", 15))
++ 	    sscanf(buf+15, "%ld", &cl);
++     }
++     pos = ftell(cf);
++     fclose(cf);
++ 
++     size = stat_info->st_size;
++ 
++     actual = size - pos;
++     if (TRACE) {
++ 	fprintf(stderr,"Cache....... checking \"%s\": content-length %ld =?= %ld\n",
++ 		cfn,cl,actual);
++     }
++ 
++     return (cl == actual ? YES : NO);
++ }
++ #endif /* CACHE_CHECK_SIZE */
++ 
++ 
+  PRIVATE BOOL do_caching ARGS1(char *, url)
+  {
+      HTList * cur = cc.no_caching;
+***************
+*** 460,465 ****
+--- 510,518 ----
+  				      time_t *,	expires)
+  {
+      struct stat stat_info;
++ #ifdef CACHE_CHECK_SIZE
++     BOOL size_ok;
++ #endif
+  
+      if (!url || !cfn || !cf || !if_ms) return CACHE_NO;
+      *cfn = NULL;
+***************
+*** 497,503 ****
+--- 550,563 ----
+  	    }
+  
+  	    success = HTCacheInfo_for(*cfn, &ld, &lc, &ex, &mu, &lm);
++ #ifdef CACHE_CHECK_SIZE
++ 	    /* Check whether file in cache has correct size */
++ 	    size_ok = cache_check_size(*cfn, &stat_info);
++ #endif
+  	    if (!success				  /* no entry */
++ #ifdef CACHE_CHECK_SIZE
++ 		|| !size_ok				  /* wrong size */
++ #endif
+  		|| ex - cc.cache_time_margin <= cur_time  /* expired */
+  		|| cur_time - lc >= refresh_interval	  /* time to refresh */
+  		|| in.no_cache_pragma) {		  /* override cache */
+***************
+*** 507,512 ****
+--- 567,576 ----
+  		if (TRACE) {
+  		    if (!success)
+  			fprintf(stderr, "NoEntry..... %s -- expiring\n",*cfn);
++ #ifdef CACHE_CHECK_SIZE
++ 		    else if (!size_ok)
++ 			fprintf(stderr, "Truncated...... %s -- refresh\n",*cfn);
++ #endif
+  		    else if (in.no_cache_pragma)
+  			fprintf(stderr, "Forced...... refresh of %s\n",*cfn);
+  		    else if (ex - cc.cache_time_margin <= cur_time)
+***************
+*** 527,533 ****
+--- 591,601 ----
+  		if (cc.cache_no_connect) {
+  		    CTRACE(stderr, "Standalone.. caching mode but expired\n");
+  		    cache_hit = YES;
++ #ifdef CACHE_CHECK_SIZE
++ 		    return size_ok ? CACHE_IF_MODIFIED : CACHE_CREATE;
++ #else
+  		    return CACHE_IF_MODIFIED;
++ #endif
+  		}
+  
+  		if (!(*cf = do_lock(*cfn))) {
+***************
+*** 550,556 ****
+--- 618,628 ----
+  		CTRACE(stderr,"IfModSince.. time: %s", ctime(if_ms));
+  
+  		free(backup);
++ #ifdef CACHE_CHECK_SIZE
++ 		return size_ok ? CACHE_IF_MODIFIED : CACHE_CREATE;
++ #else
+  		return CACHE_IF_MODIFIED;
++ #endif
+  	    }
+  	    else {
+  		CTRACE(stderr, "Cache....... not expired %s\n", *cfn);
diff -rNu /cdrom/ports/www/w3c-httpd/patches/CacheDirs.patch w3c-httpd/patches/CacheDirs.patch
--- /cdrom/ports/www/w3c-httpd/patches/CacheDirs.patch	Wed Dec 31 19:00:00 1969
+++ w3c-httpd/patches/CacheDirs.patch	Fri Jun 12 19:07:38 1998
@@ -0,0 +1,101 @@
+*** /dev/null	Tue Feb  6 11:05:04 1996
+--- WWW/README-CACHEDIRS	Tue Feb  6 13:03:37 1996
+***************
+*** 0 ****
+--- 1,12 ----
++ Patch to translate directory names in the cache from e.g.
++   /www-cache/http/www.some.where.org/
++ to
++   /www-cache/http/org/where/some/www/
++ 
++ Note that this can lead to unexpected problems, when you have two URLs
++ like <URL:http://some.where.org/www/>; and <URL:http://www.some.where.org/>.
++ [This does happen, e.g. many sites out there have "some.where.org" and
++ "www.some.where.org" point to the same machine.]
++ 
++ --
++ -- 19950915, Gertjan van Oosten, gertjan@West.NL, West Consulting B.V.
+*** WWW/Daemon/Implementation/HTCache.c.orig	Fri Aug 12 12:36:11 1994
+--- WWW/Daemon/Implementation/HTCache.c	Fri Sep 15 16:25:33 1995
+***************
+*** 5,16 ****
+--- 5,19 ----
+  ** AUTHORS:
+  **	AL	Ari Luotonen	luotonen@dxcern.cern.ch
+  **	FM	Fote Macrides	macrides@sci.wfeb.edu
++ **	GJ	Gertjan van Oosten	gertjan@West.NL
+  **
+  ** HISTORY:
+  **	31 Jan 94  AL	Written from scratch on a *very* beautiful
+  **			Sunday afternoon -- seems like the spring
+  **			is already coming, yippee!
+  **	 8 Jul 94  FM	Insulate free() from _free structure element.
++ **	15 Sep 95  GJ	Translate host names in cache to (reversed)
++ **			directories.
+  **
+  ** BUGS:
+  **
+***************
+*** 243,248 ****
+--- 246,252 ----
+  {
+      char * access = NULL;
+      char * host = NULL;
++     char * revhost = NULL;
+      char * path = NULL;
+      char * cfn = NULL;
+      BOOL welcome = NO;
+***************
+*** 274,291 ****
+  	    *cur = TOLOWER(*cur);
+  	    cur++;
+  	}
+      }
+  
+      cfn = (char*)malloc(strlen(cc.cache_root) +
+  			strlen(access) +
+! 			(host ? strlen(host) : 0) +
+  			(path ? strlen(path) : 0) +
+  			(welcome ? strlen(WELCOME_FILE) : 0) + 3);
+      if (!cfn) outofmem(__FILE__, "cache_file_name");
+!     sprintf(cfn, "%s/%s/%s%s%s", cc.cache_root, access, host, path,
+  	    (welcome ? WELCOME_FILE : ""));
+  
+!     FREE(access); FREE(host); FREE(path);
+  
+      /*
+      ** This checks that the last component is not too long.
+--- 278,310 ----
+  	    *cur = TOLOWER(*cur);
+  	    cur++;
+  	}
++ 	/*
++ 	** Now transform host name from "www.some.where.org"
++ 	** to "org/where/some/www".
++ 	** [For nameless hosts, you'd want the IP address
++ 	** translated from "10.127.7.254" to "10/127/7/254",
++ 	** but that is left as an exercise.]
++ 	*/
++ 	revhost = malloc(strlen(host)+1);
++ 	revhost[0] = '\0';
++ 	while (cur = strrchr(host, '.')) {
++ 	    strcat(revhost, cur+1);
++ 	    strcat(revhost, "/");
++ 	    *cur = '\0';
++ 	}
++ 	strcat(revhost, host);
+      }
+  
+      cfn = (char*)malloc(strlen(cc.cache_root) +
+  			strlen(access) +
+! 			(revhost ? strlen(revhost) : 0) +
+  			(path ? strlen(path) : 0) +
+  			(welcome ? strlen(WELCOME_FILE) : 0) + 3);
+      if (!cfn) outofmem(__FILE__, "cache_file_name");
+!     sprintf(cfn, "%s/%s/%s%s%s", cc.cache_root, access, revhost, path,
+  	    (welcome ? WELCOME_FILE : ""));
+  
+!     FREE(access); FREE(host); FREE(revhost); FREE(path);
+  
+      /*
+      ** This checks that the last component is not too long.
diff -rNu /cdrom/ports/www/w3c-httpd/patches/DenyAccess.patch w3c-httpd/patches/DenyAccess.patch
--- /cdrom/ports/www/w3c-httpd/patches/DenyAccess.patch	Wed Dec 31 19:00:00 1969
+++ w3c-httpd/patches/DenyAccess.patch	Fri Jun 12 22:41:16 1998
@@ -0,0 +1,97 @@
+*** /dev/null	Tue Feb  6 11:05:04 1996
+--- WWW/README-DENYACCESS	Tue Feb  6 13:11:03 1996
+***************
+*** 0 ****
+--- 1,28 ----
++ Patch to allow denial of IP addresses or domain names in a protection
++ mask.
++ 
++ With the patch, you can now specify patterns as:
++ 
++ Protection HEY-INTEL-NO-SECURITY-HOLES {
++ 	Mask		@(*.*.*.*, !132.233.*.*, !143.183.*.*, !137.46.*.*)
++ }
++ Protect	/*		HEY-INTEL-NO-SECURITY-HOLES
++ 
++ The comment from the patch is:
++ 
++ **	 9 Aug 95  GJ	Modified ip_in_def_list() to allow exclusions;
++ **			patterns can now be e.g.
++ **				@(*.*.*.*, !192.43.210.*)
++ **			which means: allow anyone in except West.NL;
++ **			the strange order of the patterns is because the
++ **			access list is built back to front, so be careful
++ **			to put the most restrictive patterns at the end!
++ **			The old patterns still work, of course, so
++ **				@(192.43.210.*)
++ **			would allow only West.NL, just as
++ **				@(!*.*.*.*, 192.43.210.*)
++ **			does (remember that this is matched back-to-front
++ **			by the server).
++ 
++ --
++ -- 19950809, Gertjan van Oosten, gertjan@west.nl, West Consulting B.V.
+*** WWW/Daemon/Implementation/HTGroup.c.orig	Wed May  4 21:03:24 1994
+--- WWW/Daemon/Implementation/HTGroup.c	Wed Aug  9 10:55:57 1995
+***************
+*** 8,18 ****
+--- 8,37 ----
+  **
+  ** AUTHORS:
+  **	AL	Ari Luotonen	luotonen@dxcern.cern.ch
++ **	GJ	Gertjan van Oosten	gertjan@West.NL
+  **
+  ** HISTORY:
++ **	 9 Aug 95  GJ	Modified ip_in_def_list() to allow exclusions;
++ **			patterns can now be e.g.
++ **				@(*.*.*.*, !192.43.210.*)
++ **			which means: allow anyone in except West.NL;
++ **			the strange order of the patterns is because the
++ **			access list is built back to front, so be careful
++ **			to put the most restrictive patterns at the end!
++ **			The old patterns still work, of course, so
++ **				@(192.43.210.*)
++ **			would allow only West.NL, just as
++ **				@(!*.*.*.*, 192.43.210.*)
++ **			does (remember that this is matched back-to-front
++ **			by the server).
+  **
+  **
+  ** BUGS:
++ **	GJ	The modifications in ip_in_def_list() do not treat the
++ **		HTPattern as an abstract datatype; it is probably best
++ **		to encapsulate these manipulations in a few extra routines
++ **		in HTWild.c, but I can't be bothered.
++ **		A five-minute hack is a five-minute hack...
+  **
+  **
+  **
+***************
+*** 581,590 ****
+  	    /* Value of ref->translation is ignored, i.e. */
+  	    /* no recursion for ip address tamplates.	  */
+  	    HTPattern * pat = HTPattern_new(ref->name);
+! 	    BOOL flag = HTIpMaskMatch(pat, ip_number, ip_name);
+  	    HTPattern_free(pat);
+  	    if (flag)
+! 		return YES;
+  	}
+      }
+      return NO;
+--- 600,615 ----
+  	    /* Value of ref->translation is ignored, i.e. */
+  	    /* no recursion for ip address tamplates.	  */
+  	    HTPattern * pat = HTPattern_new(ref->name);
+! 	    BOOL negate = (*(pat->text)=='!');	/* "!bla.bla.bla.bla" ? */
+! 	    BOOL flag;
+! 	    if (negate)
+! 	        pat->text++;			/* Skip '!' */
+! 	    flag = HTIpMaskMatch(pat, ip_number, ip_name);
+! 	    if (negate)
+! 	        pat->text--;			/* Back to '!' */
+  	    HTPattern_free(pat);
+  	    if (flag)
+! 		return negate ? NO : YES;
+  	}
+      }
+      return NO;
diff -rNu /cdrom/ports/www/w3c-httpd/patches/HTParse.c.patch w3c-httpd/patches/HTParse.c.patch
--- /cdrom/ports/www/w3c-httpd/patches/HTParse.c.patch	Wed Dec 31 19:00:00 1969
+++ w3c-httpd/patches/HTParse.c.patch	Fri Jun 12 19:59:35 1998
@@ -0,0 +1,28 @@
+*** Library/Implementation/HTParse.c	Sun Sep 25 14:53:34 1994
+--- Library/Implementation/HTParse.c.patch	Wed Nov  9 10:42:15 1994
+***************
+*** 350,360 ****
+  	path = filename;
+      if (*path == '/' && *(path+1)=='/') {	  /* Some URLs start //<foo> */
+  	path += 1;
+!     } else if (!strncmp(path, "news:", 5)) {	    /* Make group lower case */
+! 	char *group = path+5;
+! 	while (*group && *group!='@' && *group!='/') {
+! 	    *group = TOLOWER(*group);
+! 	    group++;
+  	}
+  	if (URI_TRACE)
+  	    fprintf(stderr, "into\n............ `%s'\n", filename);
+--- 322,333 ----
+  	path = filename;
+      if (*path == '/' && *(path+1)=='/') {	  /* Some URLs start //<foo> */
+  	path += 1;
+!     } else if (!strncmp(path, "news:", 5)) {
+! 	char *ptr = strchr(path+5, '@');
+! 	if (!ptr) ptr = path+5;
+! 	while (*ptr) {			    /* Make group or host lower case */
+! 	    *ptr = TOLOWER(*ptr);
+! 	    ptr++;
+  	}
+  	if (URI_TRACE)
+  	    fprintf(stderr, "into\n............ `%s'\n", filename);
diff -rNu /cdrom/ports/www/w3c-httpd/patches/HTTPS.patch w3c-httpd/patches/HTTPS.patch
--- /cdrom/ports/www/w3c-httpd/patches/HTTPS.patch	Wed Dec 31 19:00:00 1969
+++ w3c-httpd/patches/HTTPS.patch	Fri Jun 12 22:41:38 1998
@@ -0,0 +1,553 @@
+*** /dev/null	Mon Apr 15 09:53:26 1996
+--- WWW/README-HTTPS	Mon Apr 15 10:11:26 1996
+***************
+*** 0 ****
+--- 1,45 ----
++ Patch to enable SSL support, i.e. serving documents via 'https://' URLs.
++ I built this using CERN httpd 3.0 with Library 2.17 and SSLeay-0.5.1b.
++ For further information on CERN httpd see:
++ 
++ 	http://www.w3.org/pub/WWW/Daemon/
++ 
++ For further information on SSLeay see:
++ 
++ 	http://www.psy.uq.oz.au/~ftp/Crypto/
++ 	ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/
++ 	ftp://ftp.psy.uq.oz.au/pub/Crypto/SSLapps/
++ 
++ REMEMBER: export and/or import of crypto software or crypto hooks is
++ illegal in many parts of the world.
++ 
++ Apply the patch, modify WWW/All/<model>/Makefile.include (for your model
++ system) and add '-DUSE_SSL -I/usr/local/ssl/include' to CFLAGS
++ and '-L/usr/local/ssl/lib -lssl -lcrypto' to LDFLAGS (fill in the
++ correct paths to your SSL include files and libraries).
++ 
++ Add the following lines to your httpd.conf:
++  
++ Port			443
++ UseSSL			Yes
++ SSLRSAPrivateKeyFile	/usr/local/ssl/certs/httpsd.pem
++ SSLCertificateFile	/usr/local/ssl/certs/httpsd.pem
++ 
++ If you don't have UseSSL set, or have UseSSL set to No, it won't use SSL.
++ 
++ If you don't specify SSLRSAPrivateKeyFile or SSLCertificateFile, it will
++ use the default files (specific to your installation of SSL, the paths
++ given in the example are from the default installation of SSLeay).
++ 
++ Important note: don't use a pass phrase to encrypt your keys, or the
++                 daemon won't be able to read them!
++ 
++ Run 'make certificate' to generate a self-signed certificate for testing
++ purposes (set SSLTOP to the installation directory of SSLeay).
++ 
++ For more general remarks on SSLified applications, see:
++ 
++ 	ftp://ftp.psy.uq.oz.au/pub/Crypto/SSLapps/README.apps
++ 
++ -- 
++ -- 19960410, Gertjan van Oosten, gertjan@West.NL, West Consulting B.V.
+*** WWW/Makefile.orig	Sat Jun 11 13:52:14 1994
+--- WWW/Makefile	Mon Apr 15 10:13:51 1996
+***************
+*** 24,26 ****
+--- 24,38 ----
+  	rm -f Daemon/[a-z0-9]*/cgiparse
+  	rm -f Daemon/[a-z0-9]*/cgiutils
+  
++ #
++ # Target for generating a self-signed test certificate for the SSLified
++ # version of httpd (see README-HTTPS).
++ #
++ SSLTOP=/usr/local/ssl
++ certificate:
++ 	(\
++ 	cd $(SSLTOP)/certs; \
++ 	req -new -x509 -nodes -out httpsd.pem -keyout httpsd.pem; \
++ 	ln -s httpsd.pem `x509 -noout -hash < httpsd.pem`.0 ;\
++ 	chmod 644 $(SSLTOP)/certs/httpsd.pem; \
++ 	)
+*** WWW/Library/Implementation/HTFormat.h.orig	Sun Sep 25 15:15:26 1994
+--- WWW/Library/Implementation/HTFormat.h	Wed Apr 10 17:25:38 1996
+***************
+*** 61,66 ****
+--- 61,67 ----
+          char * input_pointer;
+          char * input_limit;
+          int input_file_number;
++         void *  ssl_con;
+          BOOL    s_do_buffering;
+          char *  s_buffer;
+          int     s_buffer_size;
+*** WWW/Library/Implementation/HTFormat.c.orig	Thu Sep 29 14:24:15 1994
+--- WWW/Library/Implementation/HTFormat.c	Wed Apr 10 17:25:39 1996
+***************
+*** 51,56 ****
+--- 51,59 ----
+  #include "HTGuess.h"
+  #include "HTError.h"
+  
++ #ifdef USE_SSL
++ #include <ssl.h>
++ #endif /* USE_SSL */
+  
+  PUBLIC	BOOL HTOutputSource = NO;	/* Flag: shortcut parser to stdout */
+  
+***************
+*** 474,480 ****
+      int ch;
+      do {
+  	if (isoc-> input_pointer >= isoc->input_limit) {
+! 	    int status = NETREAD(
+  		   isoc->input_file_number,
+  		   isoc->input_buffer, INPUT_BUFFER_SIZE);
+  	    if (status <= 0) {
+--- 477,491 ----
+      int ch;
+      do {
+  	if (isoc-> input_pointer >= isoc->input_limit) {
+! 	    int status =
+! #ifdef USE_SSL
+! 	        (isoc->ssl_con != NULL) ?
+! 	        SSL_read(
+! 		   isoc->ssl_con,
+! 		   isoc->input_buffer, INPUT_BUFFER_SIZE)
+! 		:
+! #endif /* USE_SSL */
+! 	        NETREAD(
+  		   isoc->input_file_number,
+  		   isoc->input_buffer, INPUT_BUFFER_SIZE);
+  	    if (status <= 0) {
+***************
+*** 507,513 ****
+  					   int *,		len)
+  {
+      if (isoc->input_pointer >= isoc->input_limit) {
+! 	int status = NETREAD(isoc->input_file_number,
+  			     isoc->input_buffer,
+  			     ((*len < INPUT_BUFFER_SIZE) ?
+  			      *len : INPUT_BUFFER_SIZE));
+--- 518,533 ----
+  					   int *,		len)
+  {
+      if (isoc->input_pointer >= isoc->input_limit) {
+! 	int status =
+! #ifdef USE_SSL
+! 	    (isoc->ssl_con != NULL) ?
+! 	    SSL_read(isoc->ssl_con,
+! 			     isoc->input_buffer,
+! 			     ((*len < INPUT_BUFFER_SIZE) ?
+! 			      *len : INPUT_BUFFER_SIZE))
+! 	    :
+! #endif /* USE_SSL */
+! 	    NETREAD(isoc->input_file_number,
+  			     isoc->input_buffer,
+  			     ((*len < INPUT_BUFFER_SIZE) ?
+  			      *len : INPUT_BUFFER_SIZE));
+***************
+*** 538,544 ****
+  	int status;
+  
+  	isoc->input_pointer = isoc->input_buffer;
+! 	status = NETREAD(isoc->input_file_number,
+  			 isoc->input_buffer,
+  			 INPUT_BUFFER_SIZE);
+  	if (status <= 0) {
+--- 558,572 ----
+  	int status;
+  
+  	isoc->input_pointer = isoc->input_buffer;
+! 	status =
+! #ifdef USE_SSL
+! 	    (isoc->ssl_con != NULL) ?
+! 	    SSL_read(isoc->ssl_con,
+! 			 isoc->input_buffer,
+! 			 INPUT_BUFFER_SIZE)
+! 	    :
+! #endif /* USE_SSL */
+! 	    NETREAD(isoc->input_file_number,
+  			 isoc->input_buffer,
+  			 INPUT_BUFFER_SIZE);
+  	if (status <= 0) {
+*** WWW/Library/Implementation/HTWriter.h.orig	Sun Sep 25 15:15:20 1994
+--- WWW/Library/Implementation/HTWriter.h	Wed Apr 10 17:25:41 1996
+***************
+*** 17,26 ****
+  
+  #include "HTStream.h"
+  
+! extern HTStream * HTWriter_new PARAMS((int soc));
+! extern HTStream * HTWriter_newNoClose PARAMS((int soc));
+  
+! extern HTStream * HTASCIIWriter PARAMS((int soc));
+  
+  #endif
+  
+--- 17,26 ----
+  
+  #include "HTStream.h"
+  
+! extern HTStream * HTWriter_new PARAMS((int soc, void *ssl_con));
+! extern HTStream * HTWriter_newNoClose PARAMS((int soc, void *ssl_con));
+  
+! extern HTStream * HTASCIIWriter PARAMS((int soc, void *ssl_con));
+  
+  #endif
+  
+*** WWW/Library/Implementation/HTWriter.c.orig	Sun Sep 25 14:53:45 1994
+--- WWW/Library/Implementation/HTWriter.c	Wed Apr 10 17:25:40 1996
+***************
+*** 9,14 ****
+--- 9,18 ----
+  #include "HTUtils.h"
+  #include "tcp.h"
+  
++ #ifdef USE_SSL
++ #include <ssl.h>
++ #endif /* USE_SSL */
++ 
+  /*		HTML Object
+  **		-----------
+  */
+***************
+*** 17,22 ****
+--- 21,27 ----
+  	CONST HTStreamClass *	isa;
+  
+  	int	soc;
++ 	void	*ssl_con;
+  	char	*write_pointer;
+  	char 	buffer[BUFFER_SIZE];
+  	BOOL	leave_open;
+***************
+*** 48,54 ****
+  	status = NETWRITE(me->soc, me->buffer,  /* Put timeout? @@@ */
+  			write_pointer - read_pointer);
+  #endif /* OLD_CODE */
+! 	status = NETWRITE(me->soc, read_pointer, write_pointer - read_pointer);
+  	if (status<0) {
+  	    if(TRACE) fprintf(stderr,
+  	    "HTWrite: Error: write() on socket returns %d !!!\n", status);
+--- 53,65 ----
+  	status = NETWRITE(me->soc, me->buffer,  /* Put timeout? @@@ */
+  			write_pointer - read_pointer);
+  #endif /* OLD_CODE */
+! 	status =
+! #ifdef USE_SSL
+! 	    (me->ssl_con != NULL) ?
+! 	    SSL_write(me->ssl_con, read_pointer, write_pointer - read_pointer)
+! 	    :
+! #endif /* USE_SSL */
+! 	    NETWRITE(me->soc, read_pointer, write_pointer - read_pointer);
+  	if (status<0) {
+  	    if(TRACE) fprintf(stderr,
+  	    "HTWrite: Error: write() on socket returns %d !!!\n", status);
+***************
+*** 110,116 ****
+      }
+  #endif
+      while (read_pointer < write_pointer) {
+!         int status = NETWRITE(me->soc, read_pointer,
+  			write_pointer - read_pointer);
+  	if (status<0) {
+  	    if(TRACE) fprintf(stderr,
+--- 121,134 ----
+      }
+  #endif
+      while (read_pointer < write_pointer) {
+!         int status =
+! #ifdef USE_SSL
+! 	    (me->ssl_con != NULL) ?
+! 	    SSL_write(me->ssl_con, read_pointer,
+! 			write_pointer - read_pointer)
+! 	    :
+! #endif /* USE_SSL */
+! 	    NETWRITE(me->soc, read_pointer,
+  			write_pointer - read_pointer);
+  	if (status<0) {
+  	    if(TRACE) fprintf(stderr,
+***************
+*** 161,167 ****
+  **	-------------------------
+  */
+  
+! PUBLIC HTStream* HTWriter_new ARGS1(int, soc)
+  {
+      HTStream* me = (HTStream*)calloc(1,sizeof(*me));
+      if (me == NULL) outofmem(__FILE__, "HTML_new");
+--- 179,185 ----
+  **	-------------------------
+  */
+  
+! PUBLIC HTStream* HTWriter_new ARGS2(int, soc, void *, ssl_con)
+  {
+      HTStream* me = (HTStream*)calloc(1,sizeof(*me));
+      if (me == NULL) outofmem(__FILE__, "HTML_new");
+***************
+*** 171,183 ****
+      me->make_ascii = NO;
+  #endif    
+      me->soc = soc;
+      me->write_pointer = me->buffer;
+      return me;
+  }
+  
+! PUBLIC HTStream* HTWriter_newNoClose ARGS1(int, soc)
+  {
+!     HTStream * me = HTWriter_new(soc);
+      if (me) me->leave_open = YES;
+      return me;
+  }
+--- 189,202 ----
+      me->make_ascii = NO;
+  #endif    
+      me->soc = soc;
++     me->ssl_con = ssl_con;
+      me->write_pointer = me->buffer;
+      return me;
+  }
+  
+! PUBLIC HTStream* HTWriter_newNoClose ARGS2(int, soc, void *, ssl_con)
+  {
+!     HTStream * me = HTWriter_new(soc, ssl_con);
+      if (me) me->leave_open = YES;
+      return me;
+  }
+***************
+*** 187,193 ****
+  **	-------------------------
+  */
+  
+! PUBLIC HTStream* HTASCIIWriter ARGS1(int, soc)
+  {
+      HTStream* me = (HTStream*)calloc(1,sizeof(*me));
+      if (me == NULL) outofmem(__FILE__, "HTML_new");
+--- 206,212 ----
+  **	-------------------------
+  */
+  
+! PUBLIC HTStream* HTASCIIWriter ARGS2(int, soc, void *, ssl_con)
+  {
+      HTStream* me = (HTStream*)calloc(1,sizeof(*me));
+      if (me == NULL) outofmem(__FILE__, "HTML_new");
+***************
+*** 197,202 ****
+--- 216,222 ----
+      me->make_ascii = YES;
+  #endif    
+      me->soc = soc;
++     me->ssl_con = ssl_con;
+      me->write_pointer = me->buffer;
+      return me;
+  }
+*** WWW/Daemon/Implementation/HTConfig.h.orig	Sun Sep 25 14:55:28 1994
+--- WWW/Daemon/Implementation/HTConfig.h	Wed Apr 10 17:17:09 1996
+***************
+*** 45,50 ****
+--- 45,53 ----
+      char *	hostname;		/* Used for CGI scripts		*/
+      HTServType	server_type;		/* Standalone or inetd		*/
+      int		port;			/* Default port number string	*/
++     BOOL	use_ssl;		/* Am I an https server?	*/
++     char *	ssl_key_file;		/* RSA private key file		*/
++     char *	ssl_cert_file;		/* Certificate file		*/
+      BOOL	no_bg;			/* Don't auto-go background	*/
+      BOOL	standalone;		/* Am I standalone?		*/
+      char *	server_root;		/* Server's "home directory"	*/
+*** WWW/Daemon/Implementation/HTConfig.c.orig	Mon Sep 26 15:22:52 1994
+--- WWW/Daemon/Implementation/HTConfig.c	Wed Apr 10 17:17:09 1996
+***************
+*** 115,120 ****
+--- 115,123 ----
+      sc.output_timeout = DEFAULT_OUTPUT_TIMEOUT;
+      sc.script_timeout = DEFAULT_SCRIPT_TIMEOUT;
+      sc.do_accept_hack = YES;
++     sc.use_ssl = NO;
++     sc.ssl_key_file = NULL;
++     sc.ssl_cert_file = NULL;
+      sc.disabled[ (int)METHOD_PUT ] = YES;
+      sc.disabled[ (int)METHOD_DELETE ] = YES;
+      sc.disabled[ (int)METHOD_CHECKIN ] = YES;
+***************
+*** 1819,1824 ****
+--- 1822,1839 ----
+  		}
+  	    }
+  
++ #ifdef USE_SSL
++ 	} else if (!strcmp(vec[0], "usessl")) {
++ 	    sc.use_ssl = positive(vec[1]);
++ 	    CTRACE(stderr,"SSL......... %sabled\n",
++ 		   sc.use_ssl ? "en" : "dis");
++ 	} else if (!strcmp(vec[0], "sslrsaprivatekeyfile")) {
++ 	    sc.ssl_key_file = tilde_to_home(vec[1]);
++ 	    CTRACE(stderr, "SSLKeyFile.. %s\n", sc.ssl_key_file);
++ 	} else if (!strcmp(vec[0], "sslcertificatefile")) {
++ 	    sc.ssl_cert_file = tilde_to_home(vec[1]);
++ 	    CTRACE(stderr, "SSLCertFile. %s\n", sc.ssl_cert_file);
++ #endif /* USE_SSL */
+  	} else if (!strncmp(vec[0],"pidfile",7)) {
+  	    sc.pid_file = tilde_to_home(vec[1]);
+  	    CTRACE(stderr, "PidFile..... %s\n", sc.pid_file);
+*** WWW/Daemon/Implementation/HTDaemon.c.orig	Mon Sep 26 15:23:00 1994
+--- WWW/Daemon/Implementation/HTDaemon.c	Wed Apr 10 17:17:11 1996
+***************
+*** 193,198 ****
+--- 193,202 ----
+  #endif
+  
+  
++ #ifdef USE_SSL
++ #include <ssl.h>
++ #endif /* USE_SSL */
++ 
+  
+  #ifdef VMS
+  #define gc()
+***************
+*** 228,233 ****
+--- 232,243 ----
+  #endif /* FORKING */
+  PRIVATE int script_pid = 0;
+  
++ #ifdef USE_SSL
++ SSL_CTX	*ssl_ctx;
++ char	ssl_file_path[1024];
++ #endif /* USE_SSL */
++ void	*ssl_con;
++ 
+  /*      Program-Global Variables
+  **      ------------------------
+  */
+***************
+*** 1559,1564 ****
+--- 1569,1575 ----
+      reset_server_env();
+  
+      isoc = HTInputSocket_new(soc);
++     isoc->ssl_con = ssl_con;
+  
+      input_timeout_on();
+      req = HTParseRequest(isoc);
+***************
+*** 1571,1577 ****
+  
+      HTSoc = soc;
+      req->isoc = isoc;
+!     req->output_stream = HTWriter_newNoClose(soc);
+  
+      if (req->method == METHOD_INVALID) {
+          if (HTReqLine) {
+--- 1582,1588 ----
+  
+      HTSoc = soc;
+      req->isoc = isoc;
+!     req->output_stream = HTWriter_newNoClose(soc, isoc->ssl_con);
+  
+      if (req->method == METHOD_INVALID) {
+          if (HTReqLine) {
+***************
+*** 2183,2188 ****
+--- 2194,2243 ----
+                  CTRACE(stderr, "Child....... I'%s\n",
+                         do_gc ? "ll do gc upon exit" : "m alive");
+  
++ #ifdef USE_SSL
++ 		if (sc.use_ssl) {
++ 		    SSL_set_fd(ssl_con, com_soc);
++ 
++ 		    /*
++ 		     * Use default paths and filename "httpsd.pem" for public
++ 		     * and private key if not specified in the config.
++ 		     * Note: don't encrypt the key with a pass phrase!
++ 		     */
++ 		    if (SSL_use_RSAPrivateKey_file(ssl_con,
++ 			    sc.ssl_key_file ? sc.ssl_key_file : ssl_file_path,
++ 			    X509_FILETYPE_PEM) <= 0) {
++ 			fprintf(stderr, "SSL_use_RSAPrivateKey_file(%s) error ",
++ 			    sc.ssl_key_file ? sc.ssl_key_file : ssl_file_path);
++ 			ERR_print_errors(stderr);
++ 			fflush(stderr);
++ 			_exit(1);
++ 		    }
++ 
++ 		    if (SSL_use_certificate_file(ssl_con,
++ 			    sc.ssl_cert_file ? sc.ssl_cert_file : ssl_file_path,
++ 			    X509_FILETYPE_PEM) <= 0) {
++ 			fprintf(stderr, "SSL_use_certificate_file(%s) error ",
++ 			    sc.ssl_cert_file ? sc.ssl_cert_file : ssl_file_path);
++ 			ERR_print_errors(stderr);
++ 			fflush(stderr);
++ 			_exit(1);
++ 		    }
++ 
++ 		    /*
++ 		     * TODO:
++ 		     * Call SSL_set_verify(ssl_con, SSL_VERIFY_..., ...)
++ 		     */
++ 
++ 		    if (SSL_accept(ssl_con) <= 0) {
++ 			fprintf(stderr, "SSL_accept error %s\n",
++ 			    ERR_error_string(ERR_get_error(), NULL));
++ 			fflush(stderr);
++ 			SSL_free(ssl_con);
++ 			_exit(1);
++ 		    }
++ 		}
++ #endif /* USE_SSL */
++ 
+                  /*
+                   * This no-linger stuff is borrowed from NCSA httpd code.
+                   * In Linux this causes problems -- is this necessary at
+***************
+*** 3044,3051 ****
+  
+      if (sc.server_type == SERVER_TYPE_STANDALONE) {
+          if (!sc.port) {
+!             sc.port = 80;
+!             CTRACE(stderr,"Default..... port 80 for standalone server\n");
+          }
+      }
+      else if (sc.server_type == SERVER_TYPE_INETD) {
+--- 3099,3113 ----
+  
+      if (sc.server_type == SERVER_TYPE_STANDALONE) {
+          if (!sc.port) {
+!             sc.port =
+! #ifdef USE_SSL
+!                 sc.use_ssl ?
+!                 443
+!                 :
+! #endif /* SSL */
+!                 80;
+!             CTRACE(stderr,"Default..... port %d for standalone server\n",
+!                 sc.port);
+          }
+      }
+      else if (sc.server_type == SERVER_TYPE_INETD) {
+***************
+*** 3243,3248 ****
+--- 3305,3326 ----
+      if (status<0 && role != passive) {
+          exit(status);
+      }
++ 
++     ssl_con = NULL;
++ #ifdef USE_SSL
++     if (sc.use_ssl) {
++ 	SSL_load_error_strings();
++ 	ssl_ctx = (SSL_CTX *)SSL_CTX_new();
++ 	ssl_con = (SSL *)SSL_new(ssl_ctx);
++ 	sprintf(ssl_file_path, "%s/%s", X509_get_default_cert_dir(), "httpsd.pem");
++ 
++ 	if (!X509_set_default_verify_paths(ssl_ctx->cert)) {
++ 	    fprintf(stderr,"HTTPSD ERROR: cannot load certificates via X509_set_default_verify_paths\n");
++ 	    ERR_print_errors(stderr);
++ 	    exit(1);
++ 	}
++     }
++ #endif /* USE_SSL */
+  
+      exit(0);
+      return 0;   /* NOTREACHED -- For gcc */
diff -rNu /cdrom/ports/www/w3c-httpd/patches/PATCHKIT.diff w3c-httpd/patches/PATCHKIT.diff
--- /cdrom/ports/www/w3c-httpd/patches/PATCHKIT.diff	Wed Dec 31 19:00:00 1969
+++ w3c-httpd/patches/PATCHKIT.diff	Fri Jun 12 20:27:55 1998
@@ -0,0 +1,707 @@
+*** 1.1	1995/07/11 17:09:01
+--- Library/Implementation/HTAAServ.c	1995/07/12 20:54:32
+***************
+*** 571,576 ****
+--- 571,588 ----
+       */
+      StrAllocCopy(untranslated, HTReqArgPath);
+  
++     if (sc.virtualize) {					/* JPH003 */
++         char * vpath;						/* JPH003 */
++ 								/* JPH003 */
++         vpath = (char *)malloc(1 + strlen(HTVirtualHost) +	/* JPH003 */
++                                strlen(HTReqArgPath) + 1);	/* JPH003 */
++         sprintf(vpath, "/%s%s", HTVirtualHost, HTReqArgPath);	/* JPH003 */
++         CTRACE(stderr, "Virtualize.. %s -> %s\n",		/* JPH003 */
++                HTReqArgPath, vpath);				/* JPH003 */
++         StrAllocCopy(HTReqArgPath, vpath);			/* JPH003 */
++         free(vpath);						/* JPH003 */
++     }								/* JPH003 */
++ 
+      /*
+      ** Translate into absolute pathname, and
+      ** get protection by "protect" and "defprot" rules.
+***************
+*** 618,623 ****
+--- 630,646 ----
+  			    StrAllocCat(welcome, "/");
+  			    physical = HTMulti(req, welcome, &stat_info2);
+  			    free(welcome);
++ 
++                             if (physical &&			/* JPH003 */
++                                 !S_ISDIR(stat_info2.st_mode) &&	/* JPH003 */
++                                 sc.virtualize) {		/* JPH003 */
++                                 CTRACE(stderr,			/* JPH003 */
++                                   "UnVirtualize %s -> %s\n",	/* JPH003 */
++                                   HTReqArgPath,			/* JPH003 */
++                                   untranslated);		/* JPH003 */
++                                 strcpy(HTReqArgPath,		/* JPH003 */
++                                        untranslated);		/* JPH003 */
++                             }					/* JPH003 */
+  
+  			    if (physical && !S_ISDIR(stat_info2.st_mode)) {
+  				char * escaped = HTEscape(HTReqArgPath,
+*** 1.1	1995/07/14 15:49:18
+--- Library/Implementation/HTConfig.c	1995/07/14 15:56:01
+***************
+*** 111,116 ****
+--- 111,118 ----
+   */
+  PUBLIC void HTDefaultConfig NOARGS
+  {
++     sc.virtualize = NO;						/* JPH003 */
++     sc.workers = 0;						/* JPH004 */
+      sc.input_timeout = DEFAULT_INPUT_TIMEOUT;
+      sc.output_timeout = DEFAULT_OUTPUT_TIMEOUT;
+      sc.script_timeout = DEFAULT_SCRIPT_TIMEOUT;
+***************
+*** 1233,1238 ****
+--- 1235,1255 ----
+  	} else if (strstr(vec[0],"icon")) {	/* All *Icon* directives */
+  	    icon_config(vec,c);
+  
++ 	} else if (strstr(vec[0], "virtualize")) {		/* JPH003 */
++ 	    sc.virtualize = positive(vec[1]);			/* JPH003 */
++ 	    CTRACE(stderr, "Virtualize.. %s\n",			/* JPH003 */
++ 		   sc.virtualize ? "On" : "Off");		/* JPH003 */
++ 								/* JPH003 */
++ 	} else if (strstr(vec[0], "workers")) {			/* JPH004 */
++ 	    sc.workers = atoi(vec[1]);				/* JPH004 */
++ 	    if (sc.workers) {					/* JPH004 */
++ 		CTRACE(stderr,					/* JPH004 */
++ 		       "PreForking.. On, %d workers\n",		/* JPH004 */
++ 		       sc.workers);				/* JPH004 */
++ 	    } else { 						/* JPH004 */
++ 		CTRACE(stderr, "PreForking.. Off\n");		/* JPH004 */
++ 	    }							/* JPH004 */
++ 								/* JPH004 */
+  	} else if (!strncmp(vec[0], "serverroot", 10)) {
+  	    sc.server_root = tilde_to_home(vec[1]);
+  	    HTSaveLocallyDir = sc.server_root;		/* Henrik Aug 31, 94 */
+*** 1.1	1995/07/11 17:09:06
+--- Library/Implementation/HTConfig.h	1995/07/12 21:50:59
+***************
+*** 47,52 ****
+--- 47,54 ----
+      int		port;			/* Default port number string	*/
+      BOOL	no_bg;			/* Don't auto-go background	*/
+      BOOL	standalone;		/* Am I standalone?		*/
++     BOOL	virtualize;		/* multi-home mode? */	/* JPH003 */
++     int		workers;		/* preforking mode? */	/* JPH004 */
+      char *	server_root;		/* Server's "home directory"	*/
+      int		security_level;		/* 0 = normal, 1 = high		*/
+      char *	errormsg_path;		/* URL for error messages	*/
+*** 1.1	1995/07/11 17:09:07
+--- Library/Implementation/HTDaemon.c	1995/10/11 16:56:00
+***************
+*** 161,166 ****
+--- 161,168 ----
+  #include <signal.h>
+  #include <sys/param.h>
+  #include <errno.h>
++ #include <sys/uio.h>						/* JPH004 */
++ #include <setjmp.h>						/* JPH007 */
+  
+  #ifndef SIGCLD
+  #ifdef SIGCHLD
+***************
+*** 251,256 ****
+--- 253,260 ----
+  /*      Server environment when handling requests
+  **      -----------------------------------------
+  */
++ PUBLIC jmp_buf		HTJumpEnv;				/* JPH007 */
++ PUBLIC char *           HTVirtualHost           = NULL;		/* JPH003 */
+  PUBLIC char *           HTReasonLine            = NULL;
+  PUBLIC int              HTSoc                   = 0;
+  PUBLIC char *           HTReqLine               = NULL;
+***************
+*** 532,543 ****
+--- 536,556 ----
+  {
+      if (sc.standalone) {
+  #if defined(__svr4__) || defined(_POSIX_SOURCE) || defined(__hpux)
++         if (kill(-pgrp, SIGTERM) == 0) {			/* JPH001 */
++         	kill(-pgrp, SIGCONT);				/* JPH001 */
++ 		sleep(5);					/* JPH001 */
++ 	}							/* JPH001 */
+          kill(-pgrp, SIGKILL);
+  #else
++         if (killpg(pgrp, SIGTERM) == 0) {			/* JPH001 */
++         	killpg(pgrp, SIGCONT);				/* JPH001 */
++ 		sleep(5);					/* JPH001 */
++ 	}							/* JPH001 */
+          killpg(pgrp, SIGKILL);
+  #endif
+          shutdown(master_soc, 2);
+          close(master_soc);
++ 	exit(1);						/* JPH001 */
+      }
+  }
+  
+***************
+*** 580,585 ****
+--- 593,600 ----
+  
+  PRIVATE void sig_pipe NOARGS
+  {
++     PRIVATE void clean_exit NOARGS;				/* JPH007 */
++ 
+      if (!sigpipe_caught) {
+          if (HTReqLine)
+              HTLog_error2("Connection interrupted [SIGPIPE], req:",HTReqLine);
+***************
+*** 587,592 ****
+--- 602,614 ----
+              HTLog_error("Connection interrupted [SIGPIPE]");
+      }
+  
++     if (sc.workers) {						/* JPH004 */
++         CTRACE(stderr, "SIGPIPE..... ignored (pre-forking)\n");	/* JPH004 */
++         sigpipe_caught = YES;					/* JPH004 */
++         set_signals();						/* JPH004 */
++         return;							/* JPH004 */
++     }								/* JPH004 */
++ 
+      if (ignore_sigpipes) {
+          CTRACE(stderr, "SIGPIPE..... ignored (writing to cache)\n");
+          sigpipe_caught = YES;
+***************
+*** 595,605 ****
+      else {
+          timeout_off();  /* So timeouts don't go to parent */
+          CTRACE(stderr, "SIGPIPE..... caught, exiting...\n");
+!         if (com_soc > 0) {
+!             shutdown(com_soc, 2);
+!             NETCLOSE(com_soc);
+!         }
+!         exit(0);
+      }
+  }
+  
+--- 617,623 ----
+      else {
+          timeout_off();  /* So timeouts don't go to parent */
+          CTRACE(stderr, "SIGPIPE..... caught, exiting...\n");
+!         clean_exit();						/* JPH007 */
+      }
+  }
+  
+***************
+*** 1444,1449 ****
+--- 1462,1471 ----
+          shutdown(com_soc, 2);
+          NETCLOSE(com_soc);
+      }
++     if (sc.workers) {						/* JPH007 */
++         longjmp(HTJumpEnv, 1);					/* JPH007 */
++         HTLog_error("Worker failed to long-jump back");		/* JPH007 */
++     }								/* JPH007 */
+      exit(0);
+  }
+  
+***************
+*** 1625,1630 ****
+--- 1647,1666 ----
+      HTVMS_enableSysPrv();
+  #endif /* VMS */
+  
++     if (sc.virtualize) {					/* JPH003 */
++         SockA vaddr;						/* JPH003 */
++         int vlen = sizeof(vaddr);				/* JPH003 */
++ 								/* JPH003 */
++         memset((char*)&vaddr, 0, sizeof(vaddr));		/* JPH003 */
++         getsockname(com_soc, (struct sockaddr*)&vaddr, &vlen);	/* JPH003 */
++         StrAllocCopy(HTVirtualHost, HTInetString(&vaddr));	/* JPH003 */
++         if (!HTVirtualHost || !*HTVirtualHost) {		/* JPH003 */
++ 		StrAllocCopy(HTVirtualHost, "0.0.0.0");		/* JPH003 */
++ 	}							/* JPH003 */
++         CTRACE(stderr, "Connection... via address %s\n",	/* JPH003 */
++                HTVirtualHost);					/* JPH003 */
++     }								/* JPH003 */
++ 
+      out.status_code = HTAA_checkAuthorization(req);
+      CTRACE(stderr, "AA.......... check returned %d\n", out.status_code);
+      CTRACE(stderr, "Translated.. \"%s\"\n",
+***************
+*** 2063,2069 ****
+  }
+  #endif /* not VMS */
+  
+! 
+  
+  /*                                                    standalone_server_loop()
+   *      New server_loop() for Unixes in standalone mode
+--- 2099,2413 ----
+  }
+  #endif /* not VMS */
+  
+! #if !defined(VMS) && defined(FORKING)				/* JPH004 */
+! PRIVATE int wait_for_work ARGS1(int, fd)			/* JPH004 */
+! {								/* JPH004 */
+!     struct iovec iov[1];					/* JPH004 */
+!     struct msghdr msg;						/* JPH004 */
+!     int passedfd = -1;		/* just in case */		/* JPH004 */
+!     char dummy;							/* JPH004 */
+! 								/* JPH004 */
+!     iov[0].iov_base = &dummy;					/* JPH004 */
+!     iov[0].iov_len = 1;						/* JPH004 */
+!     msg.msg_name = NULL;					/* JPH004 */
+!     msg.msg_namelen = 0;					/* JPH004 */
+!     msg.msg_iov = iov;						/* JPH004 */
+!     msg.msg_iovlen = 1;						/* JPH004 */
+!     msg.msg_accrights = (caddr_t)&passedfd;			/* JPH004 */
+!     msg.msg_accrightslen = sizeof(passedfd);			/* JPH004 */
+!     while (recvmsg(fd, &msg, 0) == -1) {			/* JPH007 */
+!         if (errno != EINTR) {					/* JPH007 */
+!             HTLog_error("Failed to recvmsg in worker\n");	/* JPH004 */
+!             _exit(1);						/* JPH004 */
+!         }							/* JPH007 */
+!     }								/* JPH004 */
+!     return passedfd;						/* JPH004 */
+! }								/* JPH004 */
+! 								/* JPH004 */
+! PRIVATE int work_completed ARGS1(HTWorkerStruct *, wp)		/* JPH004 */
+! {								/* JPH004 */
+!     return send(wp->fd, &wp->index, sizeof(wp->index), 0);	/* JPH004 */
+! }								/* JPH004 */
+! 								/* JPH004 */
+! PRIVATE int do_work ARGS1(HTWorkerStruct *, wp)			/* JPH004 */
+! {								/* JPH004 */
+!     int tcp_status;						/* JPH004 */
+!     static struct linger sl = {1, 600};				/* JPH004 */
+!     SockA addr;							/* JPH004 */
+!     int alen = sizeof(addr);					/* JPH004 */
+!     char * host;						/* JPH004 */
+!     int fd;							/* JPH008 */
+!     int closemask = 0;						/* JPH008 */
+! 								/* JPH004 */
+!     for (fd = 0; fd < 32; ++fd) {				/* JPH008 */
+!         closemask |= (!~fcntl(fd, F_GETFD, 0) << fd);		/* JPH008 */
+!     }								/* JPH008 */
+!     for (;;) {							/* JPH004 */
+!         com_soc = wait_for_work(wp->fd);			/* JPH004 */
+!         time(&cur_time);					/* JPH004 */
+!         child_serial++;						/* JPH004 */
+!         CTRACE(stderr, "Worker...... I'm awake\n");		/* JPH004 */
+!         if (sc.do_linger) {					/* JPH004 */
+!             setsockopt(com_soc, SOL_SOCKET, SO_LINGER,		/* JPH004 */
+!                        (char*)&sl, sizeof(sl));			/* JPH004 */
+!         }							/* JPH004 */
+!         memset((char*)&addr, 0, sizeof(addr));			/* JPH004 */
+!         getpeername(com_soc, (struct sockaddr*)&addr, &alen);	/* JPH004 */
+!         host = HTInetString(&addr);				/* JPH004 */
+!         if (!host || !*host) host = "0.0.0.0";			/* JPH004 */
+!         StrAllocCopy(HTClientHost, host);			/* JPH004 */
+!         FREE(HTClientHostName);					/* JPH004 */
+!         if (sc.do_dns_lookup) {					/* JPH004 */
+!             HTClientHostName = HTGetHostBySock(com_soc);	/* JPH004 */
+!         }							/* JPH004 */
+!         CTRACE(stderr, "Reading..... socket %d from host %s\n",	/* JPH004 */
+!                com_soc, HTClientHost);				/* JPH004 */
+!         remote_ident = NULL;					/* JPH004 */
+!         if (sc.do_rfc931) { /* ...broken?... */ }		/* JPH004 */
+!         sigpipe_caught = NO;					/* JPH004 */
+!         if (setjmp(HTJumpEnv) == 0) {				/* JPH007 */
+!             tcp_status = HTHandle(com_soc);			/* JPH004 */
+!         }							/* JPH007 */
+!         if (TRACE) {						/* JPH004 */
+!             if (tcp_status < 0) {				/* JPH004 */
+!                 fprintf(stderr,					/* JPH004 */
+!                   "ERROR....... %d handling msg (errno=%d).\n",	/* JPH004 */
+!                   tcp_status, errno);				/* JPH004 */
+!             } else if (tcp_status == 0) {			/* JPH004 */
+!                 fprintf(stderr,					/* JPH004 */
+!                   "Socket...... %d disconnected by peer\n",	/* JPH004 */
+!                   com_soc);					/* JPH004 */
+!             }							/* JPH004 */
+!         }							/* JPH004 */
+!         shutdown(com_soc, 2);					/* JPH004 */
+!         NETCLOSE(com_soc);					/* JPH004 */
+!         for (fd = 0; fd < 32; ++fd) {				/* JPH008 */
+!             if (closemask & (1 << fd)) close(fd);		/* JPH008 */
+!         }							/* JPH008 */
+!         work_completed(wp);					/* JPH004 */
+!     }								/* JPH004 */
+!     /*NOTREACHED*/						/* JPH004 */
+! }								/* JPH004 */
+! 								/* JPH004 */
+! PRIVATE int getlocaldgram ARGS2(struct sockaddr_un *, sunp,	/* JPH004 */
+!                                 int *, alenp)			/* JPH004 */
+! {								/* JPH004 */
+!     int sockfd;							/* JPH004 */
+! 								/* JPH004 */
+!     if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) {	/* JPH004 */
+!         HTLog_error("Failed to create UNIX/DGRAM socket\n");	/* JPH004 */
+!         return -1;						/* JPH004 */
+!     }								/* JPH004 */
+!     sunp->sun_family = AF_UNIX;					/* JPH004 */
+!     strcpy(sunp->sun_path, tempnam(NULL, "wwwSS"));		/* JPH004 */
+!     *alenp = sizeof(sunp->sun_family) + strlen(sunp->sun_path);	/* JPH004 */
+!     if (bind(sockfd, sunp, *alenp) == -1) {			/* JPH004 */
+!         HTLog_error2("Failed to bind UNIX/DGRAM socket to %s",	/* JPH004 */
+!                      sunp->sun_path);				/* JPH004 */
+!         return -1;						/* JPH004 */
+!     }								/* JPH004 */
+!     return sockfd;						/* JPH004 */
+! }								/* JPH004 */
+! 								/* JPH004 */
+! PRIVATE int make_worker ARGS3(HTWorkerStruct *, wp,		/* JPH004 */
+!                               struct sockaddr_un *, bossp,	/* JPH004 */
+!                               int, bosslen)			/* JPH004 */
+! {								/* JPH004 */
+!     wp->fd = getlocaldgram(&wp->addr, &wp->addrlen);		/* JPH004 */
+!     if (wp->fd == -1) {						/* JPH004 */
+!         HTLog_error("Failed to make worker process\n");		/* JPH004 */
+!         return -1;						/* JPH004 */
+!     }								/* JPH004 */
+!     if (connect(wp->fd, bossp, bosslen) == -1) {		/* JPH004 */
+!         HTLog_error("Failed to connect worker process\n");	/* JPH004 */
+!         return -1;						/* JPH004 */
+!     }								/* JPH004 */
+!     if ((wp->pid = fork()) == 0) do_work(wp);			/* JPH004 */
+!     if (wp->pid == -1) {					/* JPH004 */
+!         HTLog_error("Failed to fork worker process\n");		/* JPH004 */
+!     }								/* JPH004 */
+!     close(wp->fd);						/* JPH004 */
+!     wp->fd = -1;						/* JPH004 */
+!     return (wp->pid);						/* JPH004 */
+! }								/* JPH004 */
+! 								/* JPH004 */
+! PRIVATE int assign_work ARGS3(int, workerfd,			/* JPH004 */
+!                               int, clientfd,			/* JPH004 */
+!                               HTWorkerStruct *, wp)		/* JPH004 */
+! {								/* JPH004 */
+!     struct iovec iov[1];					/* JPH004 */
+!     struct msghdr msg;						/* JPH004 */
+! 								/* JPH004 */
+!     iov[0].iov_base = "?";		/* any old byte */	/* JPH004 */
+!     iov[0].iov_len = 1;						/* JPH004 */
+!     msg.msg_name = (caddr_t)&wp->addr;				/* JPH004 */
+!     msg.msg_namelen = wp->addrlen;				/* JPH004 */
+!     msg.msg_iov = iov;						/* JPH004 */
+!     msg.msg_iovlen = 1;						/* JPH004 */
+!     msg.msg_accrights = (caddr_t)&clientfd;			/* JPH004 */
+!     msg.msg_accrightslen = sizeof(clientfd);			/* JPH004 */
+!     if (sendmsg(workerfd, &msg, 0) == -1) {			/* JPH004 */
+!         HTLog_error("Failed to sendmsg to worker\n");		/* JPH004 */
+!         return -1;						/* JPH004 */
+!     }								/* JPH004 */
+!     return 0;							/* JPH004 */
+! }								/* JPH004 */
+! 								/* JPH004 */
+! PRIVATE int worker_done ARGS1(int, fd)				/* JPH004 */
+! {								/* JPH004 */
+!     int index = -1;			/* just in case */	/* JPH004 */
+! 								/* JPH004 */
+!     (void)recv(fd, &index, sizeof(index));			/* JPH004 */
+!     return index;						/* JPH004 */
+! }								/* JPH004 */
+! 								/* JPH004 */
+! 								/* JPH004 */
+! /*      New server_loop() for Unixes in preforking mode */	/* JPH004 */
+! 								/* JPH004 */
+! PRIVATE int preforking_server_loop NOARGS			/* JPH004 */
+! {								/* JPH004 */
+!     int soc_addr_len = sizeof(client_soc_addr);			/* JPH004 */
+!     int timeout;						/* JPH004 */
+!     int worker_soc = -1;					/* JPH004 */
+!     struct sockaddr_un boss;					/* JPH004 */
+!     int blen;							/* JPH004 */
+!     int nw = 0;							/* JPH004 */
+!     HTWorkerStruct * worker = NULL;				/* JPH004 */
+!     int * roster = NULL;					/* JPH004 */
+!     int nIdle;							/* JPH004 */
+!     int idle_index;	/* index in worker of just completed */	/* JPH004 */
+!     int idle_slot;	/* and its slot in roster table */	/* JPH004 */
+!     fd_set read_chans;						/* JPH004 */
+!     struct timeval max_wait;					/* JPH004 */
+!     int nfound;							/* JPH004 */
+! 								/* JPH004 */
+!     CTRACE(stderr, "ServerLoop.. Unix preforking\n");		/* JPH004 */
+! 								/* JPH004 */
+!     worker_soc = getlocaldgram(&boss, &blen);			/* JPH004 */
+!     if (worker_soc == -1) goto fallback;			/* JPH004 */
+!     worker = (HTWorkerStruct *)					/* JPH004 */
+!       malloc(sc.workers * sizeof(HTWorkerStruct));		/* JPH004 */
+!     if (worker == NULL) {					/* JPH004 */
+!         HTLog_error("Worker alloc failed\n");			/* JPH004 */
+!         goto fallback;						/* JPH004 */
+!     }								/* JPH004 */
+!     roster = (int *)malloc(sc.workers * sizeof(int));		/* JPH004 */
+!     if (roster == NULL) {					/* JPH004 */
+!         HTLog_error("Worker roster alloc failed\n");		/* JPH004 */
+!         goto fallback;						/* JPH004 */
+!     }								/* JPH004 */
+!     for (nIdle = 0; nIdle < sc.workers; ++nIdle) {		/* JPH004 */
+!         roster[nIdle] = nIdle;					/* JPH004 */
+!     }								/* JPH004 */
+!     for (nw = 0; nw < sc.workers; ++nw) {			/* JPH004 */
+!         worker[nw].index = nw;					/* JPH004 */
+!         worker[nw].slot = nw;					/* JPH004 */
+!         if (make_worker(worker + nw, &boss, blen) == -1) break;	/* JPH004 */
+!     }								/* JPH004 */
+!     if (nw == 0) {						/* JPH004 */
+!         HTLog_error("Unable to create any worker processes\n");	/* JPH004 */
+!         goto fallback;						/* JPH004 */
+!     }								/* JPH004 */
+!     if (nw != sc.workers) {					/* JPH004 */
+!         HTLog_errorN("Worker processes reduced to", nw);	/* JPH004 */
+!         sc.workers = nw;					/* JPH004 */
+!     }								/* JPH004 */
+! 								/* JPH004 */
+!     FD_ZERO(&open_sockets);					/* JPH004 */
+!     FD_SET(worker_soc, &open_sockets);				/* JPH004 */
+!     FD_SET(master_soc, &open_sockets);				/* JPH004 */
+!     num_sockets = 1 +						/* JPH004 */
+!       ((worker_soc > master_soc) ? worker_soc : master_soc);	/* JPH004 */
+!     for (;;) {							/* JPH004 */
+!         if (nIdle == 0) {					/* JPH004 */
+!             HTLog_error("All workers busy, not accepting\n");	/* JPH004 */
+!             FD_CLR(master_soc, &open_sockets);			/* JPH004 */
+!         }							/* JPH004 */
+!         read_chans = open_sockets;				/* JPH004 */
+!         timeout = get_next_timeout();				/* JPH004 */
+!         max_wait.tv_sec = timeout/100;				/* JPH004 */
+!         max_wait.tv_usec = (timeout%100)*10000;			/* JPH004 */
+!         timeout /= 100;						/* JPH004 */
+!         if (TRACE) {						/* JPH004 */
+!             fprintf(stderr,					/* JPH004 */
+!               "Next timeout after %d hours %d mins %d secs\n",	/* JPH004 */
+!                timeout/3600, (timeout/60)%60, timeout%60);	/* JPH004 */
+!             fprintf(stderr,					/* JPH004 */
+!               "Daemon...... %s (Mask=%x hex, max=%x hex).\n",	/* JPH004 */
+!               "Waiting for connection",				/* JPH004 */
+!               *(unsigned int *)(&read_chans),			/* JPH004 */
+!               (unsigned int)num_sockets);			/* JPH004 */
+!         }							/* JPH004 */
+! #ifdef __hpux							/* JPH004 */
+!         nfound = select(num_sockets,				/* JPH004 */
+!           (int *)&read_chans, NULL, NULL,			/* JPH004 */
+!           timeout > 0 ? &max_wait : NULL);			/* JPH004 */
+! #else								/* JPH004 */
+!         nfound = select(num_sockets,				/* JPH004 */
+!           &read_chans, NULL, NULL,				/* JPH004 */
+!           timeout > 0 ? &max_wait : NULL);			/* JPH004 */
+! #endif								/* JPH004 */
+!         if (nfound < 0) {   /* Interrupted */			/* JPH004 */
+!             if (errno != EINTR) (void)HTInetStatus("select");	/* JPH004 */
+!             continue;						/* JPH004 */
+!         }							/* JPH004 */
+!         if (nfound == 0) {  /* Timeout */			/* JPH004 */
+!             CTRACE(stderr,					/* JPH004 */
+!               "Time to do.. daily garbage collection\n");	/* JPH004 */
+!             gc_pid = fork();					/* JPH004 */
+!             if (!gc_pid) gc_and_exit(1,0);			/* JPH004 */
+!             else continue;					/* JPH004 */
+!         }							/* JPH004 */
+!         if (FD_ISSET(worker_soc, &read_chans)) {		/* JPH004 */
+!                 idle_index = worker_done(worker_soc);		/* JPH004 */
+!                 if (idle_index != -1) {				/* JPH004 */
+!                         idle_slot = worker[idle_index].slot;	/* JPH004 */
+!                         roster[idle_slot] = roster[nIdle];	/* JPH004 */
+!                         worker[roster[nIdle]].slot = idle_slot;	/* JPH004 */
+!                         roster[nIdle] = idle_index;		/* JPH004 */
+!                         worker[idle_index].slot = nIdle;	/* JPH004 */
+!                         if (nIdle++ == 0) {			/* JPH004 */
+!                             HTLog_error(			/* JPH004 */
+!                               "A worker is now available\n");	/* JPH004 */
+!                             FD_SET(master_soc, &open_sockets);	/* JPH004 */
+!                         }					/* JPH004 */
+!                 }						/* JPH004 */
+!         }							/* JPH004 */
+!         if (FD_ISSET(master_soc, &read_chans)) {		/* JPH004 */
+!             CTRACE(stderr,					/* JPH004 */
+!               "Daemon...... accepting connection...\n");	/* JPH004 */
+!             com_soc = accept(master_soc,			/* JPH004 */
+!               (struct sockaddr *)&client_soc_addr,		/* JPH004 */
+!               &soc_addr_len);					/* JPH004 */
+!             if (com_soc < 0) {					/* JPH004 */
+!                 if (errno != EINTR) HTInetStatus("accept");	/* JPH004 */
+!                 continue;					/* JPH004 */
+!             }							/* JPH004 */
+!             --nIdle;						/* JPH004 */
+!             CTRACE(stderr,					/* JPH004 */
+!               "Accepted.... socket %d, worker %d slot %d\n",	/* JPH004 */
+!               com_soc, roster[nIdle], nIdle);			/* JPH004 */
+!             assign_work(worker_soc, com_soc,			/* JPH004 */
+!               worker + roster[nIdle]);				/* JPH004 */
+!             NETCLOSE(com_soc);					/* JPH004 */
+! #ifdef SIGTSTP  /* BSD */					/* JPH004 */
+!             sig_child();	/* ??? redundant ??? */		/* JPH004 */
+! #endif								/* JPH004 */
+!         }							/* JPH004 */
+!     } /* for loop */						/* JPH004 */
+! 								/* JPH004 */
+! fallback:							/* JPH004 */
+!     if (worker_soc != -1) {					/* JPH004 */
+!         close(worker_soc);					/* JPH004 */
+!         unlink(boss.sun_path);					/* JPH004 */
+!     }								/* JPH004 */
+!     if (roster != NULL) free(roster);				/* JPH004 */
+!     if (worker != NULL) free(worker);				/* JPH004 */
+!     sc.workers = 0;						/* JPH004 */
+!     HTLog_error("Falling back to non-preforking mode\n");	/* JPH004 */
+!     return 1;							/* JPH004 */
+! }								/* JPH004 */
+! #endif								/* JPH004 */
+  
+  /*                                                    standalone_server_loop()
+   *      New server_loop() for Unixes in standalone mode
+***************
+*** 2300,2305 ****
+--- 2644,2652 ----
+          /*
+           * Use new server loop, old one is a mess.
+           */
++         if ((role == master) && (sc.workers)) {			/* JPH004 */
++             preforking_server_loop();				/* JPH004 */
++         }							/* JPH004 */
+          if (role == master) standalone_server_loop();
+  #endif
+  
+***************
+*** 2674,2685 ****
+  #if defined(__svr4__) || defined(_POSIX_SOURCE) || defined(__hpux)
+      pgrp = setsid();
+  #else
+!     pgrp = setpgrp(0, getpid());
+  
+      if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
+          ioctl(fd, TIOCNOTTY, (char*)NULL);      /* Lose controlling tty */
+          close(fd);
+      }
+  #endif
+      if (pgrp == -1)
+          HTLog_error("Can't change process group");
+--- 3021,3038 ----
+  #if defined(__svr4__) || defined(_POSIX_SOURCE) || defined(__hpux)
+      pgrp = setsid();
+  #else
+!     pgrp = (setpgrp(0, getpid()) == -1) ? -1 : getpgrp(0);	/* JPH002 */
+  
+      if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
+          ioctl(fd, TIOCNOTTY, (char*)NULL);      /* Lose controlling tty */
+          close(fd);
+      }
++ 
++     /* TIOCNOTTY can reset pgrp to zero! */			/* JPH002 */
++ 								/* JPH002 */
++     if (getpgrp(0) == 0) {					/* JPH002 */
++         pgrp = (setpgrp(0, getpid()) == -1) ? -1 : getpgrp(0);	/* JPH002 */
++     }								/* JPH002 */
+  #endif
+      if (pgrp == -1)
+          HTLog_error("Can't change process group");
+*** 1.1	1995/07/11 17:09:08
+--- Library/Implementation/HTDaemon.h	1995/07/13 02:57:04
+***************
+*** 14,19 ****
+--- 14,20 ----
+  extern BOOL ignore_sigpipes;	/* Should we catch and ignore SIGPIPE	*/
+  extern BOOL sigpipe_caught;	/* If so, have we caught a SIGPIPE	*/
+  
++ extern char *		HTVirtualHost;				/* JPH003 */
+  extern char *		HTClientProtocol;
+  extern int		HTServerPort;
+  
+***************
+*** 53,58 ****
+--- 54,71 ----
+  extern BOOL		trace_all;
+  #define VTRACE		if(trace_all)fprintf
+  
++ #ifdef FORKING							/* JPH004 */
++ #include <sys/un.h>						/* JPH004 */
++ 								/* JPH004 */
++ typedef struct _HTWorkerStruct {				/* JPH004 */
++     struct sockaddr_un	addr;					/* JPH004 */
++     int			addrlen;				/* JPH004 */
++     int			index;	/* into worker table */		/* JPH004 */
++     int			slot;	/* into roster table */		/* JPH004 */
++     int			pid;					/* JPH004 */
++     int			fd;	/* valid in workers only */	/* JPH004 */
++ } HTWorkerStruct;						/* JPH004 */
++ #endif								/* JPH004 */
+  
+  typedef struct _HTInStruct {
+      BOOL	no_cache_pragma;
+*** 1.1	1995/07/11 17:09:11
+--- Library/Implementation/HTLog.c	1995/07/14 00:08:39
+***************
+*** 62,68 ****
+  
+      /* If we have a date format to paste on the file names. Else use default */
+      time(&t);
+!     gmt = gmtime(&t);
+      result = malloc(strlen(filename)+DATE_EXT_LEN+2);
+      if (sc.log_file_date_ext) {
+  
+--- 62,68 ----
+  
+      /* If we have a date format to paste on the file names. Else use default */
+      time(&t);
+!     gmt = sc.use_gmt ? gmtime(&t) : localtime(&t);		/* JPH005 */
+      result = malloc(strlen(filename)+DATE_EXT_LEN+2);
+      if (sc.log_file_date_ext) {
+  
+***************
+*** 300,305 ****
+--- 300,312 ----
+  	}
+  	else strcpy(buf, "- -");
+  
++ 	if (sc.virtualize) {					/* JPH003 */
++ 	    fprintf(log, "%s %s %s %s [%s] \"%s\" %s\n",	/* JPH003 */
++ 		    HTVirtualHost,				/* JPH003 */
++ 		    n_pick(HTClientHostName,HTClientHost),	/* JPH003 */
++ 		    r_ident, authuser, log_time(),		/* JPH003 */
++ 		    n_noth(HTReqLine), buf);			/* JPH003 */
++ 	} else							/* JPH003 */
+  	fprintf(log, "%s %s %s [%s] \"%s\" %s\n",
+  		n_pick(HTClientHostName,HTClientHost),
+  		r_ident, authuser, log_time(), n_noth(HTReqLine), buf);
+*** 1.1	1995/07/11 17:09:15
+--- Library/Implementation/HTScript.c	1995/07/15 01:24:04
+***************
+*** 833,838 ****
+--- 833,839 ----
+      char ** argv = NULL;
+      char ** envp = NULL;
+      BOOL nph_script = NO;
++     int fd;							/* JPH006 */
+  
+      FREE(msg);		/* From previous call */
+  
+***************
+*** 939,944 ****
+--- 940,948 ----
+  	pid = fork();
+  	if (pid < 0) {	/* fork() failed */
+  	    char msg[100];
++ 
++             close(pin[0]),close(pin[1]);			/* JPH006 */
++             close(pout[0]),close(pout[1]);			/* JPH006 */
+  	    sprintf(msg, "Internal error: fork() failed with %s script",
+  		    (nph_script ? "NPH-" : HTMethod_name(req->method)));
+  	    return HTLoadError(req, 500, msg);
+***************
+*** 954,959 ****
+--- 958,964 ----
+  	    ** Standalone server, redirect socket to stdin/stdout.
+  	    */
+  	    CTRACE(stderr, "Child....... doing IO redirections\n");
++             close(0);						/* JPH006 */
+  	    if (req->content_length > 0) {	/* Need to give stdin */
+  		if (pin[0] != 0) {
+  		    CTRACE(stderr, "Child....... stdin from input pipe\n");
+***************
+*** 981,986 ****
+--- 986,992 ----
+  		   "Child....... Standalone specific IO redirections done.\n");
+  	    CTRACE(stderr, "Child....... redirecting stderr to stdout, and then doing execve()\n");
+  	    dup2(1, 2);	/* Redirect stderr to stdout */
++             for (fd = 3; fd < pout[1]; ++fd) close(fd);		/* JPH006 */
+  	    if (-1 == execve(HTReqScript, argv, envp)) {
+  		CTRACE(stderr, "ERROR....... execve() failed\n");
+  		HTLoadError(req, 500, "Internal error: execve() failed");
diff -rNu /cdrom/ports/www/w3c-httpd/patches/RefererLog.patch w3c-httpd/patches/RefererLog.patch
--- /cdrom/ports/www/w3c-httpd/patches/RefererLog.patch	Wed Dec 31 19:00:00 1969
+++ w3c-httpd/patches/RefererLog.patch	Fri Jun 12 19:07:38 1998
@@ -0,0 +1,240 @@
+*** /dev/null	Tue Feb  6 11:05:04 1996
+--- WWW/README-REFERER_LOG	Tue Feb  6 13:24:53 1996
+***************
+*** 0 ****
+--- 1,30 ----
++ Patch to add RefererLog to the configuration.
++ 
++ Apply the patch, modify WWW/All/<model>/Makefile.include (for your model
++ system) and add '-DREFERER_LOG' to CFLAGS.
++ 
++ Add the following line to your httpd.conf:
++ 
++ RefererLog	/www/logs/referer
++ 
++ The syntax is identical to that for AccessLog, in fact: for each entry
++ in the AccessLog there will be an entry in the RefererLog.
++ 
++ The format of the RefererLog is slightly different from the NCSA one
++ <URL:http://hoohoo.ncsa.uiuc.edu/docs/setup/httpd/RefererLog.html>:
++ 
++ host.some.where.org [05/Feb/1996:12:38:36 -0100] http://lycos-tmp1.psc.edu/cgi-bin/pursuit?query=something -> /
++ host.some.where.org [05/Feb/1996:12:38:55 -0100] http://www.my.domain/ -> /info/
++ some.one.else [05/Feb/1996:12:40:02 -0100] - -> /HotNews/
++ 
++ So:
++ 
++ referring-host [timestamp] referring-URL -> document
++ 
++ The referring-host and timestamp will be in the same format as in the
++ AccessLog.  If there is no referring-URL, a minus sign will be printed.
++ Anything matching the NoLog directive (so it isn't logged in the
++ AccessLog) is not logged in the RefererLog.
++ 
++ --
++ -- 19960205, Gertjan van Oosten, gertjan@West.NL, West Consulting bv
+*** WWW/Daemon/Implementation/HTConfig.h.orig	Sun Sep 25 14:55:28 1994
+--- WWW/Daemon/Implementation/HTConfig.h	Mon Feb  5 15:01:23 1996
+***************
+*** 76,81 ****
+--- 76,84 ----
+      BOOL	always_welcome;		/* Redirect directory names to	*/
+  					/* welcome page on that dir.	*/
+      char *	access_log_name;	/* Access log file name		*/
++ #ifdef REFERER_LOG
++     char *	referer_log_name;	/* Referer log file name	*/
++ #endif
+      char *	proxy_log_name;		/* Proxy access log file name	*/
+      char *	cache_log_name;		/* Cache access log file name	*/
+      char *	error_log_name;		/* Error log file name		*/
+*** WWW/Daemon/Implementation/HTConfig.c.orig	Mon Sep 26 15:22:52 1994
+--- WWW/Daemon/Implementation/HTConfig.c	Mon Feb  5 15:00:35 1996
+***************
+*** 1675,1680 ****
+--- 1675,1686 ----
+  	    sc.access_log_name = tilde_to_home(vec[1]);
+  	    CTRACE(stderr, "AccessLog... %s\n", sc.access_log_name);
+  
++ #ifdef REFERER_LOG
++ 	} else if (!strncmp(vec[0],"refererlog",10)) {
++ 	    sc.referer_log_name = tilde_to_home(vec[1]);
++ 	    CTRACE(stderr, "RefererLog... %s\n", sc.referer_log_name);
++ 
++ #endif
+  	} else if (!strncmp(vec[0],"cacheaccesslog",12)) {
+  	    sc.cache_log_name = tilde_to_home(vec[1]);
+  	    CTRACE(stderr, "Cache log... %s\n", sc.cache_log_name);
+*** WWW/Daemon/Implementation/HTLog.h.orig	Sun Sep 25 14:55:29 1994
+--- WWW/Daemon/Implementation/HTLog.h	Mon Feb  5 14:58:06 1996
+***************
+*** 8,13 ****
+--- 8,16 ----
+  PUBLIC BOOL HTLog_openAll NOPARAMS;
+  PUBLIC void HTLog_closeAll NOPARAMS;
+  PUBLIC void HTLog_access PARAMS((HTRequest *	req));
++ #ifdef REFERER_LOG
++ PUBLIC void HTLog_referer PARAMS((HTRequest *	req));
++ #endif
+  PUBLIC void HTLog_error PARAMS((CONST char * msg));
+  PUBLIC void HTLog_error2 PARAMS((CONST char *	msg,
+  				 CONST char *	param));
+*** WWW/Daemon/Implementation/HTLog.c.orig	Sun Sep 25 19:53:37 1994
+--- WWW/Daemon/Implementation/HTLog.c	Mon Feb  5 16:02:10 1996
+***************
+*** 40,45 ****
+--- 40,48 ----
+  PRIVATE FILE *	proxy_log	= NULL;		
+  PRIVATE FILE *	cache_log	= NULL;
+  PRIVATE FILE *	error_log	= NULL;
++ #ifdef REFERER_LOG
++ PRIVATE FILE *	referer_log	= NULL;
++ #endif
+  
+  extern char * HTClientHost;
+  extern char * HTClientHostName;
+***************
+*** 125,130 ****
+--- 128,136 ----
+  static access_log_times = 0;
+  static error_log_times = 0;
+  static cache_log_times = 0;
++ #ifdef REFERER_LOG
++ static referer_log_times = 0;
++ #endif
+  
+     /* flush C rtl buffers */
+     fflush(fptr);
+***************
+*** 165,170 ****
+--- 171,189 ----
+  				cache_log, "shr=get","shr=put", "shr=upd");
+        }
+     }
++ #ifdef REFERER_LOG
++    else
++    if (fptr == referer_log)
++    {
++       referer_log_times++;
++       if (referer_log_times > TIMES_TO_REOPEN)
++       {
++          referer_log_times = 0;
++          referer_log = freopen(time_escapes(sc.referer_log_name), "a+", 
++ 				referer_log, "shr=get","shr=put", "shr=upd");
++       }
++    }
++ #endif
+  
+     return(1);
+  }
+***************
+*** 316,324 ****
+--- 335,378 ----
+      }
+  
+      HTFlush(log);
++ 
++ #ifdef REFERER_LOG
++     if (log == access_log)
++ 	HTLog_referer(req);
++ #endif
+  }
+  
+  
++ #ifdef REFERER_LOG
++ PUBLIC void HTLog_referer ARGS1(HTRequest *, req)
++ {
++     time_t t;
++     struct tm * gorl;
++     FILE * log = referer_log;
++ 
++     if (!log) return;
++ 
++     if (sc.new_logfile_format) {
++ 	fprintf(log, "%s [%s] %s -> %s\n",
++ 		n_pick(HTClientHostName,HTClientHost),
++ 		log_time(), n_hyph(HTReferer), n_noth(HTReqArg));
++     }
++     else {	/* Still old format */
++ 	time(&t);
++ 	if (sc.use_gmt)
++ 	    gorl = gmtime(&t);
++ 	else
++ 	    gorl = localtime(&t);
++ 
++ 	fprintf(log, "%24.24s %s %s -> %s\n",
++ 		asctime(gorl), HTClientHost, n_hyph(HTReferer), n_noth(HTReqArg));
++     }
++ 
++     HTFlush(log);
++ }
++ #endif /* REFERER_LOG */
++ 
++ 
+  PRIVATE char * status_name NOARGS
+  {
+      switch (HTReason) {
+***************
+*** 431,436 ****
+--- 485,496 ----
+  	fclose(cache_log);
+  	cache_log = NULL;
+      }
++ #ifdef REFERER_LOG
++     if (referer_log) {
++ 	fclose(referer_log);
++ 	referer_log = NULL;
++     }
++ #endif
+  }
+  
+  
+***************
+*** 467,472 ****
+--- 527,535 ----
+      char * aln = NULL;
+      char * pln = NULL;
+      char * cln = NULL;
++ #ifdef REFERER_LOG
++     char * rln = NULL;
++ #endif
+      char * eln = NULL;
+  
+      /*
+***************
+*** 517,522 ****
+--- 580,602 ----
+  	}
+      }
+  
++ #ifdef REFERER_LOG
++     /*
++      * Open referer log file
++      */
++     if (sc.referer_log_name) {
++ 	rln = time_escapes(sc.referer_log_name);
++ 	referer_log = do_open(rln);
++ 	if (referer_log) {
++ 	    CTRACE(stderr, "Referer log... \"%s\" opened\n", rln);
++ 	}
++ 	else {
++ 	    HTLog_error2("Can't open referer log:", rln);
++ 	    flag = NO;
++ 	}
++     }
++ #endif
++ 
+      /*
+       * Open error log and flush the current error queue to it
+       */
+***************
+*** 549,554 ****
+--- 629,637 ----
+      FREE(pln);
+      FREE(eln);
+      FREE(cln);
++ #ifdef REFERER_LOG
++     FREE(rln);
++ #endif
+  
+      return flag;
+  }
diff -rNu /cdrom/ports/www/w3c-httpd/patches/SSL.patch w3c-httpd/patches/SSL.patch
--- /cdrom/ports/www/w3c-httpd/patches/SSL.patch	Wed Dec 31 19:00:00 1969
+++ w3c-httpd/patches/SSL.patch	Fri Jun 12 19:07:49 1998
@@ -0,0 +1,532 @@
+============================================================================
+README:
+============================================================================
+
+OVERVIEW
+
+	This SSL tunneling patch for CERN httpd adds support for the
+	CONNECT method used by SSL enhanced clients to open a secure
+	tunnel through the proxy.
+
+THEORY
+
+	The CONNECT method takes
+
+		hostname:port
+
+	as its argument, and the request is in the form of the
+	HTTP/1.0 request (that is, the string "HTTP/1.0" and the
+	request headers must follow the request).  Example:
+
+		CONNECT home1.netscape.com:443 HTTP/1.0<crlf>
+		<crlf>
+
+	The response will be either a normal HTTP/1.0 error response
+	(in case the host is unreachable for one reason or another),
+	or in case of success:
+
+		HTTP/1.0 200 Connection established<crlf>
+		<crlf>
+
+	after which the connection is open, and the client may start
+	the SSL handshake.
+
+	This is a superior approach because it allows the HTTP request
+	headers to be passed, making it possible to do authentication
+	on the proxy, and allows any other future extension.
+
+CONFIGURATION
+
+	Because the configuration of CERN httpd is based on URL
+	patterns, for ease of configuration, the hostname:port
+	argument in automatically transformed into an internal
+	representation:
+
+		connect://hostname:port
+
+	connect:// URLs do not exist in real life -- this is just a
+	notion in the configuration file to make life easier!!
+
+ENABLING
+
+	SSL tunneling is disabled by default.  To enable it for HTTPS
+	(uses the port 443), add the following line in the
+	configuration file:
+
+		Pass connect://*:443
+
+	To enable secure news (SNEWS, uses port 563) tunneling, add
+	line:
+
+		Pass connect://*:563
+
+	DO NOT use trailing slashes.  DO NOT allow all connect://
+	requests, the following is unsafe:
+
+		Pass connect://*
+
+PROTECTION
+
+	IP address protection should always be used in connection with
+	SSL tunneling.  To create a protection template P which allows
+	access only for hosts with IP addresses 198.93.*.* and
+	198.95.*.*, use the template:
+
+		Protection P {
+		    CONNECT-Mask @(198.93.*.*, 198.95.*.*)
+		}
+
+	Note that this only declares a template; to actually apply the
+	protection use the Protect rule, AFTER the Protection
+	declaration, but BEFORE the Pass rule:
+
+		Protect connect://* P
+
+	Or, to collect them all together:
+
+		Protection P {
+		    CONNECT-Mask @(198.93.*.*, 198.95.*.*)
+		}
+		Protect	connect://* P
+		Pass connect://*:443
+		Pass connect://*:563
+
+	The Protection binding to name P may be left out in case it's
+	only used once, and the protection configuration may be
+	inlined in place of the protection name in Protect rule:
+
+		Protect connect://* {
+		    CONNECT-Mask @(198.93.*.*, 198.95.*.*)
+		}
+		Pass connect://*:443
+		Pass connect://*:563
+
+	For a better insight of the CERN httpd's configuration system,
+	please refer to the online manual:
+
+		http://www.w3.org/httpd/
+
+PROXY AUTHENTICATION
+
+	This patch does not enable proxy authentication.  Proxy
+	authentication is not supported by the CERN proxy.  Proxy
+	authentication uses the status code 407, and headers
+	Proxy-Authenticate and Proxy-Authorization.
+
+	You MUST NOT try to use the Protect directive to turn on
+	normal user authentication on (the one that uses the 401
+	status code, and WWW-Authenticate and Authorization headers).
+	That is an incorrect way to do authentication for the proxy,
+	and causes compatibility and security problems.
+
+CHAINING PROXIES
+
+	This patch does not enable chaining proxies to do SSL
+	tunneling.  More specifically, the CERN proxy with this patch
+	IS able to act as the OUTMOST proxy in the chain, but it
+	doesn't work if it is the inner proxy that has to speak to
+	another, outer proxy to establish a secure connection through
+	that.  Therefore, a combination such as inner Netscape Proxy
+	and outer CERN httpd would work, but not vice versa.
+
+THE NETSCAPE PROXY SERVER
+
+	The Netscape Proxy Server is a commercially supported proxy
+	server available from Netscape Communications Corporation.  In
+	addition to it's unique, more efficient architecture, it
+	natively supports proxy authentication, proxy chaining, SSL
+	tunneling and HTTPS proxying, enabling also clients without
+	native SSL support to use HTTPS.
+
+AUTHOR
+	Ari Luotonen, Netscape Communications Corporation, 1995
+	<ari@netscape.com>
+
+DISCLAIMER
+
+	I do not have any official connection to the CERN httpd
+	development anymore.  I have left the CERN WWW project in
+	summer '94.  I do not provide any support for this software or
+	this patch.  For general CERN httpd support, please contact:
+
+		httpd@w3.org
+
+	THIS PATCH IS PROVIDED IN GOOD FAITH, AS IS.  I AND NETSCAPE
+	MAKE NO CLAIMS TO ITS SUITABILITY FOR ANY PARTICULAR PURPOSE,
+	AND I AND NETSCAPE PROVIDE ABSOLUTELY NO WARRANTY OF ANY KIND
+	WITH RESPECT TO THIS PATCH OR THIS SOFTWARE.  THE ENTIRE RISK
+	AS TO THE QUALITY AND PERFORMANCE OF THIS SOFTWARE/PATCH IS
+	WITH THE USER.  IN NO EVENT WILL I OR NETSCAPE BE LIABLE TO
+	ANYONE FOR ANY DAMAGES ARISING OUT THE USE OF THIS
+	SOFTWARE/PATCH, INCLUDING, WITHOUT LIMITATION, DAMAGES
+	RESULTING FROM LOST DATA OR LOST PROFITS, OR FOR ANY SPECIAL,
+	INCIDENTAL OR CONSEQUENTIAL DAMAGES.
+
+
+============================================================================
+PATCH TO WWW COMMON LIBRARY 2.17 AND CERN HTTPD 3.0:
+============================================================================
+
+*** WWW/Library/Implementation/HTAccess.c.orig	Thu Sep 29 04:53:28 1994
+--- WWW/Library/Implementation/HTAccess.c	Tue May  9 13:16:50 1995
+***************
+*** 146,151 ****
+--- 146,152 ----
+      "SHOWMETHOD",
+      "LINK",
+      "UNLINK",
++     "CONNECT",
+      NULL
+  };
+  
+*** WWW/Library/Implementation/HTAccess.h.orig	Sun Sep 25 07:15:14 1994
+--- WWW/Library/Implementation/HTAccess.h	Tue May  9 13:15:47 1995
+***************
+*** 60,65 ****
+--- 60,66 ----
+          METHOD_SHOWMETHOD,
+          METHOD_LINK,
+          METHOD_UNLINK,
++ 	METHOD_CONNECT,
+          MAX_METHODS
+  } HTMethod;
+  /*
+*** WWW/Daemon/Implementation/HTAAProt.h.orig	Sun Sep 25 06:55:47 1994
+--- WWW/Daemon/Implementation/HTAAProt.h	Mon May 15 21:05:40 1995
+***************
+*** 52,57 ****
+--- 52,58 ----
+      GroupDef *    put_mask;     /*  - " - (PUT)                         */
+      GroupDef *    post_mask;    /*  - " - (POST)                        */
+      GroupDef *    delete_mask;  /*  - " - (DELETE)                      */
++     GroupDef *    connect_mask;	/*  - " - (CONNECT)			*/
+      GroupDef *    gen_mask;     /* General mask (used when needed but   */
+                                  /* other masks not set).                */
+      HTList *      valid_schemes;/* Valid authentication schemes         */
+*** WWW/Daemon/Implementation/HTAAProt.c.orig	Sun Sep 25 11:53:03 1994
+--- WWW/Daemon/Implementation/HTAAProt.c	Mon May 15 21:18:05 1995
+***************
+*** 356,361 ****
+--- 356,373 ----
+  		    }
+  		} /* if "Post-Mask" */
+  
++ 		else if (0==strncasecomp(fieldname, "connect", 7)) {
++ 		    prot->connect_mask = HTAA_parseGroupDef(fp);
++ 		    lex_item=LEX_REC_SEP; /*groupdef parser read this already*/
++ 		    if (TRACE) {
++ 			if (prot->connect_mask) {
++ 			    fprintf(stderr, "CONNECT-Mask\n");
++ 			    HTAA_printGroupDef(prot->connect_mask);
++ 			}
++ 			else fprintf(stderr,"SYNTAX ERROR parsing CONNECT-Mask\n");
++ 		    }
++ 		} /* if "Connect-Mask" */
++ 
+  		else if (0==strncasecomp(fieldname, "delete", 6)) {
+  		    prot->delete_mask = HTAA_parseGroupDef(fp);
+  		    lex_item=LEX_REC_SEP; /*groupdef parser read this already*/
+*** WWW/Daemon/Implementation/HTAAServ.c.orig	Sun Sep 25 06:52:53 1994
+--- WWW/Daemon/Implementation/HTAAServ.c	Mon May 15 21:06:18 1995
+***************
+*** 208,213 ****
+--- 208,215 ----
+  	    mask = prot->post_mask;
+  	else if (!strcmp(method_name, "DELETE"))
+  	    mask = prot->delete_mask;
++ 	else if (!strcmp(method_name, "CONNECT"))
++ 	    mask = prot->connect_mask;
+  	if (!mask)
+  	    mask = prot->gen_mask;
+      }
+*** WWW/Daemon/Implementation/HTRequest.c.orig	Fri Aug 12 03:36:29 1994
+--- WWW/Daemon/Implementation/HTRequest.c	Mon May 15 21:32:44 1995
+***************
+*** 1006,1011 ****
+--- 1006,1028 ----
+      }
+  
+      /*
++      * SSL tunneling -- make host:port appear as connect://host:port
++      * to make it work better with the configuration system.
++      * Ari Luotonen <ari@netscape.com> May 1995
++      */
++     if (req->method == METHOD_CONNECT && HTReqArg) {
++ 	char *tmp = HTReqArg;
++ 	HTReqArg = NULL;
++ 	StrAllocCopy(HTReqArg, "connect://");
++ 	StrAllocCat(HTReqArg, tmp);
++ 	free(tmp);
++ 	if ((tmp = strchr(HTReqArg + 10, ':'))) {
++ 	    for (tmp++; *tmp && isdigit(*tmp); tmp++);
++ 	    *tmp = '\0';
++ 	}
++     }
++ 
++     /*
+      ** Check that the third argument actually is a valid
+      ** client protocol specifier (if it is not we might wait
+      ** for an eternity for the rest of an HTTP1 request when it
+*** WWW/Daemon/Implementation/HTDaemon.c.orig	Mon Sep 26 07:23:00 1994
+--- WWW/Daemon/Implementation/HTDaemon.c	Mon Jun 12 15:58:58 1995
+***************
+*** 65,70 ****
+--- 65,71 ----
+  **			defined via "ServerRoot" in the configuration file.
+  **			Commented out dead extern declarations.
+  **	 8 Jul 94  FM	Insulate free() from _free structure element.
++ **	   May 95  AL   SSL tunneling support
+  */
+  
+  /* (c) CERN WorldWideWeb project 1990-1992. See Copyright.html for details */
+***************
+*** 162,167 ****
+--- 163,173 ----
+  #include <sys/param.h>
+  #include <errno.h>
+  
++ #if !defined(__osf__) && !defined(AIX) && !defined(_HPUX_SOURCE) && \
++     !defined(BSDI) && !defined(__linux)
++ #include <sys/filio.h>
++ #endif
++ 
+  #ifndef SIGCLD
+  #ifdef SIGCHLD
+  #define SIGCLD SIGCHLD
+***************
+*** 376,381 ****
+--- 382,602 ----
+  
+  
+  
++ /*
++  * SSL tunneling support by Ari Luotonen <ari@netscape.com>, May 1995
++  */
++ 
++ 
++ #define SSL_PROXY_BUFSIZE 4096
++ 
++ 
++ int shove_buffer ARGS4(int,	sd,
++ 		       char *,	b,
++ 		       int *,	i,
++ 		       int *,	c)
++ {
++     int n = write(sd, &b[*i], *c);
++ 
++     if (n > 0)
++       {
++ 	  *i += n;
++ 	  *c -= n;
++       }
++     else if (n == -1 && (errno == EWOULDBLOCK || errno == EINTR))
++       {
++ 	  n = 0;
++       }
++ 
++     return n;
++ }
++ 
++ int drag_buffer ARGS4(int,	sd,
++ 		      char *,	b,
++ 		      int *,	i,
++ 		      int *,	c)
++ {
++     int n = read(sd, b, SSL_PROXY_BUFSIZE);
++ 
++     *i = *c = 0;
++ 
++     if (n > 0)
++       {
++ 	  *c = n;
++       }
++     else if (n == -1 && errno != EWOULDBLOCK && errno != EINTR)
++       {
++ 	  return 0;
++       }
++     return n;
++ }
++ 
++ 
++ int ssl_proxy_pump ARGS3(int,		sd1,
++ 			 int,		sd2,
++ 			 char *,	initial)
++ {
++     char b1[SSL_PROXY_BUFSIZE];
++     char b2[SSL_PROXY_BUFSIZE];
++     int i1=0, i2=0;		/* Buffer start index */
++     int c1=0, c2=0;		/* Buffer data counter */
++     int r1=0, r2=0;		/* Socket read ready */
++     int w1=0, w2=0;		/* Socket write ready */
++     int closed1=0, closed2=0;	/* Socket close */
++     int n_fds = ((sd1 > sd2) ? sd1 : sd2) + 1;
++     fd_set rd_fds, wr_fds;
++     int status;
++ 
++     memset(&rd_fds, 0, sizeof(rd_fds));
++     memset(&wr_fds, 0, sizeof(wr_fds));
++ 
++     if (initial && *initial) {
++ 	strcpy(b1, initial);
++ 	c1 = strlen(initial);
++     }
++ 
++     while (1) {
++ 	FD_SET(sd1, &rd_fds);
++ 	FD_SET(sd2, &rd_fds);
++ 	FD_SET(sd1, &wr_fds);
++ 	FD_SET(sd2, &wr_fds);
++ 
++ 	if (!(status = select(n_fds, &rd_fds, &wr_fds, NULL, NULL)))
++ 	  {
++ 	      break;
++ 	  }
++ 	else if (status == -1)
++ 	  {
++ 	      if (errno == EINTR)
++ 		  continue;
++ 	      else
++ 		  break;
++ 	  }
++ 
++ 	r1 = FD_ISSET(sd1, &rd_fds);
++ 	r2 = FD_ISSET(sd2, &rd_fds);
++ 	w1 = FD_ISSET(sd1, &wr_fds);
++ 	w2 = FD_ISSET(sd2, &wr_fds);
++ 
++ 	if (w1 && c1 > 0)
++ 	  {
++ 	      if (shove_buffer(sd1, b1, &i1, &c1) == -1)
++ 		  closed1 = 1;
++ 	  }
++ 	if (w2 && c2 > 0)
++ 	  {
++ 	      if (shove_buffer(sd2, b2, &i2, &c2) == -1)
++ 		    closed2 = 1;
++ 	  }
++ 	if (r1 && !c2)
++ 	  {
++ 	      if (!drag_buffer(sd1, b2, &i2, &c2))
++ 		  closed1 = 1;
++ 	  }
++ 	if (r2 && !c1)
++ 	  {
++ 	      if (!drag_buffer(sd2, b1, &i1, &c1))
++ 		  closed2 = 1;
++ 	  }
++ 
++ 	if (closed1 || closed2)
++ 	  {
++ 	      break;
++ 	  }
++     }
++ 
++     NETCLOSE(sd1);
++     NETCLOSE(sd2);
++ 
++     return 1;
++ }
++ 
++ 
++ BOOL ssl_proxy_get_addr ARGS3(char *,	arg,
++ 			      char **,	host,
++ 			      int *,	port)
++ {
++     char *p;
++ 
++     if (arg && host && port && !strncmp(arg, "connect://", 10)) {
++ 
++ 	*host = NULL;
++ 	StrAllocCopy(*host, arg + 10);
++ 
++ 	if ((p = strchr(*host, ':'))) {
++ 	    *p++ = '\0';
++ 	    if ((*port = atoi(p)) > 0)
++ 		return YES;
++ 	}
++     }
++     return NO;
++ }
++ 
++ 
++ int ssl_proxy_connect ARGS3(HTRequest *,	req,
++ 			    char *,		host,
++ 			    int,		port)
++ {
++     struct sockaddr_in sa;
++     struct hostent *hp;
++     int sd, status, one=1;
++ 
++     memset(&sa, 0, sizeof(sa));
++     sa.sin_family = AF_INET;
++     sa.sin_port = htons(port);
++ 
++     if (isdigit(*host))
++ 	sa.sin_addr.s_addr = inet_addr(host);
++     else if ((hp = gethostbyname(host)))
++ 	memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
++     else {
++ 	HTLoadError(req, 500, "Unable to locate host");
++ 	return -1;
++     }
++ 
++     if ((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
++ 	HTLoadError(req, 500, "Can't create socket");
++ 	return -1;
++     }
++ 
++     if ((status = connect(sd, (struct sockaddr *)&sa, sizeof(sa))) == -1) {
++ 	HTLoadError(req, 500, "Can't connect to host");
++ 	return -1;
++     }
++ 
++     if ((status = ioctl(sd, FIONBIO, &one)) == -1) {
++ 	HTLoadError(req, 500, "Can't make socket non-blocking");
++ 	return -1;
++     }
++ 
++     return sd;
++ }
++ 
++ 
++ 
++ BOOL ssl_proxy_request ARGS2(char *, arg, HTRequest *, req)
++ {
++     char *host = NULL;
++     int port = 0;
++     int sd, one=1;
++ 
++     CTRACE(stderr, "Handling CONNECT %s\n", arg);
++ 
++     if (!ssl_proxy_get_addr(arg, &host, &port)) {
++ 	HTLoadError(req, 400, "Bad CONNECT request address");
++ 	return NO;
++     }
++ 
++     if ((sd = ssl_proxy_connect(req, host, port)) < 0)
++ 	return NO;
++ 
++     if (ioctl(HTSoc, FIONBIO, &one) < -1) {
++ 	HTLoadError(req, 500, "Can't make client socket non-blocking");
++ 	return NO;
++     }
++ 
++     ssl_proxy_pump(HTSoc, sd, "HTTP/1.0 200 Connection established\r\n\r\n");
++     return YES;
++ }
+  
+  
+  #if defined(Mips)
+***************
+*** 1832,1837 ****
+--- 2053,2062 ----
+              }
+              FREE(cfn);
+          }
++ 	else if (req->method==METHOD_CONNECT) {
++ 	    /* SSL tunneling by Ari Luotonen <ari@netscape.com>, May 1995 */
++ 	    ssl_proxy_request(HTReqArg, req);
++ 	}
+          else {
+              /* Normal retrieve with no caching */
+              CTRACE(stderr, "No caching.. %s\n",

>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199806130409.VAA22755>