Index: harvest/ChangeLog
diff -c harvest/ChangeLog:2.12 harvest/ChangeLog:2.18
*** harvest/ChangeLog:2.12	Mon Jun  9 19:07:21 1997
--- harvest/ChangeLog	Mon Jun 16 21:51:56 1997
***************
*** 1,4 ****
--- 1,15 ----
  Changes in current version
+ 	- Replaced HTMLparse with a newer version from the Mosaic 2.7b5
+ 	  which handles comments correctly (Simon Wilkinson)
+         - Changed Postscript.sum to a sh script, so stderr doesn't corrupt the
+ 	  generated SOIF (Simon Wilkinson)
+         - Added some #includes for AIX compatibility (Simon Wilkinson)
+         - Default url-filter now blocks VRML files (Craig Counterman)
+ 	- Perl scripts which forced /usr/local/harvest changed 
+ 	  (Craig Counterman)
+ 	- Altered rfc1738 unescaping so it can cope with badly formed URLs
+ 	  (Simon Wilkinson)
+ 	- Assorted changes for compilation under BSDI (Simon Wilkinson)
  	- Fixed configure files so libraries are included in correct order
            for Solaris (Simon Wilkinson)
  	- Fixed SGML.sum so that all debug output is sent to STDERR so it
Index: harvest/components/broker/standard/WWW/BrokerQuery.pl
diff -c harvest/components/broker/standard/WWW/BrokerQuery.pl:2.4 harvest/components/broker/standard/WWW/BrokerQuery.pl:2.5
*** harvest/components/broker/standard/WWW/BrokerQuery.pl:2.4	Mon Jun  9 18:35:12 1997
--- harvest/components/broker/standard/WWW/BrokerQuery.pl	Fri Jun 13 02:04:21 1997
***************
*** 2,14 ****
  #  *MUST* have the above line.  httpd cannot run this program without it!
  
  #  Change this variable to your HARVEST_HOME
! $ENV{'HARVEST_HOME'} = "/usr/local/harvest";
  
  #  Set this to a location for BrokerQuery.log, or to /dev/null
  #  $BQLOG = "/usr/local/etc/httpd/logs/BrokerQuery.log";
  $BQLOG = "/dev/null";
  
! $rcsid = 'BrokerQuery.pl,v 2.4 1997/06/09 17:35:12 sxw Exp';
  #######################################################################
  #
  #  BrokerQuery.pl - Customizable WWW Interface to the Harvest Broker
--- 2,15 ----
  #  *MUST* have the above line.  httpd cannot run this program without it!
  
  #  Change this variable to your HARVEST_HOME
! $ENV{'HARVEST_HOME'} = "/usr/local/harvest" 
!     unless defined($ENV{'HARVEST_HOME'});
  
  #  Set this to a location for BrokerQuery.log, or to /dev/null
  #  $BQLOG = "/usr/local/etc/httpd/logs/BrokerQuery.log";
  $BQLOG = "/dev/null";
  
! $rcsid = 'BrokerQuery.pl,v 2.5 1997/06/13 01:04:21 sxw Exp';
  #######################################################################
  #
  #  BrokerQuery.pl - Customizable WWW Interface to the Harvest Broker
***************
*** 95,101 ****
  $DIR = &mydir ($0);
  @X = split ('/', $0); $MYNAME = pop @X;
  $ENV{'TMPDIR'} = "/tmp" unless defined($ENV{'TMPDIR'});
- $ENV{'HARVEST_HOME'}= "/usr/local/harvest" unless defined($ENV{'HARVEST_HOME'});
  unshift(@INC, "$ENV{'HARVEST_HOME'}/lib");
  
  &not_configured unless (-d $ENV{'HARVEST_HOME'});
--- 96,101 ----
Index: harvest/components/broker/standard/WWW/DisplayObject.c
diff -c harvest/components/broker/standard/WWW/DisplayObject.c:2.1 harvest/components/broker/standard/WWW/DisplayObject.c:2.2
*** harvest/components/broker/standard/WWW/DisplayObject.c:2.1	Fri Mar 21 17:19:13 1997
--- harvest/components/broker/standard/WWW/DisplayObject.c	Tue Jun 10 20:37:22 1997
***************
*** 1,4 ****
! static char rcsid[] = "DisplayObject.c,v 2.1 1997/03/21 17:19:13 sxw Exp";
  /*
   *  DisplayObject.c - httpd-based CGI program that HTML-ifies a
   *  SOIF Object for clients.
--- 1,4 ----
! static char rcsid[] = "DisplayObject.c,v 2.2 1997/06/10 19:37:22 sxw Exp";
  /*
   *  DisplayObject.c - httpd-based CGI program that HTML-ifies a
   *  SOIF Object for clients.
***************
*** 215,221 ****
  int n;
  {
  	extern int sys_nerr;
! #if !defined(__FreeBSD__) && !defined(__NetBSD__)
  	extern char *sys_errlist[];
  #endif
  
--- 215,221 ----
  int n;
  {
  	extern int sys_nerr;
! #if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__bsdi__)
  	extern char *sys_errlist[];
  #endif
  
Index: harvest/components/broker/standard/WWW/GathererAdmin.pl.cgi
diff -c harvest/components/broker/standard/WWW/GathererAdmin.pl.cgi:2.1 harvest/components/broker/standard/WWW/GathererAdmin.pl.cgi:2.2
*** harvest/components/broker/standard/WWW/GathererAdmin.pl.cgi:2.1	Fri Mar 21 17:19:14 1997
--- harvest/components/broker/standard/WWW/GathererAdmin.pl.cgi	Fri Jun 13 02:06:38 1997
***************
*** 3,9 ****
  
  # GathererAdmin.pl.cgi - A CGI interface to gatherer configuration
  #
! # GathererAdmin.pl.cgi,v 2.1 1997/03/21 17:19:14 sxw Exp
  #
  # This is a work in progress
  #
--- 3,9 ----
  
  # GathererAdmin.pl.cgi - A CGI interface to gatherer configuration
  #
! # GathererAdmin.pl.cgi,v 2.2 1997/06/13 01:06:38 sxw Exp
  #
  # This is a work in progress
  #
***************
*** 39,45 ****
  # 
  
  #  Change this variable to your HARVEST_HOME
! $ENV{'HARVEST_HOME'} = "/usr/local/harvest";
  $HH=$ENV{'HARVEST_HOME'};
  
  #  Set this to a location for BrokerQuery.log, or to /dev/null
--- 39,46 ----
  # 
  
  #  Change this variable to your HARVEST_HOME
! $ENV{'HARVEST_HOME'} = "/usr/local/harvest"
!     unless (defined($ENV{'HARVEST_HOME'}));
  $HH=$ENV{'HARVEST_HOME'};
  
  #  Set this to a location for BrokerQuery.log, or to /dev/null
***************
*** 49,55 ****
  $DIR = &mydir ($0);
  $MYNAME = $0;
  $ENV{'TMPDIR'} = "/tmp" unless defined($ENV{'TMPDIR'});
! $ENV{'HARVEST_HOME'}= "/usr/local/harvest" unless defined($ENV{'HARVEST_HOME'});
  unshift(@INC, "$ENV{'HARVEST_HOME'}/lib");
  
  require 'socket.ph';	# not sys/socket.ph, we use $HARVEST_HOME/lib/socket.ph
--- 50,56 ----
  $DIR = &mydir ($0);
  $MYNAME = $0;
  $ENV{'TMPDIR'} = "/tmp" unless defined($ENV{'TMPDIR'});
! 
  unshift(@INC, "$ENV{'HARVEST_HOME'}/lib");
  
  require 'socket.ph';	# not sys/socket.ph, we use $HARVEST_HOME/lib/socket.ph
Index: harvest/components/broker/standard/WWW/nph-search
diff -c harvest/components/broker/standard/WWW/nph-search:2.5 harvest/components/broker/standard/WWW/nph-search:2.6
*** harvest/components/broker/standard/WWW/nph-search:2.5	Mon Jun  9 18:35:12 1997
--- harvest/components/broker/standard/WWW/nph-search	Fri Jun 13 02:06:39 1997
***************
*** 2,14 ****
  #  *MUST* have the above line.  httpd cannot run this program without it!
  
  #  Change this variable to your HARVEST_HOME
! $ENV{'HARVEST_HOME'} = "/usr/local/harvest";
  
  #  Set this to a location for BrokerQuery.log, or to /dev/null
  #  $BQLOG = "/usr/local/etc/httpd/logs/BrokerQuery.log";
  $BQLOG = "/dev/null";
  
! $rcsid = 'nph-search,v 2.5 1997/06/09 17:35:12 sxw Exp';
  #######################################################################
  #
  #  nph-search - Customizable WWW Interface to the Harvest Broker
--- 2,15 ----
  #  *MUST* have the above line.  httpd cannot run this program without it!
  
  #  Change this variable to your HARVEST_HOME
! $ENV{'HARVEST_HOME'} = "/usr/local/harvest" 
!     unless defined($ENV{'HARVEST_HOME'});
  
  #  Set this to a location for BrokerQuery.log, or to /dev/null
  #  $BQLOG = "/usr/local/etc/httpd/logs/BrokerQuery.log";
  $BQLOG = "/dev/null";
  
! $rcsid = 'nph-search,v 2.6 1997/06/13 01:06:39 sxw Exp';
  #######################################################################
  #
  #  nph-search - Customizable WWW Interface to the Harvest Broker
***************
*** 121,127 ****
  $DIR = &mydir ($0);
  @X = split ('/', $0); $MYNAME = pop @X;
  $ENV{'TMPDIR'} = "/tmp" unless defined($ENV{'TMPDIR'});
- $ENV{'HARVEST_HOME'}= "/usr/local/harvest" unless defined($ENV{'HARVEST_HOME'});
  unshift(@INC, "$ENV{'HARVEST_HOME'}/lib");
  
  &not_configured unless (-d $ENV{'HARVEST_HOME'});
--- 122,127 ----
Index: harvest/components/broker/standard/glimpse/agrep/agrep.c
diff -c harvest/components/broker/standard/glimpse/agrep/agrep.c:2.1 harvest/components/broker/standard/glimpse/agrep/agrep.c:2.2
*** harvest/components/broker/standard/glimpse/agrep/agrep.c:2.1	Fri May  2 21:03:12 1997
--- harvest/components/broker/standard/glimpse/agrep/agrep.c	Tue Jun 10 20:13:01 1997
***************
*** 3,10 ****
   * bgopal: (1993-4) added a library interface and removed some bugs: also
   * selectively modified many routines to work with our text-compression algo.
   */
- #include <sys/stat.h>
  #include <sys/types.h>
  #include "agrep.h"
  #include "checkfile.h"
  #include <errno.h>
--- 3,10 ----
   * bgopal: (1993-4) added a library interface and removed some bugs: also
   * selectively modified many routines to work with our text-compression algo.
   */
  #include <sys/types.h>
+ #include <sys/stat.h>
  #include "agrep.h"
  #include "checkfile.h"
  #include <errno.h>
Index: harvest/components/gatherer/standard/pstext/libs/src/sio/sprint.c
diff -c harvest/components/gatherer/standard/pstext/libs/src/sio/sprint.c:2.0 harvest/components/gatherer/standard/pstext/libs/src/sio/sprint.c:2.1
*** harvest/components/gatherer/standard/pstext/libs/src/sio/sprint.c:2.0	Sun Mar 16 22:07:09 1997
--- harvest/components/gatherer/standard/pstext/libs/src/sio/sprint.c	Tue Jun 10 20:27:40 1997
***************
*** 185,197 ****
  	register char *s = buf ;
  	register char *p ;
  	int decimal_point ;
! # if !defined(__FreeBSD__) && !defined(__NetBSD__)
  	char *ecvt(), *fcvt() ;
  # endif
  	char *conv_10() ;
  	char *strcpy() ;
  		
! # if !defined(__FreeBSD__) && !defined(__NetBSD__)
  	if ( format == 'f' )
  		p = fcvt( num, precision, &decimal_point, is_negative ) ;
  	else /* either e or E format */
--- 185,197 ----
  	register char *s = buf ;
  	register char *p ;
  	int decimal_point ;
! # if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__bsdi__)
  	char *ecvt(), *fcvt() ;
  # endif
  	char *conv_10() ;
  	char *strcpy() ;
  		
! # if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__bsdi__)
  	if ( format == 'f' )
  		p = fcvt( num, precision, &decimal_point, is_negative ) ;
  	else /* either e or E format */
***************
*** 417,423 ****
  	boolean_e adjust_width ;
  	bool_int is_negative ;
  
! # if !defined(__FreeBSD__) && !defined(__NetBSD__)
  	char *gcvt() ;
  # endif
  	char *strchr() ;
--- 417,423 ----
  	boolean_e adjust_width ;
  	bool_int is_negative ;
  
! # if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__bsdi__)
  	char *gcvt() ;
  # endif
  	char *strchr() ;
***************
*** 645,651 ****
  					/*
  					 * We use &num_buf[ 1 ], so that we have room for the sign
  					 */
! # if !defined(__FreeBSD__) && !defined(__NetBSD__)
  					s = gcvt( va_arg( ap, double ), precision, &num_buf[ 1 ] ) ;
  # endif
  					if ( *s == '-' )
--- 645,651 ----
  					/*
  					 * We use &num_buf[ 1 ], so that we have room for the sign
  					 */
! # if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__bsdi__)
  					s = gcvt( va_arg( ap, double ), precision, &num_buf[ 1 ] ) ;
  # endif
  					if ( *s == '-' )
Index: harvest/components/gatherer/standard/summarizers/PostScript.sum
diff -c harvest/components/gatherer/standard/summarizers/PostScript.sum:2.0 harvest/components/gatherer/standard/summarizers/PostScript.sum:2.1
*** harvest/components/gatherer/standard/summarizers/PostScript.sum:2.0	Sun Mar 16 22:08:29 1997
--- harvest/components/gatherer/standard/summarizers/PostScript.sum	Sat Jun 14 17:28:40 1997
***************
*** 1,88 ****
! #!/bin/csh -f
  #
! #  PostScript.sum - converts the PostScript to ASCII
  #
! #  PostScript.sum,v 1.12 1995/09/05 20:17:27 hardy Exp
  #
! ######################################################################
! #  Copyright (c) 1994, 1995.  All rights reserved.
  #  
! #    The Harvest software was developed by the Internet Research Task
! #    Force Research Group on Resource Discovery (IRTF-RD):
  #  
! #          Mic Bowman of Transarc Corporation.
! #          Peter Danzig of the University of Southern California.
! #          Darren R. Hardy of the University of Colorado at Boulder.
! #          Udi Manber of the University of Arizona.
! #          Michael F. Schwartz of the University of Colorado at Boulder.
! #          Duane Wessels of the University of Colorado at Boulder.
! #  
! #    This copyright notice applies to software in the Harvest
! #    ``src/'' directory only.  Users should consult the individual
! #    copyright notices in the ``components/'' subdirectories for
! #    copyright information about other software bundled with the
! #    Harvest source code distribution.
! #  
! #  TERMS OF USE
! #    
! #    The Harvest software may be used and re-distributed without
! #    charge, provided that the software origin and research team are
! #    cited in any use of the system.  Most commonly this is
! #    accomplished by including a link to the Harvest Home Page
! #    (http://harvest.cs.colorado.edu/) from the query page of any
! #    Broker you deploy, as well as in the query result pages.  These
! #    links are generated automatically by the standard Broker
! #    software distribution.
! #    
! #    The Harvest software is provided ``as is'', without express or
! #    implied warranty, and with no support nor obligation to assist
! #    in its use, correction, modification or enhancement.  We assume
! #    no liability with respect to the infringement of copyrights,
! #    trade secrets, or any patents, and are not responsible for
! #    consequential damages.  Proper use of the Harvest software is
! #    entirely the responsibility of the user.
! #  
! #  DERIVATIVE WORKS
! #  
! #    Users may make derivative works from the Harvest software, subject 
! #    to the following constraints:
! #  
! #      - You must include the above copyright notice and these 
! #        accompanying paragraphs in all forms of derivative works, 
! #        and any documentation and other materials related to such 
! #        distribution and use acknowledge that the software was 
! #        developed at the above institutions.
! #  
! #      - You must notify IRTF-RD regarding your distribution of 
! #        the derivative work.
! #  
! #      - You must clearly notify users that your are distributing 
! #        a modified version and not the original Harvest software.
! #  
! #      - Any derivative product is also subject to these copyright 
! #        and use restrictions.
! #  
! #    Note that the Harvest software is NOT in the public domain.  We
! #    retain copyright, as specified above.
! #  
! #  HISTORY OF FREE SOFTWARE STATUS
! #  
! #    Originally we required sites to license the software in cases
! #    where they were going to build commercial products/services
! #    around Harvest.  In June 1995 we changed this policy.  We now
! #    allow people to use the core Harvest software (the code found in
! #    the Harvest ``src/'' directory) for free.  We made this change
! #    in the interest of encouraging the widest possible deployment of
! #    the technology.  The Harvest software is really a reference
! #    implementation of a set of protocols and formats, some of which
! #    we intend to standardize.  We encourage commercial
! #    re-implementations of code complying to this set of standards.  
! #  
! #  
  pstext -e $1
! if ($status) then
  	ps2txt $1 | fmt | head -20 | wrapit "Partial-Text"
  else
! 	pstext $1 | head -500 | Text.sum 
! endif
  exit 0
--- 1,36 ----
! #!/bin/sh
! #############################################################################
  #
! #  Harvest Indexer http://www.tardis.ed.ac.uk/harvest/
! #  ---------------------------------------------------
  #
! #  The Harvest Indexer is a continued development of code developed by
! #  the Harvest Project. Development is carried out by numerous individuals
! #  in the Internet community, and is not officially connected with the
! #  original Harvest Project or its funding sources.
! # 
! #  Please mail harvest@tardis.ed.ac.uk if you are interested in participating
! #  in the development effort.
  #
! #  This program is free software; you can redistribute it and/or modify
! #  it under the terms of the GNU General Public License as published by
! #  the Free Software Foundation; either version 2 of the License, or
! #  (at your option) any later version.
  #  
! #  This program is distributed in the hope that it will be useful,
! #  but WITHOUT ANY WARRANTY; without even the implied warranty of
! #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! #  GNU General Public License for more details.
  #  
! #  You should have received a copy of the GNU General Public License
! #  along with this program; if not, write to the Free Software
! #  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! # 
! 
  pstext -e $1
! if [ ! $? = 0 ] ; then
  	ps2txt $1 | fmt | head -20 | wrapit "Partial-Text"
  else
! 	pstext $1 | head -500 | Text.sum
! fi
  exit 0
Index: harvest/components/gatherer/standard/unbinhex/fileio/wrfile.c
diff -c harvest/components/gatherer/standard/unbinhex/fileio/wrfile.c:2.0 harvest/components/gatherer/standard/unbinhex/fileio/wrfile.c:2.1
*** harvest/components/gatherer/standard/unbinhex/fileio/wrfile.c:2.0	Sun Mar 16 22:09:34 1997
--- harvest/components/gatherer/standard/unbinhex/fileio/wrfile.c	Tue Jun 10 20:26:57 1997
***************
*** 1,4 ****
! #if defined(TYPES_H) || defined(__FreeBSD__) || defined(__NetBSD__)
  #include <sys/types.h>
  #endif /* TYPES_H */
  #include <sys/stat.h>
--- 1,4 ----
! #if defined(TYPES_H) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__bsdi__)
  #include <sys/types.h>
  #endif /* TYPES_H */
  #include <sys/stat.h>
Index: harvest/components/gatherer/standard/unbinhex/hexbin/hexbin.c
diff -c harvest/components/gatherer/standard/unbinhex/hexbin/hexbin.c:2.0 harvest/components/gatherer/standard/unbinhex/hexbin/hexbin.c:2.1
*** harvest/components/gatherer/standard/unbinhex/hexbin/hexbin.c:2.0	Sun Mar 16 22:09:52 1997
--- harvest/components/gatherer/standard/unbinhex/hexbin/hexbin.c	Tue Jun 10 20:26:32 1997
***************
*** 1,4 ****
! #if defined(TYPES_H) || defined(__FreeBSD__) || defined(__NetBSD__)
  #include <sys/types.h>
  #endif /* TYPES_H */
  #include <sys/stat.h>
--- 1,4 ----
! #if defined(TYPES_H) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__bsdi__)
  #include <sys/types.h>
  #endif /* TYPES_H */
  #include <sys/stat.h>
Index: harvest/src/broker/main.c
diff -c harvest/src/broker/main.c:2.2 harvest/src/broker/main.c:2.3
*** harvest/src/broker/main.c:2.2	Wed Mar 26 16:36:59 1997
--- harvest/src/broker/main.c	Fri Jun 13 02:07:23 1997
***************
*** 1,4 ****
! static char rcsid[] = "main.c,v 2.2 1997/03/26 16:36:59 sxw Exp";
  /*
   *  main.c -- main module of the Harvest Broker.
   *
--- 1,4 ----
! static char rcsid[] = "main.c,v 2.3 1997/06/13 01:07:23 sxw Exp";
  /*
   *  main.c -- main module of the Harvest Broker.
   *
***************
*** 799,805 ****
  #if defined(HAVE_SRAND48)
  	srand48(time(NULL));
  #elif defined(HAVE_SRANDOM)
- 	int srandom();
  	(void) srandom(time(NULL));
  #else
  	srand(time(NULL));
--- 799,804 ----
Index: harvest/src/broker/stor_man.c
diff -c harvest/src/broker/stor_man.c:2.1 harvest/src/broker/stor_man.c:2.2
*** harvest/src/broker/stor_man.c:2.1	Fri Mar 21 17:20:13 1997
--- harvest/src/broker/stor_man.c	Tue Jun 10 20:45:08 1997
***************
*** 1,4 ****
! static char rcsid[] = "stor_man.c,v 2.1 1997/03/21 17:20:13 sxw Exp";
  /*
   *   stor_man.c -- Stores and retreives Summary Objects in the Broker.
   *   This storage manager is based on the UNIX file system.
--- 1,4 ----
! static char rcsid[] = "stor_man.c,v 2.2 1997/06/10 19:45:08 sxw Exp";
  /*
   *   stor_man.c -- Stores and retreives Summary Objects in the Broker.
   *   This storage manager is based on the UNIX file system.
***************
*** 259,265 ****
--- 259,267 ----
  	extern long lrand48();
  	return ((fd_t) lrand48());
  #elif defined(HAVE_RANDOM)
+ #ifndef random
  	extern int random();
+ #endif
  	return ((fd_t) random());
  #else
  	extern int rand();
Index: harvest/src/common/url/ftpget.c
diff -c harvest/src/common/url/ftpget.c:2.0 harvest/src/common/url/ftpget.c:2.1
*** harvest/src/common/url/ftpget.c:2.0	Sun Mar 16 22:15:42 1997
--- harvest/src/common/url/ftpget.c	Fri Jun 13 02:07:54 1997
***************
*** 91,101 ****
--- 91,103 ----
  #include <signal.h>
  #include <sys/types.h>
  #include <sys/stat.h>
+ #include <time.h>
  
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
  
+ 
  #include "util.h"
  
  typedef struct _ext_table_entry {
Index: harvest/src/common/url/rfc1738.c
diff -c harvest/src/common/url/rfc1738.c:2.1 harvest/src/common/url/rfc1738.c:2.2
*** harvest/src/common/url/rfc1738.c:2.1	Fri Mar 21 18:01:25 1997
--- harvest/src/common/url/rfc1738.c	Thu Jun 12 23:26:27 1997
***************
*** 1,4 ****
! static char rcsid[] = "rfc1738.c,v 2.1 1997/03/21 18:01:25 sxw Exp";
  /*
   *  rfc1738.c - code to comply with RFC 1738 
   *
--- 1,4 ----
! static char rcsid[] = "rfc1738.c,v 2.2 1997/06/12 22:26:27 sxw Exp";
  /*
   *  rfc1738.c - code to comply with RFC 1738 
   *
***************
*** 184,189 ****
--- 184,190 ----
  /*
   *  rfc1738_unescape() - Converts escaped characters (%xy numbers) in 
   *  given the string.  %% is a %. %ab is the 8-bit hexadecimal number "ab"
+  *  Adapted to cope with single %s and with invalid %ab's
   */
  void rfc1738_unescape(s)
       char *s;
***************
*** 194,200 ****
  
  	for (i = j = 0; s[j]; i++, j++) {
  		s[i] = s[j];
! 		if (s[i] == '%') {
  			hexnum[0] = s[++j];
  			if (hexnum[0] != '%') {
  				hexnum[1] = s[++j];
--- 195,202 ----
  
  	for (i = j = 0; s[j]; i++, j++) {
  		s[i] = s[j];
! 		if (s[i] == '%' && s[j+1]!='\0' && s[j+2]!='\0' &&
! 		    isxdigit(s[j+1]) && isxdigit(s[j+2])) {
  			hexnum[0] = s[++j];
  			if (hexnum[0] != '%') {
  				hexnum[1] = s[++j];
Index: harvest/src/common/url/test-socket-ph.pl
diff -c harvest/src/common/url/test-socket-ph.pl:2.0 harvest/src/common/url/test-socket-ph.pl:2.1
*** harvest/src/common/url/test-socket-ph.pl:2.0	Sun Mar 16 22:16:10 1997
--- harvest/src/common/url/test-socket-ph.pl	Fri Jun 13 02:06:43 1997
***************
*** 16,23 ****
  
  #  Change this variable to your HARVEST_HOME
  #
- $ENV{'HARVEST_HOME'} = "/usr/local/harvest";
- 
  $ENV{'HARVEST_HOME'}= "/usr/local/harvest"
  	unless defined($ENV{'HARVEST_HOME'});
  
--- 16,21 ----
Index: harvest/src/gatherer/enumerate/HTMLparse.c
diff -c harvest/src/gatherer/enumerate/HTMLparse.c:2.1 harvest/src/gatherer/enumerate/HTMLparse.c:2.2
*** harvest/src/gatherer/enumerate/HTMLparse.c:2.1	Fri Mar 21 19:21:21 1997
--- harvest/src/gatherer/enumerate/HTMLparse.c	Fri Jun 13 20:20:50 1997
***************
*** 1,8 ****
! /* Adapated from NCSA Mosaic to be used with the Harvest system 
!  *
!  * HTMLparse.c,v 2.1 1997/03/21 19:21:21 sxw Exp
!  *
!  */
  /****************************************************************************
   * NCSA Mosaic for the X Window System                                      *
   * Software Development Group                                               *
--- 1,7 ----
! static char rcsid[]="HTMLparse.c,v 2.2 1997/06/13 19:20:50 sxw Exp";
! /*  
!  * HTMLparse.c taken from Mosaic 2.7b5 with some alterations for Harvest
!  * 
  /****************************************************************************
   * NCSA Mosaic for the X Window System                                      *
   * Software Development Group                                               *
***************
*** 71,106 ****
  
  #include "util.h"
  
  #ifdef NOT_ASCII
  #define TOLOWER(x)	(tolower(x))
  #else
  
- static struct mark_up *AddObj();
- static void FreeObjList();
- static int ParseMarkType();
- 
- extern char *Url;
- 
  /*
   * A hack to speed up caseless_equal.  Thanks to Quincey Koziol for
   * developing it for me
   */
! unsigned char map_table[256] =
! {
!     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
!     24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
!     45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98,
!     99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
!     116, 117, 118, 119, 120, 121, 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
!     103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
!     120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
!     137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
!     154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
!     171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187,
!     188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
!     205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
!     222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
!     239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255};
  
  #define TOLOWER(x)	(map_table[x])
  #endif /* NOT_ASCII */
--- 70,105 ----
  
  #include "util.h"
  
+ static void FreeObjList();
+ static struct mark_up *AddObj();
+ 
+ char *ParseMarkTag();
+ 
+ extern int tableSupportEnabled;
+ 
  #ifdef NOT_ASCII
  #define TOLOWER(x)	(tolower(x))
  #else
  
  /*
   * A hack to speed up caseless_equal.  Thanks to Quincey Koziol for
   * developing it for me
   */
! unsigned char map_table[256]={
!     0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,
!     24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,
!     45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,97,98,
!     99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,
!     116,117,118,119,120,121,122,91,92,93,94,95,96,97,98,99,100,101,102,
!     103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,
!     120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,
!     137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,
!     154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,
!     171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,
!     188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,
!     205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,
!     222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,
!     239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};
  
  #define TOLOWER(x)	(map_table[x])
  #endif /* NOT_ASCII */
***************
*** 111,136 ****
   * The strings must be of the same length to be equal.
   * return 1 if equal, 0 otherwise.
   */
! int caseless_equal(str1, str2)
!      char *str1;
!      char *str2;
  {
! 	if ((str1 == NULL) || (str2 == NULL)) {
! 		return (0);
  	}
! 	while ((*str1 != '\0') && (*str2 != '\0')) {
! 		if (TOLOWER((int) *str1) != TOLOWER((int) *str2)) {
! 			return (0);
  		}
  		str1++;
  		str2++;
  	}
  
! 	if ((*str1 == '\0') && (*str2 == '\0')) {
! 		return (1);
! 	} else {
! 		return (0);
  	}
  }
  
  
--- 110,143 ----
   * The strings must be of the same length to be equal.
   * return 1 if equal, 0 otherwise.
   */
! int
! caseless_equal(str1, str2)
! 	char *str1;
! 	char *str2;
  {
! 	if ((str1 == NULL)||(str2 == NULL))
! 	{
! 		return(0);
  	}
! 
! 	while ((*str1 != '\0')&&(*str2 != '\0'))
! 	{
! 		if (TOLOWER(*str1) != TOLOWER(*str2))
! 		{
! 			return(0);
  		}
  		str1++;
  		str2++;
  	}
  
! 	if ((*str1 == '\0')&&(*str2 == '\0'))
! 	{
! 		return(1);
  	}
+ 	else
+ 	{
+ 		return(0);
+ 	}
  }
  
  
***************
*** 139,166 ****
   * The strings must both be at least of length count to be equal.
   * return 1 if equal, 0 otherwise.
   */
! int caseless_equal_prefix(str1, str2, cnt)
!      char *str1;
!      char *str2;
!      int cnt;
  {
  	int i;
  
! 	if ((str1 == NULL) || (str2 == NULL)) {
! 		return (0);
  	}
! 	if (cnt < 1) {
! 		return (1);
  	}
! 	for (i = 0; i < cnt; i++) {
! 		if (TOLOWER((int) *str1) != TOLOWER((int) *str2)) {
! 			return (0);
  		}
  		str1++;
  		str2++;
  	}
  
! 	return (1);
  }
  
  
--- 146,180 ----
   * The strings must both be at least of length count to be equal.
   * return 1 if equal, 0 otherwise.
   */
! int
! caseless_equal_prefix(str1, str2, cnt)
! 	char *str1;
! 	char *str2;
! 	int cnt;
  {
  	int i;
  
! 	if ((str1 == NULL)||(str2 == NULL))
! 	{
! 		return(0);
  	}
! 
! 	if (cnt < 1)
! 	{
! 		return(1);
  	}
! 
! 	for (i=0; i < cnt; i++)
! 	{
! 		if (TOLOWER(*str1) != TOLOWER(*str2))
! 		{
! 			return(0);
  		}
  		str1++;
  		str2++;
  	}
  
! 	return(1);
  }
  
  
***************
*** 172,179 ****
   * txt buffer.  The resultant string will probably be shorter,
   * it can never get longer.
   */
! void clean_white_space(txt)
!      char *txt;
  {
  	char *ptr;
  	char *start;
--- 186,194 ----
   * txt buffer.  The resultant string will probably be shorter,
   * it can never get longer.
   */
! void
! clean_white_space(txt)
! 	char *txt;
  {
  	char *ptr;
  	char *start;
***************
*** 184,190 ****
  	/*
  	 * Remove leading white space
  	 */
! 	while (isspace((int) *ptr)) {
  		ptr++;
  	}
  
--- 199,206 ----
  	/*
  	 * Remove leading white space
  	 */
! 	while (isspace((int)*ptr))
! 	{
  		ptr++;
  	}
  
***************
*** 191,229 ****
  	/*
  	 * find a word, copying if we removed some space already
  	 */
! 	if (start == ptr) {
! 		while ((!isspace((int) *ptr)) && (*ptr != '\0')) {
  			ptr++;
  		}
  		start = ptr;
! 	} else {
! 		while ((!isspace((int) *ptr)) && (*ptr != '\0')) {
  			*start++ = *ptr++;
  		}
  	}
  
! 	while (*ptr != '\0') {
  		/*
  		 * Remove trailing whitespace.
  		 */
! 		while (isspace((int) *ptr)) {
  			ptr++;
  		}
! 		if (*ptr == '\0') {
  			break;
  		}
  		/*
  		 * If there are more words, insert a space and if space was 
  		 * removed move up remaining text.
  		 */
  		*start++ = ' ';
! 		if (start == ptr) {
! 			while ((!isspace((int) *ptr)) && (*ptr != '\0')) {
  				ptr++;
  			}
  			start = ptr;
! 		} else {
! 			while ((!isspace((int) *ptr)) && (*ptr != '\0')) {
  				*start++ = *ptr++;
  			}
  		}
--- 207,259 ----
  	/*
  	 * find a word, copying if we removed some space already
  	 */
! 	if (start == ptr)
! 	{
! 		while ((!isspace((int)*ptr))&&(*ptr != '\0'))
! 		{
  			ptr++;
  		}
  		start = ptr;
! 	}
! 	else
! 	{
! 		while ((!isspace((int)*ptr))&&(*ptr != '\0'))
! 		{
  			*start++ = *ptr++;
  		}
  	}
  
! 	while (*ptr != '\0')
! 	{
  		/*
  		 * Remove trailing whitespace.
  		 */
! 		while (isspace((int)*ptr))
! 		{
  			ptr++;
  		}
! 		if (*ptr == '\0')
! 		{
  			break;
  		}
+ 
  		/*
  		 * If there are more words, insert a space and if space was 
  		 * removed move up remaining text.
  		 */
  		*start++ = ' ';
! 		if (start == ptr)
! 		{
! 			while ((!isspace((int)*ptr))&&(*ptr != '\0'))
! 			{
  				ptr++;
  			}
  			start = ptr;
! 		}
! 		else
! 		{
! 			while ((!isspace((int)*ptr))&&(*ptr != '\0'))
! 			{
  				*start++ = *ptr++;
  			}
  		}
***************
*** 241,254 ****
   * don't want to type everything twice, I always use caseless_equal_prefix
   * Turns out the escapes are case sensitive, use strncmp.
   * termination states:
!  *      0: terminated with a ';'
!  *      1: unterminated
!  *      2: terminated with whitespace
   */
! char ExpandEscapes(esc, endp, termination)
!      char *esc;
!      char **endp;
!      int termination;
  {
  	int cnt;
  	char val;
--- 271,285 ----
   * don't want to type everything twice, I always use caseless_equal_prefix
   * Turns out the escapes are case sensitive, use strncmp.
   * termination states:
!  *	0: terminated with a ';'
!  *	1: unterminated
!  *	2: terminated with whitespace
   */
! char
! ExpandEscapes(esc, endp, termination)
! 	char *esc;
! 	char **endp;
! 	int termination;
  {
  	int cnt;
  	char val;
***************
*** 257,302 ****
  	unterminated = (termination & 0x01);
  
  	esc++;
! 	if (*esc == '#') {
! 		if (unterminated) {
  			char *tptr;
  			char tchar;
  
! 			tptr = (char *) (esc + 1);
! 			while (isdigit((int) *tptr)) {
  				tptr++;
  			}
  			tchar = *tptr;
  			*tptr = '\0';
! 			val = (char) atoi((esc + 1));
  			*tptr = tchar;
  			*endp = tptr;
- 		} else {
- 			val = (char) atoi((esc + 1));
- 			*endp = (char *) (esc + strlen(esc));
  		}
! 	} else {
  		cnt = 0;
! 		while (AmpEscapes[cnt].tag != NULL) {
! 			if (strncmp(esc, AmpEscapes[cnt].tag,
! 				strlen(AmpEscapes[cnt].tag)) == 0) {
  				val = AmpEscapes[cnt].value;
! 				*endp = (char *) (esc +
! 				    strlen(AmpEscapes[cnt].tag));
  				break;
  			}
  			cnt++;
  		}
! 		if (AmpEscapes[cnt].tag == NULL) {
  #ifdef VERBOSE
! 			errorlog("Error bad & string\n");
  #endif
  			val = '\0';
! 			*endp = (char *) NULL;
  		}
  	}
  
! 	return (val);
  }
  
  
--- 288,345 ----
  	unterminated = (termination & 0x01);
  
  	esc++;
! 	if (*esc == '#')
! 	{
! 		if (unterminated)
! 		{
  			char *tptr;
  			char tchar;
  
! 			tptr = (char *)(esc + 1);
! 			while (isdigit((int)*tptr))
! 			{
  				tptr++;
  			}
  			tchar = *tptr;
  			*tptr = '\0';
! 			val = (char)atoi((esc + 1));
  			*tptr = tchar;
  			*endp = tptr;
  		}
! 		else
! 		{
! 			val = (char)atoi((esc + 1));
! 			*endp = (char *)(esc + strlen(esc));
! 		}
! 	}
! 	else
! 	{
! 		int escLen, ampLen;
  		cnt = 0;
! 		escLen = strlen(esc);	
! 		while (AmpEscapes[cnt].tag != NULL)
! 		{
! 			ampLen = strlen(AmpEscapes[cnt].tag);
! 			if ((escLen == ampLen) && (strncmp(esc, AmpEscapes[cnt].tag, ampLen) == 0))
! 			{
  				val = AmpEscapes[cnt].value;
! 				*endp = (char *)(esc +
! 					strlen(AmpEscapes[cnt].tag));
  				break;
  			}
  			cnt++;
  		}
! 		if (AmpEscapes[cnt].tag == NULL)
! 		{
  #ifdef VERBOSE
! 		       	errorlog ("Error bad & string\n");
  #endif
  			val = '\0';
! 			*endp = (char *)NULL;
  		}
  	}
  
! 	return(val);
  }
  
  
***************
*** 311,318 ****
   * The cleaning is done by rearranging chars in the passed txt buffer.
   * if any escapes are replaced, the string becomes shorter.
   */
! void clean_text(txt)
!      char *txt;
  {
  	int unterminated;
  	int space_terminated;
--- 354,362 ----
   * The cleaning is done by rearranging chars in the passed txt buffer.
   * if any escapes are replaced, the string becomes shorter.
   */
! void
! clean_text(txt)
! 	char *txt;
  {
  	int unterminated;
  	int space_terminated;
***************
*** 324,342 ****
  	char tchar;
  	char val;
  
! 	if (txt == NULL) {
  		return;
  	}
  	/*
  	 * Fix from "Peter J. Scott" <pjs@euclid.Jpl.Nasa.Gov> Jan 8, 1996:
  	 * Turn carriage returns into spaces.
  	 */
  	ptr = txt;
! 	while (*ptr != '\0') {
! 		if (*ptr == '\r')
! 			*ptr = ' ';
! 		ptr++;
! 	}
  
  	/*
  	 * Quick scan to find escape sequences.
--- 368,389 ----
  	char tchar;
  	char val;
  
! 	if (txt == NULL)
! 	{
  		return;
  	}
+ 
  	/*
  	 * Fix from "Peter J. Scott" <pjs@euclid.Jpl.Nasa.Gov> Jan 8, 1996:
  	 * Turn carriage returns into spaces.
  	 */
  	ptr = txt;
! 	while (*ptr != '\0')
! 	  {
! 	    if (*ptr == '\r')
! 	      *ptr = ' ';
! 	    ptr++;
! 	  }
  
  	/*
  	 * Quick scan to find escape sequences.
***************
*** 344,365 ****
  	 * return if there are none.
  	 */
  	ptr = txt;
! 	while (*ptr != '\0') {
! 		if ((*ptr == '&') &&
! 		    ((isalpha((int) *(ptr + 1))) || (*(ptr + 1) == '#'))) {
  			break;
  		}
  		ptr++;
  	}
! 	if (*ptr == '\0') {
  		return;
  	}
  	/*
  	 * Loop, replaceing escape sequences, and moving up remaining
  	 * text.
  	 */
  	ptr2 = ptr;
! 	while (*ptr != '\0') {
  
  		unterminated = 0;
  		space_terminated = 0;
--- 391,417 ----
  	 * return if there are none.
  	 */
  	ptr = txt;
! 	while (*ptr != '\0')
! 	{
! 		if ((*ptr == '&')&&
! 			((isalpha((int)*(ptr + 1)))||(*(ptr + 1) == '#')))
! 		{
  			break;
  		}
  		ptr++;
  	}
! 	if (*ptr == '\0')
! 	{
  		return;
  	}
+ 
  	/*
  	 * Loop, replaceing escape sequences, and moving up remaining
  	 * text.
  	 */
  	ptr2 = ptr;
! 	while (*ptr != '\0')
! 	{
  
  		unterminated = 0;
  		space_terminated = 0;
***************
*** 367,383 ****
  		 * Extract the escape sequence from start to ptr
  		 */
  		start = ptr;
! 		while ((*ptr != ';') && (!isspace((int) *ptr)) && (*ptr != '\0')) {
  			ptr++;
  		}
! 		if (*ptr == '\0') {
  #ifdef VERBOSE
! 			errorlog("warning:  unterminated & (%s)\n", start);
  #endif
  			unterminated = 1;
! 		} else if (isspace((int) *ptr)) {
  			space_terminated = 1;
  		}
  		/*
  		 * Copy the escape sequence into a separate buffer.
  		 * Then clean spaces so the "& lt ;" = "&lt;" etc.
--- 419,441 ----
  		 * Extract the escape sequence from start to ptr
  		 */
  		start = ptr;
! 		while ((*ptr != ';')&&(!isspace((int)*ptr))&&(*ptr != '\0'))
! 		{
  			ptr++;
  		}
! 		if (*ptr == '\0')
! 		{
  #ifdef VERBOSE
! 		  
! 		        errorlog("warning:  unterminated & (%s)\n",start);
  #endif
  			unterminated = 1;
! 		}
! 		else if (isspace((int)*ptr))
! 		{
  			space_terminated = 1;
  		}
+ 
  		/*
  		 * Copy the escape sequence into a separate buffer.
  		 * Then clean spaces so the "& lt ;" = "&lt;" etc.
***************
*** 385,393 ****
  		 */
  		tchar = *ptr;
  		*ptr = '\0';
! 		text = (char *) malloc(strlen(start) + 1);
! 		if (text == NULL) {
! 			errorlog("Cannot malloc space for & text\n");
  			*ptr = tchar;
  			return;
  		}
--- 443,452 ----
  		 */
  		tchar = *ptr;
  		*ptr = '\0';
! 		text = (char *)malloc(strlen(start) + 1);
! 		if (text == NULL)
! 		{
!    		        errorlog("Cannot malloc space for & text\n");
  			*ptr = tchar;
  			return;
  		}
***************
*** 399,412 ****
  		 * Replace escape sequence with appropriate character
  		 */
  		val = ExpandEscapes(text, &tend,
! 		    ((space_terminated << 1) + unterminated));
! 		if (val != '\0') {
! 			if (unterminated) {
  				tchar = *tend;
  				*tend = '\0';
! 				ptr = (char *) (start + strlen(text) - 1);
  				*tend = tchar;
! 			} else if (space_terminated) {
  				ptr--;
  			}
  			*ptr2 = val;
--- 458,475 ----
  		 * Replace escape sequence with appropriate character
  		 */
  		val = ExpandEscapes(text, &tend,
! 			((space_terminated << 1) + unterminated));
! 		if (val != '\0')
! 		{
! 			if (unterminated)
! 			{
  				tchar = *tend;
  				*tend = '\0';
! 				ptr = (char *)(start + strlen(text) - 1);
  				*tend = tchar;
! 			}
! 			else if (space_terminated)
! 			{
  				ptr--;
  			}
  			*ptr2 = val;
***************
*** 416,424 ****
  		/*
  		 * invalid escape sequence. skip it.
  		 */
! 		else {
  #ifdef VERBOSE
! 			errorlog("Error bad & string\n");
  #endif
  			ptr = start;
  			*ptr2 = *ptr;
--- 479,488 ----
  		/*
  		 * invalid escape sequence. skip it.
  		 */
! 		else
! 		{
  #ifdef VERBOSE
! 		errorlog("Error bad & string\n");
  #endif
  			ptr = start;
  			*ptr2 = *ptr;
***************
*** 431,439 ****
  		 */
  		ptr2++;
  		ptr++;
! 		while (*ptr != '\0') {
! 			if ((*ptr == '&') &&
! 			    ((isalpha((int) *(ptr + 1))) || (*(ptr + 1) == '#'))) {
  				break;
  			}
  			*ptr2++ = *ptr++;
--- 495,505 ----
  		 */
  		ptr2++;
  		ptr++;
! 		while (*ptr != '\0')
! 		{
! 			if ((*ptr == '&')&&
! 			    ((isalpha((int)*(ptr + 1)))||(*(ptr + 1) == '#')))
! 			{
  				break;
  			}
  			*ptr2++ = *ptr++;
***************
*** 452,481 ****
   * The returned text has already expanded '&' escapes.
   */
  char *
!      get_text(start, endp)
!      char *start;
!      char **endp;
  {
  	char *ptr;
  	char *text;
  	char tchar;
  
! 	if (start == NULL) {
! 		return (NULL);
  	}
  	/*
  	 * Copy text up to beginning of a mark, or the end
  	 */
  	ptr = start;
! 	while (*ptr != '\0') {
! 		if (*ptr == '<') {
! 			if (isalpha((int) (*(ptr + 1)))) {
  				break;
! 			} else if (*(ptr + 1) == '/') {
! 				if (isalpha((int) (*(ptr + 2)))) {
  					break;
  				}
! 			} else if (*(ptr + 1) == '!') {		/* a comment */
  				break;
  			}
  		}
--- 518,557 ----
   * The returned text has already expanded '&' escapes.
   */
  char *
! get_text(start, endp)
! 	char *start;
! 	char **endp;
  {
  	char *ptr;
  	char *text;
  	char tchar;
  
! 	if (start == NULL)
! 	{
! 		return(NULL);
  	}
+ 
  	/*
  	 * Copy text up to beginning of a mark, or the end
  	 */
  	ptr = start;
! 	while (*ptr != '\0')
! 	{
! 		if (*ptr == '<')
! 		{
! 			if (isalpha((int)(*(ptr + 1))))
! 			{
  				break;
! 			}
! 			else if (*(ptr + 1) == '/')
! 			{
! 				if (isalpha((int)(*(ptr + 2))))
! 				{
  					break;
  				}
! 			}
! 			else if (*(ptr + 1) == '!')  /* a comment */
! 			{
  				break;
  			}
  		}
***************
*** 483,491 ****
  	}
  	*endp = ptr;
  
! 	if (ptr == start) {
! 		return (NULL);
  	}
  	/*
  	 * Copy the text into its own buffer, and clean it
  	 * of escape sequences.
--- 559,569 ----
  	}
  	*endp = ptr;
  
! 	if (ptr == start)
! 	{
! 		return(NULL);
  	}
+ 
  	/*
  	 * Copy the text into its own buffer, and clean it
  	 * of escape sequences.
***************
*** 492,508 ****
  	 */
  	tchar = *ptr;
  	*ptr = '\0';
! 	text = (char *) malloc(strlen(start) + 1);
! 	if (text == NULL) {
  		errorlog("Cannot malloc space for text\n");
  		*ptr = tchar;
! 		return (NULL);
  	}
  	strcpy(text, start);
  	*ptr = tchar;
  	clean_text(text);
  
! 	return (text);
  }
  
  
--- 570,587 ----
  	 */
  	tchar = *ptr;
  	*ptr = '\0';
! 	text = (char *)malloc(strlen(start) + 1);
! 	if (text == NULL)
! 	{
  		errorlog("Cannot malloc space for text\n");
  		*ptr = tchar;
! 		return(NULL);
  	}
  	strcpy(text, start);
  	*ptr = tchar;
  	clean_text(text);
  
! 	return(text);
  }
  
  
***************
*** 512,554 ****
   * endp pointing to the ttrailing '>' in the original string.
   */
  struct mark_up *
!         get_mark(start, endp)
!      char *start;
!      char **endp;
  {
  	char *ptr;
  	char *text;
  	char tchar;
  	struct mark_up *mark;
  
! 	if (start == NULL) {
! 		return (NULL);
  	}
! 	if (*start != '<') {
! 		return (NULL);
  	}
  	start++;
  
! 	mark = (struct mark_up *) malloc(sizeof(struct mark_up));
! 	if (mark == NULL) {
! 		errorlog("Cannot malloc space for mark_up struct\n");
! 		return (NULL);
  	}
  	/*
  	 * Grab the mark text
  	 */
  	ptr = start;
! 	while ((*ptr != '>') && (*ptr != '\0')) {
  		ptr++;
  	}
! 	*endp = ptr;
  
! 	if (*ptr != '>') {
  #ifdef VERBOSE
! 		errorlog("error: bad mark format\n");
  #endif
! 		return (NULL);
  	}
  	/*
  	 * Copy the mark text to its own buffer, and
  	 * clean it of escapes, and odd white space.
--- 591,691 ----
   * endp pointing to the ttrailing '>' in the original string.
   */
  struct mark_up *
! get_mark(start, endp)
! 	char *start;
! 	char **endp;
  {
  	char *ptr;
  	char *text;
  	char tchar;
  	struct mark_up *mark;
+ 	int  comment=0;       /* amb - comment==1 if we are in a comment */
+ 	char *first_gt=NULL;  /* keep track of ">" for old broken comments */
  
! 	if (start == NULL)
! 	{
! 		return(NULL);
  	}
! 
! 	if (*start != '<')
! 	{
! 		return(NULL);
  	}
+ 
+ 	/* amb - check if we are in a comment, start tag is <!-- */
+ 	if (strncmp (start, "<!--", 4)==0)
+ 	  comment=1;
+ 
  	start++;
+ 	first_gt = NULL;
  
! 	mark = (struct mark_up *)malloc(sizeof(struct mark_up));
! 	if (mark == NULL)
! 	{
! 	        errorlog("Cannot malloc space for mark_up struct\n");
! 		return(NULL);
  	}
+ 
  	/*
  	 * Grab the mark text
  	 */
  	ptr = start;
! 
! 	/* amb - skip over the comment text */
! 	/* end tag is --*>, where * is zero or more spaces (ugh) */
! 	if (comment)
! 	  {
! 	    while (*ptr != '\0')
! 	      {
! 		if ( (*ptr == '>') && (!first_gt) )
! 		  first_gt = ptr;
! 		if (strncmp (ptr, "--", 2) == 0)   /* found double dash (--) */
! 		  {
! 		    ptr += 2;
! 		    while ((*ptr != '\0') && ((*ptr == ' ') || (*ptr == '\n')
! 					      || (*ptr == '-') ))
! 		      ptr++;                   /* skip spaces and newlines */ 
! 		    if (*ptr == '>')                /* completed end comment */
! 		      {
! 			*endp = ptr;
! 			mark->is_end = 1;
! 			mark->type = M_COMMENT;
! 			mark->start = NULL;
! 			mark->text = NULL;
! 			mark->end = NULL;
! 			mark->next = NULL;
! 			return(mark);
! 		      }
! 		  }
! 		else                         /* if no double dash (--) found */
! 		  ptr++;
! 	      }
! 	    /* if we get here, this document must use the old broken
! 	       comment style */
! 	    if (first_gt) {
! 		ptr = first_gt;
! 	    }
! 	  } /* end of: if (comment) */
! 
! 	while (ptr&&(*ptr != '>')&&(*ptr != '\0'))
! 	{
  		ptr++;
  	}
! 	if (ptr) {
! 		*endp=ptr;
! 	}
! 	else {
! 		return(NULL); /*only if EOF and no close comment -- SWP*/
! 	}
  
! 	if (*ptr != '>')
! 	{
  #ifdef VERBOSE
! 		errorlog(stderr, "error: bad mark format\n");
  #endif
! 		return(NULL);
  	}
+ 
  	/*
  	 * Copy the mark text to its own buffer, and
  	 * clean it of escapes, and odd white space.
***************
*** 555,565 ****
  	 */
  	tchar = *ptr;
  	*ptr = '\0';
! 	text = (char *) malloc(strlen(start) + 1);
! 	if (text == NULL) {
! 		errorlog("Cannot malloc space for mark\n");
  		*ptr = tchar;
! 		return (NULL);
  	}
  	strcpy(text, start);
  	*ptr = tchar;
--- 692,703 ----
  	 */
  	tchar = *ptr;
  	*ptr = '\0';
! 	text = (char *)malloc(strlen(start) + 1);
! 	if (text == NULL)
! 	{
! 	        errorlog("Cannot malloc space for mark\n");
  		*ptr = tchar;
! 		return(NULL);
  	}
  	strcpy(text, start);
  	*ptr = tchar;
***************
*** 567,573 ****
  /*
   * No longer needed because the parsing code is now smarter
   *
!  clean_white_space(text);
   *
   */
  
--- 705,711 ----
  /*
   * No longer needed because the parsing code is now smarter
   *
! 	clean_white_space(text);
   *
   */
  
***************
*** 575,587 ****
  	 * Set whether this is the start or end of a mark
  	 * block, as well as determining its type.
  	 */
! 	if (*text == '/') {
  		mark->is_end = 1;
! 		mark->type = ParseMarkType((char *) (text + 1));
  		mark->start = NULL;
  		mark->text = NULL;
  		mark->end = text;
! 	} else {
  		mark->is_end = 0;
  		mark->type = ParseMarkType(text);
  		mark->start = text;
--- 713,728 ----
  	 * Set whether this is the start or end of a mark
  	 * block, as well as determining its type.
  	 */
! 	if (*text == '/')
! 	{
  		mark->is_end = 1;
! 		mark->type = ParseMarkType((char *)(text + 1));
  		mark->start = NULL;
  		mark->text = NULL;
  		mark->end = text;
! 	}
! 	else
! 	{
  		mark->is_end = 0;
  		mark->type = ParseMarkType(text);
  		mark->start = text;
***************
*** 588,597 ****
  		mark->text = NULL;
  		mark->end = NULL;
  	}
  	mark->text = NULL;
  	mark->next = NULL;
  
! 	return (mark);
  }
  
  
--- 729,739 ----
  		mark->text = NULL;
  		mark->end = NULL;
  	}
+ 
  	mark->text = NULL;
  	mark->next = NULL;
  
! 	return(mark);
  }
  
  
***************
*** 600,630 ****
   * end of the plain text mark, or the end of the file.
   */
  char *
!      get_plain_text(start, endp)
!      char *start;
!      char **endp;
  {
  	char *ptr;
  	char *text;
  	char tchar;
  
! 	if (start == NULL) {
! 		return (NULL);
  	}
  	/*
  	 * Read until stopped by end plain text mark.
  	 */
  	ptr = start;
! 	while (*ptr != '\0') {
  		/*
  		 * Beginning of a mark is '<' followed by any letter,
  		 * or followed by '!' for a comment,
  		 * or '</' followed by any letter.
  		 */
! 		if ((*ptr == '<') &&
! 		    ((isalpha((int) (*(ptr + 1)))) ||
! 			(*(ptr + 1) == '!') ||
! 			((*(ptr + 1) == '/') && (isalpha((int) (*(ptr + 2))))))) {
  			struct mark_up *mp;
  			char *ep;
  
--- 742,776 ----
   * end of the plain text mark, or the end of the file.
   */
  char *
! get_plain_text(start, endp)
! 	char *start;
! 	char **endp;
  {
  	char *ptr;
  	char *text;
  	char tchar;
  
! 	if (start == NULL)
! 	{
! 		return(NULL);
  	}
+ 
  	/*
  	 * Read until stopped by end plain text mark.
  	 */
  	ptr = start;
! 	while (*ptr != '\0')
! 	{
  		/*
  		 * Beginning of a mark is '<' followed by any letter,
  		 * or followed by '!' for a comment,
  		 * or '</' followed by any letter.
  		 */
! 		if ((*ptr == '<')&&
! 			((isalpha((int)(*(ptr + 1))))||
! 			(*(ptr + 1) == '!')||
! 			((*(ptr + 1) == '/')&&(isalpha((int)(*(ptr + 2)))))))
! 		{
  			struct mark_up *mp;
  			char *ep;
  
***************
*** 633,654 ****
  			 * end of plain text, break out
  			 */
  			mp = get_mark(ptr, &ep);
! 			if (mp != NULL) {
! 				if (((mp->type == M_PLAIN_TEXT) ||
! 					(mp->type == M_LISTING_TEXT)) && (mp->is_end)) {
! 					if (mp->end != NULL) {
! 						free((char *) mp->end);
  					}
! 					free((char *) mp);
  					break;
  				}
! 				if (mp->start != NULL) {
! 					free((char *) mp->start);
  				}
! 				if (mp->end != NULL) {
! 					free((char *) mp->end);
  				}
! 				free((char *) mp);
  			}
  		}
  		ptr++;
--- 779,805 ----
  			 * end of plain text, break out
  			 */
  			mp = get_mark(ptr, &ep);
! 			if (mp != NULL)
! 			{
! 				if (((mp->type == M_PLAIN_TEXT)||
! 				    (mp->type == M_LISTING_TEXT))&&(mp->is_end))
! 				{
! 					if (mp->end != NULL)
! 					{
! 						free((char *)mp->end);
  					}
! 					free((char *)mp);
  					break;
  				}
! 				if (mp->start != NULL)
! 				{
! 					free((char *)mp->start);
  				}
! 				if (mp->end != NULL)
! 				{
! 					free((char *)mp->end);
  				}
! 				free((char *)mp);
  			}
  		}
  		ptr++;
***************
*** 655,663 ****
  	}
  	*endp = ptr;
  
! 	if (ptr == start) {
! 		return (NULL);
  	}
  	/*
  	 * Copy text to its own malloced buffer, and clean it of
  	 * HTML escapes.
--- 806,816 ----
  	}
  	*endp = ptr;
  
! 	if (ptr == start)
! 	{
! 		return(NULL);
  	}
+ 
  	/*
  	 * Copy text to its own malloced buffer, and clean it of
  	 * HTML escapes.
***************
*** 664,683 ****
  	 */
  	tchar = *ptr;
  	*ptr = '\0';
! 	text = (char *) malloc(strlen(start) + 1);
! 	if (text == NULL) {
  		errorlog("Cannot malloc space for text\n");
  		*ptr = tchar;
! 		return (NULL);
  	}
  	strcpy(text, start);
  	*ptr = tchar;
  	clean_text(text);
  
! 	return (text);
  }
  
  
  /*
   * Main parser of HTML text.  Takes raw text, and produces a linked
   * list of mark objects.  Mark objects are either text strings, or
--- 817,839 ----
  	 */
  	tchar = *ptr;
  	*ptr = '\0';
! 	text = (char *)malloc(strlen(start) + 1);
! 	if (text == NULL)
! 	{
  		errorlog("Cannot malloc space for text\n");
  		*ptr = tchar;
! 		return(NULL);
  	}
  	strcpy(text, start);
  	*ptr = tchar;
  	clean_text(text);
  
! 	return(text);
  }
  
  
+ static char *atts[]={"text","bgcolor","alink","vlink","link",NULL};
+ 
  /*
   * Main parser of HTML text.  Takes raw text, and produces a linked
   * list of mark objects.  Mark objects are either text strings, or
***************
*** 686,694 ****
   * may want to add code to append to the old list.
   */
  struct mark_up *
!         HTMLParse(old_list, str)
!      struct mark_up *old_list;
!      char *str;
  {
  	int preformat;
  	char *start, *end;
--- 842,851 ----
   * may want to add code to append to the old list.
   */
  struct mark_up *
! HTMLParse(old_list, str, hw)
! 	struct mark_up *old_list;
! 	char *str;
!         void *hw;
  {
  	int preformat;
  	char *start, *end;
***************
*** 696,705 ****
  	struct mark_up *mark;
  	struct mark_up *list;
  	struct mark_up *current;
- #ifdef TIMING
- 	gettimeofday(&Tv, &Tz);
- 	errorlog("HTMLParse enter (%d.%d)\n", Tv.tv_sec, Tv.tv_usec);
- #endif
  
  	preformat = 0;
  
--- 853,858 ----
***************
*** 708,716 ****
  	 */
  	FreeObjList(old_list);
  
! 	if (str == NULL) {
! 		return (NULL);
  	}
  	list = NULL;
  	current = NULL;
  
--- 861,871 ----
  	 */
  	FreeObjList(old_list);
  
! 	if (str == NULL)
! 	{
! 		return(NULL);
  	}
+ 
  	list = NULL;
  	current = NULL;
  
***************
*** 718,724 ****
  	end = str;
  
  	mark = NULL;
! 	while (*start != '\0') {
  		/*
  		 * Get some text (if any).  If our last mark was
  		 * a begin plain text we call different function
--- 873,880 ----
  	end = str;
  
  	mark = NULL;
! 	while (*start != '\0')
! 	{
  		/*
  		 * Get some text (if any).  If our last mark was
  		 * a begin plain text we call different function
***************
*** 725,735 ****
  		 * If last mark was <PLAINTEXT> we lump all the rest of
  		 * the text in.
  		 */
! 		if ((mark != NULL) && (mark->type == M_PLAIN_FILE) &&
! 		    (!mark->is_end)) {
  			text = start;
  			end = text;
! 			while (*end != '\0') {
  				end++;
  			}
  			/*
--- 881,893 ----
  		 * If last mark was <PLAINTEXT> we lump all the rest of
  		 * the text in.
  		 */
! 		if ((mark != NULL)&&(mark->type == M_PLAIN_FILE)&&
! 			(!mark->is_end))
! 		{
  			text = start;
  			end = text;
! 			while (*end != '\0')
! 			{
  				end++;
  			}
  			/*
***************
*** 736,754 ****
  			 * Copy text to its own malloced buffer, and clean it of
  			 * HTML escapes.
  			 */
! 			tptr = (char *) malloc(strlen(text) + 1);
! 			if (tptr == NULL) {
! 				errorlog("Cannot malloc space for text\n");
! 				return (list);
  			}
  			strcpy(tptr, text);
  			text = tptr;
! 		} else if ((mark != NULL) &&
! 			    ((mark->type == M_PLAIN_TEXT) ||
! 				(mark->type == M_LISTING_TEXT)) &&
! 		    (!mark->is_end)) {
  			text = get_plain_text(start, &end);
! 		} else {
  			text = get_text(start, &end);
  		}
  
--- 894,917 ----
  			 * Copy text to its own malloced buffer, and clean it of
  			 * HTML escapes.
  			 */
! 			tptr = (char *)malloc(strlen(text) + 1);
! 			if (tptr == NULL)
! 			{
! 			        errorlog("Cannot malloc space for text\n");
! 				return(list);
  			}
  			strcpy(tptr, text);
  			text = tptr;
! 		}
! 		else if ((mark != NULL)&&
! 			 ((mark->type == M_PLAIN_TEXT)||
! 			  (mark->type == M_LISTING_TEXT))&&
! 			 (!mark->is_end))
! 		{
  			text = get_plain_text(start, &end);
! 		}
! 		else
! 		{
  			text = get_text(start, &end);
  		}
  
***************
*** 756,771 ****
  		 * If text is OK, put it into a mark structure, and add
  		 * it to the linked list.
  		 */
! 		if (text == NULL) {
! 			if (start != end) {
! 				errorlog("%s: error parsing text, bailing out\n", Url);
! 				return (list);
  			}
! 		} else {
! 			mark = (struct mark_up *) malloc(sizeof(struct mark_up));
! 			if (mark == NULL) {
  				errorlog("Cannot malloc for mark_up struct\n");
! 				return (list);
  			}
  			mark->type = M_NONE;
  			mark->is_end = 0;
--- 919,939 ----
  		 * If text is OK, put it into a mark structure, and add
  		 * it to the linked list.
  		 */
! 		if (text == NULL)
! 		{
! 			if (start != end)
! 			{
! 			       	errorlog("error parsing text, bailing out\n");
! 				return(list);
  			}
! 		}
! 		else
! 		{
! 			mark = (struct mark_up *)malloc(sizeof(struct mark_up));
! 			if (mark == NULL)
! 			{
  				errorlog("Cannot malloc for mark_up struct\n");
! 				return(list);
  			}
  			mark->type = M_NONE;
  			mark->is_end = 0;
***************
*** 777,819 ****
  		}
  		start = end;
  
! 		if (*start == '\0') {
  			break;
  		}
  		/*
  		 * Get the next mark if any, and if it is
  		 * valid, add it to the linked list.
  		 */
  		mark = get_mark(start, &end);
! 		if (mark == NULL) {
! 			if (start != end) {
! 				errorlog("%s: error parsing mark, bailing out\n", Url);
! 				return (list);
  			}
- 		} else {
- 			mark->next = NULL;
- 			current = AddObj(&list, current, mark, preformat);
  		}
  
! 		start = (char *) (end + 1);
  
! 		if ((mark != NULL) && (mark->type == M_PLAIN_FILE) &&
! 		    (!mark->is_end)) {
  			/*
  			 * A linefeed immediately after the <PLAINTEXT>
  			 * mark is to be ignored.
  			 */
! 			if (*start == '\n') {
  				start++;
  			}
! 		} else if ((mark != NULL) && ((mark->type == M_PLAIN_TEXT) ||
! 				(mark->type == M_LISTING_TEXT)) &&
! 		    (!mark->is_end)) {
  			/*
  			 * A linefeed immediately after the <XMP>
  			 * or <LISTING> mark is to be ignored.
  			 */
! 			if (*start == '\n') {
  				start++;
  			}
  		}
--- 945,1001 ----
  		}
  		start = end;
  
! 		if (*start == '\0')
! 		{
  			break;
  		}
+ 
  		/*
  		 * Get the next mark if any, and if it is
  		 * valid, add it to the linked list.
  		 */
  		mark = get_mark(start, &end);
! 		if (mark == NULL)
! 		{
! 			if (start != end)
! 			{
! 			        errorlog("error parsing mark, bailing out\n");
! 				return(list);
  			}
  		}
+ 		else
+ 		{
+ 		    mark->next = NULL;
+                     current = AddObj(&list, current, mark, preformat);
+                     
+ 		}
+                 
+                 
  
! 		start = (char *)(end + 1);
  
! 		if ((mark != NULL)&&(mark->type == M_PLAIN_FILE)&&
! 			(!mark->is_end))
! 		{
  			/*
  			 * A linefeed immediately after the <PLAINTEXT>
  			 * mark is to be ignored.
  			 */
! 			if (*start == '\n')
! 			{
  				start++;
  			}
! 		}
! 		else if ((mark != NULL)&&((mark->type == M_PLAIN_TEXT)||
! 			(mark->type == M_LISTING_TEXT))&&
! 			(!mark->is_end))
! 		{
  			/*
  			 * A linefeed immediately after the <XMP>
  			 * or <LISTING> mark is to be ignored.
  			 */
! 			if (*start == '\n')
! 			{
  				start++;
  			}
  		}
***************
*** 821,866 ****
  		 * If we are parsing pre-formatted text we need to set a
  		 * flag so we don't throw out needed linefeeds.
  		 */
! 		else if ((mark != NULL) && (mark->type == M_PREFORMAT)) {
! 			if (mark->is_end) {
  				preformat = 0;
! 			} else {
  				preformat = 1;
  				/*
  				 * A linefeed immediately after the <PRE>
  				 * mark is to be ignored.
  				 */
! 				if (*start == '\n') {
  					start++;
  				}
  			}
  		}
  	}
! #ifdef TIMING
! 	gettimeofday(&Tv, &Tz);
! 	errorlog("HTMLParse exit (%d.%d)\n", Tv.tv_sec, Tv.tv_usec);
! #endif
! 	return (list);
  }
  
  
  /*
   * Determine mark type from the identifying string passed
   */
! static int ParseMarkType(str)
!      char *str;
  {
  	int type;
  	char *tptr;
  	char tchar;
  
! 	if (str == NULL) {
! 		return (M_NONE);
  	}
  	type = M_UNKNOWN;
  	tptr = str;
! 	while (*tptr != '\0') {
! 		if (isspace((int) *tptr)) {
  			break;
  		}
  		tptr++;
--- 1003,1056 ----
  		 * If we are parsing pre-formatted text we need to set a
  		 * flag so we don't throw out needed linefeeds.
  		 */
! 		else if ((mark != NULL)&&(mark->type == M_PREFORMAT))
! 		{
! 			if (mark->is_end)
! 			{
  				preformat = 0;
! 			}
! 			else
! 			{
  				preformat = 1;
  				/*
  				 * A linefeed immediately after the <PRE>
  				 * mark is to be ignored.
  				 */
! 				if (*start == '\n')
! 				{
  					start++;
  				}
  			}
  		}
  	}
! 	return(list);
  }
  
  
+ 
  /*
   * Determine mark type from the identifying string passed
   */
! 
! int
! ParseMarkType(str)
! 	char *str;
  {
  	int type;
  	char *tptr;
  	char tchar;
  
! 	if (str == NULL)
! 	{
! 		return(M_NONE);
  	}
+ 
  	type = M_UNKNOWN;
  	tptr = str;
! 	while (*tptr != '\0')
! 	{
! 		if (isspace((int)*tptr))
! 		{
  			break;
  		}
  		tptr++;
***************
*** 868,1001 ****
  	tchar = *tptr;
  	*tptr = '\0';
  
! 	if (caseless_equal(str, MT_ANCHOR)) {
  		type = M_ANCHOR;
! 	} else if (caseless_equal(str, MT_FRAME)) {
!                 type = M_FRAME; /*DFM from NEW MOSAIC*/
!         } else if (caseless_equal(str, MT_AREA)) {
!                 type = M_AREA; /*DFM from NEW MOSAIC*/
! 	} else if (caseless_equal(str, MT_TITLE)) {
  		type = M_TITLE;
! 	} else if (caseless_equal(str, MT_FIXED)) {
  		type = M_FIXED;
! 	} else if (caseless_equal(str, MT_BOLD)) {
  		type = M_BOLD;
! 	} else if (caseless_equal(str, MT_ITALIC)) {
  		type = M_ITALIC;
! 	} else if (caseless_equal(str, MT_EMPHASIZED)) {
  		type = M_EMPHASIZED;
! 	} else if (caseless_equal(str, MT_STRONG)) {
  		type = M_STRONG;
! 	} else if (caseless_equal(str, MT_CODE)) {
  		type = M_CODE;
! 	} else if (caseless_equal(str, MT_SAMPLE)) {
  		type = M_SAMPLE;
! 	} else if (caseless_equal(str, MT_KEYBOARD)) {
  		type = M_KEYBOARD;
! 	} else if (caseless_equal(str, MT_VARIABLE)) {
  		type = M_VARIABLE;
! 	} else if (caseless_equal(str, MT_CITATION)) {
  		type = M_CITATION;
! 	} else if (caseless_equal(str, MT_STRIKEOUT)) {
  		type = M_STRIKEOUT;
! 	} else if (caseless_equal(str, MT_HEADER_1)) {
  		type = M_HEADER_1;
! 	} else if (caseless_equal(str, MT_HEADER_2)) {
  		type = M_HEADER_2;
! 	} else if (caseless_equal(str, MT_HEADER_3)) {
  		type = M_HEADER_3;
! 	} else if (caseless_equal(str, MT_HEADER_4)) {
  		type = M_HEADER_4;
! 	} else if (caseless_equal(str, MT_HEADER_5)) {
  		type = M_HEADER_5;
! 	} else if (caseless_equal(str, MT_HEADER_6)) {
  		type = M_HEADER_6;
! 	} else if (caseless_equal(str, MT_ADDRESS)) {
  		type = M_ADDRESS;
! 	} else if (caseless_equal(str, MT_PLAIN_TEXT)) {
  		type = M_PLAIN_TEXT;
! 	} else if (caseless_equal(str, MT_LISTING_TEXT)) {
  		type = M_LISTING_TEXT;
! 	} else if (caseless_equal(str, MT_PLAIN_FILE)) {
  		type = M_PLAIN_FILE;
! 	} else if (caseless_equal(str, MT_PARAGRAPH)) {
  		type = M_PARAGRAPH;
! 	} else if (caseless_equal(str, MT_UNUM_LIST)) {
  		type = M_UNUM_LIST;
! 	} else if (caseless_equal(str, MT_NUM_LIST)) {
  		type = M_NUM_LIST;
! 	} else if (caseless_equal(str, MT_MENU)) {
  		type = M_MENU;
! 	} else if (caseless_equal(str, MT_DIRECTORY)) {
  		type = M_DIRECTORY;
! 	} else if (caseless_equal(str, MT_LIST_ITEM)) {
  		type = M_LIST_ITEM;
! 	} else if (caseless_equal(str, MT_DESC_LIST)) {
  		type = M_DESC_LIST;
! 	} else if (caseless_equal(str, MT_DESC_TITLE)) {
  		type = M_DESC_TITLE;
! 	} else if (caseless_equal(str, MT_DESC_TEXT)) {
  		type = M_DESC_TEXT;
! 	} else if (caseless_equal(str, MT_PREFORMAT)) {
  		type = M_PREFORMAT;
! 	} else if (caseless_equal(str, MT_BLOCKQUOTE)) {
  		type = M_BLOCKQUOTE;
! 	} else if (caseless_equal(str, MT_INDEX)) {
  		type = M_INDEX;
! 	} else if (caseless_equal(str, MT_HRULE)) {
  		type = M_HRULE;
! 	} else if (caseless_equal(str, MT_BASE)) {
  		type = M_BASE;
! 	} else if (caseless_equal(str, MT_LINEBREAK)) {
  		type = M_LINEBREAK;
! 	} else if (caseless_equal(str, MT_IMAGE)) {
  		type = M_IMAGE;
!         } else if (caseless_equal(str, MT_FIGURE)) {
!                 type = M_FIGURE; /*DFM from NEW MOSAIC*/
! 	} else if (caseless_equal(str, MT_SELECT)) {
  		type = M_SELECT;
! 	} else if (caseless_equal(str, MT_OPTION)) {
  		type = M_OPTION;
! 	} else if (caseless_equal(str, MT_INPUT)) {
  		type = M_INPUT;
! 	} else if (caseless_equal(str, MT_TEXTAREA)) {
  		type = M_TEXTAREA;
! 	} else if (caseless_equal(str, MT_FORM)) {
  		type = M_FORM;
! 	/*ALL DFM from New Mosaic*/
! 	} else if (caseless_equal(str, MT_SUP)) {
! 		type = M_SUP;
!         } else if (caseless_equal(str, MT_SUB)) {
                  type = M_SUB;
!         } else if (caseless_equal(str, MT_DOC_HEAD)) {
!                 type = M_DOC_HEAD;
!         } else if (caseless_equal(str, MT_UNDERLINED)) {
!                 type = M_UNDERLINED;
!         } else if (caseless_equal(str, MT_DOC_BODY)) {
!                 type = M_DOC_BODY;
!         } else if (caseless_equal(str, MT_TABLE)) {
!                 type = M_TABLE;
!         } else if (caseless_equal(str, MT_CAPTION)) {
!                 type = M_CAPTION;
!         } else if (caseless_equal(str, MT_TABLE_ROW)) {
!                 type = M_TABLE_ROW;
!         } else if (caseless_equal(str, MT_TABLE_HEADER)) {
!                 type = M_TABLE_HEADER;
!         } else if (caseless_equal(str, MT_TABLE_DATA)) {
!                 type = M_TABLE_DATA;
!         } else if (caseless_equal(str, MT_MAP)) {
!                 type = M_MAP;
! 	} else if (caseless_equal(str, MT_META)) {
! 	        type = M_META;
! 	} else {
  #ifdef VERBOSE
! 		errorlog("warning: unknown mark (%s)\n", str);
  #endif
  		type = M_UNKNOWN;
  	}
  
  	*tptr = tchar;
! 	return (type);
  }
  
  
--- 1058,1310 ----
  	tchar = *tptr;
  	*tptr = '\0';
  
! 	if (caseless_equal(str, MT_ANCHOR))
! 	{
  		type = M_ANCHOR;
! 	}
! 	else if (caseless_equal(str, MT_FRAME))
! 	{
! 		type = M_FRAME;
! 	}
! 	else if (caseless_equal(str, MT_AREA))
! 	{
! 	        type = M_AREA;
!         }
! 	else if (caseless_equal(str, MT_TITLE))
! 	{
  		type = M_TITLE;
! 	}
! 	else if (caseless_equal(str, MT_FIXED))
! 	{
  		type = M_FIXED;
! 	}
! 	else if (caseless_equal(str, MT_BOLD))
! 	{
  		type = M_BOLD;
! 	}
! 	else if (caseless_equal(str, MT_ITALIC))
! 	{
  		type = M_ITALIC;
! 	}
! 	else if (caseless_equal(str, MT_EMPHASIZED))
! 	{
  		type = M_EMPHASIZED;
! 	}
! 	else if (caseless_equal(str, MT_STRONG))
! 	{
  		type = M_STRONG;
! 	}
! 	else if (caseless_equal(str, MT_CODE))
! 	{
  		type = M_CODE;
! 	}
! 	else if (caseless_equal(str, MT_SAMPLE))
! 	{
  		type = M_SAMPLE;
! 	}
! 	else if (caseless_equal(str, MT_KEYBOARD))
! 	{
  		type = M_KEYBOARD;
! 	}
! 	else if (caseless_equal(str, MT_VARIABLE))
! 	{
  		type = M_VARIABLE;
! 	}
! 	else if (caseless_equal(str, MT_CITATION))
! 	{
  		type = M_CITATION;
! 	}
! 	else if (caseless_equal(str, MT_STRIKEOUT))
! 	{
  		type = M_STRIKEOUT;
! 	}
! 	else if (caseless_equal(str, MT_HEADER_1))
! 	{
  		type = M_HEADER_1;
! 	}
! 	else if (caseless_equal(str, MT_HEADER_2))
! 	{
  		type = M_HEADER_2;
! 	}
! 	else if (caseless_equal(str, MT_HEADER_3))
! 	{
  		type = M_HEADER_3;
! 	}
! 	else if (caseless_equal(str, MT_HEADER_4))
! 	{
  		type = M_HEADER_4;
! 	}
! 	else if (caseless_equal(str, MT_HEADER_5))
! 	{
  		type = M_HEADER_5;
! 	}
! 	else if (caseless_equal(str, MT_HEADER_6))
! 	{
  		type = M_HEADER_6;
! 	}
! 	else if (caseless_equal(str, MT_ADDRESS))
! 	{
  		type = M_ADDRESS;
! 	}
! 	else if (caseless_equal(str, MT_PLAIN_TEXT))
! 	{
  		type = M_PLAIN_TEXT;
! 	}
! 	else if (caseless_equal(str, MT_LISTING_TEXT))
! 	{
  		type = M_LISTING_TEXT;
! 	}
! 	else if (caseless_equal(str, MT_PLAIN_FILE))
! 	{
  		type = M_PLAIN_FILE;
! 	}
! 	else if (caseless_equal(str, MT_PARAGRAPH))
! 	{
  		type = M_PARAGRAPH;
! 	}
! 	else if (caseless_equal(str, MT_UNUM_LIST))
! 	{
  		type = M_UNUM_LIST;
! 	}
! 	else if (caseless_equal(str, MT_NUM_LIST))
! 	{
  		type = M_NUM_LIST;
! 	}
! 	else if (caseless_equal(str, MT_MENU))
! 	{
  		type = M_MENU;
! 	}
! 	else if (caseless_equal(str, MT_DIRECTORY))
! 	{
  		type = M_DIRECTORY;
! 	}
! 	else if (caseless_equal(str, MT_LIST_ITEM))
! 	{
  		type = M_LIST_ITEM;
! 	}
! 	else if (caseless_equal(str, MT_DESC_LIST))
! 	{
  		type = M_DESC_LIST;
! 	}
! 	else if (caseless_equal(str, MT_DESC_TITLE))
! 	{
  		type = M_DESC_TITLE;
! 	}
! 	else if (caseless_equal(str, MT_DESC_TEXT))
! 	{
  		type = M_DESC_TEXT;
! 	}
! 	else if (caseless_equal(str, MT_PREFORMAT))
! 	{
  		type = M_PREFORMAT;
! 	}
! 	else if (caseless_equal(str, MT_BLOCKQUOTE))
! 	{
  		type = M_BLOCKQUOTE;
! 	}
! 	else if (caseless_equal(str, MT_INDEX))
! 	{
  		type = M_INDEX;
! 	}
! 	else if (caseless_equal(str, MT_HRULE))
! 	{
  		type = M_HRULE;
! 	}
! 	else if (caseless_equal(str, MT_BASE))
! 	{
  		type = M_BASE;
! 	}
! 	else if (caseless_equal(str, MT_LINEBREAK))
! 	{
  		type = M_LINEBREAK;
! 	}
! 	else if (caseless_equal(str, MT_IMAGE))
! 	{
  		type = M_IMAGE;
! 	}
! 	else if (caseless_equal(str, MT_FIGURE))
! 	{
! 		type = M_FIGURE;
! 	}
! 	else if (caseless_equal(str, MT_SELECT))
! 	{
  		type = M_SELECT;
! 	}
! 	else if (caseless_equal(str, MT_OPTION))
! 	{
  		type = M_OPTION;
! 	}
! 	else if (caseless_equal(str, MT_INPUT))
! 	{
  		type = M_INPUT;
! 	}
! 	else if (caseless_equal(str, MT_TEXTAREA))
! 	{
  		type = M_TEXTAREA;
! 	}
! 	else if (caseless_equal(str, MT_FORM))
! 	{
  		type = M_FORM;
! 	}
! /*amb*/
!         else if (caseless_equal(str, MT_SUP))
!         {
!                 type = M_SUP;
!         }
!         else if (caseless_equal(str, MT_SUB))
!         {
                  type = M_SUB;
!         }
! 	else if (caseless_equal(str, MT_DOC_HEAD))
!         {
! 	        type = M_DOC_HEAD;
!         }
! 	else if (caseless_equal(str, MT_UNDERLINED))
!         {
! 	        type = M_UNDERLINED;
!         }
! 	else if (caseless_equal(str, MT_DOC_BODY))
!         {
! 	        type = M_DOC_BODY;
!         }
! 	else if (caseless_equal(str, MT_TABLE))
! 	{
! 		type = M_TABLE;
! 	}
! 	else if (caseless_equal(str, MT_CAPTION))
! 	{
! 		type = M_CAPTION;
! 	}
! 	else if (caseless_equal(str, MT_TABLE_ROW))
! 	{
! 		type = M_TABLE_ROW;
! 	}
! 	else if (caseless_equal(str, MT_TABLE_HEADER))
! 	{
! 		type = M_TABLE_HEADER;
! 	}
! 	else if (caseless_equal(str, MT_TABLE_DATA))
! 	{
! 		type = M_TABLE_DATA;
! 	}
! 	else if (caseless_equal(str, MT_MAP))
! 	{
! 		type=M_MAP;
! 	}
! 	else if (caseless_equal(str, MT_META))
! 	{
! 	        type=M_META;
!         }
! 	else
! 	{
  #ifdef VERBOSE
! 	        errorlog("warning: unknown mark (%s)\n", str);
  #endif
  		type = M_UNKNOWN;
  	}
  
  	*tptr = tchar;
! 	return(type);
  }
  
  
***************
*** 1008,1017 ****
   * Finally the function returns the tag value in a malloced buffer.
   */
  char *
!      AnchorTag(ptrp, startp, endp)
!      char **ptrp;
!      char **startp;
!      char **endp;
  {
  	char *tag_val;
  	char *ptr;
--- 1317,1326 ----
   * Finally the function returns the tag value in a malloced buffer.
   */
  char *
! AnchorTag(ptrp, startp, endp)
! 	char **ptrp;
! 	char **startp;
! 	char **endp;
  {
  	char *tag_val;
  	char *ptr;
***************
*** 1026,1032 ****
  	 * remove leading spaces, and set start
  	 */
  	ptr = *ptrp;
! 	while (isspace((int) *ptr)) {
  		ptr++;
  	}
  	*startp = ptr;
--- 1335,1342 ----
  	 * remove leading spaces, and set start
  	 */
  	ptr = *ptrp;
! 	while (isspace((int)*ptr))
! 	{
  		ptr++;
  	}
  	*startp = ptr;
***************
*** 1034,1119 ****
  	/*
  	 * Find and set the end of the tag
  	 */
! 	while ((!isspace((int) *ptr)) && (*ptr != '=') && (*ptr != '\0')) {
  		ptr++;
  	}
  	*endp = ptr;
  
! 	if (*ptr == '\0') {
  		*ptrp = ptr;
! 		return (NULL);
! 	}
  	/*
  	 * Move to the start of the tag value, if there is one.
- 	 * set the has_value flag.
  	 */
! 	has_value = 0;
! 	while ((isspace((int) *ptr)) || (*ptr == '=')) {
! 		if (*ptr == '=') {
! 			has_value = 1;
  		}
  		ptr++;
! 	}
! 
  	/*
  	 * For a tag with no value, this is a boolean flag.
  	 * Return the string "1" so we know the tag is there.
  	 */
! 	if (!has_value) {
  		*ptrp = *endp;
  		/*
  		 * set a tag value of 1.
  		 */
! 		tag_val = (char *) malloc(strlen("1") + 1);
! 		if (tag_val == NULL) {
! 			errorlog("can't malloc space for tag value\n");
! 			return (NULL);
  		}
  		strcpy(tag_val, "1");
  
! 		return (tag_val);
  	}
! 	if (*ptr == '\"') {
  		quoted = 1;
  		ptr++;
  	}
  	start = ptr;
  	/*
  	 * Get tag value.  Either a quoted string or a single word
  	 */
! 	if (quoted) {
! 		while ((*ptr != '\"') && (*ptr != '\0')) {
  			ptr++;
  		}
! 	} else {
! 		while ((!isspace((int) *ptr)) && (*ptr != '\0')) {
  			ptr++;
  		}
  	}
! 	if ((quoted) && (*ptr == '\0')) {
  		*ptrp = ptr;
! 		return (NULL);
  	}
  	/*
  	 * Copy the tag value out into a malloced string
  	 */
  	tchar = *ptr;
  	*ptr = '\0';
! 	tag_val = (char *) malloc(strlen(start) + 1);
! 	if (tag_val == NULL) {
! 		errorlog("can't malloc space for tag value\n");
  		*ptr = tchar;
  		*ptrp = ptr;
! 		return (NULL);
  	}
  	strcpy(tag_val, start);
  	*ptr = tchar;
! 	if (quoted) {
  		ptr++;
  	}
  	*ptrp = ptr;
  
! 	return (tag_val);
  }
  
  
--- 1344,1458 ----
  	/*
  	 * Find and set the end of the tag
  	 */
! 	while ((!isspace((int)*ptr))&&(*ptr != '=')&&(*ptr != '\0'))
! 	{
  		ptr++;
  	}
  	*endp = ptr;
  
!         has_value=0;
! 	if (*ptr == '\0')
! 	{
  		*ptrp = ptr;
! /*		return(NULL);*/
!                     /* try to handle <A NAME=blah></A> correctly -bjs*/
! 	} else {
  	/*
  	 * Move to the start of the tag value, if there is one.
  	 */
!             while ((isspace((int)*ptr))||(*ptr == '='))
!             {
! 		if (*ptr == '=')
! 		{
!                     has_value = 1;
  		}
  		ptr++;
!             }
!         }
!         
  	/*
  	 * For a tag with no value, this is a boolean flag.
  	 * Return the string "1" so we know the tag is there.
  	 */
! 	if (!has_value)
! 	{
  		*ptrp = *endp;
  		/*
  		 * set a tag value of 1.
  		 */
! 		tag_val = (char *)malloc(strlen("1") + 1);
! 		if (tag_val == NULL)
! 		{
! 		        errorlog(stderr, "can't malloc space for tag value\n");
! 			return(NULL);
  		}
  		strcpy(tag_val, "1");
  
! 		return(tag_val);
  	}
! 
! 	if (*ptr == '\"')
! 	{
  		quoted = 1;
  		ptr++;
  	}
+ 
  	start = ptr;
  	/*
  	 * Get tag value.  Either a quoted string or a single word
  	 */
! 	if (quoted)
! 	{
! 		while ((*ptr != '\"')&&(*ptr != '\0'))
! 		{
  			ptr++;
  		}
! 	}
! 	else
! 	{
! 		while ((!isspace((int)*ptr))&&(*ptr != '\0'))
! 		{
  			ptr++;
  		}
  	}
! /* amb - everyone forgets the end quotes on anchor
!    attributes, so we'll let it slide */
! 
! /*
! 	if ((quoted)&&(*ptr == '\0'))
! 	{
  		*ptrp = ptr;
! 		return(NULL);
  	}
+ */
+ 
  	/*
  	 * Copy the tag value out into a malloced string
  	 */
  	tchar = *ptr;
  	*ptr = '\0';
! 	tag_val = (char *)malloc(strlen(start) + 1);
! 	if (tag_val == NULL)
! 	{
! 
!        		errorlog("can't malloc space for tag value\n");
  		*ptr = tchar;
  		*ptrp = ptr;
! 
! 		return(NULL);
  	}
  	strcpy(tag_val, start);
  	*ptr = tchar;
! 
! 	/* If you forgot the end quote, you need to make sure you aren't
! 		indexing ptr past the end of its own array -- SWP */
! 	if (quoted && *ptr!='\0')
! 	{
  		ptr++;
  	}
  	*ptrp = ptr;
  
! 	return(tag_val);
  }
  
  
***************
*** 1123,1133 ****
   * If the passed tag is not found, return NULL.
   * If the passed tag is found but has no value, return "".
   */
! char *
!      ParseMarkTag(text, mtext, mtag)
!      char *text;
!      char *mtext;
!      char *mtag;
  {
  	char *ptr;
  	char *start;
--- 1462,1471 ----
   * If the passed tag is not found, return NULL.
   * If the passed tag is found but has no value, return "".
   */
! char* ParseMarkTag(text, mtext, mtag)
! 	char *text;
! 	char *mtext;
! 	char *mtag;
  {
  	char *ptr;
  	char *start;
***************
*** 1135,1228 ****
  	char *tag_val;
  	char tchar;
  
! 	if ((text == NULL) || (mtext == NULL) || (mtag == NULL)) {
! 		return (NULL);
  	}
- 	ptr = (char *) (text + strlen(mtext));
  
! 	while (*ptr != '\0') {
  		tag_val = AnchorTag(&ptr, &start, &end);
  
  		tchar = *end;
  		*end = '\0';
! 		if (caseless_equal(start, mtag)) {
  			*end = tchar;
! 			if (tag_val == NULL) {
! 				tag_val = (char *) malloc(1);
  				*tag_val = '\0';
! 				return (tag_val);
! 			} else {
! 				return (tag_val);
  			}
  		}
  		*end = tchar;
! 		if (tag_val != NULL) {
  			free(tag_val);
  		}
  	}
! 	return (NULL);
  }
  
  /* HTMLlists.c */
- /****************************************************************************
-  * NCSA Mosaic for the X Window System                                      *
-  * Software Development Group                                               *
-  * National Center for Supercomputing Applications                          *
-  * University of Illinois at Urbana-Champaign                               *
-  * 605 E. Springfield, Champaign IL 61820                                   *
-  * mosaic@ncsa.uiuc.edu                                                     *
-  *                                                                          *
-  * Copyright (C) 1993, Board of Trustees of the University of Illinois      *
-  *                                                                          *
-  * NCSA Mosaic software, both binary and source (hereafter, Software) is    *
-  * copyrighted by The Board of Trustees of the University of Illinois       *
-  * (UI), and ownership remains with the UI.                                 *
-  *                                                                          *
-  * The UI grants you (hereafter, Licensee) a license to use the Software    *
-  * for academic, research and internal business purposes only, without a    *
-  * fee.  Licensee may distribute the binary and source code (if released)   *
-  * to third parties provided that the copyright notice and this statement   *
-  * appears on all copies and that no charge is associated with such         *
-  * copies.                                                                  *
-  *                                                                          *
-  * Licensee may make derivative works.  However, if Licensee distributes    *
-  * any derivative work based on or derived from the Software, then          *
-  * Licensee will (1) notify NCSA regarding its distribution of the          *
-  * derivative work, and (2) clearly notify users that such derivative       *
-  * work is a modified version and not the original NCSA Mosaic              *
-  * distributed by the UI.                                                   *
-  *                                                                          *
-  * Any Licensee wishing to make commercial use of the Software should       *
-  * contact the UI, c/o NCSA, to negotiate an appropriate license for such   *
-  * commercial use.  Commercial use includes (1) integration of all or       *
-  * part of the source code into a product for sale or license by or on      *
-  * behalf of Licensee to third parties, or (2) distribution of the binary   *
-  * code or source code to third parties that need it to utilize a           *
-  * commercial product sold or licensed by or on behalf of Licensee.         *
-  *                                                                          *
-  * UI MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR   *
-  * ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED          *
-  * WARRANTY.  THE UI SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY THE    *
-  * USERS OF THIS SOFTWARE.                                                  *
-  *                                                                          *
-  * By using or copying this Software, Licensee agrees to abide by the       *
-  * copyright law and all other applicable laws of the U.S. including, but   *
-  * not limited to, export control laws, and the terms of this license.      *
-  * UI shall have the right to terminate this license immediately by         *
-  * written notice upon Licensee's breach of, or non-compliance with, any    *
-  * of its terms.  Licensee may be held legally responsible for any          *
-  * copyright infringement that is caused or encouraged by Licensee's        *
-  * failure to abide by the terms of this license.                           *
-  *                                                                          *
-  * Comments and questions are welcome and can be sent to                    *
-  * mosaic-x@ncsa.uiuc.edu.                                                  *
-  ****************************************************************************/
  
- #if 0
- #include <stdio.h>
- #include "HTML.h"
- #endif
- 
  /*
   * Code to manage a linked list of parsed HTML objects generated
   * from a raw text file.
--- 1473,1516 ----
  	char *tag_val;
  	char tchar;
  
! 	if ((text == NULL)||(mtext == NULL)||(mtag == NULL))
! 	{
! 		return(NULL);
  	}
  
! 	ptr = (char *)(text + strlen(mtext));
! 
! 	while (*ptr != '\0')
! 	{
  		tag_val = AnchorTag(&ptr, &start, &end);
  
  		tchar = *end;
  		*end = '\0';
! 		if (caseless_equal(start, mtag))
! 		{
  			*end = tchar;
! 			if (tag_val == NULL)
! 			{
! 				tag_val = (char *)malloc(1);
  				*tag_val = '\0';
! 				return(tag_val);
  			}
+ 			else
+ 			{
+ 				return(tag_val);
+ 			}
  		}
  		*end = tchar;
! 		if (tag_val != NULL)
! 		{
  			free(tag_val);
  		}
  	}
! 	return(NULL);
  }
  
  /* HTMLlists.c */
  
  /*
   * Code to manage a linked list of parsed HTML objects generated
   * from a raw text file.
***************
*** 1230,1236 ****
   * make up a page of a formatted document.
   */
  
- 
  /*
   * Free up the passed linked list of parsed elements, freeing
   * all memory associates with each element.
--- 1518,1523 ----
***************
*** 1238,1265 ****
  static void FreeObjList(List)
       struct mark_up *List;
  {
! 	struct mark_up *current;
! 	struct mark_up *mptr;
! 
! 	current = List;
! 	while (current != NULL) {
! 		mptr = current;
! 		current = current->next;
! 		mptr->next = NULL;
! 		if (mptr->start != NULL) {
! 			free((char *) mptr->start);
! 		}
! 		if (mptr->text != NULL) {
! 			free((char *) mptr->text);
! 		}
! 		if (mptr->end != NULL) {
! 			free((char *) mptr->end);
! 		}
! 		free((char *) mptr);
! 	}
  }
! 
! 
  /*
   * Add an object to the parsed object list.
   * return a pointer to the current (end) position in the list.
--- 1525,1552 ----
  static void FreeObjList(List)
       struct mark_up *List;
  {
!         struct mark_up *current;
!         struct mark_up *mptr;
!  
!         current = List;
!         while (current != NULL) {
!                 mptr = current;
!                 current = current->next;
!                 mptr->next = NULL;
!                 if (mptr->start != NULL) {
!                         free((char *) mptr->start);
!                 }
!                 if (mptr->text != NULL) {
!                         free((char *) mptr->text);
!                 }
!                 if (mptr->end != NULL) {
!                         free((char *) mptr->end);
!                 }
!                 free((char *) mptr);
!         }
  }
!  
!  
  /*
   * Add an object to the parsed object list.
   * return a pointer to the current (end) position in the list.
***************
*** 1274,1297 ****
       struct mark_up *mark;
       int keep_wsp;
  {
! 	if (mark == NULL) {
! 		return (current);
! 	}
! 	/*
! 	 * Throw out normal text blocks that are only white space,
! 	 * unless keep_wsp is set.
! 	 */
! 	if ((mark->type == M_NONE) && (!keep_wsp)) {
! 		char *ptr;
! 
! 		ptr = mark->text;
! 		if (ptr == NULL) {
! 			free((char *) mark);
! 			return (current);
! 		}
! /*
!  * No longer throw out whitespace, it is important to keep
!  * white space between tags.
   while ((*ptr == ' ')||(*ptr == '\t')||(*ptr == '\n'))
   {
   ptr++;
--- 1561,1584 ----
       struct mark_up *mark;
       int keep_wsp;
  {
!   if (mark == NULL) {
!                 return (current);
!   }
!   /*
!    * Throw out normal text blocks that are only white space,
!    * unless keep_wsp is set.
!    */
!   if ((mark->type == M_NONE) && (!keep_wsp)) {
!                 char *ptr;
!  
!                 ptr = mark->text;
!                 if (ptr == NULL) {
!                         free((char *) mark);
!                         return (current);
!                 }
! 		/*
! 		 * No longer throw out whitespace, it is important to keep
! 		 * white space between tags.
   while ((*ptr == ' ')||(*ptr == '\t')||(*ptr == '\n'))
   {
   ptr++;
***************
*** 1298,1326 ****
   }
   *
   */
! 
! 		if (*ptr == '\0') {
! 			free(mark->text);
! 			free((char *) mark);
! 			return (current);
! 		}
! 	}
! 	/*
! 	 * Add object to either the head of the list for a new list,
! 	 * or at the end after the current pointer.
! 	 */
! 	if (*listp == NULL) {
! 		*listp = mark;
! 		current = *listp;
! 	} else {
! 		current->next = mark;
! 		current = current->next;
! 	}
! 
! 	current->next = NULL;
! 
! 	return (current);
  }
  
- /* NOTE: the rest of this file was deleted since HTML.sum.c doesn't need it
-  * and it needs X11 to compile */
--- 1585,1610 ----
   }
   *
   */
!                 if (*ptr == '\0') {
!                         free(mark->text);
!                         free((char *) mark);
!                         return (current);
!                 }
!   }
!   /*
!    * Add object to either the head of the list for a new list,
!    * or at the end after the current pointer.
!    */
!   if (*listp == NULL) {
!                 *listp = mark;
!                 current = *listp;
!   } else {
!                 current->next = mark;
!                 current = current->next;
!   }
!  
!         current->next = NULL;
!  
!         return (current);
  }
  
Index: harvest/src/gatherer/enumerate/URL-filter-default
diff -c harvest/src/gatherer/enumerate/URL-filter-default:2.1 harvest/src/gatherer/enumerate/URL-filter-default:2.2
*** harvest/src/gatherer/enumerate/URL-filter-default:2.1	Fri Mar 21 19:21:25 1997
--- harvest/src/gatherer/enumerate/URL-filter-default	Fri Jun 13 02:08:27 1997
***************
*** 1,4 ****
! # URL-filter-default,v 2.1 1997/03/21 19:21:25 sxw Exp
  #
  # Default URL-path filter file
  #
--- 1,4 ----
! # URL-filter-default,v 2.2 1997/06/13 01:08:27 sxw Exp
  #
  # Default URL-path filter file
  #
***************
*** 27,30 ****
--- 27,32 ----
  Deny	\.AU$
  Deny	\.snd$
  Deny	\.SND$
+ Deny	\.wrl$
+ Deny 	\.WRL$
  Allow	.
Index: harvest/src/gatherer/enumerate/robots-txt.c
diff -c harvest/src/gatherer/enumerate/robots-txt.c:2.2 harvest/src/gatherer/enumerate/robots-txt.c:2.3
*** harvest/src/gatherer/enumerate/robots-txt.c:2.2	Wed May 14 23:41:39 1997
--- harvest/src/gatherer/enumerate/robots-txt.c	Thu Jun 12 21:08:18 1997
***************
*** 1,4 ****
! static char rcsid[]="robots-txt.c,v 2.2 1997/05/14 22:41:39 sxw Exp";
  /*
   *  DEBUG: section  48, level 1, 5      Gatherer enumeration robots.txt stuff
   *
--- 1,4 ----
! static char rcsid[]="robots-txt.c,v 2.3 1997/06/12 20:08:18 sxw Exp";
  /*
   *  DEBUG: section  48, level 1, 5      Gatherer enumeration robots.txt stuff
   *
***************
*** 227,232 ****
--- 227,237 ----
  	    if (lastline == user_agent) {
  	        *QT = Q;
  	        QT  = &Q->next;
+ 		W=xmalloc(sizeof(word_list));
+ 		if ((t = strtok(NULL, " \t")))
+ 		  W->word=xstrdup(t);
+ 		*DAWLT = W;
+ 		DAWLT = &W->next;
  		lastline = disallow;
  	    }
  	    else if (lastline == disallow) {
Index: harvest/src/gatherer/essence/file/print.c
diff -c harvest/src/gatherer/essence/file/print.c:2.0 harvest/src/gatherer/essence/file/print.c:2.1
*** harvest/src/gatherer/essence/file/print.c:2.0	Sun Mar 16 22:18:40 1997
--- harvest/src/gatherer/essence/file/print.c	Tue Jun 10 20:39:37 1997
***************
*** 78,84 ****
       char *f, *a;
  {
  	extern int errno, sys_nerr;
! #if !defined(__FreeBSD__) && !defined(__NetBSD__)
  	extern char *sys_errlist[];
  #endif
  	int myerrno;
--- 78,84 ----
       char *f, *a;
  {
  	extern int errno, sys_nerr;
! #if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__bsdi__)
  	extern char *sys_errlist[];
  #endif
  	int myerrno;
