Harvest v1.3 Patchlevel 1 fixes

To apply this patch:

cd to the top of the source tree (to the directory containing the "src"
and "components" subdirectories) and do:
        patch -p -s < ThisFile

Patch will work silently unless an error occurs.
If you want to watch patch do its thing, leave out the "-s" argument to patch.

Finally, to rebuild after applying this patch, do:
        make
	make install

Brief notes on what this patch fixes:

Cached:
	* fixes memory management problems when clients time out.
	* increases maximum number of swap files
	* fixes a bug where the cache sends the wrong objects after
	  a restart.
	* improvements to the directory listing produced by ftpget.pl.


Index: src/broker/broker.h
===================================================================
RCS file: /projects/agile/cvs/harvest/src/broker/broker.h,v
retrieving revision 1.107
retrieving revision 1.108
diff -c -r1.107 -r1.108
*** 1.107	1995/09/05 18:25:33
--- 1.108	1995/09/10 17:11:49
***************
*** 1,7 ****
  /*
   *  broker.h -- Global definitions and data type for the broker.
   *  
!  *  $Id: broker.h,v 1.107 1995/09/05 18:25:33 hardy Exp $
   *  ----------------------------------------------------------------------
   *  Copyright (c) 1994, 1995.  All rights reserved.
   *  
--- 1,7 ----
  /*
   *  broker.h -- Global definitions and data type for the broker.
   *  
!  *  $Id: broker.h,v 1.108 1995/09/10 17:11:49 duane Exp $
   *  ----------------------------------------------------------------------
   *  Copyright (c) 1994, 1995.  All rights reserved.
   *  
***************
*** 99,104 ****
--- 99,107 ----
  #include <varargs.h>
  #include <sys/wait.h>
  #include <sys/socket.h>
+ #ifdef _AIX
+ #include <sys/select.h>
+ #endif
  #include <netinet/in.h>
  #include "config.h"
  #include "util.h"
Index: src/common/url/ftpget.pl.in
===================================================================
RCS file: /projects/agile/cvs/harvest/src/common/url/ftpget.pl.in,v
retrieving revision 1.11
retrieving revision 1.12
diff -c -r1.11 -r1.12
*** 1.11	1995/09/06 20:52:07
--- 1.12	1995/09/07 23:48:23
***************
*** 2,8 ****
      eval 'exec perl -S $0 "$@"'
      if $running_under_some_shell;  
  
! # $Id: ftpget.pl.in,v 1.11 1995/09/06 20:52:07 duane Exp $
  
  # ftpget.pl beaten (not hacked) to stuff HTTP and MIME on top of an FTP 
  # retrieval.  Works like this:
--- 2,8 ----
      eval 'exec perl -S $0 "$@"'
      if $running_under_some_shell;  
  
! # $Id: ftpget.pl.in,v 1.12 1995/09/07 23:48:23 duane Exp $
  
  # ftpget.pl beaten (not hacked) to stuff HTTP and MIME on top of an FTP 
  # retrieval.  Works like this:
***************
*** 134,140 ****
  if ($#ARGV > $[-1 && $ARGV[0] eq '-v') {
  	@F = split ('/', $0);
  	print pop @F, ': ';
! 	print '$Id: ftpget.pl.in,v 1.11 1995/09/06 20:52:07 duane Exp $';
  	print "\n";
  	exit (0);
  }
--- 134,140 ----
  if ($#ARGV > $[-1 && $ARGV[0] eq '-v') {
  	@F = split ('/', $0);
  	print pop @F, ': ';
! 	print '$Id: ftpget.pl.in,v 1.12 1995/09/07 23:48:23 duane Exp $';
  	print "\n";
  	exit (0);
  }
***************
*** 324,330 ****
  		print OUT "<HR>\n";
  		print OUT "<H4>README file from $URL</H4>\n";
  		print OUT "<PRE>\n";
! 		print OUT while (<README>);
  		close README;
  		print OUT "</PRE>\n";
  		print OUT "<HR>\n";
--- 324,334 ----
  		print OUT "<HR>\n";
  		print OUT "<H4>README file from $URL</H4>\n";
  		print OUT "<PRE>\n";
! 		while (<README>) {
! 				# this s// makes URLs into live links
! 				s/([a-z]+:\/\/\S+[\w\/])/<A HREF="$1">$1<\/A>/;
! 				print OUT;
! 		}
  		close README;
  		print OUT "</PRE>\n";
  		print OUT "<HR>\n";
***************
*** 435,440 ****
--- 439,445 ----
          ($p, $s, $d, $f, $fl) = @list;
          #$s /= 1024;                            # rounds down
          $s = ($s + 1023) / 1024 if defined($s); # rounds up
+         $longf = $f;				# save original, long filename
  	$f = substr($f,0,$fieldsize-5) . '>'	# compensate for long filenames
  		if (length($f) > ($fieldsize-4));
          $fA = "$f</A>";
***************
*** 443,449 ****
          if ($p =~ /^-/) {
                  $icon = sprintf('<IMG BORDER=0 SRC="internal-gopher-%s" ALT="[FI
  LE]">',
!                  &get_mime_icon($f));
                  $link = sprintf ('<A HREF="%s%s">%s', $URLescaped,
                   &url_escape($f), &make_leader($fA));
                  $buf =  sprintf ("%s %s  [%s] %6dk\n", $icon, $link, $d, $s);
--- 448,454 ----
          if ($p =~ /^-/) {
                  $icon = sprintf('<IMG BORDER=0 SRC="internal-gopher-%s" ALT="[FI
  LE]">',
!                  &get_mime_icon($longf));
                  $link = sprintf ('<A HREF="%s%s">%s', $URLescaped,
                   &url_escape($f), &make_leader($fA));
                  $buf =  sprintf ("%s %s  [%s] %6dk\n", $icon, $link, $d, $s);
***************
*** 456,462 ****
          } elsif ($p =~ /^l/) {
                  $icon = sprintf('<IMG BORDER=0 SRC="internal-gopher-%s" ALT="[LI
  NK]">',
!                  ($_ = &get_mime_icon($f)) eq 'unknown' && defined($fl) ?
                   &get_mime_icon($fl) : $_);
                  $link = sprintf ('<A HREF="%s%s">%s', $URLescaped,
                   &url_escape($f), &make_leader($fA));
--- 461,467 ----
          } elsif ($p =~ /^l/) {
                  $icon = sprintf('<IMG BORDER=0 SRC="internal-gopher-%s" ALT="[LI
  NK]">',
!                  ($_ = &get_mime_icon($longf)) eq 'unknown' && defined($fl) ?
                   &get_mime_icon($fl) : $_);
                  $link = sprintf ('<A HREF="%s%s">%s', $URLescaped,
                   &url_escape($f), &make_leader($fA));
Index: src/cache/server/icp.c
===================================================================
RCS file: /projects/agile/cvs/harvest/src/cache/server/icp.c,v
retrieving revision 1.106
retrieving revision 1.107
diff -c -r1.106 -r1.107
*** 1.106	1995/09/07 18:20:31
--- 1.107	1995/09/08 18:19:36
***************
*** 1,5 ****
! 
! static char rcsid[] = "$Id: icp.c,v 1.106 1995/09/07 18:20:31 duane Exp $";
  /* 
   *  File:         icp.c
   *  Description:  Implementation of binary cache protocol.
--- 1,4 ----
! static char rcsid[] = "$Id: icp.c,v 1.107 1995/09/08 18:19:36 hardy Exp $";
  /* 
   *  File:         icp.c
   *  Description:  Implementation of binary cache protocol.
***************
*** 1264,1275 ****
      handler = NULL;
      client_data = NULL;
      comm_get_select_handler(fd, COMM_SELECT_READ, (PF *) & handler, (caddr_t *) & client_data);
!     if ((handler != NULL) && (client_data != NULL)) {
! 	rw_state = (icpReadWriteData *) client_data;
! 	if (rw_state->buf)
! 	    safe_free(rw_state->buf);
! 	safe_free(rw_state);
!     }
      if (astm->url) {
  	/* try to unregister us from dnsserver pending list */
  	/* this call will take care of that */
--- 1263,1269 ----
      handler = NULL;
      client_data = NULL;
      comm_get_select_handler(fd, COMM_SELECT_READ, (PF *) & handler, (caddr_t *) & client_data);
! 
      if (astm->url) {
  	/* try to unregister us from dnsserver pending list */
  	/* this call will take care of that */
***************
*** 1279,1285 ****
  	storeUnregister(astm->entry, fd);
  	storeUnlockObject(astm->entry);
      }
!     safe_free(astm->url);
      safe_free(astm->mime_hdr);
      safe_free(astm->type);
      safe_free(astm);
--- 1273,1288 ----
  	storeUnregister(astm->entry, fd);
  	storeUnlockObject(astm->entry);
      }
! 
!     if ((handler != NULL) && (client_data != NULL)) {
! 	rw_state = (icpReadWriteData *) client_data;
! 	if (rw_state->buf)
! 	    safe_free(rw_state->buf);
! 	safe_free(rw_state);
!     }
! 
!     /* astm->url is already freed by safe_free(rw_state->buf) */
!     /* safe_free(astm->url); */
      safe_free(astm->mime_hdr);
      safe_free(astm->type);
      safe_free(astm);
Index: src/cache/server/store.c
===================================================================
RCS file: /projects/agile/cvs/harvest/src/cache/server/store.c,v
retrieving revision 1.133
retrieving revision 1.135
diff -c -r1.133 -r1.135
*** 1.133	1995/09/07 07:46:54
--- 1.135	1995/09/10 04:17:12
***************
*** 1,4 ****
! static char rcsid[] = "$Id: store.c,v 1.133 1995/09/07 07:46:54 duane Exp $";
  /* 
   *  File:         store.c
   *  Description:  Storage manager for the Cache
--- 1,4 ----
! static char rcsid[] = "$Id: store.c,v 1.135 1995/09/10 04:17:12 duane Exp $";
  /* 
   *  File:         store.c
   *  Description:  Storage manager for the Cache
***************
*** 88,94 ****
  #include <sys/time.h>
  #include <sys/types.h>
  #include <sys/stat.h>
- #include <sys/stat.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <unistd.h>
--- 88,93 ----
***************
*** 106,112 ****
  
  extern time_t cached_curtime;
  
! #define MAX_SWAP_FILE 		(64*1024)
  #define SWAP_BUF 		(64*1024)
  #define FATAL_BUF_SIZE 		1024
  #define SWAP_DIRECTORIES 	100
--- 105,111 ----
  
  extern time_t cached_curtime;
  
! #define MAX_SWAP_FILE 		(512*1024)
  #define SWAP_BUF 		(64*1024)
  #define FATAL_BUF_SIZE 		1024
  #define SWAP_DIRECTORIES 	100
***************
*** 1002,1007 ****
--- 1001,1009 ----
  {
      char msgbuf[MAX_URL + 256];
      char filename[MAX_FILE_NAME_LEN];
+ #ifndef METADATA_IN_SWAPFILE
+     struct stat sb;
+ #endif
  
      debug(5, "storeSwapOutHandle: <URL:%s>\n", e->url);
  
***************
*** 1035,1047 ****
      if (store_mem_obj(e,swap_offset) >= e->object_len) {	/* swapping complete */
  	e->swap_status = SWAP_OK;
  	safe_free(store_mem_obj(e,e_swap_buf));
  	file_close(store_mem_obj(e,swap_fd));
  	debug(5, "storeSwapOutHandle: SwapOut complete: <URL:%s> to %s.\n",
  	      e->url, storeSwapFullPath(e->swap_file_number, NULL));
  
  #ifndef METADATA_IN_SWAPFILE
!         sprintf(msgbuf, "FILE: %s URL: %s %d\n", filename, e->url,
!                 cached_curtime + e->ttl);
          file_write(swaplog_fd, msgbuf, strlen(msgbuf),swaplog_lock,NULL,NULL);
  #endif
  
--- 1037,1053 ----
      if (store_mem_obj(e,swap_offset) >= e->object_len) {	/* swapping complete */
  	e->swap_status = SWAP_OK;
  	safe_free(store_mem_obj(e,e_swap_buf));
+ #ifndef METADATA_IN_SWAPFILE
+ 	if (stat(filename, &sb) < 0)
+             sb.st_mtime = cached_curtime;
+ #endif
  	file_close(store_mem_obj(e,swap_fd));
  	debug(5, "storeSwapOutHandle: SwapOut complete: <URL:%s> to %s.\n",
  	      e->url, storeSwapFullPath(e->swap_file_number, NULL));
  
  #ifndef METADATA_IN_SWAPFILE
!         sprintf(msgbuf, "FILE: %s URL: %s %d %d\n", filename, e->url,
!                 cached_curtime + e->ttl, sb.st_mtime);
          file_write(swaplog_fd, msgbuf, strlen(msgbuf),swaplog_lock,NULL,NULL);
  #endif
  
***************
*** 1247,1252 ****
--- 1253,1260 ----
      int objcount = 0;		/* # objects successfully reloaded */
      int expcount = 0;		/* # objects expired */
      int linecount = 0;		/* # lines parsed from cache logfile */
+     int clashcount = 0;		/* # swapfile clashes avoided */
+     int dupcount = 0;		/* # duplicates purged */
      char line_in[4096];
      char swapfile[1024];
      char url[MAX_URL];
***************
*** 1254,1259 ****
--- 1262,1268 ----
      struct stat buf;
      time_t start, stop, r;
      time_t expires;
+     time_t timestamp;
  
  
      debug(1, "Rebuilding storage from disk image in %s\n", swappath);
***************
*** 1268,1273 ****
--- 1277,1285 ----
  	if ((linecount++ & 0x7F) == 0)	/* update timestamp */
  	    cached_curtime = time(NULL);
  
+ 	if ((linecount & 0xFFF) == 0)
+             debug(1, "  %7d Lines read so far.\n", linecount);
+ 
  	debug(10, "line_in: %s", line_in);
  	if ((line_in[0] == '\0') || (line_in[0] == '\n') ||
  	    (line_in[0] == '#'))
***************
*** 1276,1297 ****
  	url[0] = swapfile[0] = '\0';
  	expires = cached_curtime;
  
! 	if (sscanf(line_in, "FILE: %[^ ] URL: %[^\n ] %d",
!             swapfile, url, &expires) != 3) {
  	    if (swapfile[0])
  		unlink(swapfile);
  	    continue;
  	}
  
! 	if (expires < cached_curtime) {
! 	    debug(3, "storeRebuildFromDisk: Expired: <URL:%s>\n", url);
! 	    unlink(swapfile);
! 	    expcount++;
  	    continue;
  	}
  
! 	if (stat(swapfile, &buf) < 0) {
! 	    debug(3, "storeRebuildFromDisk: Cached file missing: <URL:%s>: %s: %s.\n", url, swapfile, strerror(errno));
  	    continue;
  	}
  
--- 1288,1308 ----
  	url[0] = swapfile[0] = '\0';
  	expires = cached_curtime;
  
! 	if (sscanf(line_in, "FILE: %[^ ] URL: %[^ ] %d %d",
!             swapfile, url, &expires, &timestamp) != 4) {
  	    if (swapfile[0])
  		unlink(swapfile);
  	    continue;
  	}
  
! 	if (stat(swapfile, &buf) < 0) {
! 	    debug(3, "storeRebuildFromDisk: Cached file missing: <URL:%s>: %s: %s.\n", url, swapfile, strerror(errno));
  	    continue;
  	}
  
! 	if (buf.st_mtime != timestamp) {
! 	    /* this log entry doesn't correspond to this file */
!             clashcount++;
  	    continue;
  	}
  
***************
*** 1300,1312 ****
  
  	if (e = storeGet(url)) {
  	    debug(6, "storeRebuildFromDisk: Duplicate: <URL:%s>\n", url);
! 	    if (expires > (e->ttl + e->lastref)) {
! 		storeRelease(e);
! 		objcount--;
! 	    } else {
! 		unlink(swapfile);
! 		continue;
! 	    }
  	}
  
  	/* update store_swap_size */
--- 1311,1326 ----
  
  	if (e = storeGet(url)) {
  	    debug(6, "storeRebuildFromDisk: Duplicate: <URL:%s>\n", url);
! 	    storeRelease(e);
! 	    objcount--;
!             dupcount++;
! 	}
! 
! 	if (expires < cached_curtime) {
! 	    debug(3, "storeRebuildFromDisk: Expired: <URL:%s>\n", url);
! 	    unlink(swapfile);
! 	    expcount++;
! 	    continue;
  	}
  
  	/* update store_swap_size */
***************
*** 1313,1320 ****
  	store_swap_size += ((buf.st_size + 1023) >> 10);
  	objcount++;
  
! 	fprintf(swaplog_tmp_stream, "FILE: %s URL: %s %d\n",
! 	    swapfile, url, expires);
  	storeAddDiskRestore(url, swapfile, buf.st_size,
  	    expires - cached_curtime);
  	CacheInfo->proto_newobject(CacheInfo,
--- 1327,1334 ----
  	store_swap_size += ((buf.st_size + 1023) >> 10);
  	objcount++;
  
! 	fprintf(swaplog_tmp_stream, "FILE: %s URL: %s %d %d\n",
! 	    swapfile, url, expires, buf.st_mtime);
  	storeAddDiskRestore(url, swapfile, buf.st_size,
  	    expires - cached_curtime);
  	CacheInfo->proto_newobject(CacheInfo,
***************
*** 1326,1334 ****
      stop = time(NULL);
      r = stop - start;
      debug(1, "Finished rebuilding storage from disk image.\n");
!     debug(1, "  Read %d lines from previous logfile.\n", linecount);
!     debug(1, "  Loaded %d objects.\n", objcount);
!     debug(1, "  Expired %d objects.\n", expcount);
      debug(1, "  Took %d seconds (%6.1lf objects/sec).\n",
  	  r > 0 ? r : 0, (double) objcount / (r > 0 ? r : 1));
      debug(1, "  store_swap_size = %dk\n", store_swap_size);
--- 1340,1350 ----
      stop = time(NULL);
      r = stop - start;
      debug(1, "Finished rebuilding storage from disk image.\n");
!     debug(1, "  %7d Lines read from previous logfile.\n", linecount);
!     debug(1, "  %7d Objects loaded.\n", objcount);
!     debug(1, "  %7d Ojbects expired.\n", expcount);
!     debug(1, "  %7d Duplicate URLs purged.\n", dupcount);
!     debug(1, "  %7d Swapfile clashes avoided.\n", clashcount);
      debug(1, "  Took %d seconds (%6.1lf objects/sec).\n",
  	  r > 0 ? r : 0, (double) objcount / (r > 0 ? r : 1));
      debug(1, "  store_swap_size = %dk\n", store_swap_size);
Index: src/common/include/version.h
===================================================================
RCS file: /projects/agile/cvs/harvest/src/common/include/version.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -c -r1.3 -r1.4
*** 1.3	1995/09/06 20:51:55
--- 1.4	1995/09/10 05:51:07
***************
*** 2,6 ****
   *  HARVEST_VERSION - String for version id of this distribution
   */
  #ifndef HARVEST_VERSION
! #define HARVEST_VERSION	"1.3 pl 0"
  #endif
--- 2,6 ----
   *  HARVEST_VERSION - String for version id of this distribution
   */
  #ifndef HARVEST_VERSION
! #define HARVEST_VERSION	"1.3 pl 1"
  #endif
