Since W3C has discontinued the maintenance of httpd the IFCTF has had to take
over.  We distribute our changes as patches against w3c-httpd-3.0A.tar.Z, W3C's
last version.  All our patches are contained in this file, which should be
applied with patch -p0 in the WWW directory where W3C's tarball is exploded.
(patch will skip over this text.)

Our changes were:

* Builds for pure BSD UNIX (4.3BSD).  WWW_MACH is 4.3bsd.  To build, change the
  all: target in the top-level Makefile to:

all :
	(cd All/Implementation; make WWW_MACH=4.3bsd)

* Axed getdomainname() from HTGetHostName, we want to have nothing to do with
  Sun's NIS abomination, not to mention that not everyone runs SonOS and pure
  BSD doesn't have getdomainname().

* Y2K fixes.  Credit goes to AT&T for their Y2K patch, although I did it a bit
  differently.  Also get rid of mktime and the kludge to convert it to GMT, and
  do it all ourselves 100% in GMT from start to finish.

* Incorporated security fix DFN-CERT#34784 in cgiparse.

* Added ForceDirSlash option to the config file to force all requests for dir
  to be redirected to dir/ regardless of the existence of a welcome page.

* When FTP directories are HTML-ized (by the proxy) the FTP server's date
  strings are shown as they are instead of trying to turn them into seconds
  from epoch then back to dates (an exercise in futility without second-
  precision date/time spec and without knowing the remote timezone).

* In HTML-ized directories (UNIX or FTP) links to subdirectories end in
  trailing slash.

* Pitch the silly SIGTERM handler that sent itself a SIGKILL followed by code
  that never executed as a result. No SIGTERM handler at all is better than
  that.

* In htadm (on UNIX) use link rather than rename to save old passwd file to
  eliminate window of no passwd file at all.

diff /dev/null All/4.3bsd/Makefile.include
*** /dev/null	Thu Jul 10 02:00:02 2003
--- All/4.3bsd/Makefile.include	Tue Jul  1 18:53:07 2003
***************
*** 0 ****
--- 1,40 ----
+ #  Make WWW under unix for a.n.other unix system (bsd)
+ 
+ # For W3 distribution, machine type for subdirectories
+ WWW_MACH = 4.3bsd
+ 
+ # The ASIS repository's name for the machine we are on
+ ASIS_MACH = vax/4.3bsd
+ 
+ 
+ CFLAGS =  -O -D__BSD__ -DPURE_BSD
+ LFLAGS =
+ CC = cc
+ 
+ # Directory for installed binary:
+ BINDIR = /usr/local
+ 
+ # Where is the W3 object library to be installed (not normally done)?
+ LIBDIR = $(WWW)/Library/Implementation/$(WWW_MACH)
+ 
+ #_________________ OK if normal W3 distribution
+ # Where is the WWW source root?
+ WWW = ../..
+ 
+ #  Where should temporary (object) files go?
+ WTMP = ../..
+ 
+ 
+ 
+ #
+ #	WHEN COMPILING WITH DIRECT WAIS SUPPORT:
+ #
+ #	Uncomment these six lines (and edit them, if necessary).
+ #
+ # WAIS = ../../../freeWAIS
+ # WAISLIB =  $(WAIS)/bin/client.a $(WAIS)/bin/wais.a
+ # MATHLIB = -lm
+ # WAISINC = -I$(WAIS)/include
+ # WAISCFLAGS = -DHT_DIRECT_WAIS
+ # HTWAIS = $(WTMP)/Library/$(WWW_MACH)/HTWAIS.o
+ 
diff -ca Library/Impl.orig/HTBTree.c Library/Implementation/HTBTree.c
*** Library/Impl.orig/HTBTree.c	Wed Apr 27 01:34:05 1994
--- Library/Implementation/HTBTree.c	Tue Jul  1 18:41:31 2003
***************
*** 9,15 ****
--- 9,17 ----
  
  #include "HTUtils.h"
  #include "HTBTree.h"
+ #ifndef PURE_BSD
  #include <stdlib.h>
+ #endif
  #include <string.h>
  
  #define MAXIMUM(a,b) ((a)>(b)?(a):(b))
diff -ca Library/Impl.orig/HTDirBrw.c Library/Implementation/HTDirBrw.c
*** Library/Impl.orig/HTDirBrw.c	Sun Sep 25 06:53:22 1994
--- Library/Implementation/HTDirBrw.c	Thu Jul 10 10:48:31 2003
***************
*** 9,14 ****
--- 9,15 ----
  ** Authors:
  **		HF	Henrik Frystyk, CERN, <frystyk@dxcern.cern.ch>
  **		AL	Ari Luotonen, CERN, <luotonen@www.cern.ch>
+ **		MS	Michael Sokolov <msokolov@ivan.Harhan.ORG>
  ** History:
  **	   Mar 94  HF	Written by Henrik Frystyk, frystyk@dxcern.cern.ch,
  **			but with some of the Directory stuff brought from
***************
*** 18,23 ****
--- 19,31 ----
  **	   Jul 94  FM	Compile substitute strftime() for VMS && !DECC (and
  **			use sys$share:vaxcrtl/share in .opt file for linking).
  **			Insulate free() from _free structure element.
+ **	 1 Jul 03  MS	Don't try to turn FTP dates back into seconds from
+ **			epoch (an exercise in futility without second-precision
+ **			date/time spec and without knowing the remote timezone)
+ **			and instead using the FTP server's date strings as they
+ **			are.
+ **	 1 Jul 03  MS	Fix support for sans-strftime systems.
+ **	10 Jul 03  MS	Links to subdirectories end in trailing slash.
  ** BUGS:
  **
  */
***************
*** 284,290 ****
      FREE(file_info->f_uid);
      FREE(file_info->f_gid);
      file_info->f_size = 0L;
!     file_info->f_mtime = (time_t) 0;
  }
  
  
--- 292,298 ----
      FREE(file_info->f_uid);
      FREE(file_info->f_gid);
      file_info->f_size = 0L;
!     FREE(file_info->f_mtime);
  }
  
  
***************
*** 622,627 ****
--- 630,637 ----
  	escaped = HTEscape(nkey->filename, URL_XPALPHAS);
  	*(tail+tailend) = '\0';
  	StrAllocCat(tail, escaped);
+ 	if (nkey->is_dir)
+ 	    StrAllocCat(tail, "/");
  
  	if (TRACE) fprintf(stderr, "OutList: %s\n", tail);
  	if (HTDirShowMask & HT_DIR_ICON_ANCHOR  &&
***************
*** 984,995 ****
  		bodyptr = nodekey->body;
  		memset((void *) bodyptr, ' ', HTBodyLength);
  		if (HTDirShowMask & HT_DIR_SHOW_DATE) {
! #if defined(Mips) || (defined(VMS) && !defined(DECC))
  		    struct tm * t = localtime(&file_info.st_mtime);
  
  		    sprintf(bodyptr,"%02d-%s-%02d %02d:%02d",
  			    t->tm_mday,
! 			    months[t->tm_mon],
  			    t->tm_year % 100,
  			    t->tm_hour,
  			    t->tm_min);
--- 994,1006 ----
  		bodyptr = nodekey->body;
  		memset((void *) bodyptr, ' ', HTBodyLength);
  		if (HTDirShowMask & HT_DIR_SHOW_DATE) {
! #if defined(PURE_BSD) || defined(Mips) || (defined(VMS) && !defined(DECC))
  		    struct tm * t = localtime(&file_info.st_mtime);
+ 		    extern char *month_names[];
  
  		    sprintf(bodyptr,"%02d-%s-%02d %02d:%02d",
  			    t->tm_mday,
! 			    month_names[t->tm_mon],
  			    t->tm_year % 100,
  			    t->tm_hour,
  			    t->tm_min);
***************
*** 996,1002 ****
  #else
  		    strftime(bodyptr, HT_LENGTH_DATE+1, "%d-%b-%y %H:%M",
  			     localtime(&file_info.st_mtime));
! #endif /* Mips || (VMS && !DECC) */
  		    bodyptr += HT_LENGTH_DATE;
  		    *bodyptr = ' ';
  		    bodyptr += HT_LENGTH_SPACE;
--- 1007,1013 ----
  #else
  		    strftime(bodyptr, HT_LENGTH_DATE+1, "%d-%b-%y %H:%M",
  			     localtime(&file_info.st_mtime));
! #endif /* PURE_BSD || Mips || (VMS && !DECC) */
  		    bodyptr += HT_LENGTH_DATE;
  		    *bodyptr = ' ';
  		    bodyptr += HT_LENGTH_SPACE;
***************
*** 1254,1276 ****
  		bodyptr = nodekey->body;
  		memset((void *) bodyptr, ' ', HTBodyLength);
  		if (HTDirShowMask & HT_DIR_SHOW_DATE) {
! 		    if (file_info.f_mtime) {
! #if defined(Mips) || (defined(VMS) && !defined(DECC))
! 			struct tm * t = localtime(&file_info.f_mtime);
! 
! 			sprintf(bodyptr,"%02d-%s-%02d %02d:%02d",
! 				t->tm_mday,
! 				months[t->tm_mon],
! 				t->tm_year % 100,
! 				t->tm_hour,
! 				t->tm_min);
! #else
! 			strftime(bodyptr, HT_LENGTH_DATE+1, "%d-%b-%y %H:%M",
! 				 localtime(&file_info.f_mtime));
! #endif /* Mips || (VMS && !DECC) */
! 		    } else {
  			*bodyptr = '-';
- 		    }
                      bodyptr += HT_LENGTH_DATE;
                      *bodyptr = ' ';
                      bodyptr += HT_LENGTH_SPACE;
--- 1265,1275 ----
  		bodyptr = nodekey->body;
  		memset((void *) bodyptr, ' ', HTBodyLength);
  		if (HTDirShowMask & HT_DIR_SHOW_DATE) {
! 		    if (file_info.f_mtime)
! 			strncpy(bodyptr, file_info.f_mtime,
! 				strlen(file_info.f_mtime));
! 		    else
  			*bodyptr = '-';
                      bodyptr += HT_LENGTH_DATE;
                      *bodyptr = ' ';
                      bodyptr += HT_LENGTH_SPACE;
diff -ca Library/Impl.orig/HTDirBrw.h Library/Implementation/HTDirBrw.h
*** Library/Impl.orig/HTDirBrw.h	Sun Sep 25 07:15:35 1994
--- Library/Implementation/HTDirBrw.h	Tue Jul  1 23:04:34 2003
***************
*** 130,136 ****
      char *              f_uid;
      char *              f_gid;
      unsigned long       f_size;
!     time_t              f_mtime;
  } dir_file_info;
  /*
  
--- 130,136 ----
      char *              f_uid;
      char *              f_gid;
      unsigned long       f_size;
!     char *              f_mtime;
  } dir_file_info;
  /*
  
diff -ca Library/Impl.orig/HTError.c Library/Implementation/HTError.c
*** Library/Impl.orig/HTError.c	Sun Jun  2 16:06:52 1996
--- Library/Implementation/HTError.c	Tue Jul  1 19:27:06 2003
***************
*** 286,292 ****
  /*
  **	Find a URL for this error code
  */
! PUBLIC char * HTError_findUrl (int code)
  {
      int cnt;
      char * filename = NULL;
--- 286,292 ----
  /*
  **	Find a URL for this error code
  */
! PUBLIC char * HTError_findUrl ARGS1(int, code)
  {
      int cnt;
      char * filename = NULL;
***************
*** 303,309 ****
      return filename;
  }
  
! PUBLIC BOOL HTError_addUrl (int code, CONST char * url)
  {
      if (url) {
  	int cnt;
--- 303,309 ----
      return filename;
  }
  
! PUBLIC BOOL HTError_addUrl ARGS2(int, code, CONST char *, url)
  {
      if (url) {
  	int cnt;
***************
*** 320,326 ****
      return NO;
  }
  
! PUBLIC BOOL HTError_deleteUrl (int code)
  {
      int cnt;
      for (cnt=0; cnt < HTERR_ELEMENTS; cnt++) {
--- 320,326 ----
      return NO;
  }
  
! PUBLIC BOOL HTError_deleteUrl ARGS1(int, code)
  {
      int cnt;
      for (cnt=0; cnt < HTERR_ELEMENTS; cnt++) {
diff -ca Library/Impl.orig/HTError.h Library/Implementation/HTError.h
*** Library/Impl.orig/HTError.h	Sun Jun  2 15:32:36 1996
--- Library/Implementation/HTError.h	Tue Jul  1 16:00:24 2003
***************
*** 194,202 ****
    Find an Error URL
    
   */
! extern char * HTError_findUrl (int code);
! extern BOOL HTError_addUrl (int code, CONST char * url);
! extern BOOL HTError_deleteUrl (int code);
  /*
  
    Freeing an Error List
--- 194,202 ----
    Find an Error URL
    
   */
! extern char * HTError_findUrl PARAMS((int code));
! extern BOOL HTError_addUrl PARAMS((int code, CONST char * url));
! extern BOOL HTError_deleteUrl PARAMS((int code));
  /*
  
    Freeing an Error List
diff -ca Library/Impl.orig/HTFTP.c Library/Implementation/HTFTP.c
*** Library/Impl.orig/HTFTP.c	Sun Sep 25 06:53:25 1994
--- Library/Implementation/HTFTP.c	Thu Jul 10 10:22:42 2003
***************
*** 24,29 ****
--- 24,30 ----
  **      FM      Foteos Macrides <macrides@sci.wfeb.edu>
  **	HF	Henrik Frystyk <frystyk@dxcern.cern.ch>
  **	AL	Ari Luotonen <luotonen@www.cern.ch>
+ **	MS	Michael Sokolov <msokolov@ivan.Harhan.ORG>
  **
  ** History:
  **	 2 May 91	Written TBL, as a part of the WorldWideWeb project.
***************
*** 46,51 ****
--- 47,57 ----
  **	 2 May 94 (AL)	Fixed possible security hole when the URL contains
  **			a newline, that could cause multiple commands to be
  **			sent to an FTP server.
+ **	 1 Jul 03 (MS)	Don't try to turn FTP dates back into seconds from
+ **			epoch (an exercise in futility without second-precision
+ **			date/time spec and without knowing the remote timezone)
+ **			and instead using the FTP server's date strings as they
+ **			are.
  **
  ** Options:
  **	LISTEN		The default way to open a dats connection is by using
***************
*** 378,521 ****
  } /* is_ls_date() */
  #endif
  
- /*								HTStrpMonth()
- **
- **	Returns the number of the month given or -1 on error.
- **
- **	BUG: Handles US dates only!!!
- */
- PRIVATE int HTStrpMonth ARGS1(char *, month)
- {
-     int ret;
-     if (!strncmp(month, "JAN", 3))
- 	ret = 0;
-     else if (!strncmp(month, "FEB", 3))
- 	ret = 1;
-     else if (!strncmp(month, "MAR", 3))
- 	ret = 2;
-     else if (!strncmp(month, "APR", 3))
- 	ret = 3;
-     else if (!strncmp(month, "MAY", 3))
- 	ret = 4;
-     else if (!strncmp(month, "JUN", 3))
- 	ret = 5;
-     else if (!strncmp(month, "JUL", 3))
- 	ret = 6;
-     else if (!strncmp(month, "AUG", 3))
- 	ret = 7;
-     else if (!strncmp(month, "SEP", 3))
- 	ret = 8;
-     else if (!strncmp(month, "OCT", 3))
- 	ret = 9;
-     else if (!strncmp(month, "NOV", 3))
- 	ret = 10;
-     else if (!strncmp(month, "DEC", 3))
- 	ret = 11;
-     else {
- 	ret = -1;
- 	if (PROT_TRACE)
- 	    fprintf(stderr, "HTStrpMonth. Couldn't resolve date.\n");
-     }
-     return ret;
- }
  
- 
- /*								HTStrpTime()
- **
- **	Converts a date string from 'ls -l' to a time_t number
- **	This is needed in order to put out the date using the same format
- **	for all directory listings.
- **
- **	Returns 0 on error.
- */
- PRIVATE time_t HTStrpTime ARGS1(char *, datestr)
- {
-     struct tm *time_info;		    /* Points to static tm structure */
-     char *bcol = datestr;			             /* Column begin */
-     char *ecol;						       /* Column end */
-     long tval;
-     int cnt;
-     time_t curtime = time(NULL);
-     if ((time_info = gmtime(&curtime)) == NULL) {
- 	if (PROT_TRACE)
- 	    fprintf(stderr, "HTStrpTime.. Can't get current time.\n");
- 	return (time_t) 0;
-     }
-     time_info->tm_isdst = -1;			      /* Disable summer time */
-     for (cnt=0; cnt<3; cnt++)
-     {					    /* Month */
- 	*bcol = toupper(*bcol);
-         bcol++;
-     }
-     if ((time_info->tm_mon = HTStrpMonth(datestr)) < 0)
- 	return (time_t) 0;
-     ecol = bcol;		   			       	      /* Day */
-     while (*ecol++ == ' ');		       /* Spool to other side of day */
-     while (*ecol++ != ' ');
-     *--ecol = '\0';
-     time_info->tm_mday = atoi(bcol);
-     time_info->tm_wday = 0;
-     time_info->tm_yday = 0;
-     bcol = ++ecol;				             	     /* Year */
-     if ((ecol = strchr(bcol, ':')) == NULL) {
- 	time_info->tm_year = atoi(bcol)-1900;
- 	time_info->tm_sec = 0;
- 	time_info->tm_min = 0;
- 	time_info->tm_hour = 0;
-     } else {							     /* Time */
- 	/* If the time is given as hh:mm, then the file is less than 1 year
- 	   old, but we might shift calandar year. This is avoided by checking 
- 	   if the date parsed is future or not. */
- 	*ecol = '\0';
- 	time_info->tm_sec = 0;
- 	time_info->tm_min = atoi(++ecol);	       	/* Right side of ':' */
- 	time_info->tm_hour = atoi(bcol);		 /* Left side of ':' */
- 	if (mktime(time_info) > curtime)
- 	    --time_info->tm_year;
-     }
-     return ((tval = mktime(time_info)) == -1 ? (time_t) 0 : tval); 
- }
- 
- 
- /*								HTVMSStrpTime()
- **
- **	Converts a date string from vms to a time_t number
- **	This is needed in order to put out the date using the same format
- **	for all directory listings.
- **
- **	Returns 0 on error
- */
- PRIVATE time_t HTVMSStrpTime ARGS1(char *, datestr)
- {
-     struct tm *time_info;		    /* Points to static tm structure */
-     char *col;
-     long tval;
-     time_t curtime = time(NULL);
-     if ((time_info = gmtime(&curtime)) == NULL)
- 	return (time_t) 0;
-     time_info->tm_isdst = -1;			      /* Disable summer time */
-     if ((col = strtok(datestr, "-")) == NULL)
- 	return (time_t) 0;
-     time_info->tm_mday = atoi(col);				      /* Day */
-     time_info->tm_wday = 0;
-     time_info->tm_yday = 0;
-     if ((col = strtok(NULL, "-")) == NULL ||
- 	(time_info->tm_mon = HTStrpMonth(col)) < 0)
- 	return (time_t) 0;
-     if ((col = strtok(NULL, " ")) == NULL)			     /* Year */
- 	return (time_t) 0;
-     time_info->tm_year = atoi(col)-1900;
-     if ((col = strtok(NULL, ":")) == NULL)			     /* Hour */
- 	return (time_t) 0;
-     time_info->tm_hour = atoi(col);
-     if ((col = strtok(NULL, " ")) == NULL)			     /* Mins */
- 	return (time_t) 0;
-     time_info->tm_min = atoi(col);
-     time_info->tm_sec = 0;
-     return ((tval = mktime(time_info)) < 0 ? (time_t) 0 : tval);
- }
- 
- 
  /*								HTFTPFilePerm()
  **
  **	Converts the file type from 'ls -l' into a long. The reason for
--- 384,390 ----
***************
*** 622,629 ****
      while (*column++ == ' ');
      strptr = --column+12;		      	     /* Find the date column */
      *strptr++ = '\0';
!     if ((f_info->f_mtime = HTStrpTime(column)) == (time_t) 0)
! 	return NO;
      while (*strptr++ == ' ');			        /* Spool to filename */
      if ((f_info->f_mode & S_IFMT) == S_IFLNK) {        /* Strip any '->' */
  	char *link = strstr(strptr-1, " -> ");
--- 491,497 ----
      while (*column++ == ' ');
      strptr = --column+12;		      	     /* Find the date column */
      *strptr++ = '\0';
!     StrAllocCopy(f_info->f_mtime, column);
      while (*strptr++ == ' ');			        /* Spool to filename */
      if ((f_info->f_mode & S_IFMT) == S_IFLNK) {        /* Strip any '->' */
  	char *link = strstr(strptr-1, " -> ");
***************
*** 648,653 ****
--- 516,522 ----
  {
      int i, j, ialloc;
      char *cp, *cpd, *cps, *cdir, *sp = " ";
+     char datebuf[16];
      
      /**  Get rid of information lines by making them blank too **/
      /**  Valid lines have the semi-colon version number token  **/
***************
*** 693,702 ****
      
      /** Track down the date **/
      if ((cpd=strchr(cp, '-')) != NULL) {
! 	if ((int)strlen(cpd) > 9 && isdigit(*(cpd-1)) &&
! 	    isalpha(*(cpd+1)) && *(cpd+4) == '-') {
! 	    if ((f_info->f_mtime = HTVMSStrpTime(cpd-2)) == (time_t) 0)
! 		return NO;
  	}
      }
      
--- 562,574 ----
      
      /** Track down the date **/
      if ((cpd=strchr(cp, '-')) != NULL) {
! 	if ((int)strlen(cpd) >= 15 && isdigit(cpd[-1]) && isalpha(cpd[1]) &&
! 	    cpd[4] == '-' && isdigit(cpd[5]) && isdigit(cpd[7]) &&
! 	    cpd[9] == ' ' && isdigit(cpd[10]) && cpd[12] == ':' &&
! 	    isdigit(cpd[13])) {
! 		strncpy(datebuf, cpd - 2, 7);
! 		strncpy(datebuf + 7, cpd + 7, 8);
! 		StrAllocCopy(f_info->f_mtime, datebuf);
  	}
      }
      
diff -ca Library/Impl.orig/HTString.c Library/Implementation/HTString.c
*** Library/Impl.orig/HTString.c	Sun Sep 25 06:53:36 1994
--- Library/Implementation/HTString.c	Thu Jul 10 10:28:39 2003
***************
*** 5,10 ****
--- 5,11 ----
  **	02-Dec-91 (JFG) Added stralloccopy and stralloccat
  **	23 Jan 92 (TBL) Changed strallocc* to 8 char HTSAC* for VM and suchlike
  **	 6 Oct 92 (TBL) Moved WWW_TraceFlag in here to be in library
+ **	 1 Jul 03 (MS)  Provide strstr and strtol for PURE_BSD
  */
  
  #include "tcp.h"
***************
*** 57,63 ****
--- 58,96 ----
  }
  #endif
  
+ #ifdef PURE_BSD
+ /* must provide our own strstr */
+ PUBLIC char * strstr ARGS2(char *,	s1,
+ 			   char *,	s2)
+ {
+     char * try = s1;
  
+     if (!s1 || !s2 || !*s2) return s1;
+ 
+     while (*try) {
+ 	if (*try == *s2) {
+ 	    char * cur1 = try + 1;
+ 	    char * cur2 = s2 + 1;
+ 	    while (*cur1 && *cur2 && *cur1 == *cur2) {
+ 		cur1++;
+ 		cur2++;
+ 	    }
+ 	    if (!*cur2) {
+ 		CTRACE(stderr,
+ 	      "Debug....... strcasestr(s1 = \"%s\", s2 = \"%s\") => \"%s\"\n",
+ 		       s1,s2,try);
+ 		return try;
+ 	    }
+ 	}
+ 	try++;
+     }
+     CTRACE(stderr,
+ 	   "Debug....... strcasestr(s1 = \"%s\", s2 = \"%s\") => No match\n",
+ 	   s1,s2);
+     return NULL;
+ }
+ #endif
+ 
  /*
   * strcasestr(s1,s2) -- like strstr(s1,s2) but case-insensitive.
   */
***************
*** 91,97 ****
--- 124,213 ----
      return NULL;
  }
  
+ #ifdef PURE_BSD
+ /* must provide our own strtol */
+ /* borrowed from 4.4BSD */
+ long
+ strtol(nptr, endptr, base)
+ 	char *nptr;
+ 	char **endptr;
+ 	register int base;
+ {
+ 	register char *s = nptr;
+ 	register unsigned long acc;
+ 	register int c;
+ 	register unsigned long cutoff;
+ 	register int neg = 0, any, cutlim;
  
+ 	/*
+ 	 * Skip white space and pick up leading +/- sign if any.
+ 	 * If base is 0, allow 0x for hex and 0 for octal, else
+ 	 * assume decimal; if base is already 16, allow 0x.
+ 	 */
+ 	do {
+ 		c = *s++;
+ 	} while (isspace(c));
+ 	if (c == '-') {
+ 		neg = 1;
+ 		c = *s++;
+ 	} else if (c == '+')
+ 		c = *s++;
+ 	if ((base == 0 || base == 16) &&
+ 	    c == '0' && (*s == 'x' || *s == 'X')) {
+ 		c = s[1];
+ 		s += 2;
+ 		base = 16;
+ 	}
+ 	if (base == 0)
+ 		base = c == '0' ? 8 : 10;
+ 
+ 	/*
+ 	 * Compute the cutoff value between legal numbers and illegal
+ 	 * numbers.  That is the largest legal value, divided by the
+ 	 * base.  An input number that is greater than this value, if
+ 	 * followed by a legal input character, is too big.  One that
+ 	 * is equal to this value may be valid or not; the limit
+ 	 * between valid and invalid numbers is then based on the last
+ 	 * digit.  For instance, if the range for longs is
+ 	 * [-2147483648..2147483647] and the input base is 10,
+ 	 * cutoff will be set to 214748364 and cutlim to either
+ 	 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ 	 * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ 	 * the number is too big, and we will return a range error.
+ 	 *
+ 	 * Set any if any `digits' consumed; make it negative to indicate
+ 	 * overflow.
+ 	 */
+ 	cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+ 	cutlim = cutoff % (unsigned long)base;
+ 	cutoff /= (unsigned long)base;
+ 	for (acc = 0, any = 0;; c = *s++) {
+ 		if (isdigit(c))
+ 			c -= '0';
+ 		else if (isalpha(c))
+ 			c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ 		else
+ 			break;
+ 		if (c >= base)
+ 			break;
+ 		if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+ 			any = -1;
+ 		else {
+ 			any = 1;
+ 			acc *= base;
+ 			acc += c;
+ 		}
+ 	}
+ 	if (any < 0) {
+ 		acc = neg ? LONG_MIN : LONG_MAX;
+ 		errno = ERANGE;
+ 	} else if (neg)
+ 		acc = -acc;
+ 	if (endptr != 0)
+ 		*endptr = (char *)(any ? s - 1 : nptr);
+ 	return (acc);
+ }
+ #endif
  
  /*	Allocate a new copy of a string, and returns it
  */
diff -ca Library/Impl.orig/HTTCP.c Library/Implementation/HTTCP.c
*** Library/Impl.orig/HTTCP.c	Fri Jun 21 08:47:26 1996
--- Library/Implementation/HTTCP.c	Thu Jul 10 10:35:06 2003
***************
*** 10,15 ****
--- 10,19 ----
  **	31 May 94  HF	Added cache on host id's; now use inet_ntoa() to
  **			HTInetString and some other fixes. Added HTDoConnect
  **			and HTDoAccept
+ **	 1 Jul 03  MS	Axe getdomainname() from HTGetHostName, we want to have
+ **			nothing to do with Sun's NIS abomination, not to
+ **			mention that not everyone runs SonOS and pure BSD
+ **			doesn't have getdomainname().
  */
  
  #ifndef VMS
***************
*** 741,752 ****
  **	1) gethostname()
  **	2) if the hostname doesn't contain any '.' try to read
  **	   /etc/resolv.conf. If there is no domain line in this file then
! **	3) Try getdomainname and do as the man pages say for resolv.conf (sun)
! **		If there is no domain line in this file, then it is derived
! **		from the domain name set by the domainname(1) command, usually
! **		by removing the first component. For example, if the domain-
! **		name is set to ``foo.podunk.edu'' then the default domain name
! **		used will be ``pudunk.edu''.
  **
  **	This is the same procedure as used by res_init() and sendmail.
  **
--- 745,751 ----
  **	1) gethostname()
  **	2) if the hostname doesn't contain any '.' try to read
  **	   /etc/resolv.conf. If there is no domain line in this file then
! **	3) Look for domain line in resolv.conf.
  **
  **	This is the same procedure as used by res_init() and sendmail.
  **
***************
*** 796,820 ****
  	    }
  	}
  	fclose(fp);
-     }
- 
-     /* If everything else has failed then try getdomainname */
-     if (fqdn==1) {
- 	if (getdomainname(name, MAXHOSTNAMELEN)) {
- 	    if (PROT_TRACE)
- 		fprintf(stderr, "HostName.... Can't get domain name\n");
- 	    StrAllocCopy(hostname, "");
- 	    return NULL;
- 	}
- 
- 	/* If the host name and the first part of the domain name are different
- 	   then use the former as it is more exact (I guess) */
- 	if (strncmp(name, hostname, (int) strlen(hostname))) {
- 	    char *domain = strchr(name, '.');
- 	    if (!domain)
- 		domain = name;
- 	    StrAllocCat(hostname, domain);
- 	}
      }
  #endif /* not VMS */
  
--- 795,800 ----
diff -ca Library/Impl.orig/HTUtils.h Library/Implementation/HTUtils.h
*** Library/Impl.orig/HTUtils.h	Sun Sep 25 07:15:29 1994
--- Library/Implementation/HTUtils.h	Tue Jul  1 22:13:16 2003
***************
*** 101,111 ****
     VAXC (but not DECC) on VMS. This makes a big performance difference. (Foteos Macrides).
     
   */
- #ifdef vax
- #ifdef unix
- #define ultrix  /* Assume vax+unix=ultrix */
- #endif
- #endif
  
  #ifndef VMS
  #ifndef ultrix
--- 101,106 ----
***************
*** 112,124 ****
  #ifdef NeXT
  #include <libc.h>       /* NeXT */
  #endif
! #ifndef Mips
  #ifndef MACH /* Vincent.Cate@furmint.nectar.cs.cmu.edu */
  #include <stdlib.h>     /* ANSI */
  #endif
! #else /* Mips */
  #define S_ISDIR(m)      (((m)&S_IFMT) == S_IFDIR)
  #define S_ISREG(m)      (((m)&S_IFMT) == S_IFREG)
  #endif /* Mips */
  #else /* ultrix */
  #include <malloc.h>
--- 107,126 ----
  #ifdef NeXT
  #include <libc.h>       /* NeXT */
  #endif
! #if !defined(Mips) && !defined(PURE_BSD)
  #ifndef MACH /* Vincent.Cate@furmint.nectar.cs.cmu.edu */
  #include <stdlib.h>     /* ANSI */
  #endif
! #else /* Mips or pure BSD */
! #ifndef S_ISDIR
  #define S_ISDIR(m)      (((m)&S_IFMT) == S_IFDIR)
+ #endif
+ #ifndef S_ISREG
  #define S_ISREG(m)      (((m)&S_IFMT) == S_IFREG)
+ #endif
+ #ifdef PURE_BSD
+ #define	remove	unlink
+ #endif
  #endif /* Mips */
  #else /* ultrix */
  #include <malloc.h>
***************
*** 125,130 ****
--- 127,135 ----
  #include <memory.h>
  #include <stdio.h>
  #include <stdlib.h>   /* ANSI */   /* BSN */
+ #endif
+ #ifdef PURE_BSD
+ extern char *malloc(), *calloc(), *realloc();
  #endif
  
  #else   /* VMS */
diff -ca Library/Impl.orig/HTWriter.c Library/Implementation/HTWriter.c
*** Library/Impl.orig/HTWriter.c	Mon Jul 15 13:11:16 1996
--- Library/Implementation/HTWriter.c	Tue Jul  1 23:40:37 2003
***************
*** 57,64 ****
            }
            else {
                if(TRACE) fprintf(stderr,
!               "HTWrite: Error: write() on socket returns %d (errno %d -- ``%s''!!!\n",
!                                 status, errno, strerror(errno));
                return;
            }
  	}
--- 57,64 ----
            }
            else {
                if(TRACE) fprintf(stderr,
!               "HTWrite: Error: write() on socket returns %d (errno %d)\n",
!                                 status, errno);
                return;
            }
  	}
***************
*** 130,137 ****
            }
            else {
                if(TRACE) fprintf(stderr,
!               "HTWriter_write: Error on socket output stream!!! (errno %d -- ``%s''\n",
!                                 errno, strerror(errno));
                return;
            }
  	}
--- 130,137 ----
            }
            else {
                if(TRACE) fprintf(stderr,
!               "HTWriter_write: Error on socket output stream!!! (errno %d)\n",
!                                 errno);
                return;
            }
  	}
diff -ca Library/Impl.orig/Version.make Library/Implementation/Version.make
*** Library/Impl.orig/Version.make	Sun Sep 25 06:53:46 1994
--- Library/Implementation/Version.make	Thu Jul 10 10:52:53 2003
***************
*** 1 ****
! VC = 2.17
--- 1 ----
! VC = 2.17-IFCTF
diff -ca Library/Impl.orig/tcp.h Library/Implementation/tcp.h
*** Library/Impl.orig/tcp.h	Sun Sep 25 07:15:30 1994
--- Library/Implementation/tcp.h	Thu Jul 10 10:40:03 2003
***************
*** 19,24 ****
--- 19,26 ----
    SCW                     Susan C. Weber <sweber@kyle.eitech.com>
                           
    HF                      Henrik Frystyk, <frystyk@dxcern.cern.ch>
+ 
+   MS			  Michael Sokolov <msokolov@ivan.Harhan.ORG>
                           
    HISTORY:
    
***************
*** 31,36 ****
--- 33,40 ----
    29 Apr 93               Windows/NT code from (SCW)
                           
    29 Sep 93               VMS fixes (MD)
+ 
+    1 Jul 03		  Restore to pure BSD traditions (MS)
                           
   */
  
***************
*** 203,212 ****
  #define VM
  #endif
  
- #ifdef NEWLIB
- #pragma linkage(newlib,OS)      /* Enables recursive NEWLIB */
- #endif
- 
  /*      VM doesn't have a built-in predefined token, so we cheat: */
  #ifndef VM
  #include <string.h>             /* For bzero etc - not  VM */
--- 207,212 ----
***************
*** 707,716 ****
--- 707,740 ----
  #include <string.h>
  
  #include <errno.h>          /* independent */
+ #ifdef PURE_BSD
+ extern int errno;
+ typedef int mode_t;
+ #endif
  #include <sys/time.h>       /* independent */
  #include <sys/stat.h>
  #include <sys/param.h>
  #include <sys/file.h>       /* For open() etc */
+ #ifndef S_ISCHR
+ #define S_ISCHR(m)      (m & S_IFCHR)
+ #endif
+ #ifndef S_ISBLK
+ #define S_ISBLK(m)      (m & S_IFBLK)
+ #endif
+ #ifndef S_IRWXU
+ #define S_IRWXU 0000700
+ #define S_IRWXG 0000070
+ #define S_IRWXO 0000007
+ #define S_IRUSR 0000400
+ #define S_IWUSR 0000200
+ #define S_IXUSR 0000100
+ #define S_IRGRP 0000040
+ #define S_IWGRP 0000020
+ #define S_IXGRP 0000010
+ #define S_IROTH 0000004
+ #define S_IWOTH 0000002
+ #define S_IXOTH 0000001
+ #endif /* S_IRWXU */
  #define INCLUDES_DONE
  #endif  /* Normal includes */
  /*
***************
*** 722,730 ****
  #ifdef unix                       /* if this is to compile on a UNIX machine */
  #define GOT_READ_DIR 1       /* if directory reading functions are available */
  
- #ifndef NeXT
- #define USE_DIRENT                /* Try this all the time, Henrik May 29 94 */
- #endif
  #ifdef USE_DIRENT                                           /* sys v version */
  #include <dirent.h>
  #define STRUCT_DIRENT struct dirent
--- 746,751 ----
diff -ca Daemon/Impl.orig/CGIParse.c Daemon/Implementation/CGIParse.c
*** Daemon/Impl.orig/CGIParse.c	Tue Jul 12 07:50:32 1994
--- Daemon/Implementation/CGIParse.c	Thu Jul 10 10:59:09 2003
***************
*** 9,17 ****
--- 9,19 ----
  **
  ** AUTHORS:
  **	AL	Ari Luotonen	luotonen@dxcern.cern.ch
+ **	MS	Michael Sokolov	msokolov@ivan.Harhan.ORG
  **
  ** HISTORY:
  **	 9 Jan 94  AL	Written on a melancholic Sunday evening.
+ **	 2 Jul 03  MS	Security fix (DFN-CERT#34784)
  **
  ** BUGS:
  **
***************
*** 293,299 ****
  	*cur = 0;
  
  	if (init) {
! 	    printf("QUERY_STRING='%s'; export QUERY_STRING\n", query_string);
  	    exit(0);
  	}
      }
--- 295,302 ----
  	*cur = 0;
  
  	if (init) {
! 	    printf("QUERY_STRING=%s; export QUERY_STRING\n",
! 		   sh_escape(query_string));
  	    exit(0);
  	}
      }
diff -ca Daemon/Impl.orig/CommonMakefile Daemon/Implementation/CommonMakefile
*** Daemon/Impl.orig/CommonMakefile	Fri Jun 21 12:35:05 1996
--- Daemon/Implementation/CommonMakefile	Tue Jul  1 19:39:14 2003
***************
*** 160,166 ****
  PURIFY_CACHE = /home2/frystyk/purify-cache
  
  PURIFY = purify \
! 	-logfile=$(HOME)/purify.log
  	-cache-dir=$(PURIFY_CACHE)
  
  #
--- 160,166 ----
  PURIFY_CACHE = /home2/frystyk/purify-cache
  
  PURIFY = purify \
! 	-logfile=$(HOME)/purify.log \
  	-cache-dir=$(PURIFY_CACHE)
  
  #
diff -ca Daemon/Impl.orig/HTAAProt.c Daemon/Implementation/HTAAProt.c
*** Daemon/Impl.orig/HTAAProt.c	Sun Sep 25 11:53:03 1994
--- Daemon/Implementation/HTAAProt.c	Tue Jul  1 20:44:53 2003
***************
*** 18,24 ****
  */
  
  #include <string.h>
- #include <time.h>
  
  #ifndef VMS
  #include <pwd.h>	/* Unix password file routine: getpwnam()	*/
--- 18,23 ----
diff -ca Daemon/Impl.orig/HTAAServ.c Daemon/Implementation/HTAAServ.c
*** Daemon/Impl.orig/HTAAServ.c	Sun Jul 14 15:38:03 1996
--- Daemon/Implementation/HTAAServ.c	Thu Jul 10 00:04:50 2003
***************
*** 43,49 ****
  
  #include <stdio.h>		/* FILE */
  #include <string.h>		/* strchr() */
- #include <time.h>
  
  #include "HTUtils.h"
  #include "HTString.h"
--- 43,48 ----
***************
*** 614,635 ****
  			** If it's a directory and our URL doesn't end in a
  			** slash, find out if we could send a redirection
  			** to the welcome page on that directory instead.
  			*/
! 			if (sc.always_welcome && S_ISDIR(stat_info.st_mode) &&
! 			    physical[ strlen(physical)-1 ] != '/') {
  
  			    char * welcome = NULL;
! 			    StrAllocCopy(welcome, physical);
! 			    StrAllocCat(welcome, "/");
! 			    physical = HTMulti(req, welcome, &stat_info2);
! 			    free(welcome);
  
! 			    if (physical && !S_ISDIR(stat_info2.st_mode)) {
  				char * escaped = HTEscape(HTReqArgPath,
  							  URL_PATH);
  				int keylen = HTReqArgKeywords ?
  				    strlen(HTReqArgKeywords) : 0;
  
  				HTLocation = (char*)malloc(strlen(escaped) +
  							   keylen + 3);
  				sprintf(HTLocation, "%s/%s%s",
--- 613,655 ----
  			** If it's a directory and our URL doesn't end in a
  			** slash, find out if we could send a redirection
  			** to the welcome page on that directory instead.
+ 			** We may also be configured to always force a redirect
+ 			** in this case whether a welcome page exists or not.
  			*/
! 			if (S_ISDIR(stat_info.st_mode) &&
! 			    physical[ strlen(physical)-1 ] != '/' &&
! 			    (sc.always_welcome || sc.force_dir_slash)) {
  
  			    char * welcome = NULL;
! 			    BOOL welcome_present = NO;
  
! 			    if (!sc.force_dir_slash) {
! 				StrAllocCopy(welcome, physical);
! 				StrAllocCat(welcome, "/");
! 				physical = HTMulti(req, welcome, &stat_info2);
! 				if (physical && !S_ISDIR(stat_info2.st_mode))
! 				    welcome_present = YES;
! 				free(welcome);
! 				FREE(physical);
! 			    }
! 
! 			    if (sc.force_dir_slash || welcome_present) {
  				char * escaped = HTEscape(HTReqArgPath,
  							  URL_PATH);
  				int keylen = HTReqArgKeywords ?
  				    strlen(HTReqArgKeywords) : 0;
  
+ 				/*
+ 				** Not so fast - we must still check AA: they
+ 				** may not be allowed to know about the dir's
+ 				** existence!
+ 				*/
+ 				HTReason = check_authorization(req, NO);
+ 				if (HTReason != HTAA_OK) {
+ 				    free(escaped);
+ 				    goto done;
+ 				}
+ 
  				HTLocation = (char*)malloc(strlen(escaped) +
  							   keylen + 3);
  				sprintf(HTLocation, "%s/%s%s",
***************
*** 637,647 ****
  					keylen ? "?" : "",
  					keylen ? HTReqArgKeywords : "");
  				free(escaped);
- 				free(physical);
  				HTReason = HTAA_OK_REDIRECT;
  				goto done;
  			    }
- 			    FREE(physical);
  			}
  
  			HTSetAttributes(req, &stat_info);
--- 657,665 ----
***************
*** 750,758 ****
  	} /* not a script request */
      } /* if translation succeeded */
  
      FREE(untranslated);
  
-   done:
      switch (HTReason) {
  
        case HTAA_NO_AUTH:
--- 768,776 ----
  	} /* not a script request */
      } /* if translation succeeded */
  
+   done:
      FREE(untranslated);
  
      switch (HTReason) {
  
        case HTAA_NO_AUTH:
diff -ca Daemon/Impl.orig/HTAdm.c Daemon/Implementation/HTAdm.c
*** Daemon/Impl.orig/HTAdm.c	Tue Jul 12 07:50:52 1994
--- Daemon/Implementation/HTAdm.c	Wed Jul  9 20:03:51 2003
***************
*** 40,45 ****
--- 40,46 ----
  ** AUTHORS:
  **	AL	Ari Luotonen	luotonen@dxcern.cern.ch
  **      MD      Mark Donszelmann   duns@vxdeop.cern.ch
+ **	MS	Michael Sokolov	msokolov@ivan.Harhan.ORG
  **
  ** HISTORY:
  **	 7 Oct 93  AL	Written on a rainy October night.
***************
*** 47,52 ****
--- 48,56 ----
  **	 5 Nov 93  MD   Some fixes for VMS.
  **	21 Feb 94  AL	Sets permissions according to original password
  **			file, not current umask (for Unix).
+ **	 9 Jul 03  MS	Catch and stop usernames longer than MAX_USERNAME_LEN.
+ **			On UNIX use link rather than rename to save old passwd
+ **			file to eliminate window of no passwd file at all.
  ** BUGS:
  **
  */
***************
*** 53,66 ****
  
  #include "tcp.h"
  
! #ifdef VMS
! #include <stat.h>
! #include <types.h>
! #else /* not VMS */
! #include <sys/types.h>
! #ifndef Mips
! #include <sys/stat.h>
! #endif
  #include <fcntl.h>
  #endif /* not VMS */
  
--- 57,63 ----
  
  #include "tcp.h"
  
! #ifndef VMS
  #include <fcntl.h>
  #endif /* not VMS */
  
***************
*** 271,276 ****
--- 268,280 ----
  	    exit(4);
  	}
  
+ 	if (open == HTADM_ADDUSER || strlen(username) > MAX_USERNAME_LEN) {
+ 	    fprintf(stderr,
+ 		    "htadm:  Error: User name cannot exceed %d characters\n",
+ 		    MAX_USERNAME_LEN);
+ 	    exit(7);
+ 	}
+ 
  	if (oper == HTADM_ADDUSER || oper == HTADM_PASSWD) {
  	    if (!password) {
  		for (;;) {
***************
*** 344,350 ****
--- 348,358 ----
  #else
  	StrAllocCat(backup, "_bak");
  #endif /* VMS */
+ #ifdef unix
+ 	link(argv[2], backup);
+ #else
  	rename(argv[2], backup);
+ #endif /* unix */
  	rename(filename, argv[2]);
  
  	break;
diff -ca Daemon/Impl.orig/HTAuth.c Daemon/Implementation/HTAuth.c
*** Daemon/Impl.orig/HTAuth.c	Tue Jul 12 07:50:55 1994
--- Daemon/Implementation/HTAuth.c	Tue Jul  1 20:45:56 2003
***************
*** 14,20 ****
  */
  
  #include <string.h>
- #include <time.h>
  
  #include "HTUtils.h"
  #include "HTPasswd.h"	/* Password file routines	*/
--- 14,19 ----
diff -ca Daemon/Impl.orig/HTCache.c Daemon/Implementation/HTCache.c
*** Daemon/Impl.orig/HTCache.c	Tue Jul 12 07:50:59 1994
--- Daemon/Implementation/HTCache.c	Tue Jul  1 20:48:24 2003
***************
*** 17,33 ****
  **
  */
  
- #ifdef VMS
- #define __TYPES
- #include <types.h>
- #include <time.h>
- #define __TIME
- #else /* not VMS */
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/stat.h>
- #endif /* not VMS */
- 
  #include "HTFile.h"
  #include "HTUtils.h"
  #include "HTParse.h"	/* HTEscape() */
--- 17,22 ----
diff -ca Daemon/Impl.orig/HTCacheInfo.c Daemon/Implementation/HTCacheInfo.c
*** Daemon/Impl.orig/HTCacheInfo.c	Tue Jul 12 07:51:05 1994
--- Daemon/Implementation/HTCacheInfo.c	Tue Jul  1 20:48:33 2003
***************
*** 21,28 ****
   *
   */
  
- #include <time.h>
- 
  #include "HTUtils.h"
  #include "tcp.h"
  #include "HTSUtils.h"
--- 21,26 ----
diff -ca Daemon/Impl.orig/HTConfig.c Daemon/Implementation/HTConfig.c
*** Daemon/Impl.orig/HTConfig.c	Sat Jun 29 06:35:06 1996
--- Daemon/Implementation/HTConfig.c	Thu Jul 10 18:32:02 2003
***************
*** 6,11 ****
--- 6,12 ----
  **	MD		Mark Donszelmann <duns@vxdeop.cern.ch>
  **	TBL		Tim Berners-Lee	 <timbl@info.cern.ch>
  **	FM		Foteos Macrides
+ **	MS		Michael Sokolov  <msokolov@ivan.Harhan.ORG>
  **
  ** History:
  **	 3 Jun 91	Written TBL
***************
*** 31,42 ****
  **	06 Jul 94  FM	Require that username own the file for access to
  **			UserDir on VMS (otherwise, a user could alias the
  **			the UserDir and access any file with SYSPRV).
  **
  */
  
  /* (c) CERN WorldWideWeb project 1990,91. See Copyright.html for details */
- #include <time.h>
- 
  #include "HTRules.h"
  
  #include "tcp.h"
--- 32,45 ----
  **	06 Jul 94  FM	Require that username own the file for access to
  **			UserDir on VMS (otherwise, a user could alias the
  **			the UserDir and access any file with SYSPRV).
+ **	 1 Jul 03  MS	Use setenv on pure BSD for xxx_proxy.
+ **	 9 Jul 03  MS	Added ForceDirSlash option to the config file to force
+ **			all requests for dir to be redirected to dir/
+ **			regardless of the existence of a welcome page.
  **
  */
  
  /* (c) CERN WorldWideWeb project 1990,91. See Copyright.html for details */
  #include "HTRules.h"
  
  #include "tcp.h"
***************
*** 1578,1584 ****
--- 1581,1589 ----
  		access = "no";
  
  	    if (access) {
+ #if !defined(PURE_BSD) && !defined(NeXT)
  		char * envstr = (char *)malloc(strlen(vec[1]) + 20);
+ #endif
  		char * envname = (char *)malloc(20);
  		char * old;
  
***************
*** 1594,1604 ****
  		}
  
  		sprintf(envname, "%s_proxy", access);
- 		sprintf(envstr, "%s_proxy=%s", access, vec[1]);
  
  		old = getenv(envname);
  #ifndef NeXT
  		putenv(envstr);
  #else
  		HTLog_error("xxx_proxy directive not supported on the NeXT");
  		HTLog_error("Use xxx_proxy environment variables instead");
--- 1599,1613 ----
  		}
  
  		sprintf(envname, "%s_proxy", access);
  
  		old = getenv(envname);
  #ifndef NeXT
+ #ifdef PURE_BSD
+ 		setenv(envname, vec[1], 1);
+ #else
+ 		sprintf(envstr, "%s_proxy=%s", access, vec[1]);
  		putenv(envstr);
+ #endif
  #else
  		HTLog_error("xxx_proxy directive not supported on the NeXT");
  		HTLog_error("Use xxx_proxy environment variables instead");
***************
*** 1756,1761 ****
--- 1765,1776 ----
  	    CTRACE(stderr,
  		   "Directory... names %sget redirected to welcome pages\n",
  		   sc.always_welcome ? "" : "don't ");
+ 
+ 	} else if (!strncmp(vec[0], "forcedirslash", 9)) {
+ 	    sc.force_dir_slash = positive(vec[1]);
+ 	    CTRACE(stderr,
+ 		   "dir=>dir/... redirect %sforced\n",
+ 		   sc.force_dir_slash ? "" : "not ");
  
  	} else if (!strncmp(vec[0], "welcome", 7)) {
  	    HTAddWelcome(vec[1]);
diff -ca Daemon/Impl.orig/HTConfig.h Daemon/Implementation/HTConfig.h
*** Daemon/Impl.orig/HTConfig.h	Sun Jun 23 06:57:40 1996
--- Daemon/Implementation/HTConfig.h	Wed Jul  9 23:03:35 2003
***************
*** 81,86 ****
--- 81,88 ----
      char *      meta_suffix;            /* Suffix for metafiles         */
      BOOL        always_welcome;         /* Redirect directory names to  */
                                          /* welcome page on that dir.    */
+     BOOL	force_dir_slash;	/* Redirect dir to dir/ even if */
+ 					/* no welcome page		*/
      char *      access_log_name;        /* Access log file name         */
      char *      proxy_log_name;         /* Proxy access log file name   */
      char *      cache_log_name;         /* Cache access log file name   */
diff -ca Daemon/Impl.orig/HTDaemon.c Daemon/Implementation/HTDaemon.c
*** Daemon/Impl.orig/HTDaemon.c	Sun Jul 14 15:37:49 1996
--- Daemon/Implementation/HTDaemon.c	Tue Jul 15 15:31:10 2003
***************
*** 13,18 ****
--- 13,19 ----
  **      AL      Ari Luotonen, CERN
  **      MD      Mark Donszelmann, CERN
  **      FM      Foteos Macrides, WFEB
+ **	MS	Michael Sokolov, IFCTF
  **
  **  History:
  **         Sep 91  TBL  Made from earlier daemon files. (TBL)
***************
*** 65,70 ****
--- 66,75 ----
  **			defined via "ServerRoot" in the configuration file.
  **			Commented out dead extern declarations.
  **	 8 Jul 94  FM	Insulate free() from _free structure element.
+ **	 1 Jul 03  MS	Fixes for pure BSD wait.
+ **	10 Jul 03  MS	setpgrp doesn't return the pgrp, it _TAKES_ it as arg.
+ **	15 Jul 03  MS	Pitch the silly SIGTERM handler. None at all is better
+ **			than that.
  */
  
  /* (c) CERN WorldWideWeb project 1990-1992. See Copyright.html for details */
***************
*** 76,83 ****
  **  These may be undefined and redefined by syspec.h
  */
  
- #include <time.h>
- 
  #define FORKING
  
  #ifdef __svr4__
--- 81,86 ----
***************
*** 176,181 ****
--- 179,188 ----
  #include <sys/ioctl.h>
  #endif /* BSD */
  
+ #ifdef PURE_BSD
+ #define	WEXITSTATUS(x) ((x).w_retcode)
+ #endif
+ 
  #endif /* FORKING */
  
  
***************
*** 487,493 ****
  #endif /* Mips */
  #endif
  
! #if defined(NeXT) || defined(_AIX)
      union wait status;
  #else
      int status;
--- 494,500 ----
  #endif /* Mips */
  #endif
  
! #if defined(NeXT) || defined(_AIX) || defined(PURE_BSD)
      union wait status;
  #else
      int status;
***************
*** 529,548 ****
  
  
  #ifndef VMS
- PRIVATE void sig_term NOARGS
- {
-     if (sc.standalone) {
- #if defined(__svr4__) || defined(_POSIX_SOURCE) || defined(__hpux)
-         kill(-pgrp, SIGKILL);
- #else
-         killpg(pgrp, SIGKILL);
- #endif
-         shutdown(master_soc, 2);
-         close(master_soc);
-     }
- }
- 
- 
  PRIVATE void dump_core NOARGS
  {
      if (HTReqLine)
--- 536,541 ----
***************
*** 610,616 ****
  PRIVATE void set_signals NOARGS
  {
  #ifndef VMS
-     signal(SIGTERM, (void (*)())sig_term);
      signal(SIGHUP, (void (*)())sig_hup);
      signal(SIGSEGV, (void (*)())sig_segv);
      signal(SIGBUS, (void (*)())sig_bus);
--- 603,608 ----
***************
*** 2724,2730 ****
  #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 */
--- 2716,2723 ----
  #if defined(__svr4__) || defined(_POSIX_SOURCE) || defined(__hpux)
      pgrp = setsid();
  #else
!     pgrp = getpid();
!     setpgrp(0, pgrp);
  
      if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
          ioctl(fd, TIOCNOTTY, (char*)NULL);      /* Lose controlling tty */
diff -ca Daemon/Impl.orig/HTLoad.c Daemon/Implementation/HTLoad.c
*** Daemon/Impl.orig/HTLoad.c	Tue Jul 12 07:51:33 1994
--- Daemon/Implementation/HTLoad.c	Tue Jul  1 20:54:28 2003
***************
*** 18,34 ****
  
  #include <string.h>
  #include <stdio.h>
- #include <time.h>
- 
- #ifdef VMS
- #include <types.h>
- #include <stat.h>
- #else
- #include <sys/types.h>
- #ifndef Mips
- #include <sys/stat.h>
- #endif
- #endif
  
  #include "HTFile.h"
  #include "HTUtils.h"
--- 18,23 ----
diff -ca Daemon/Impl.orig/HTLog.c Daemon/Implementation/HTLog.c
*** Daemon/Impl.orig/HTLog.c	Sun Jun 30 17:07:23 1996
--- Daemon/Implementation/HTLog.c	Tue Jul  1 22:07:46 2003
***************
*** 14,20 ****
  */
  
  #include <stdio.h>
- #include <time.h>
  
  #include "tcp.h"
  #include "HTUtils.h"	/* gmtime foor VMS */
--- 14,19 ----
***************
*** 67,73 ****
  	    gorl = localtime(&cur_time);
  
  	/* Not all platforms have strftime() :-( */
! #if defined(Mips) || defined(_AUX) || (defined(VMS) && !defined(DECC))
  	/* A shortcut as we should use the value of log_file_date_ext :-( */
  	sprintf(date, "%s%02d%02d",
  		month_names[gorl->tm_mon], gorl->tm_mday, gorl->tm_year);
--- 66,72 ----
  	    gorl = localtime(&cur_time);
  
  	/* Not all platforms have strftime() :-( */
! #if defined(PURE_BSD) || defined(Mips) || defined(_AUX) || (defined(VMS) && !defined(DECC))
  	/* A shortcut as we should use the value of log_file_date_ext :-( */
  	sprintf(date, "%s%02d%02d",
  		month_names[gorl->tm_mon], gorl->tm_mday, gorl->tm_year);
diff -ca Daemon/Impl.orig/HTRFC931.c Daemon/Implementation/HTRFC931.c
*** Daemon/Impl.orig/HTRFC931.c	Tue Jul 12 07:51:40 1994
--- Daemon/Implementation/HTRFC931.c	Tue Jul  1 21:02:07 2003
***************
*** 19,28 ****
  #include "HTTCP.h"
  #include "HTLog.h"
  
- #ifndef _HPUX_SOURCE
- #define _HPUX_SOURCE
- #endif
- 
  /* System libraries. */
  #ifndef VMS
  
--- 19,24 ----
***************
*** 39,45 ****
   * now I just do -Ddecstation on the command line.
   *					<httpd@info.cern.ch>
   */
! #if !defined(decstation) && !defined(Mips)
  #include <sys/socket.h>
  #endif
  
--- 35,41 ----
   * now I just do -Ddecstation on the command line.
   *					<httpd@info.cern.ch>
   */
! #if !defined(decstation) && !defined(Mips) && !defined(PURE_BSD)
  #include <sys/socket.h>
  #endif
  
diff -ca Daemon/Impl.orig/HTRequest.c Daemon/Implementation/HTRequest.c
*** Daemon/Impl.orig/HTRequest.c	Sun Jun 30 17:08:15 1996
--- Daemon/Implementation/HTRequest.c	Tue Jul  1 20:49:34 2003
***************
*** 15,21 ****
  
  #include <string.h>
  #include <stdio.h>
- #include <time.h>
  
  #include "HTUtils.h"
  #include "HTAccess.h"	/* HTRequest */
--- 15,20 ----
diff -ca Daemon/Impl.orig/HTRetrieve.c Daemon/Implementation/HTRetrieve.c
*** Daemon/Impl.orig/HTRetrieve.c	Sun Sep 25 06:48:06 1994
--- Daemon/Implementation/HTRetrieve.c	Tue Jul  1 20:49:49 2003
***************
*** 20,27 ****
  
  /* (c) CERN WorldWideWeb project 1990,91. See Copyright.html for details */
  
- #include <time.h>
- 
  #define USE_PLAINTEXT	/* Makes retrieval of postscript easier for now */
  			/* but not good sgml */
  
--- 20,25 ----
diff -ca Daemon/Impl.orig/HTSUtils.c Daemon/Implementation/HTSUtils.c
*** Daemon/Impl.orig/HTSUtils.c	Sun Jun  2 11:42:06 1996
--- Daemon/Implementation/HTSUtils.c	Thu Jul 10 23:30:07 2003
***************
*** 5,13 ****
--- 5,18 ----
  ** AUTHORS:
  **	AL	Ari Luotonen	luotonen@dxcern.cern.ch
  **	MD	Mark Dönszelmann 	duns@vxdeop.cern.ch
+ **	MS	Michael Sokolov	msokolov@ivan.Harhan.ORG
  **
  ** HISTORY:
  **	10 Mar 94  AL	First written.
+ **	 1 Jul 03  MS	Y2K fixes.  Credit goes to AT&T for their Y2K patch,
+ **			although I did it a bit differently.  Also get rid of
+ **			mktime and the kludge to convert it to GMT, and do it
+ **			all ourselves 100% in GMT from start to finish.
  **
  ** BUGS:
  **	MD : VMS does not support GMT, so no offset given...
***************
*** 19,27 ****
  #include "tcp.h"
  #include "HTConfig.h"
  
! #if defined(Mips) || (defined(VMS) && !defined(DECC))
  PRIVATE char * wkdays[7] = {
!     "Mon","Tue","Wed","Thu","Fri","Sat","Sun"
  };
  #endif
  
--- 24,32 ----
  #include "tcp.h"
  #include "HTConfig.h"
  
! #if defined(PURE_BSD) || defined(Mips) || defined(_AUX) || (defined(VMS) && !defined(DECC))
  PRIVATE char * wkdays[7] = {
!     "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
  };
  #endif
  
***************
*** 31,37 ****
--- 36,52 ----
      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  };
  
+ PRIVATE int dmsize[12] =
+ 	{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  
+ /*
+  * Accurate only for the past couple of centuries;
+  * that will probably do.
+  */
+ 
+ #define	isleap(y) (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0)
+ 
+ 
  /*								isNumber()
   *		Does a character string represent an integer
   */
***************
*** 79,90 ****
  PUBLIC time_t parse_http_time ARGS1(char *, str)
  {
      char * s;
!     struct tm tm;
      time_t t;
- #ifdef ISC3   /* Lauren */
-     struct tm * gorl;		/* GMT or localtime */
-     long z = 0L;
- #endif
  
      if (!str) return 0;
  
--- 94,101 ----
  PUBLIC time_t parse_http_time ARGS1(char *, str)
  {
      char * s;
!     int century, year, month, day, hour, mins, secs;
      time_t t;
  
      if (!str) return 0;
  
***************
*** 98,109 ****
  		       "ERROR....... Not a valid time format \"%s\"\n", s);
  		return 0;
  	    }
! 	    tm.tm_mday = make_num(s);
! 	    tm.tm_mon = make_month(s+3);
! 	    tm.tm_year = make_num(s+7);
! 	    tm.tm_hour = make_num(s+10);
! 	    tm.tm_min = make_num(s+13);
! 	    tm.tm_sec = make_num(s+16);
  	}
  	else {				/* Second format */
  	    CTRACE(stderr, "Format...... Wkd, 00 Mon 0000 00:00:00 GMT\n");
--- 109,124 ----
  		       "ERROR....... Not a valid time format \"%s\"\n", s);
  		return 0;
  	    }
! 	    day = make_num(s);
! 	    month = make_month(s+3);
! 	    year = make_num(s+7);
! 	    if (year >= 70)
! 		century = 19;
! 	    else
! 		century = 20;
! 	    hour = make_num(s+10);
! 	    mins = make_num(s+13);
! 	    secs = make_num(s+16);
  	}
  	else {				/* Second format */
  	    CTRACE(stderr, "Format...... Wkd, 00 Mon 0000 00:00:00 GMT\n");
***************
*** 112,123 ****
  		       "ERROR....... Not a valid time format \"%s\"\n", s);
  		return 0;
  	    }
! 	    tm.tm_mday = make_num(s);
! 	    tm.tm_mon = make_month(s+3);
! 	    tm.tm_year = (100*make_num(s+7) - 1900) + make_num(s+9);
! 	    tm.tm_hour = make_num(s+12);
! 	    tm.tm_min = make_num(s+15);
! 	    tm.tm_sec = make_num(s+18);
  
  	}
      }
--- 127,139 ----
  		       "ERROR....... Not a valid time format \"%s\"\n", s);
  		return 0;
  	    }
! 	    day = make_num(s);
! 	    month = make_month(s+3);
! 	    century = make_num(s+7);
! 	    year = make_num(s+9);
! 	    hour = make_num(s+12);
! 	    mins = make_num(s+15);
! 	    secs = make_num(s+18);
  
  	}
      }
***************
*** 130,211 ****
  	    CTRACE(stderr, "ERROR....... Not a valid time format \"%s\"\n", s);
  	    return 0;
  	}
! 	tm.tm_mday = make_num(s+8);
! 	tm.tm_mon = make_month(s+4);
! 	tm.tm_year = make_num(s+22);
! 	tm.tm_hour = make_num(s+11);
! 	tm.tm_min = make_num(s+14);
! 	tm.tm_sec = make_num(s+17);
      }
!     if (tm.tm_sec  < 0  ||  tm.tm_sec  > 59  ||
! 	tm.tm_min  < 0  ||  tm.tm_min  > 59  ||
! 	tm.tm_hour < 0  ||  tm.tm_hour > 23  ||
! 	tm.tm_mday < 1  ||  tm.tm_mday > 31  ||
! 	tm.tm_mon  < 0  ||  tm.tm_mon  > 11  ||
! 	tm.tm_year <70  ||  tm.tm_year >120) {
  	CTRACE(stderr,
! 	"ERROR....... Parsed illegal time: %02d.%02d.%02d %02d:%02d:%02d\n",
! 	       tm.tm_mday, tm.tm_mon+1, tm.tm_year,
! 	       tm.tm_hour, tm.tm_min, tm.tm_sec);
  	return 0;
      }
  
!     tm.tm_isdst = -1;
  
-     /*
-      *	What a pain it is to get the timezone correctly.
-      */
- 
- #if defined(sun) && !defined(__svr4__)
-     t = timegm(&tm);
- #else /* not sun, except svr4 */
- 
-     t = mktime(&tm);
- 
- /* BSD, have tm_gmtoff */
- #if defined(SIGTSTP) && !defined(AIX) && !defined(__sgi) && !defined(_AUX) && !defined(__svr4__)
-     {
- 	time_t cur_t = time(NULL);
- 	struct tm * local = localtime(&cur_t);
- 	t += local->tm_gmtoff;
- 	CTRACE(stderr,"TimeZone.... %02d hours from GMT\n",
- 	       (int)local->tm_gmtoff / 3600);
-     }
- #else /* SysV or VMS */
-     {
- #ifdef VMS
- 	CTRACE(stderr,"TimeZone.... undefined\n");
- #else /* SysV */
- #ifdef ISC3   /* Lauren */
- 	time_t cur_t = time(NULL);
- 	gorl = localtime(&cur_t);
- 	if (daylight && gorl->tm_isdst)	/* daylight time? */
- 	    z = altzone;	/* yes */
- 	else
- 	    z = timezone;	/* no */
- 
- 	z /= 60;		/* convert to minutes */
- 	z = -z;			/* ISC 3.0 has it vice versa */
- 	t += z * 60;	
- 	CTRACE(stderr,"TimeZone.... %02d hours from GMT\n", z / 60);
- #else
- 	int dst = 0;
- 	/*
- 	 * The following assumes a fixed DST offset of 1 hour,
- 	 * which is probably wrong.
- 	 */
- 	if (tm.tm_isdst > 0)
- 	    dst = -3600;
- 	t -= (timezone + dst);
- 	CTRACE(stderr,"TimeZone.... %02d hours from GMT\n", 
- 	       (timezone + dst) / 3600);
- #endif
- #endif /* SysV */
-     }
- #endif /* SysV or VMS */
- 
- #endif /* not sun, except svr4 */
- 
      CTRACE(stderr, "Time string. %s", str);
      CTRACE(stderr, "Parsed...... to %ld seconds, %s", (long)t, ctime(&t));
      return t;
--- 146,184 ----
  	    CTRACE(stderr, "ERROR....... Not a valid time format \"%s\"\n", s);
  	    return 0;
  	}
! 	day = make_num(s+8);
! 	month = make_month(s+4);
! 	century = make_num(s+20);
! 	year = make_num(s+22);
! 	hour = make_num(s+11);
! 	mins = make_num(s+14);
! 	secs = make_num(s+17);
      }
!     year += century * 100;
!     if (secs  < 0  ||  secs  > 59  ||
! 	mins  < 0  ||  mins  > 59  ||
! 	hour  < 0  ||  hour  > 23  ||
! 	day   < 1  ||  day   > 31  ||
! 	month < 0  ||  month > 11  ||
! 	year  < 1970) {
  	CTRACE(stderr,
! 	"ERROR....... Parsed illegal time: %02d.%02d.%04d %02d:%02d:%02d\n",
! 	       day, month+1, year, hour, mins, secs);
  	return 0;
      }
  
!     t = 0;
!     if (isleap(year) && month > 1)
! 	++t;
!     for (--year; year >= 70; --year)
! 	t += isleap(year) ? 366 : 365;
!     while (month)
! 	t += dmsize[--month];
!     t += day - 1;
!     t = 24 * t + hour;
!     t = 60 * t + mins;
!     t = 60 * t + secs;
  
      CTRACE(stderr, "Time string. %s", str);
      CTRACE(stderr, "Parsed...... to %ld seconds, %s", (long)t, ctime(&t));
      return t;
***************
*** 215,229 ****
  PUBLIC char * http_time ARGS1(time_t *, t)
  {
      static char buf[40];
! #if defined(Mips) || defined(_AUX) || (defined(VMS) && !defined(DECC))
      {
  #if 1
  	struct tm * gmt = gmtime(t);
! 	sprintf(buf,"%s, %02d %s 19%02d %02d:%02d:%02d GMT",
  		wkdays[gmt->tm_wday],
  		gmt->tm_mday,
  		month_names[gmt->tm_mon],
! 		gmt->tm_year % 100,
  		gmt->tm_hour,
  		gmt->tm_min,
  		gmt->tm_sec);
--- 188,202 ----
  PUBLIC char * http_time ARGS1(time_t *, t)
  {
      static char buf[40];
! #if defined(PURE_BSD) || defined(Mips) || defined(_AUX) || (defined(VMS) && !defined(DECC))
      {
  #if 1
  	struct tm * gmt = gmtime(t);
! 	sprintf(buf,"%s, %02d %s %04d %02d:%02d:%02d GMT",
  		wkdays[gmt->tm_wday],
  		gmt->tm_mday,
  		month_names[gmt->tm_mon],
! 		gmt->tm_year + 1900,
  		gmt->tm_hour,
  		gmt->tm_min,
  		gmt->tm_sec);
***************
*** 237,244 ****
  		gmt->tm_hour,
  		gmt->tm_min,
  		gmt->tm_sec);
-     }
  #endif
  #else
  #if defined(HT_REENTRANT) || defined(SOLARIS)
      {
--- 210,217 ----
  		gmt->tm_hour,
  		gmt->tm_min,
  		gmt->tm_sec);
  #endif
+     }
  #else
  #if defined(HT_REENTRANT) || defined(SOLARIS)
      {
diff -ca Daemon/Impl.orig/HTScript.c Daemon/Implementation/HTScript.c
*** Daemon/Impl.orig/HTScript.c	Sun Jun 23 06:31:49 1996
--- Daemon/Implementation/HTScript.c	Tue Jul  1 20:50:21 2003
***************
*** 47,53 ****
  
  #include <string.h>
  #include <stdio.h>
- #include <time.h>
  
  #ifdef Mips
  #include <sys/wait.h>
--- 47,52 ----
diff -ca Daemon/Impl.orig/HTgc.c Daemon/Implementation/HTgc.c
*** Daemon/Impl.orig/HTgc.c	Tue Jul 12 07:52:08 1994
--- Daemon/Implementation/HTgc.c	Tue Jul  1 20:50:44 2003
***************
*** 15,27 ****
  
  #include <string.h>
  #include <stdio.h>
- #ifdef VMS
- #include <types.h>
- #include <time.h>
- #else /* not VMS */
- #include <sys/types.h>
- #include <sys/time.h>
- #endif /* not VMS */
  
  #include "HTUtils.h"
  #include "tcp.h"
--- 15,20 ----
diff -ca Daemon/Impl.orig/HTims.c Daemon/Implementation/HTims.c
*** Daemon/Impl.orig/HTims.c	Tue Jul 12 07:52:10 1994
--- Daemon/Implementation/HTims.c	Tue Jul  1 20:50:53 2003
***************
*** 14,21 ****
   *	 8 Jul 94  FM	Insulate free() from _free structure element.
   */
  
- #include <time.h>
- 
  #include "HTims.h"
  #include "HTSUtils.h"
  #include "HTDaemon.h"
--- 14,19 ----
diff -ca Daemon/Impl.orig/Version.make Daemon/Implementation/Version.make
*** Daemon/Impl.orig/Version.make	Sun Jun  2 11:14:53 1996
--- Daemon/Implementation/Version.make	Thu Jul 10 12:19:19 2003
***************
*** 1 ****
! VD = 3.0A
--- 1 ----
! VD = 3.0A-IFCTF
diff -ca Daemon/Impl.orig/cgiutils.c Daemon/Implementation/cgiutils.c
*** Daemon/Impl.orig/cgiutils.c	Tue Jul 12 07:52:13 1994
--- Daemon/Implementation/cgiutils.c	Tue Jul  1 20:51:02 2003
***************
*** 23,29 ****
  #include <stdio.h>
  #include <string.h>
  #include <ctype.h>
- #include <time.h>
  
  #include "HTUtils.h"
  #include "tcp.h"
--- 23,28 ----
