From nobody  Fri Jun 12 21:09:20 1998
Received: (from nobody@localhost)
          by hub.freebsd.org (8.8.8/8.8.8) id VAA22755;
          Fri, 12 Jun 1998 21:09:20 -0700 (PDT)
          (envelope-from nobody)
Message-Id: <199806130409.VAA22755@hub.freebsd.org>
Date: Fri, 12 Jun 1998 21:09:20 -0700 (PDT)
From: giffunip@asme.org
To: freebsd-gnats-submit@freebsd.org
Subject: Update to the w3c-httpd port
X-Send-Pr-Version: www-1.0

>Number:         6935
>Category:       ports
>Synopsis:       Update to the w3c-httpd port
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jun 12 21:10:01 PDT 1998
>Closed-Date:    Fri Jul 3 16:01:56 PDT 1998
>Last-Modified:  Fri Jul  3 16:02:40 PDT 1998
>Originator:     Pedro F. Giffuni
>Release:        2.2.5-R
>Organization:
U. Nacional de Colombia
>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",

>Release-Note:
>Audit-Trail:

From: asami@FreeBSD.ORG (Satoshi Asami)
To: giffunip@asme.org
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: ports/6935: Update to the w3c-httpd port
Date: Sat, 13 Jun 1998 02:03:49 -0700 (PDT)

  * 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.
 
 Are these patches available on the web?  If so, you can just list them 
 as PATCHFILES (see handbook for details).
 
  * diff -rNu /cdrom/ports/www/w3c-httpd/patches/CacheCheckSize.patch w3c-httpd/patches/CacheCheckSize.patch
 
 Besides, patches not named "patch-*" are going to be ignored by
 bsd.port.mk anyway. :)
 
 Satoshi

From: Pedro Giffuni <giffunip@asme.org>
To: Satoshi Asami <asami@FreeBSD.ORG>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: ports/6935: Update to the w3c-httpd port
Date: Sat, 13 Jun 1998 09:41:43 -0500

 Satoshi Asami wrote:
 
 > Are these patches available on the web?  If so, you can just list them
 > as PATCHFILES (see handbook for details).
 >
 
 They are available, but in different places, and one of them applied to a different directory so I had to edit
 it. Some are compressed and some are not. It was MUCH simpler to add the with the other patches.
 
 >  * diff -rNu /cdrom/ports/www/w3c-httpd/patches/CacheCheckSize.patch w3c-httpd/patches/CacheCheckSize.patch
 > Besides, patches not named "patch-*" are going to be ignored by
 > bsd.port.mk anyway. :)
 >
 
 Ugh....I wanted to have them clearly labelled so the new port maintainer will identify them clearly.  You're
 right, I thought the patches had been applied because the original package comes with some confusing *.orig
 files :(.
 
 Please close the PR, I have to rename the patches and check that at least the basic stuff still works.
 
     Pedro.
 
State-Changed-From-To: open->closed 
State-Changed-By: steve 
State-Changed-When: Sat Jun 13 11:26:06 PDT 1998 
State-Changed-Why:  
Closed at originator's request. 
State-Changed-From-To: closed->feedback 
State-Changed-By: asami 
State-Changed-When: Sun Jun 14 17:54:36 PDT 1998 
State-Changed-Why:  
New version can be submitted as a followup to this one. 

From: asami@FreeBSD.ORG (Satoshi Asami)
To: giffunip@asme.org
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: ports/6935: Update to the w3c-httpd port
Date: Sun, 14 Jun 1998 17:57:28 -0700 (PDT)

  * They are available, but in different places, and one of them
  * applied to a different directory so I had to edit it. Some are
  * compressed and some are not. It was MUCH simpler to add the with
  * the other patches.
 
 Then, the only one that needs to be added is the one in a different
 directory.  You can list multiple PATCH_SITES so they will all be
 grabbed.  The decompression is handled on a per-file basis so it's not
 a problem to have compressed and uncompressed patchfiles.
 
 Given the above, I do not agree to put whole patchfiles (which are all
 quite large) in the repository.  We are going to have the repository
 size explode if people start doing this when PATCHFILES can clearly
 handle them. :)
 
  * Please close the PR, I have to rename the patches and check that at
  * least the basic stuff still works.
 
 There's really no need to close the PR, you can just send the new
 version as an update to this PR (just like this message was).  I put
 the PR in the "feebdack" state.
 
 Satoshi
State-Changed-From-To: feedback->closed 
State-Changed-By: steve 
State-Changed-When: Fri Jul 3 16:01:56 PDT 1998 
State-Changed-Why:  
Patches were supplied in another PR (6945) which I will commit 
shortly. 
>Unformatted:
