about summary refs log tree commit diff stats
path: root/WWW/Library/Implementation
diff options
context:
space:
mode:
Diffstat (limited to 'WWW/Library/Implementation')
-rw-r--r--WWW/Library/Implementation/HTAABrow.c3
-rw-r--r--WWW/Library/Implementation/HTAccess.c3
-rw-r--r--WWW/Library/Implementation/HTAccess.h5
-rw-r--r--WWW/Library/Implementation/HTAnchor.c273
-rw-r--r--WWW/Library/Implementation/HTAnchor.h23
-rw-r--r--WWW/Library/Implementation/HTBTree.c648
-rw-r--r--WWW/Library/Implementation/HTBTree.h14
-rw-r--r--WWW/Library/Implementation/HTChunk.c4
-rw-r--r--WWW/Library/Implementation/HTFTP.c3
-rw-r--r--WWW/Library/Implementation/HTFile.c179
-rw-r--r--WWW/Library/Implementation/HTFile.h48
-rw-r--r--WWW/Library/Implementation/HTFormat.c11
-rw-r--r--WWW/Library/Implementation/HTFormat.h3
-rw-r--r--WWW/Library/Implementation/HTList.c6
-rw-r--r--WWW/Library/Implementation/HTMIME.c37
-rw-r--r--WWW/Library/Implementation/HTNews.c6
-rw-r--r--WWW/Library/Implementation/HTParse.c50
-rw-r--r--WWW/Library/Implementation/HTPlain.c3
-rw-r--r--WWW/Library/Implementation/HTTCP.c21
-rw-r--r--WWW/Library/Implementation/HTTP.c10
-rw-r--r--WWW/Library/Implementation/HTTP.h7
-rw-r--r--WWW/Library/Implementation/HTTelnet.c57
-rw-r--r--WWW/Library/Implementation/HTUtils.h7
-rw-r--r--WWW/Library/Implementation/SGML.c413
-rw-r--r--WWW/Library/Implementation/SGML.h18
-rw-r--r--WWW/Library/Implementation/www_tcp.h4
26 files changed, 1011 insertions, 845 deletions
diff --git a/WWW/Library/Implementation/HTAABrow.c b/WWW/Library/Implementation/HTAABrow.c
index 02db254c..dde97869 100644
--- a/WWW/Library/Implementation/HTAABrow.c
+++ b/WWW/Library/Implementation/HTAABrow.c
@@ -57,13 +57,12 @@
 #include <HTAlert.h>		/* HTConfirm(), HTPrompt()	*/
 #include <HTAAUtil.h>		/* AA common to both sides	*/
 #include <HTAssoc.h>		/* Assoc list			*/
+#include <HTAccess.h>		/* Are we using an HTTP gateway? */
 #include <HTAABrow.h>		/* Implemented here		*/
 #include <HTUU.h>		/* Uuencoding and uudecoding	*/
 
 #include <LYLeaks.h>
 
-extern BOOL using_proxy;	/* Are we using an HTTP gateway? */
-
 /*
 **  Local datatype definitions
 **
diff --git a/WWW/Library/Implementation/HTAccess.c b/WWW/Library/Implementation/HTAccess.c
index 0fe6bc34..64ddf380 100644
--- a/WWW/Library/Implementation/HTAccess.c
+++ b/WWW/Library/Implementation/HTAccess.c
@@ -590,9 +590,6 @@ PRIVATE int get_physical ARGS2(
  *  I want the "pop" to occur as soon as possible after loading
  *  has finished. - kw @@@
  */
-
-extern char*UCAssume_MIMEcharset;
-
 PUBLIC void LYUCPushAssumed ARGS1(
     HTParentAnchor *,	anchor)
 {
diff --git a/WWW/Library/Implementation/HTAccess.h b/WWW/Library/Implementation/HTAccess.h
index 0c763051..ab833272 100644
--- a/WWW/Library/Implementation/HTAccess.h
+++ b/WWW/Library/Implementation/HTAccess.h
@@ -310,7 +310,6 @@ extern void LYUCPushAssumed PARAMS((
     HTParentAnchor *	anchor));
 extern int LYUCPopAssumed NOPARAMS;
 
-#endif /* HTACCESS_H */
-/*
+extern BOOL using_proxy;
 
-   end of HTAccess  */
+#endif /* HTACCESS_H */
diff --git a/WWW/Library/Implementation/HTAnchor.c b/WWW/Library/Implementation/HTAnchor.c
index a489c4c0..20360edc 100644
--- a/WWW/Library/Implementation/HTAnchor.c
+++ b/WWW/Library/Implementation/HTAnchor.c
@@ -70,34 +70,14 @@ PRIVATE HTParentAnchor * HTParentAnchor_new NOARGS
     HTParentAnchor *newAnchor = typecalloc(HTParentAnchor);
     if (newAnchor == NULL)
 	outofmem(__FILE__, "HTParentAnchor_new");
+    /* calloc: all pointers initialized to NULL */
+
     newAnchor->parent = newAnchor;
-    newAnchor->bookmark = NULL;		/* Bookmark filename. - FM */
     newAnchor->isISMAPScript = FALSE;	/* Lynx appends ?0,0 if TRUE. - FM */
     newAnchor->isHEAD = FALSE;		/* HEAD request if TRUE. - FM */
     newAnchor->safe = FALSE;		/* Safe. - FM */
-#ifdef SOURCE_CACHE
-    newAnchor->source_cache_file = NULL;
-    newAnchor->source_cache_chunk = NULL;
-#endif
-    newAnchor->FileCache = NULL;	/* Path to a disk-cached copy. - FM */
-    newAnchor->SugFname = NULL;		/* Suggested filename. - FM */
-    newAnchor->RevTitle = NULL;		/* TITLE for a LINK with REV. - FM */
-    newAnchor->citehost = NULL;		/* LINK REL=citehost - RDC */
-    newAnchor->cache_control = NULL;	/* Cache-Control. - FM */
     newAnchor->no_cache = FALSE;	/* no-cache? - FM */
-    newAnchor->content_type = NULL;	/* Content-Type. - FM */
-    newAnchor->content_language = NULL; /* Content-Language. - FM */
-    newAnchor->content_encoding = NULL; /* Compression algorithm. - FM */
-    newAnchor->content_base = NULL;	/* Content-Base. - FM */
-    newAnchor->content_disposition = NULL; /* Content-Disposition. - FM */
-    newAnchor->content_location = NULL; /* Content-Location. - FM */
-    newAnchor->content_md5 = NULL;	/* Content-MD5. - FM */
     newAnchor->content_length = 0;	/* Content-Length. - FM */
-    newAnchor->date = NULL;		/* Date. - FM */
-    newAnchor->expires = NULL;		/* Expires. - FM */
-    newAnchor->last_modified = NULL;	/* Last-Modified. - FM */
-    newAnchor->ETag = NULL;		/* ETag (HTTP/1.1 cache validator) */
-    newAnchor->server = NULL;		/* Server. - FM */
     return(newAnchor);
 }
 
@@ -154,12 +134,6 @@ PRIVATE BOOL HTIdentical ARGS2(
 	CONST char *,	t)
 {
     if (s && t) {  /* Make sure they point to something */
-#ifdef SH_EX	/* 1998/04/28 (Tue) 22:02:58 */
-	if (*s == 'P' || *t == 'P') {
-	    if (strcmp(s + 1, "Name") == 0 || strcmp(t + 1, "Name") == 0)
-		return NO;
-	}
-#endif
 	for (; *s && *t; s++, t++) {
 	    if (*s != *t) {
 		return(NO);
@@ -172,11 +146,40 @@ PRIVATE BOOL HTIdentical ARGS2(
 }
 #endif /* CASE_INSENSITIVE_ANCHORS */
 
+/*
+ *  Three-way compare function
+ */
+PRIVATE int compare ARGS2(
+	void *, l,
+	void *, r)
+{
+    CONST char* a = ((HTChildAnchor *)l)->tag;
+    CONST char* b = ((HTChildAnchor *)r)->tag;
+
+    if (a && b) {  /* Make sure they point to something */
+#ifdef CASE_INSENSITIVE_ANCHORS
+	return strcasecomp(a, b); /* Case insensitive */
+#else
+	return strcmp(a, b);      /* Case sensitive - FM */
+#endif /* CASE_INSENSITIVE_ANCHORS */
+    } else {
+	/*  bring up an order when one or both strings are nulls */
+	if (a) {
+	    return 1;
+	} else if (b) {
+	    return -1;
+	} else {
+	    /* both nulls - assume equivalent */
+	    return 0;
+	}
+    }
+}
+
 
 /*	Create new or find old sub-anchor
 **	---------------------------------
 **
-**	Me one is for a new anchor being edited into an existing
+**	This one is for a new anchor being edited into an existing
 **	document.  The parent anchor must already exist.
 */
 PUBLIC HTChildAnchor * HTAnchor_findChild ARGS2(
@@ -184,32 +187,33 @@ PUBLIC HTChildAnchor * HTAnchor_findChild ARGS2(
 	CONST char *,		tag)
 {
     HTChildAnchor *child;
-    HTList *kids;
 
     if (!parent) {
 	CTRACE((tfp, "HTAnchor_findChild called with NULL parent.\n"));
 	return(NULL);
     }
-    if ((kids = parent->children) != 0) {
-	/*
-	**  Parent has children.  Search them.
-	*/
-	if (tag && *tag) {		/* TBL */
-	    while (NULL != (child=(HTChildAnchor *)HTList_nextObject(kids))) {
-#ifdef CASE_INSENSITIVE_ANCHORS
-		if (HTEquivalent(child->tag, tag)) /* Case insensitive */
-#else
-		if (HTIdentical(child->tag, tag)) /* Case sensitive - FM */
-#endif /* CASE_INSENSITIVE_ANCHORS */
-		{
-		    CTRACE((tfp, "Child anchor %p of parent %p with name `%s' already exists.\n",
-				(void *)child, (void *)parent, tag));
-		    return(child);
-		}
+
+    if (tag && *tag) {	       /* TBL */
+	if (parent->children) {
+	   /*
+	   **  Parent has children.  Search them.
+	   */
+	   HTChildAnchor sample;
+	   sample.tag = (char*)tag;    /* for compare() only */
+
+	   child = (HTChildAnchor *)HTBTree_search(parent->children, &sample);
+	   if (child != NULL) {
+	       CTRACE((tfp, "Child anchor %p of parent %p with name `%s' already exists.\n",
+		       (void *)child, (void *)parent, tag));
+	       return(child);
 	    }
-	}  /*  end if tag is void */
-    } else {  /* parent doesn't have any children yet : create family */
-	parent->children = HTList_new();
+	} else {  /* parent doesn't have any children yet : create family */
+	   parent->children = HTBTree_new(compare);
+	}
+    } else { /*  if tag is void */
+	if (!parent->children_notag)
+	   /* create a family of this kind */
+	   parent->children_notag = HTList_new();
     }
 
     child = HTChildAnchor_new();
@@ -217,13 +221,24 @@ PUBLIC HTChildAnchor * HTAnchor_findChild ARGS2(
 		(void *)child,
 		NonNull(tag),
 		(void *)parent)); /* int for apollo */
-    HTList_addObject (parent->children, child);
     child->parent = parent;
-    StrAllocCopy(child->tag, tag);
+
+    if (tag && *tag) {
+	StrAllocCopy(child->tag, tag);   /* should be set before HTBTree_add */
+	HTBTree_add(parent->children, child);
+    } else {
+	child->tag = 0;
+	HTList_addObject(parent->children_notag, child);
+    }
+
     return(child);
 }
 
 
+PRIVATE HTParentAnchor * HTAnchor_findAddress_nofragment PARAMS((
+	CONST DocAddress *	newdoc));
+
+
 /*	Create or find a child anchor with a possible link
 **	--------------------------------------------------
 **
@@ -239,30 +254,45 @@ PUBLIC HTChildAnchor * HTAnchor_findChildAndLink ARGS4(
 {
     HTChildAnchor * child = HTAnchor_findChild(parent, tag);
 
-    CTRACE((tfp,"Entered HTAnchor_findChildAndLink\n"));
+    CTRACE((tfp,"Entered HTAnchor_findChildAndLink:  tag=`%s',%s href=`%s'\n",
+	       NonNull(tag),
+	       (ltype == HTInternalLink) ? " (internal link)" : "",
+	       NonNull(href) ));
 
     if (href && *href) {
-	char *relative_to = HTAnchor_address((HTAnchor *)parent);
+	CONST char *fragment = NULL;
 	DocAddress parsed_doc;
-	HTAnchor * dest;
-
-	parsed_doc.address = HTParse(href, relative_to, PARSE_ALL);
-#ifndef DONT_TRACK_INTERNAL_LINKS
-	if (ltype && parent->post_data && ltype == LINK_INTERNAL) {
-	    /* for internal links, find a destination with the same
-	       post data if the source of the link has post data. - kw */
-	    parsed_doc.post_data = parent->post_data;
-	    parsed_doc.post_content_type = parent->post_content_type;
-	} else
-#endif
-	{
+	HTParentAnchor * dest;
+
+	if (*href == '#' && ltype == HTInternalLink) {
+	    dest = parent;
+	    fragment = href+1;
+	} else {
+	    char *relative_to = HTAnchor_address((HTAnchor *)parent);
+	   /* hmm, it seems HTML.c always resolve href to absolute url??? */
+	    parsed_doc.address = HTParse(href, relative_to,
+	       PARSE_ACCESS | PARSE_HOST | PARSE_PATH | PARSE_PUNCTUATION);
 	    parsed_doc.post_data = NULL;
 	    parsed_doc.post_content_type = NULL;
+	    parsed_doc.bookmark = NULL;
+	    parsed_doc.isHEAD = FALSE;
+	    parsed_doc.safe = FALSE;
+	    dest = HTAnchor_findAddress_nofragment(&parsed_doc);
+	    FREE(relative_to);
+	    FREE(parsed_doc.address);
+	    fragment = HTParse(href, "", PARSE_ANCHOR);
 	}
-	parsed_doc.bookmark = NULL;
-	parsed_doc.isHEAD = FALSE;
-	parsed_doc.safe = FALSE;
-	dest = HTAnchor_findAddress(&parsed_doc);
+
+	/*
+	** [comment from HTAnchor_findAddress()]
+	** If the address represents a sub-anchor, we load its parent,
+	** then we create a child anchor within that document.
+	*/
+	if (*fragment)
+	    dest = (HTParentAnchor *)HTAnchor_findChild(dest, fragment);
+
+	if (!(*href == '#' && ltype == HTInternalLink))
+	    FREE(fragment);
 
 #define DUPLICATE_ANCHOR_NAME_WORKAROUND
 
@@ -276,7 +306,7 @@ PUBLIC HTChildAnchor * HTAnchor_findChildAndLink ARGS4(
 		CTRACE((tfp,
 		       "*** Duplicate ChildAnchor %p named `%s' with %d links",
 		       child, tag, child_links));
-		if (dest == testdest1 && ltype == child->mainLink.type) {
+		if ((HTAnchor *)dest == testdest1 && ltype == child->mainLink.type) {
 		    CTRACE((tfp,", same dest %p and type, keeping it\n",
 			   testdest1));
 		} else {
@@ -287,9 +317,7 @@ PUBLIC HTChildAnchor * HTAnchor_findChildAndLink ARGS4(
 	    }
 	}
 #endif
-	HTAnchor_link((HTAnchor *)child, dest, ltype);
-	FREE(parsed_doc.address);
-	FREE(relative_to);
+	HTAnchor_link((HTAnchor *)child, (HTAnchor *)dest, ltype);
     }
     return(child);
 }
@@ -366,14 +394,22 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1(
 	parsed_doc.isHEAD = newdoc->isHEAD;
 	parsed_doc.safe = newdoc->safe;
 
-	foundParent = (HTParentAnchor *)HTAnchor_findAddress(&parsed_doc);
+	foundParent = HTAnchor_findAddress_nofragment(&parsed_doc);
 	foundAnchor = HTAnchor_findChild (foundParent, tag);
 	FREE(parsed_doc.address);
 	FREE(tag);
 	return (HTAnchor *)foundAnchor;
-    } else {
+    }
+    FREE(tag);
+    return (HTAnchor *)HTAnchor_findAddress_nofragment(newdoc);
+}
+
+/*  The address has no anchor tag for sure.
+ */
+PRIVATE HTParentAnchor * HTAnchor_findAddress_nofragment ARGS1(
+	CONST DocAddress *,	newdoc)
+{
 	/*
-	**  If the address has no anchor tag,
 	**  check whether we have this node.
 	*/
 	int hash;
@@ -381,8 +417,6 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1(
 	HTList *grownups;
 	HTParentAnchor * foundAnchor;
 
-	FREE(tag);
-
 	/*
 	**  Select list from hash table,
 	*/
@@ -417,8 +451,8 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1(
 	    {
 		CTRACE((tfp, "Anchor %p with address `%s' already exists.\n",
 			    (void *)foundAnchor, newdoc->address));
-		 return (HTAnchor *)foundAnchor;
-	     }
+		return foundAnchor;
+	    }
 	}
 
 	/*
@@ -438,13 +472,14 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1(
 	foundAnchor->isHEAD = newdoc->isHEAD;
 	foundAnchor->safe = newdoc->safe;
 	HTList_addObject (adults, foundAnchor);
-	return (HTAnchor *)foundAnchor;
-    }
+
+	return foundAnchor;
 }
+
 /*	Create new or find old named anchor - simple form
 **	-------------------------------------------------
 **
-**	Like the previous one, but simpler to use for simple cases.
+**     Like HTAnchor_findAddress, but simpler to use for simple cases.
 **	No post data etc. can be supplied. - kw
 */
 PUBLIC HTAnchor * HTAnchor_findSimpleAddress ARGS1(
@@ -628,6 +663,7 @@ PUBLIC BOOL HTAnchor_delete ARGS1(
      * 05-27-94 Lynx 2-3-1 Garrett Arch Blythe
      */
     HTList *cur;
+    HTBTElement *ele;
     HTChildAnchor *child;
 
     /*
@@ -668,12 +704,18 @@ PUBLIC BOOL HTAnchor_delete ARGS1(
 	 *  Delete all outgoing links from children, do not
 	 *  delete the children, though.
 	 */
-	if (!HTList_isEmpty(me->children)) {
-	    cur = me->children;
+	if (!HTList_isEmpty(me->children_notag)) {
+	    cur = me->children_notag;
 	    while ((child = (HTChildAnchor *)HTList_nextObject(cur)) != 0) {
-		if (child != NULL) {
-		    deleteLinks((HTAnchor *)child);
-		}
+		deleteLinks((HTAnchor *)child);
+	    }
+	}
+	if (me->children) {
+	    ele = HTBTree_next(me->children, NULL);
+	    while (ele != NULL) {
+		child = (HTChildAnchor *)HTBTree_object(ele);
+		deleteLinks((HTAnchor *)child);
+		ele = HTBTree_next(me->children, ele);
 	    }
 	}
 	me->underway = FALSE;
@@ -688,26 +730,33 @@ PUBLIC BOOL HTAnchor_delete ARGS1(
      *	No more incoming links : kill everything
      *	First, recursively delete children and their links.
      */
-    if (!HTList_isEmpty(me->children)) {
+    if (me->children) {
+	ele = HTBTree_next(me->children, NULL);
+	while (ele != NULL) {
+	    child = (HTChildAnchor *)HTBTree_object(ele);
+	    deleteLinks((HTAnchor *)child);
+	    FREE(child->tag);
+	    ele = HTBTree_next(me->children, ele);
+	}
+	HTBTreeAndObject_free(me->children);
+	me->children = NULL;
+    }
+    /* ...and this kind of children */
+    if (!HTList_isEmpty(me->children_notag)) {
 	while ((child = (HTChildAnchor *)HTList_removeLastObject(
-							me->children)) != 0) {
-	    if (child) {
-		deleteLinks((HTAnchor *)child);
-		if (child->tag) {
-		    FREE(child->tag);
-		}
-		FREE(child);
-	    }
+						       me->children_notag)) != 0) {
+	   deleteLinks((HTAnchor *)child);
+	   FREE(child);
 	}
     }
     me->underway = FALSE;
 
     /*
-     *	Delete our empty list of children.
+     * Delete our empty list of children_notag.
      */
-    if (me->children) {
-	HTList_delete(me->children);
-	me->children = NULL;
+    if (me->children_notag) {
+	HTList_delete(me->children_notag);
+	me->children_notag = NULL;
     }
 
     /*
@@ -811,22 +860,6 @@ PUBLIC BOOL HTAnchor_delete ARGS1(
 }
 
 
-/*		Move an anchor to the head of the list of its siblings
-**		------------------------------------------------------
-**
-**	This is to ensure that an anchor which might have already existed
-**	is put in the correct order as we load the document.
-*/
-PUBLIC void HTAnchor_makeLastChild ARGS1(
-	HTChildAnchor *,	me)
-{
-    if (me->parent != (HTParentAnchor *)me) {  /* Make sure it's a child */
-	HTList * siblings = me->parent->children;
-	HTList_removeObject (siblings, me);
-	HTList_addObject (siblings, me);
-    }
-}
-
 /*	Data access functions
 **	---------------------
 */
@@ -916,12 +949,6 @@ PUBLIC BOOL HTAnchor_isISMAPScript ARGS1(
     return( me ? me->parent->isISMAPScript : NO);
 }
 
-PUBLIC BOOL HTAnchor_hasChildren ARGS1(
-	HTParentAnchor *,	me)
-{
-    return (BOOL) ( me ? ! HTList_isEmpty(me->children) : NO);
-}
-
 #if defined(USE_COLOR_STYLE)
 /*	Style handling.
 */
diff --git a/WWW/Library/Implementation/HTAnchor.h b/WWW/Library/Implementation/HTAnchor.h
index 89a7f88f..b72cb1de 100644
--- a/WWW/Library/Implementation/HTAnchor.h
+++ b/WWW/Library/Implementation/HTAnchor.h
@@ -15,6 +15,7 @@
 /* Version 1 of 24-Oct-1991 (JFG), written in C, browser-independent */
 
 #include <HTList.h>
+#include <HTBTree.h>
 #include <HTChunk.h>
 #include <HTAtom.h>
 #include <UCDefs.h>
@@ -52,7 +53,8 @@ struct _HTParentAnchor {
   HTParentAnchor * parent;	/* Parent of this anchor (self) */
 
   /* ParentAnchor-specific information */
-  HTList *	children;	/* Subanchors of this, if any */
+  HTList *     children_notag; /* Subanchors <a href=...>, tag is NULL */
+  HTBTree *    children;       /* Subanchors <a name="tag">, sorted by tag */
   HTList *	sources;	/* List of anchors pointing to this, if any */
   HyperDoc *	document;	/* The document within which this is an anchor */
   char *	address;	/* Absolute address of this node */
@@ -129,11 +131,8 @@ typedef struct _DocAddress {
     BOOL   safe;
 } DocAddress;
 
-/* "internal" means "within the same document, with certainty".
-   It includes a space so it cannot conflict with any (valid) "TYPE"
-   attributes on A elements. [According to which DTD, anyway??] - kw */
-
-#define LINK_INTERNAL HTAtom_for("internal link")
+/* "internal" means "within the same document, with certainty". */
+extern HTLinkType * HTInternalLink;
 
 /*	Create new or find old sub-anchor
 **	---------------------------------
@@ -195,15 +194,6 @@ extern void HTAnchor_clearSourceCache PARAMS((
 	HTParentAnchor *	me));
 #endif
 
-/*		Move an anchor to the head of the list of its siblings
-**		------------------------------------------------------
-**
-**	This is to ensure that an anchor which might have already existed
-**	is put in the correct order as we load the document.
-*/
-extern void HTAnchor_makeLastChild PARAMS((
-	HTChildAnchor *		me));
-
 /*	Data access functions
 **	---------------------
 */
@@ -244,9 +234,6 @@ extern BOOL HTAnchor_isIndex PARAMS((
 extern BOOL HTAnchor_isISMAPScript PARAMS((
 	HTAnchor *		me));
 
-extern BOOL HTAnchor_hasChildren PARAMS((
-	HTParentAnchor *	me));
-
 #if defined(USE_COLOR_STYLE)
 extern CONST char * HTAnchor_style PARAMS((
 	HTParentAnchor *	me));
diff --git a/WWW/Library/Implementation/HTBTree.c b/WWW/Library/Implementation/HTBTree.c
index db3b50db..ca03df51 100644
--- a/WWW/Library/Implementation/HTBTree.c
+++ b/WWW/Library/Implementation/HTBTree.c
@@ -20,7 +20,7 @@ PUBLIC HTBTree * HTBTree_new ARGS1(HTComparer, comp)
     ** for it when given a mean to compare things
     */
 {
-    HTBTree * tree = (HTBTree *)malloc(sizeof(HTBTree));
+    HTBTree * tree = typeMalloc(HTBTree);
     if (tree==NULL) outofmem(__FILE__, "HTBTree_new");
 
     tree->compare = comp;
@@ -38,7 +38,7 @@ PRIVATE void HTBTElement_free ARGS1(HTBTElement*, element)
     */
 {
     if (element) {
-        if (element->left != NULL)
+	if (element->left != NULL)
 	    HTBTElement_free(element->left);
 	if (element->right != NULL)
 	    HTBTElement_free(element->right);
@@ -64,7 +64,7 @@ PRIVATE void HTBTElementAndObject_free ARGS1(HTBTElement*, element)
     */
 {
     if (element) {     /* Just in case nothing was in the tree anyway */
-        if (element->left != NULL)
+	if (element->left != NULL)
 	    HTBTElementAndObject_free(element->left);
 	if (element->right != NULL)
 	    HTBTElementAndObject_free(element->right);
@@ -83,6 +83,30 @@ PUBLIC void HTBTreeAndObject_free ARGS1(HTBTree*, tree)
 }
 
 
+PUBLIC void * HTBTree_search ARGS2(
+		   HTBTree*,  tree,
+		   void*,     object)
+    /**********************************************************************
+    ** Returns a pointer to equivalent object in a tree or NULL if none.
+    */
+{
+    HTBTElement * cur = tree->top;
+    int res;
+
+    while (cur != NULL)
+    {
+	res = tree->compare(object, cur->object);
+
+	if (res == 0)
+	    return cur->object;
+	else if (res < 0)
+	    cur = cur->left;
+	else if (res > 0)
+	    cur = cur->right;
+    }
+    return NULL;
+}
+
 
 
 PUBLIC void HTBTree_add ARGS2(
@@ -91,7 +115,7 @@ PUBLIC void HTBTree_add ARGS2(
     /**********************************************************************
     ** This void is the core of HTBTree.c . It will
     **       1/ add a new element to the tree at the right place
-    **          so that the tree remains sorted
+    **		so that the tree remains sorted
     **       2/ balance the tree to be as fast as possible when reading it
     */
 {
@@ -101,27 +125,27 @@ PUBLIC void HTBTree_add ARGS2(
     HTBTElement * father_of_forefather;
     BOOL father_found,top_found;
     int depth,depth2,corrections;
-        /* father_of_element is a pointer to the structure that is the father of the
-        ** new object "object".
-        ** added_element is a pointer to the structure that contains or will contain
-        ** the new object "object".
-        ** father_of_forefather and forefather_of_element are pointers that are used
-        ** to modify the depths of upper elements, when needed.
-        **
-        ** father_found indicates by a value NO when the future father of "object"
-        ** is found.
-        ** top_found indicates by a value NO when, in case of a difference of depths
-        **  < 2, the top of the tree is encountered and forbids any further try to
-        ** balance the tree.
-        ** corrections is an integer used to avoid infinite loops in cases
-        ** such as:
-        **
-        **             3                        3
-        **          4                              4
-        **           5                            5
-        **
-        ** 3 is used here to show that it need not be the top of the tree.
-        */
+	/* father_of_element is a pointer to the structure that is the father of the
+	** new object "object".
+	** added_element is a pointer to the structure that contains or will contain
+	** the new object "object".
+	** father_of_forefather and forefather_of_element are pointers that are used
+	** to modify the depths of upper elements, when needed.
+	**
+	** father_found indicates by a value NO when the future father of "object"
+	** is found.
+	** top_found indicates by a value NO when, in case of a difference of depths
+	**  < 2, the top of the tree is encountered and forbids any further try to
+	** balance the tree.
+	** corrections is an integer used to avoid infinite loops in cases
+	** such as:
+	**
+	**             3                        3
+	**          4                              4
+	**           5                            5
+	**
+	** 3 is used here to show that it need not be the top of the tree.
+	*/
 
     /*
     ** 1/ Adding of the element to the binary tree
@@ -129,124 +153,124 @@ PUBLIC void HTBTree_add ARGS2(
 
     if (tree->top == NULL)
     {
-        tree->top = (HTBTElement *)malloc(sizeof(HTBTElement));
-        if (tree->top == NULL) outofmem(__FILE__, "HTBTree_add");
-        tree->top->up = NULL;
-        tree->top->object = object;
-        tree->top->left = NULL;
-        tree->top->left_depth = 0;
-        tree->top->right = NULL;
-        tree->top->right_depth = 0;
+	tree->top = typeMalloc(HTBTElement);
+	if (tree->top == NULL) outofmem(__FILE__, "HTBTree_add");
+	tree->top->up = NULL;
+	tree->top->object = object;
+	tree->top->left = NULL;
+	tree->top->left_depth = 0;
+	tree->top->right = NULL;
+	tree->top->right_depth = 0;
     }
     else
     {
-        father_found = YES;
-        father_of_element = tree->top;
-        added_element = NULL;
-        father_of_forefather = NULL;
-        forefather_of_element = NULL;
-        while (father_found)
-        {
-            if (tree->compare(object,father_of_element->object)<0)
+	father_found = YES;
+	father_of_element = tree->top;
+	added_element = NULL;
+	father_of_forefather = NULL;
+	forefather_of_element = NULL;
+	while (father_found)
+	{
+	    int res = tree->compare(object,father_of_element->object);
+	    if (res < 0)
 	    {
-                if (father_of_element->left != NULL)
-                    father_of_element = father_of_element->left;
-                else
-	        {
-                    father_found = NO;
-                    father_of_element->left =
-                        (HTBTElement *)malloc(sizeof(HTBTElement));
-                    if (father_of_element->left==NULL)
-                        outofmem(__FILE__, "HTBTree_add");
-                    added_element = father_of_element->left;
-                    added_element->up = father_of_element;
-                    added_element->object = object;
-                    added_element->left = NULL;
-                    added_element->left_depth = 0;
-                    added_element->right = NULL;
-                    added_element->right_depth = 0;
-                }
-   	    }
-            if (tree->compare(object,father_of_element->object)>=0)
-            {
-                if (father_of_element->right != NULL)
-                    father_of_element = father_of_element->right;
-                else
-                {
-                    father_found = NO;
-                    father_of_element->right =
-                        (HTBTElement *)malloc(sizeof(HTBTElement));
-                    if (father_of_element->right==NULL)
-                        outofmem(__FILE__, "HTBTree_add");
-                    added_element = father_of_element->right;
-                    added_element->up = father_of_element;
-                    added_element->object = object;
-                    added_element->left = NULL;
-                    added_element->left_depth = 0;
-                    added_element->right = NULL;
-                    added_element->right_depth = 0;
-    	        }
-            }
+		if (father_of_element->left != NULL)
+		    father_of_element = father_of_element->left;
+		else
+		{
+		    father_found = NO;
+		    father_of_element->left = typeMalloc(HTBTElement);
+		    if (father_of_element->left==NULL)
+			outofmem(__FILE__, "HTBTree_add");
+		    added_element = father_of_element->left;
+		    added_element->up = father_of_element;
+		    added_element->object = object;
+		    added_element->left = NULL;
+		    added_element->left_depth = 0;
+		    added_element->right = NULL;
+		    added_element->right_depth = 0;
+		}
+	    }
+	    else /* res >= 0 */
+	   {
+		if (father_of_element->right != NULL)
+		    father_of_element = father_of_element->right;
+		else
+		{
+		    father_found = NO;
+		    father_of_element->right = typeMalloc(HTBTElement);
+		    if (father_of_element->right==NULL)
+			outofmem(__FILE__, "HTBTree_add");
+		    added_element = father_of_element->right;
+		    added_element->up = father_of_element;
+		    added_element->object = object;
+		    added_element->left = NULL;
+		    added_element->left_depth = 0;
+		    added_element->right = NULL;
+		    added_element->right_depth = 0;
+		}
+	    }
 	}
-            /*
-            ** Changing of all depths that need to be changed
-            */
-        father_of_forefather = father_of_element;
-        forefather_of_element = added_element;
-        do
-        {
-            if (father_of_forefather->left == forefather_of_element)
-            {
-                depth = father_of_forefather->left_depth;
-                father_of_forefather->left_depth = 1
-                            + MAXIMUM(forefather_of_element->right_depth,
-                                  forefather_of_element->left_depth);
-                depth2 = father_of_forefather->left_depth;
-            }
-            else
+
+	/*
+	** Changing of all depths that need to be changed
+	*/
+	father_of_forefather = father_of_element;
+	forefather_of_element = added_element;
+	do
+	{
+	    if (father_of_forefather->left == forefather_of_element)
 	    {
-                depth = father_of_forefather->right_depth;
-                father_of_forefather->right_depth = 1
-                            + MAXIMUM(forefather_of_element->right_depth,
-                                  forefather_of_element->left_depth);
-                depth2 = father_of_forefather->right_depth;
-            }
-            forefather_of_element = father_of_forefather;
-            father_of_forefather = father_of_forefather->up;
-        } while ((depth != depth2) && (father_of_forefather != NULL));
-
-
-
-            /*
-            ** 2/ Balancing the binary tree, if necessary
-            */
-        top_found = YES;
-        corrections = 0;
-        while ((top_found) && (corrections < 7))
-        {
-            if ((abs(father_of_element->left_depth
-                      - father_of_element->right_depth)) < 2)
+		depth = father_of_forefather->left_depth;
+		father_of_forefather->left_depth = 1
+			    + MAXIMUM(forefather_of_element->right_depth,
+				  forefather_of_element->left_depth);
+		depth2 = father_of_forefather->left_depth;
+	    }
+	    else
+	    {
+		depth = father_of_forefather->right_depth;
+		father_of_forefather->right_depth = 1
+			    + MAXIMUM(forefather_of_element->right_depth,
+				  forefather_of_element->left_depth);
+		depth2 = father_of_forefather->right_depth;
+	    }
+	    forefather_of_element = father_of_forefather;
+	    father_of_forefather = father_of_forefather->up;
+	} while ((depth != depth2) && (father_of_forefather != NULL));
+
+
+
+	    /*
+	    ** 2/ Balancing the binary tree, if necessary
+	    */
+	top_found = YES;
+	corrections = 0;
+	while ((top_found) && (corrections < 7))
+	{
+	    if ((abs(father_of_element->left_depth
+		      - father_of_element->right_depth)) < 2)
 	    {
-                if (father_of_element->up != NULL)
-                    father_of_element = father_of_element->up;
-                else top_found = NO;
+		if (father_of_element->up != NULL)
+		    father_of_element = father_of_element->up;
+		else top_found = NO;
 	    }
-            else
- 	    {                /* We start the process of balancing */
-
-                corrections = corrections + 1;
-                    /*
-                    ** corrections is an integer used to avoid infinite
-                    ** loops in cases such as:
-                    **
-                    **             3                        3
-                    **          4                              4
-                    **           5                            5
-                    **
-                    ** 3 is used to show that it need not be the top of the tree
-		    ** But let's avoid these two exceptions anyhow
-		    ** with the two following conditions (4 March 94 - AS)
-                    */
+	    else
+	    {		     /* We start the process of balancing */
+
+		corrections = corrections + 1;
+		   /*
+		   ** corrections is an integer used to avoid infinite
+		   ** loops in cases such as:
+		   **
+		   **             3                        3
+		   **          4                              4
+		   **           5                            5
+		   **
+		   ** 3 is used to show that it need not be the top of the tree
+		   ** But let's avoid these two exceptions anyhow
+		   ** with the two following conditions (4 March 94 - AS)
+		   */
 
 		if ((father_of_element->left == NULL)
 		    && (father_of_element->right->right == NULL)
@@ -261,26 +285,26 @@ PUBLIC void HTBTree_add ARGS2(
 		    corrections = 7;
 
 
-                if (father_of_element->left_depth > father_of_element->right_depth)
-	        {
-                    added_element = father_of_element->left;
-                    father_of_element->left_depth = added_element->right_depth;
-                    added_element->right_depth = 1
-                                    + MAXIMUM(father_of_element->right_depth,
-                                          father_of_element->left_depth);
-                    if (father_of_element->up != NULL)
+		if (father_of_element->left_depth > father_of_element->right_depth)
+		{
+		    added_element = father_of_element->left;
+		    father_of_element->left_depth = added_element->right_depth;
+		    added_element->right_depth = 1
+				    + MAXIMUM(father_of_element->right_depth,
+					  father_of_element->left_depth);
+		    if (father_of_element->up != NULL)
 		    {
 			/* Bug fixed in March 94  -  AS */
 			BOOL first_time;
 
-                        father_of_forefather = father_of_element->up;
-                        forefather_of_element = added_element;
+			father_of_forefather = father_of_element->up;
+			forefather_of_element = added_element;
 			first_time = YES;
-                        do
-                        {
-                            if (father_of_forefather->left
-                                 == forefather_of_element->up)
-                              {
+			do
+			{
+			    if (father_of_forefather->left
+				 == forefather_of_element->up)
+			      {
 				  depth = father_of_forefather->left_depth;
 				  if (first_time)
 				  {
@@ -294,11 +318,11 @@ PUBLIC void HTBTree_add ARGS2(
 					   + MAXIMUM(forefather_of_element->up->left_depth,
 					      forefather_of_element->up->right_depth);
 
-                                depth2 = father_of_forefather->left_depth;
+				depth2 = father_of_forefather->left_depth;
 			    }
-                            else
+			    else
 			    {
-                                depth = father_of_forefather->right_depth;
+				depth = father_of_forefather->right_depth;
 				if (first_time)
 				{
 				    father_of_forefather->right_depth = 1
@@ -310,100 +334,100 @@ PUBLIC void HTBTree_add ARGS2(
 				    father_of_forefather->right_depth = 1
 				      + MAXIMUM(forefather_of_element->up->left_depth,
 					   forefather_of_element->up->right_depth);
-                                depth2 = father_of_forefather->right_depth;
+				depth2 = father_of_forefather->right_depth;
 			    }
-                            forefather_of_element = forefather_of_element->up;
-                            father_of_forefather = father_of_forefather->up;
+			    forefather_of_element = forefather_of_element->up;
+			    father_of_forefather = father_of_forefather->up;
 			} while ((depth != depth2) &&
 				 (father_of_forefather != NULL));
-                        father_of_forefather = father_of_element->up;
-                        if (father_of_forefather->left == father_of_element)
-	                {
-                            /*
-                            **                   3                       3
-                            **               4                       5
-                            ** When tree   5   6        becomes    7    4
-                            **            7 8                          8 6
-                            **
-                            ** 3 is used to show that it may not be the top of the
-                            ** tree.
-                            */
-                            father_of_forefather->left = added_element;
-                            father_of_element->left = added_element->right;
-                            added_element->right = father_of_element;
-                        }
-                        if (father_of_forefather->right == father_of_element)
-		        {
-                            /*
-                            **          3                       3
-                            **               4                       5
-                            ** When tree   5   6        becomes    7    4
-                            **            7 8                          8 6
-                            **
-                            ** 3 is used to show that it may not be the top of the
-                            ** tree
-                            */
-                            father_of_forefather->right = added_element;
-                            father_of_element->left = added_element->right;
-                            added_element->right = father_of_element;
-                        }
-                        added_element->up = father_of_forefather;
+			father_of_forefather = father_of_element->up;
+			if (father_of_forefather->left == father_of_element)
+			{
+			    /*
+			    **                   3                       3
+			    **               4                       5
+			    ** When tree   5   6        becomes    7    4
+			    **            7 8                          8 6
+			    **
+			    ** 3 is used to show that it may not be the top of the
+			    ** tree.
+			    */
+			    father_of_forefather->left = added_element;
+			    father_of_element->left = added_element->right;
+			    added_element->right = father_of_element;
+			}
+			if (father_of_forefather->right == father_of_element)
+			{
+			    /*
+			    **          3                       3
+			    **               4                       5
+			    ** When tree   5   6        becomes    7    4
+			    **            7 8                          8 6
+			    **
+			    ** 3 is used to show that it may not be the top of the
+			    ** tree
+			    */
+			    father_of_forefather->right = added_element;
+			    father_of_element->left = added_element->right;
+			    added_element->right = father_of_element;
+			}
+			added_element->up = father_of_forefather;
 		    }
-                    else
+		    else
 		    {
-                        /*
-                        **
-                        **               1                       2
-                        ** When tree   2   3        becomes    4    1
-                        **            4 5                          5 3
-                        **
-                        ** 1 is used to show that it is the top of the tree
-                        */
-                        added_element->up = NULL;
-                        father_of_element->left = added_element->right;
-                        added_element->right = father_of_element;
+			/*
+			**
+			**               1                       2
+			** When tree   2   3        becomes    4    1
+			**            4 5                          5 3
+			**
+			** 1 is used to show that it is the top of the tree
+			*/
+			added_element->up = NULL;
+			father_of_element->left = added_element->right;
+			added_element->right = father_of_element;
 		    }
-                    father_of_element->up = added_element;
-                    if (father_of_element->left != NULL)
-                        father_of_element->left->up = father_of_element;
-	        }
-                else
-	        {
-                    added_element = father_of_element->right;
-                    father_of_element->right_depth = added_element->left_depth;
-                    added_element->left_depth = 1 +
-                            MAXIMUM(father_of_element->right_depth,
-                                father_of_element->left_depth);
-                    if (father_of_element->up != NULL)
+		    father_of_element->up = added_element;
+		    if (father_of_element->left != NULL)
+			father_of_element->left->up = father_of_element;
+		}
+		else
+		{
+		    added_element = father_of_element->right;
+		    father_of_element->right_depth = added_element->left_depth;
+		    added_element->left_depth = 1 +
+			    MAXIMUM(father_of_element->right_depth,
+				father_of_element->left_depth);
+		    if (father_of_element->up != NULL)
 			/* Bug fixed in March 94  -  AS */
 		    {
 			BOOL first_time;
 
-                        father_of_forefather = father_of_element->up;
-                        forefather_of_element = added_element;
+			father_of_forefather = father_of_element->up;
+			forefather_of_element = added_element;
 			first_time = YES;
-                        do
-                        {
-                            if (father_of_forefather->left
+			do
+			{
+			    if (father_of_forefather->left
 				== forefather_of_element->up)
-                            {
-                                depth = father_of_forefather->left_depth;
-                                if (first_time)
+			    {
+				depth = father_of_forefather->left_depth;
+				if (first_time)
 				{
 				    father_of_forefather->left_depth = 1
 				       + MAXIMUM(forefather_of_element->left_depth,
 					       forefather_of_element->right_depth);
 				    first_time = NO;
 				}
-                                else
+				else
 				    father_of_forefather->left_depth = 1
 				      + MAXIMUM(forefather_of_element->up->left_depth,
-				       	  forefather_of_element->up->right_depth);
+					  forefather_of_element->up->right_depth);
 				depth2 = father_of_forefather->left_depth;
 			    }
-                            else
+			    else
 			    {
-                                depth = father_of_forefather->right_depth;
+				depth = father_of_forefather->right_depth;
 				if (first_time)
 				{
 				    father_of_forefather->right_depth = 1
@@ -415,78 +439,78 @@ PUBLIC void HTBTree_add ARGS2(
 				    father_of_forefather->right_depth = 1
 				      + MAXIMUM(forefather_of_element->up->left_depth,
 					   forefather_of_element->up->right_depth);
-                                depth2 = father_of_forefather->right_depth;
+				depth2 = father_of_forefather->right_depth;
 			    }
-                            father_of_forefather = father_of_forefather->up;
-                            forefather_of_element = forefather_of_element->up;
+			    father_of_forefather = father_of_forefather->up;
+			    forefather_of_element = forefather_of_element->up;
 			} while ((depth != depth2) &&
 				 (father_of_forefather != NULL));
-                        father_of_forefather = father_of_element->up;
-                        if (father_of_forefather->left == father_of_element)
-		        {
-                            /*
-                            **                    3                       3
-                            **               4                       6
-                            ** When tree   5   6        becomes    4    8
-                            **                7 8                 5 7
-                            **
-                            ** 3 is used to show that it may not be the top of the
-                            ** tree.
-                            */
-                            father_of_forefather->left = added_element;
-                            father_of_element->right = added_element->left;
-                            added_element->left = father_of_element;
-                        }
-                        if (father_of_forefather->right == father_of_element)
-		        {
-                            /*
-                            **           3                      3
-                            **               4                       6
-                            ** When tree   5   6        becomes    4    8
-                            **                7 8                 5 7
-                            **
-                            ** 3 is used to show that it may not be the top of the
-                            ** tree
-                            */
-                            father_of_forefather->right = added_element;
-                            father_of_element->right = added_element->left;
-                            added_element->left = father_of_element;
-                        }
-                        added_element->up = father_of_forefather;
+			father_of_forefather = father_of_element->up;
+			if (father_of_forefather->left == father_of_element)
+			{
+			    /*
+			    **                    3                       3
+			    **               4                       6
+			    ** When tree   5   6        becomes    4    8
+			    **                7 8                 5 7
+			    **
+			    ** 3 is used to show that it may not be the top of the
+			    ** tree.
+			    */
+			    father_of_forefather->left = added_element;
+			    father_of_element->right = added_element->left;
+			    added_element->left = father_of_element;
+			}
+			if (father_of_forefather->right == father_of_element)
+			{
+			    /*
+			    **           3                      3
+			    **               4                       6
+			    ** When tree   5   6        becomes    4    8
+			    **                7 8                 5 7
+			    **
+			    ** 3 is used to show that it may not be the top of the
+			    ** tree
+			    */
+			    father_of_forefather->right = added_element;
+			    father_of_element->right = added_element->left;
+			    added_element->left = father_of_element;
+			}
+			added_element->up = father_of_forefather;
 		    }
-                    else
-                    {
-                        /*
-                        **
-                        **               1                       3
-                        ** When tree   2   3        becomes    1    5
-                        **                4 5                 2 4
-                        **
-                        ** 1 is used to show that it is the top of the tree.
-                        */
-                        added_element->up = NULL;
-                        father_of_element->right = added_element->left;
-                        added_element->left = father_of_element;
+		    else
+		    {
+			/*
+			**
+			**               1                       3
+			** When tree   2   3        becomes    1    5
+			**                4 5                 2 4
+			**
+			** 1 is used to show that it is the top of the tree.
+			*/
+			added_element->up = NULL;
+			father_of_element->right = added_element->left;
+			added_element->left = father_of_element;
 		    }
-                    father_of_element->up = added_element;
-                    if (father_of_element->right != NULL)
-		        father_of_element->right->up = father_of_element;
+		    father_of_element->up = added_element;
+		    if (father_of_element->right != NULL)
+			father_of_element->right->up = father_of_element;
 		}
 	    }
-        }
-        while (father_of_element->up != NULL)
+	}
+	while (father_of_element->up != NULL)
 	{
-            father_of_element = father_of_element->up;
-        }
-        tree->top = father_of_element;
+	    father_of_element = father_of_element->up;
+	}
+	tree->top = father_of_element;
     }
 }
 
 
 
 PUBLIC HTBTElement * HTBTree_next ARGS2(
-                               HTBTree*,       tree,
-                               HTBTElement*,   ele)
+			       HTBTree*,       tree,
+			       HTBTElement*,   ele)
     /**************************************************************************
     ** this function returns a pointer to the leftmost element if ele is NULL,
     ** and to the next object to the right otherwise.
@@ -498,30 +522,30 @@ PUBLIC HTBTElement * HTBTree_next ARGS2(
 
     if (ele == NULL)
     {
-        father_of_element = tree->top;
-        if (father_of_element != NULL)
-            while (father_of_element->left != NULL)
-                father_of_element = father_of_element->left;
+	father_of_element = tree->top;
+	if (father_of_element != NULL)
+	    while (father_of_element->left != NULL)
+		father_of_element = father_of_element->left;
     }
     else
     {
-        father_of_element = ele;
-        if (father_of_element->right != NULL)
+	father_of_element = ele;
+	if (father_of_element->right != NULL)
 	{
-            father_of_element = father_of_element->right;
-            while (father_of_element->left != NULL)
-                father_of_element = father_of_element->left;
+	    father_of_element = father_of_element->right;
+	    while (father_of_element->left != NULL)
+		father_of_element = father_of_element->left;
 	}
-        else
+	else
 	{
-            father_of_forefather = father_of_element->up;
-	        while (father_of_forefather &&
+	    father_of_forefather = father_of_element->up;
+		while (father_of_forefather &&
 		       (father_of_forefather->right == father_of_element))
-      	        {
-                    father_of_element = father_of_forefather;
+		{
+		    father_of_element = father_of_forefather;
 		    father_of_forefather = father_of_element->up;
 		}
-            father_of_element = father_of_forefather;
+	    father_of_element = father_of_forefather;
 	}
     }
 #ifdef BTREE_TRACE
@@ -530,22 +554,22 @@ PUBLIC HTBTElement * HTBTree_next ARGS2(
     */
     if (father_of_element != NULL)
     {
-        printf("\nObject = %s\t",(char *)father_of_element->object);
-        if (father_of_element->up != NULL)
-            printf("Objet du pere = %s\n",
+	printf("\nObject = %s\t",(char *)father_of_element->object);
+	if (father_of_element->up != NULL)
+	    printf("Objet du pere = %s\n",
 		   (char *)father_of_element->up->object);
-        else printf("Pas de Pere\n");
-        if (father_of_element->left != NULL)
-            printf("Objet du fils gauche = %s\t",
+	else printf("Pas de Pere\n");
+	if (father_of_element->left != NULL)
+	    printf("Objet du fils gauche = %s\t",
 		   (char *)father_of_element->left->object);
-        else printf("Pas de fils gauche\t");
-        if (father_of_element->right != NULL)
-            printf("Objet du fils droit = %s\n",
+	else printf("Pas de fils gauche\t");
+	if (father_of_element->right != NULL)
+	    printf("Objet du fils droit = %s\n",
 		   (char *)father_of_element->right->object);
-        else printf("Pas de fils droit\n");
-        printf("Profondeur gauche = %d\t",father_of_element->left_depth);
-        printf("Profondeur droite = %d\n",father_of_element->right_depth);
-        printf("      **************\n");
+	else printf("Pas de fils droit\n");
+	printf("Profondeur gauche = %d\t",father_of_element->left_depth);
+	printf("Profondeur droite = %d\n",father_of_element->right_depth);
+	printf("      **************\n");
     }
 #endif
     return father_of_element;
@@ -702,9 +726,9 @@ main ()
     while (next_element != NULL)
     {
 #ifndef BTREE_TRACE
-        printf("The next element is %s\n",next_element->object);
+	printf("The next element is %s\n",next_element->object);
 #endif
-        next_element = HTBTree_next(tree,next_element);
+	next_element = HTBTree_next(tree,next_element);
     }
     HTBTree_free(tree);
 }
diff --git a/WWW/Library/Implementation/HTBTree.h b/WWW/Library/Implementation/HTBTree.h
index d4b2ac08..cbbfad43 100644
--- a/WWW/Library/Implementation/HTBTree.h
+++ b/WWW/Library/Implementation/HTBTree.h
@@ -15,7 +15,7 @@
 #ifndef HTUTILS_H
 #include <HTUtils.h>
 #endif
- 
+
 /*
 
 Data structures
@@ -76,6 +76,16 @@ extern void HTBTree_add PARAMS((HTBTree* tree, void * object));
 
 /*
 
+Search an object in a binary tree
+
+  returns          Pointer to equivalent object in a tree or NULL if none.
+ */
+
+extern void * HTBTree_search PARAMS((HTBTree* tree, void * object));
+
+
+/*
+
 Find user object for element
 
  */
@@ -91,7 +101,7 @@ Find next element in depth-first order
   ele                    if NULL, start with leftmost element. if != 0 give next object to
                          the right.
 
-  returns                Pointer to element ot NULL if none left.
+  returns                Pointer to element or NULL if none left.
 
  */
 extern HTBTElement * HTBTree_next PARAMS((HTBTree* tree, HTBTElement * ele));
diff --git a/WWW/Library/Implementation/HTChunk.c b/WWW/Library/Implementation/HTChunk.c
index 05a5da61..6c2d1687 100644
--- a/WWW/Library/Implementation/HTChunk.c
+++ b/WWW/Library/Implementation/HTChunk.c
@@ -61,7 +61,7 @@ PUBLIC HTChunk * HTChunkCreate2 ARGS2 (int,grow, size_t, needed)
 	ch->allocated = needed-1 - ((needed-1) % ch->growby)
 	    + ch->growby; /* Round up */
 	CTRACE((tfp, "HTChunkCreate2: requested %d, allocate %d\n",
-	       needed, ch->allocated));
+	       (int) needed, ch->allocated));
 	ch->data = typecallocn(char, ch->allocated);
 	if (!ch->data)
 	    outofmem(__FILE__, "HTChunkCreate2 data");
@@ -249,7 +249,7 @@ PUBLIC void HTChunkTerminate ARGS1 (HTChunk *,ch)
 PUBLIC void HTChunkPuts ARGS2 (HTChunk *,ch, CONST char *,s)
 {
     CONST char * p;
-    for (p=s; *p; p++) {
+    for (p = s; *p; p++) {
 	HTChunkPutc(ch, *p);
 	if (ch->allocated == 0)
 	    return;		/* must have been allocation failure - kw */
diff --git a/WWW/Library/Implementation/HTFTP.c b/WWW/Library/Implementation/HTFTP.c
index 39cfd1c9..3c884e63 100644
--- a/WWW/Library/Implementation/HTFTP.c
+++ b/WWW/Library/Implementation/HTFTP.c
@@ -63,6 +63,7 @@ BUGS:	@@@	Limit connection cache size!
 
 #include <HTFTP.h>	/* Implemented here */
 #include <HTTCP.h>
+#include <HTTP.h>
 #include <HTFont.h>
 
 #define REPEAT_PORT	/* Give the port number for each file */
@@ -2746,8 +2747,6 @@ AgainForMultiNet:
 	    BytesReceived += chunk->size;
 	    if (BytesReceived > BytesReported + 1024) {
 #ifdef _WINDOWS
-		extern int ws_read_per_sec;
-
 		sprintf(NumBytes,gettext("Transferred %d bytes (%5d)"),
 				BytesReceived, ws_read_per_sec);
 #else
diff --git a/WWW/Library/Implementation/HTFile.c b/WWW/Library/Implementation/HTFile.c
index 3a90e3b2..e9d5e231 100644
--- a/WWW/Library/Implementation/HTFile.c
+++ b/WWW/Library/Implementation/HTFile.c
@@ -129,8 +129,6 @@ PUBLIC int HTDirReadme = HT_DIR_README_NONE;
 PUBLIC int HTDirReadme = HT_DIR_README_TOP;
 #endif /* DIRED_SUPPORT */
 
-extern BOOL HTPassEightBitRaw;
-
 PRIVATE char *HTMountRoot = "/Net/";		/* Where to find mounts */
 #ifdef VMS
 PRIVATE char *HTCacheRoot = "/WWW$SCRATCH";	/* Where to cache things */
@@ -2035,30 +2033,26 @@ PUBLIC int HTStat ARGS2(
 	struct stat *,	data)
 {
     int result = -1;
-    char *temp_name = NULL;
     size_t len = strlen(filename);
 
     if (len != 0 && LYIsPathSep(filename[len-1])) {
+	char *temp_name = NULL;
 	HTSprintf0(&temp_name, "%s.", filename);
+	result = HTStat(temp_name, data);
+	FREE(temp_name);
     } else {
-	temp_name = (char *)filename;
-    }
+	result = stat(filename, data);
 #ifdef _WINDOWS
-    /*
-     * Someone claims that stat() doesn't give the proper result for a
-     * directory on Windows.
-     */
-    if (access(temp_name, 0) == 0) {
-	if (stat(temp_name, data) == -1)
+	/*
+	 * Someone claims that stat() doesn't give the proper result for a
+	 * directory on Windows.
+	 */
+	if (result == -1
+	 && access(filename, 0) == 0) {
 	    data->st_mode = S_IFDIR;
-	result = 0;
-    }
-#else
-    result = stat(temp_name, data);
+	    result = 0;
+	}
 #endif
-
-    if (temp_name != filename) {
-	FREE(temp_name);
     }
     return result;
 }
@@ -2754,6 +2748,155 @@ PUBLIC int HTLoadFile ARGS4(
     }
 }
 
+static CONST char *program_paths[pp_Last];
+
+/*
+ * Given a program number, return its path
+ */
+PUBLIC CONST char * HTGetProgramPath ARGS1(
+	ProgramPaths,	code)
+{
+    CONST char *result = NULL;
+    if (code > ppUnknown && code < pp_Last)
+	result = program_paths[code];
+    return result;
+}
+
+/*
+ * Store a program's path
+ */
+PUBLIC void HTSetProgramPath ARGS2(
+	ProgramPaths,	code,
+	CONST char *,	path)
+{
+    if (code > ppUnknown && code < pp_Last) {
+	program_paths[code] = isEmpty(path) ? 0 : path;
+    }
+}
+
+/*
+ * Reset the list of known program paths to the ones that are compiled-in
+ */
+PUBLIC void HTInitProgramPaths NOARGS
+{
+    ProgramPaths code;
+    CONST char *path;
+    CONST char *test;
+
+    for (code = ppUnknown + 1; code < pp_Last; ++code) {
+	switch (code) {
+#ifdef BZIP2_PATH
+	case ppBZIP2:
+	    path = BZIP2_PATH;
+	    break;
+#endif
+#ifdef CHMOD_PATH
+	case ppCHMOD:
+	    path = CHMOD_PATH;
+	    break;
+#endif
+#ifdef COMPRESS_PATH
+	case ppCOMPRESS:
+	    path = COMPRESS_PATH;
+	    break;
+#endif
+#ifdef COPY_PATH
+	case ppCOPY:
+	    path = COPY_PATH;
+	    break;
+#endif
+#ifdef CSWING_PATH
+	case ppCSWING:
+	    path = CSWING_PATH;
+	    break;
+#endif
+#ifdef GZIP_PATH
+	case ppGZIP:
+	    path = GZIP_PATH;
+	    break;
+#endif
+#ifdef INSTALL_PATH
+	case ppINSTALL:
+	    path = INSTALL_PATH;
+	    break;
+#endif
+#ifdef MKDIR_PATH
+	case ppMKDIR:
+	    path = MKDIR_PATH;
+	    break;
+#endif
+#ifdef MV_PATH
+	case ppMV:
+	    path = MV_PATH;
+	    break;
+#endif
+#ifdef RLOGIN_PATH
+	case ppRLOGIN:
+	    path = RLOGIN_PATH;
+	    break;
+#endif
+#ifdef RM_PATH
+	case ppRM:
+	    path = RM_PATH;
+	    break;
+#endif
+#ifdef TAR_PATH
+	case ppTAR:
+	    path = TAR_PATH;
+	    break;
+#endif
+#ifdef TELNET_PATH
+	case ppTELNET:
+	    path = TELNET_PATH;
+	    break;
+#endif
+#ifdef TN3270_PATH
+	case ppTN3270:
+	    path = TN3270_PATH;
+	    break;
+#endif
+#ifdef TOUCH_PATH
+	case ppTOUCH:
+	    path = TOUCH_PATH;
+	    break;
+#endif
+#ifdef UNCOMPRESS_PATH
+	case ppUNCOMPRESS:
+	    path = UNCOMPRESS_PATH;
+	    break;
+#endif
+#ifdef UNZIP_PATH
+	case ppUNZIP:
+	    path = UNZIP_PATH;
+	    break;
+#endif
+#ifdef UUDECODE_PATH
+	case ppUUDECODE:
+	    path = UUDECODE_PATH;
+	    break;
+#endif
+#ifdef ZCAT_PATH
+	case ppZCAT:
+	    path = ZCAT_PATH;
+	    break;
+#endif
+#ifdef ZIP_PATH
+	case ppZIP:
+	    path = ZIP_PATH;
+	    break;
+#endif
+	default:
+	    path = NULL;
+	    break;
+	}
+	test = HTGetProgramPath(code);
+	if (test != NULL && test != path) {
+	    free((char *)test);
+	}
+	HTSetProgramPath(code, path);
+    }
+}
+
 /*
 **	Protocol descriptors
 */
diff --git a/WWW/Library/Implementation/HTFile.h b/WWW/Library/Implementation/HTFile.h
index bd0a90ee..258c30f5 100644
--- a/WWW/Library/Implementation/HTFile.h
+++ b/WWW/Library/Implementation/HTFile.h
@@ -276,6 +276,54 @@ extern CONST char * HTFileSuffix PARAMS((
                 CONST char* enc));
 
 /*
+ * Enumerate external programs that lynx may assume exists.  Unlike those
+ * given in download scripts, etc., lynx would really like to know their
+ * absolute paths, for better security.
+ */
+typedef enum {
+    ppUnknown = 0
+    ,ppBZIP2
+    ,ppCHMOD
+    ,ppCOMPRESS
+    ,ppCOPY
+    ,ppCSWING
+    ,ppGZIP
+    ,ppINSTALL
+    ,ppMKDIR
+    ,ppMV
+    ,ppRLOGIN
+    ,ppRM
+    ,ppTAR
+    ,ppTELNET
+    ,ppTN3270
+    ,ppTOUCH
+    ,ppUNCOMPRESS
+    ,ppUNZIP
+    ,ppUUDECODE
+    ,ppZCAT
+    ,ppZIP
+    ,pp_Last
+} ProgramPaths;
+
+/*
+ * Given a program number, return its path
+ */
+extern CONST char * HTGetProgramPath PARAMS((
+		ProgramPaths code));
+
+/*
+ * Store a program's path 
+ */
+extern void HTSetProgramPath PARAMS((
+		ProgramPaths code,
+		CONST char *path));
+
+/*
+ * Reset the list of known program paths to the ones that are compiled-in
+ */
+extern void HTInitProgramPaths NOPARAMS;
+
+/*
 **  The Protocols
 */
 #ifdef GLOBALREF_IS_MACRO
diff --git a/WWW/Library/Implementation/HTFormat.c b/WWW/Library/Implementation/HTFormat.c
index 70184064..4a8e1778 100644
--- a/WWW/Library/Implementation/HTFormat.c
+++ b/WWW/Library/Implementation/HTFormat.c
@@ -55,7 +55,6 @@ PUBLIC long int HTMaxBytes  = 0;	/* No effective limit */
 #endif
 
 PUBLIC	BOOL HTOutputSource = NO;	/* Flag: shortcut parser to stdout */
-/* extern  BOOL interactive; LJM */
 
 #ifdef ORIGINAL
 struct _HTStream {
@@ -627,8 +626,8 @@ PUBLIC void HTDisplayPartial NOARGS
 		 * If partial_threshold <= 0, then it's a full page
 		 */
 	) {
-	    NumOfLines_partial = HText_getNumOfLines();
-	    LYMainLoop_pageDisplay(Newline_partial);
+	    if (LYMainLoop_pageDisplay(Newline_partial))
+		NumOfLines_partial = HText_getNumOfLines();
 	}
     }
 #else /* nothing */
@@ -688,12 +687,6 @@ PUBLIC int HTCopy ARGS4(
     BOOL suppress_readprogress = NO;
     int bytes;
     int rv = 0;
-#ifdef _WINDOWS	/* 1997/11/11 (Tue) 15:18:16 */
-    long file_length;
-    extern int bytes_already_read;
-
-    file_length = anchor->content_length;
-#endif
 
     /*	Push the data down the stream
     */
diff --git a/WWW/Library/Implementation/HTFormat.h b/WWW/Library/Implementation/HTFormat.h
index 63c96f5b..13daca35 100644
--- a/WWW/Library/Implementation/HTFormat.h
+++ b/WWW/Library/Implementation/HTFormat.h
@@ -38,7 +38,8 @@ typedef HTAtom * HTFormat;
 
  */
                         /* Internal ones */
-#define WWW_SOURCE HTAtom_for("www/source")     /* Whatever it was originally*/
+/* #define WWW_SOURCE HTAtom_for("www/source") */    /* Whatever it was originally*/
+extern HTAtom * WWW_SOURCE;     /* calculated once, heavy used */
 
 /*
 
diff --git a/WWW/Library/Implementation/HTList.c b/WWW/Library/Implementation/HTList.c
index 90871f90..cc46beda 100644
--- a/WWW/Library/Implementation/HTList.c
+++ b/WWW/Library/Implementation/HTList.c
@@ -17,7 +17,7 @@ PUBLIC HTList * HTList_new NOARGS
 {
     HTList *newList;
 
-    if ((newList = typecalloc(HTList)) == NULL)
+    if ((newList = typeMalloc(HTList)) == NULL)
 	outofmem(__FILE__, "HTList_new");
 
     newList->object = NULL;
@@ -96,7 +96,7 @@ PUBLIC void HTList_addObject ARGS2(
     HTList *newNode;
 
     if (me) {
-	if ((newNode = typecalloc(HTList)) == NULL)
+	if ((newNode = typeMalloc(HTList)) == NULL)
 	    outofmem(__FILE__, "HTList_addObject");
 	newNode->object = newObject;
 	newNode->next = me->next;
@@ -157,7 +157,7 @@ PUBLIC void HTList_insertObjectAt ARGS3(
     prevNode = temp;
     while ((temp = temp->next)) {
 	if (Pos == 0) {
-	    if ((newNode = typecalloc(HTList)) == NULL)
+	    if ((newNode = typeMalloc(HTList)) == NULL)
 		outofmem(__FILE__, "HTList_addObjectAt");
 	    newNode->object = newObject;
 	    newNode->next = temp;
diff --git a/WWW/Library/Implementation/HTMIME.c b/WWW/Library/Implementation/HTMIME.c
index 1750a5e3..0838a9a9 100644
--- a/WWW/Library/Implementation/HTMIME.c
+++ b/WWW/Library/Implementation/HTMIME.c
@@ -26,8 +26,6 @@
 #include <LYUtils.h>
 #include <LYLeaks.h>
 
-extern BOOL HTPassEightBitRaw;
-
 /*		MIME Object
 **		-----------
 */
@@ -200,6 +198,16 @@ PRIVATE char *parse_parameter ARGS2(
     return result;
 }
 
+PRIVATE BOOL content_is_compressed ARGS1(HTStream *, me)
+{
+    char *encoding = me->anchor->content_encoding;
+
+    return encoding != 0
+        && strcmp(encoding, "8bit") != 0
+	&& strcmp(encoding, "7bit") != 0
+	&& strcmp(encoding, "binary") != 0;
+}
+
 PRIVATE int pumpData ARGS1(HTStream *, me)
 {
     if (strchr(HTAtom_name(me->format), ';') != NULL) {
@@ -467,9 +475,11 @@ PRIVATE int pumpData ARGS1(HTStream *, me)
     } else {
 	me->state = MIME_IGNORE;	/* What else to do? */
     }
-    if (me->refresh_url != NULL) {
+    if (me->refresh_url != NULL && !content_is_compressed(me)) {
 	char *url = parse_parameter(me->refresh_url, "URL");
 	char *txt = NULL;
+	char *arg = NULL;
+	char *base = "";	/* FIXME: refresh_url may be relative to doc */
 	int num = 0;
 
 	if (url != NULL) {
@@ -479,7 +489,10 @@ PRIVATE int pumpData ARGS1(HTStream *, me)
 	    HTSprintf0(&txt, gettext("Refresh: "));
 	    if (num != 0)
 		HTSprintf(&txt, gettext("%.*s seconds "), num, me->refresh_url);
-	    HTSprintf(&txt, "<a href=\"%s\">%s</a><br>", url, url);
+	    if ((arg = strchr(url, '?')) != NULL)
+		*arg = '\0';
+	    HTSprintf(&txt, "<a href=\"%s%s\">%s</a><br>", base, url, url);
+	    CTRACE((tfp, "URL %s%s\n", base, url));
 	    (me->isa->put_string)(me, txt);
 	    free(url);
 	    free(txt);
@@ -658,20 +671,18 @@ PRIVATE int dispatchField ARGS1(HTStream *, me)
 	LYLowerCase(me->value);
 	StrAllocCopy(me->anchor->content_encoding, me->value);
 	FREE(me->compression_encoding);
-	if (!strcmp(me->value, "8bit") ||
-	    !strcmp(me->value, "7bit") ||
-	    !strcmp(me->value, "binary")) {
-	    /*
-	    **	Some server indicated "8bit", "7bit" or "binary"
-	    **	inappropriately.  We'll ignore it. - FM
-	    */
-	    CTRACE((tfp, "                Ignoring it!\n"));
-	} else {
+	if (content_is_compressed(me)) {
 	    /*
 	    **	Save it to use as a flag for setting
 	    **	up a "www/compressed" target. - FM
 	    */
 	    StrAllocCopy(me->compression_encoding, me->value);
+	} else {
+	    /*
+	    **	Some server indicated "8bit", "7bit" or "binary"
+	    **	inappropriately.  We'll ignore it. - FM
+	    */
+	    CTRACE((tfp, "                Ignoring it!\n"));
 	}
 	break;
     case miCONTENT_FEATURES:
diff --git a/WWW/Library/Implementation/HTNews.c b/WWW/Library/Implementation/HTNews.c
index ce7c16df..72ae27de 100644
--- a/WWW/Library/Implementation/HTNews.c
+++ b/WWW/Library/Implementation/HTNews.c
@@ -17,6 +17,7 @@
 #include <HTCJK.h>
 #include <HTMIME.h>
 #include <HTFont.h>
+#include <HTFormat.h>
 #include <HTTCP.h>
 #include <LYUtils.h>
 #include <LYStrings.h>
@@ -73,11 +74,6 @@ struct _HTStream
 
 #define LINE_LENGTH 512			/* Maximum length of line of ARTICLE etc */
 #define GROUP_NAME_LENGTH	256	/* Maximum length of group name */
-extern BOOLEAN scan_for_buried_news_references;
-extern BOOLEAN LYListNewsNumbers;
-extern BOOLEAN LYListNewsDates;
-extern int interrupted_in_htgetcharacter;
-extern BOOL keep_mime_headers;	 /* Include mime headers and force raw text */
 extern BOOL using_proxy;	/* Are we using an NNTP proxy? */
 
 /*
diff --git a/WWW/Library/Implementation/HTParse.c b/WWW/Library/Implementation/HTParse.c
index 4b09e64a..35a0ad38 100644
--- a/WWW/Library/Implementation/HTParse.c
+++ b/WWW/Library/Implementation/HTParse.c
@@ -8,6 +8,10 @@
 #include <LYUtils.h>
 #include <LYLeaks.h>
 
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
 #define HEX_ESCAPE '%'
 
 struct struct_parts {
@@ -131,7 +135,8 @@ PRIVATE void scan ARGS2(
     /*
     **	Check schemes that commonly have unescaped hashes.
     */
-    if (parts->access && parts->anchor) {
+    if (parts->access && parts->anchor &&
+		/* optimize */ strchr("lnsdLNSD", *parts->access) != NULL) {
 	if ((!parts->host && strcasecomp(parts->access, "lynxcgi")) ||
 	    !strcasecomp(parts->access, "nntp") ||
 	    !strcasecomp(parts->access, "snews") ||
@@ -154,6 +159,14 @@ PRIVATE void scan ARGS2(
 } /*scan */
 
 
+#if defined(HAVE_ALLOCA) && !defined(LY_FIND_LEAKS)
+#define LYalloca(x)        alloca(x)
+#define LYalloca_free(x)   x = 0 /*avoid warning*/
+#else
+#define LYalloca(x)        malloc(x)
+#define LYalloca_free(x)   free(x)
+#endif
+
 /*	Parse a Name relative to another name.			HTParse()
 **	--------------------------------------
 **
@@ -166,7 +179,7 @@ PRIVATE void scan ARGS2(
 **	wanted		A mask for the bits which are wanted.
 **
 ** On exit,
-**	returns		A pointer to a calloc'd string which MUST BE FREED
+**     returns         A pointer to a malloc'd string which MUST BE FREED
 */
 PUBLIC char * HTParse ARGS3(
 	CONST char *,	aName,
@@ -175,7 +188,7 @@ PUBLIC char * HTParse ARGS3(
 {
     char * result = NULL;
     char * return_value = NULL;
-    int len;
+    int len, len1, len2;
     char * name = NULL;
     char * rel = NULL;
     char * p;
@@ -193,19 +206,25 @@ PUBLIC char * HTParse ARGS3(
 	    wanted &= ~(PARSE_STRICTPATH | PARSE_QUERY); /* ignore details */
     }
     /*
-    **	Allocate the output string.
+    ** Allocate the temporary string. Optimized.
     */
-    len = strlen(aName) + strlen(relatedName) + 10;
-    result = typecallocn(char, len);	/* Lots of space: more than enough */
+    len1 = strlen(aName) + 1;
+    len2 = strlen(relatedName) + 1;
+    len = len1 + len2 + 8;     /* Lots of space: more than enough */
+
+    result = (char*)LYalloca(len + len1 + len2);
     if (result == NULL) {
 	outofmem(__FILE__, "HTParse");
     }
+    *result = '\0';
+    name = result + len;
+    rel = name + len1;
 
     /*
     **	Make working copies of the input strings to cut up.
     */
-    StrAllocCopy(name, aName);
-    StrAllocCopy(rel, relatedName);
+    memcpy(name, aName, len1);
+    memcpy(rel, relatedName, len2);
 
     /*
     **	Cut up the strings into URL fields.
@@ -309,10 +328,10 @@ PUBLIC char * HTParse ARGS3(
 		    *p2 = '\0'; /* It is the default: ignore it */
 		}
 		if (p2 == NULL) {
-		    int len2 = strlen(tail);
+		    int len3 = strlen(tail);
 
-		    if (len2 > 0) {
-			h = tail + len2 - 1;	/* last char of hostname */
+		    if (len3 > 0) {
+			h = tail + len3 - 1;	/* last char of hostname */
 			if (*h == '.')
 			    *h = '\0';		/* chop final . */
 		    }
@@ -448,15 +467,14 @@ PUBLIC char * HTParse ARGS3(
 			     given.anchor : related.anchor);
 	}
     CTRACE((tfp, "HTParse:      result:%s\n", result));
-    FREE(rel);
-    FREE(name);
 
     StrAllocCopy(return_value, result);
-    FREE(result);
+    LYalloca_free(result);
 
     return return_value;		/* exactly the right length */
 }
 
+
 /*	Simplify a filename.				HTSimplify()
 **	--------------------
 **
@@ -550,7 +568,7 @@ PUBLIC void HTSimplify ARGS1(
 		    q = p;
 		    q1 = (p + 2);
 		    while (*q1 != '\0')
-		       *q++ = *q1++;
+			*q++ = *q1++;
 		    *q = '\0';		/* terminate */
 		    p--;
 		} else if (p[1] == '.' && p[2] == '?') {
@@ -560,7 +578,7 @@ PUBLIC void HTSimplify ARGS1(
 		    q = (p + 1);
 		    q1 = (p + 2);
 		    while (*q1 != '\0')
-		       *q++ = *q1++;
+			*q++ = *q1++;
 		    *q = '\0';		/* terminate */
 		    p--;
 		} else if (p[1] == '.' && p[2] == '\0') {
diff --git a/WWW/Library/Implementation/HTPlain.c b/WWW/Library/Implementation/HTPlain.c
index 1ef4ca57..74c50f48 100644
--- a/WWW/Library/Implementation/HTPlain.c
+++ b/WWW/Library/Implementation/HTPlain.c
@@ -30,9 +30,6 @@
 #include <LYCharSets.h>
 #include <LYLeaks.h>
 
-extern BOOL HTPassEightBitRaw;
-extern BOOL HTPassHighCtrlRaw;
-
 PUBLIC int HTPlain_lastraw = -1;
 PRIVATE int HTPlain_bs_pending = 0; /* 1:bs 2:underline 3:underline+bs - kw */
 
diff --git a/WWW/Library/Implementation/HTTCP.c b/WWW/Library/Implementation/HTTCP.c
index d753edc8..0863dacb 100644
--- a/WWW/Library/Implementation/HTTCP.c
+++ b/WWW/Library/Implementation/HTTCP.c
@@ -649,10 +649,6 @@ PUBLIC struct hostent * LYGetHostByName ARGS1(
     char *host = str;
 #endif
 
-#ifdef __DJGPP__
-    _resolve_hook = ResolveYield;
-#endif
-
 #ifdef NSL_FORK
     /* for transfer of result between from child to parent: */
     static AlignedHOSTENT aligned_full_rehostent;
@@ -686,6 +682,10 @@ PUBLIC struct hostent * LYGetHostByName ARGS1(
 
     struct hostent *result_phost = NULL;
 
+#ifdef __DJGPP__
+    _resolve_hook = ResolveYield;
+#endif
+
     if (!str) {
 	CTRACE((tfp, "LYGetHostByName: Can't parse `NULL'.\n"));
 	lynx_nsl_status = HT_INTERNAL;
@@ -1565,7 +1565,6 @@ PUBLIC int HTDoConnect ARGS4(
     _HTProgress (line);
 #ifdef INET6
     /* HTParseInet() is useless! */
-    _HTProgress(host);
     res0 = HTGetAddrInfo(host, default_port);
     if (res0 == NULL) {
 	HTSprintf0 (&line, gettext("Unable to locate remote host %s."), host);
@@ -1627,7 +1626,7 @@ PUBLIC int HTDoConnect ARGS4(
     }
 #endif /* INET6 */
 
-#ifndef DOSPATH
+#if !defined(DOSPATH) || defined(__DJGPP__)
 #if !defined(NO_IOCTL) || defined(USE_FCNTL)
     /*
     **	Make the socket non-blocking, so the connect can be canceled.
@@ -1645,7 +1644,7 @@ PUBLIC int HTDoConnect ARGS4(
 	    _HTProgress(gettext("Could not make connection non-blocking."));
     }
 #endif /* !NO_IOCTL || USE_FCNTL */
-#endif /* !DOSPATH */
+#endif /* !DOSPATH || __DJGPP__ */
 
     /*
     **	Issue the connect.  Since the server can't do an instantaneous
@@ -1671,7 +1670,7 @@ PUBLIC int HTDoConnect ARGS4(
 #else
     status = connect(*s, (struct sockaddr*)&soc_address, sizeof(soc_address));
 #endif /* INET6 */
-#ifndef __DJGPP__
+
     /*
     **	According to the Sun man page for connect:
     **	   EINPROGRESS	       The socket is non-blocking and the  con-
@@ -1878,7 +1877,7 @@ PUBLIC int HTDoConnect ARGS4(
 	break;
     }
 #endif /* INET6 */
-#endif /* !__DJGPP__ */
+
 #ifdef INET6
     if (*s < 0)
 #else
@@ -1891,7 +1890,7 @@ PUBLIC int HTDoConnect ARGS4(
 	*/
 	NETCLOSE(*s);
     }
-#ifndef DOSPATH
+#if !defined(DOSPATH) || defined(__DJGPP__)
 #if !defined(NO_IOCTL) || defined(USE_FCNTL)
     else {
 	/*
@@ -1907,7 +1906,7 @@ PUBLIC int HTDoConnect ARGS4(
 	    _HTProgress(gettext("Could not restore socket to blocking."));
     }
 #endif /* !NO_IOCTL || USE_FCNTL */
-#endif /* !DOSPATH */
+#endif /* !DOSPATH || __DJGPP__ */
 
 #ifdef INET6
     FREE(line);
diff --git a/WWW/Library/Implementation/HTTP.c b/WWW/Library/Implementation/HTTP.c
index 3dfad753..9270209d 100644
--- a/WWW/Library/Implementation/HTTP.c
+++ b/WWW/Library/Implementation/HTTP.c
@@ -33,6 +33,7 @@
 #include <HTML.h>
 #include <HTInit.h>
 #include <HTAABrow.h>
+#include <HTAccess.h>		/* Are we using an HTTP gateway? */
 
 #include <LYCookie.h>
 #include <LYGlobalDefs.h>
@@ -47,14 +48,7 @@ struct _HTStream
 
 extern char * HTAppName;	/* Application name: please supply */
 extern char * HTAppVersion;	/* Application version: please supply */
-extern char * personal_mail_address;	/* User's name/email address */
-extern char * LYUserAgent;	/* Lynx User-Agent string */
-extern BOOL LYNoRefererHeader;	/* Never send Referer header? */
-extern BOOL LYNoRefererForThis; /* No Referer header for this URL? */
-extern BOOL LYNoFromHeader;	/* Never send From header? */
-extern BOOL LYSetCookies;	/* Act on Set-Cookie headers? */
-
-extern BOOL using_proxy;	/* Are we using an HTTP gateway? */
+
 PUBLIC BOOL reloading = FALSE;	/* Reloading => send no-cache pragma to proxy */
 PUBLIC char * redirecting_url = NULL;	    /* Location: value. */
 PUBLIC BOOL permanent_redirection = FALSE;  /* Got 301 status? */
diff --git a/WWW/Library/Implementation/HTTP.h b/WWW/Library/Implementation/HTTP.h
index b8212a98..971305f9 100644
--- a/WWW/Library/Implementation/HTTP.h
+++ b/WWW/Library/Implementation/HTTP.h
@@ -19,6 +19,7 @@ GLOBALREF HTProtocol HTTPS;
 #define URL_POST_METHOD 2
 #define URL_MAIL_METHOD 3
 
+extern int ws_read_per_sec;
 extern BOOL reloading;
 extern char * redirecting_url;
 extern BOOL permanent_redirection;
@@ -29,9 +30,3 @@ extern SSL * SSL_handle;
 #endif
 
 #endif /* HTTP_H */
-
-/*
-
-   end of HTTP module definition
-
- */
diff --git a/WWW/Library/Implementation/HTTelnet.c b/WWW/Library/Implementation/HTTelnet.c
index e5182b90..5ff87b49 100644
--- a/WWW/Library/Implementation/HTTelnet.c
+++ b/WWW/Library/Implementation/HTTelnet.c
@@ -36,7 +36,7 @@
 
 PRIVATE void do_system ARGS1(char *, command)
 {
-    if (command != 0) {
+    if (!isEmpty(command)) {
 	CTRACE((tfp, "HTTelnet: Command is: %s\n\n", command));
 	LYSystem(command);
 	FREE(command);
@@ -48,6 +48,7 @@ PRIVATE void do_system ARGS1(char *, command)
 */
 PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 {
+    CONST char *program;
 	char * user = host;
 	char * password = NULL;
 	char * cp;
@@ -155,14 +156,14 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 #if	!defined(TELNET_DONE) && (defined(NeXT) && defined(NeXTSTEP) && NeXTSTEP<=20100)
 #define FMT_TELNET "%s%s%s %s %s"
 
-#ifdef TELNET_PATH
-	HTAddParam(&command, FMT_TELNET, 1, TELNET_PATH);
-	HTOptParam(&command, FMT_TELNET, 2, user ? " -l " : "");
-	HTAddParam(&command, FMT_TELNET, 3, user);
-	HTAddParam(&command, FMT_TELNET, 4, hostname);
-	HTAddParam(&command, FMT_TELNET, 5, port);
-	HTEndParam(&command, FMT_TELNET, 5);
-#endif
+	if ((program = HTGetProgramPath(ppTELNET)) != NULL) {
+	    HTAddParam(&command, FMT_TELNET, 1, program);
+	    HTOptParam(&command, FMT_TELNET, 2, user ? " -l " : "");
+	    HTAddParam(&command, FMT_TELNET, 3, user);
+	    HTAddParam(&command, FMT_TELNET, 4, hostname);
+	    HTAddParam(&command, FMT_TELNET, 5, port);
+	    HTEndParam(&command, FMT_TELNET, 5);
+	}
 	do_system(command);
 #define TELNET_DONE
 #endif
@@ -176,31 +177,31 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 
 	switch (login_protocol) {
 	case rlogin:
-#ifdef RLOGIN_PATH
-	    HTAddParam(&command, FMT_RLOGIN, 1, RLOGIN_PATH);
-	    HTAddParam(&command, FMT_RLOGIN, 2, hostname);
-	    HTOptParam(&command, FMT_RLOGIN, 3, user ? " -l " : "");
-	    HTAddParam(&command, FMT_RLOGIN, 4, user);
-	    HTEndParam(&command, FMT_RLOGIN, 4);
-#endif
+	    if ((program = HTGetProgramPath(ppRLOGIN)) != NULL) {
+		HTAddParam(&command, FMT_RLOGIN, 1, program);
+		HTAddParam(&command, FMT_RLOGIN, 2, hostname);
+		HTOptParam(&command, FMT_RLOGIN, 3, user ? " -l " : "");
+		HTAddParam(&command, FMT_RLOGIN, 4, user);
+		HTEndParam(&command, FMT_RLOGIN, 4);
+	    }
 	    break;
 
 	case tn3270:
-#ifdef TN3270_PATH
-	    HTAddParam(&command, FMT_TN3270, 1, TN3270_PATH);
-	    HTAddParam(&command, FMT_TN3270, 2, hostname);
-	    HTAddParam(&command, FMT_TN3270, 3, port);
-	    HTEndParam(&command, FMT_TN3270, 3);
-#endif
+	    if ((program = HTGetProgramPath(ppTN3270)) != NULL) {
+		HTAddParam(&command, FMT_TN3270, 1, program);
+		HTAddParam(&command, FMT_TN3270, 2, hostname);
+		HTAddParam(&command, FMT_TN3270, 3, port);
+		HTEndParam(&command, FMT_TN3270, 3);
+	    }
 	    break;
 
 	case telnet:
-#ifdef TELNET_PATH
-	    HTAddParam(&command, FMT_TELNET, 1, TELNET_PATH);
-	    HTAddParam(&command, FMT_TELNET, 2, hostname);
-	    HTAddParam(&command, FMT_TELNET, 3, port);
-	    HTEndParam(&command, FMT_TELNET, 3);
-#endif
+	    if ((program = HTGetProgramPath(ppTELNET)) != NULL) {
+		HTAddParam(&command, FMT_TELNET, 1, program);
+		HTAddParam(&command, FMT_TELNET, 2, hostname);
+		HTAddParam(&command, FMT_TELNET, 3, port);
+		HTEndParam(&command, FMT_TELNET, 3);
+	    }
 	    break;
 	}
 
diff --git a/WWW/Library/Implementation/HTUtils.h b/WWW/Library/Implementation/HTUtils.h
index 8b097216..a5038dc3 100644
--- a/WWW/Library/Implementation/HTUtils.h
+++ b/WWW/Library/Implementation/HTUtils.h
@@ -180,7 +180,7 @@ typedef unsigned short mode_t;
 #endif
 
 #if defined(UNIX)
-#  if (defined(__BEOS__) || defined(__CYGWIN__) || defined(__EMX__))
+#  if (defined(__BEOS__) || defined(__CYGWIN__) || defined(__DJGPP__) || defined(__EMX__))
 #    define SINGLE_USER_UNIX	/* well, at least they try */
 #  else
 #    define MULTI_USER_UNIX
@@ -323,6 +323,8 @@ Macros for declarations
 #define NULL ((void *)0)
 #endif
 
+#define isEmpty(s)   ((s) == 0 || *(s) == 0)
+
 #define NonNull(s) (((s) != 0) ? s : "")
 #define NONNULL(s) (((s) != 0) ? s : "(null)")
 
@@ -332,6 +334,9 @@ Macros for declarations
 #define	typecalloc(cast)		(cast *)calloc(1,sizeof(cast))
 #define	typecallocn(cast,ntypes)	(cast *)calloc(ntypes,sizeof(cast))
 
+#define typeMalloc(cast)                (cast *)malloc(sizeof(cast))
+#define typeMallocn(cast,ntypes)        (cast *)malloc(ntypes*sizeof(cast))
+
 /*
 
 OFTEN USED INTEGER MACROS
diff --git a/WWW/Library/Implementation/SGML.c b/WWW/Library/Implementation/SGML.c
index a11532c2..023aeb8d 100644
--- a/WWW/Library/Implementation/SGML.c
+++ b/WWW/Library/Implementation/SGML.c
@@ -29,6 +29,7 @@
 
 #include <LYCharSets.h>
 #include <LYCharVals.h>	 /* S/390 -- gil -- 0635 */
+#include <LYGlobalDefs.h>
 #include <LYStrings.h>
 #include <LYLeaks.h>
 
@@ -43,11 +44,6 @@
 
 #ifdef USE_PRETTYSRC
 
-#  define PSRC(x) if (psrc_view) { x };
-#  define NPSRC(x) if (!psrc_view) { x };
-#  define IFDEFPSRC(x) x
-#  define IFNDEFPSRC(x)
-
 char* entity_string; /* this is used for printing entity name.
     Unconditionally added since redundant assigments don't hurt much*/
 
@@ -62,11 +58,6 @@ PRIVATE void fake_put_character ARGS2(
 
 #define PUTS_TR(x) psrc_convert_string = TRUE; PUTS(x)
 
-#else
-#  define PSRC(x)
-#  define NPSRC(x)
-#  define IFDEFPSRC(x)
-#  define IFNDEFPSRC(x) x
 #endif
 
  /* will use an inlined version */
@@ -77,14 +68,16 @@ PRIVATE void fake_put_character ARGS2(
 	ch->allocated = ch->allocated + ch->growby;\
 	ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated)\
 			    : typecallocn(char, ch->allocated);\
-      if (!ch->data)\
-	  outofmem(__FILE__, "HTChunkPutc");\
+	if (!ch->data)\
+	    outofmem(__FILE__, "HTChunkPutc");\
     }\
     ch->data[ch->size++] = c;
 #endif
 
 #define PUTS(str) ((*context->actions->put_string)(context->target, str))
-
+#define PUTC(ch)  ((*context->actions->put_character)(context->target, ch))
+#define PUTUTF8(code) (UCPutUtf8_charstring((HTStream *)context->target, \
+		      (putc_func_t*)(context->actions->put_character), code))
 
 #define OPT 1
 
@@ -98,8 +91,6 @@ PUBLIC BOOL HTPassEightBitNum = FALSE;	/* Pass ^ numeric entities raw. */
 PUBLIC BOOL HTPassHighCtrlRaw = FALSE;	/* Pass 127-160,173,&#127; raw. */
 PUBLIC BOOL HTPassHighCtrlNum = FALSE;	/* Pass &#128;-&#159; raw.	*/
 
-/*  extern int LYlowest_eightbit[];  for completeness here  */
-
 /*	The State (context) of the parser
 **
 **	This is passed with each call to make the parser reentrant
@@ -281,6 +272,27 @@ PRIVATE char *state_name ARGS1(sgml_state, n)
 }
 #endif
 
+/* storage for Element Stack */
+#define DEPTH 10
+static HTElement pool[DEPTH];
+static int depth = 0;
+
+PRIVATE HTElement* pool_get NOARGS
+{
+    depth++;
+    if (depth > DEPTH)
+	return (HTElement*) malloc(sizeof(HTElement));
+    return (pool + depth - 1);
+}
+
+PRIVATE void pool_free ARGS1(HTElement*, e)
+{
+    if (depth > DEPTH)
+	FREE(e);
+    depth--;
+    return;
+}
+
 #ifdef USE_PRETTYSRC
 
 PRIVATE void HTMLSRC_apply_markup ARGS3(
@@ -319,10 +331,10 @@ PRIVATE void HTMLSRC_apply_markup ARGS3(
 
 #if ANSI_PREPRO
 #  define PSRCSTART(x)	HTMLSRC_apply_markup(context,HTL_##x,START)
-#  define PSRCSTOP(x)  HTMLSRC_apply_markup(context,HTL_##x,STOP)
+#  define PSRCSTOP(x)   HTMLSRC_apply_markup(context,HTL_##x,STOP)
 #else
 #  define PSRCSTART(x)	HTMLSRC_apply_markup(context,HTL_/**/x,START)
-#  define PSRCSTOP(x)  HTMLSRC_apply_markup(context,HTL_/**/x,STOP)
+#  define PSRCSTOP(x)   HTMLSRC_apply_markup(context,HTL_/**/x,STOP)
 #endif
 
 #define attr_is_href context->cur_attr_is_href
@@ -431,17 +443,9 @@ PRIVATE void change_chartrans_handling ARGS1(
     }
 }
 
-#define PUTC(ch) ((*context->actions->put_character)(context->target, ch))
-#define PUTUTF8(code) (UCPutUtf8_charstring((HTStream *)context->target, \
-		      (putc_func_t*)(context->actions->put_character), code))
-
-extern BOOL historical_comments;
-extern BOOL minimal_comments;
-extern BOOL soft_dquotes;
-
 #ifdef USE_COLOR_STYLE
 #include <AttrList.h>
-static int current_is_class=0;
+static int current_is_class = 0;
 #endif
 
 /*	Handle Attribute
@@ -453,7 +457,6 @@ PRIVATE void handle_attribute_name ARGS2(
 	HTStream *,	context,
 	CONST char *,	s)
 {
-
     HTTag * tag = context->current_tag;
     attr * attributes = tag->attributes;
     int high, low, i, diff;
@@ -486,25 +489,23 @@ PRIVATE void handle_attribute_name ARGS2(
 	if (diff == 0) {		/* success: found it */
 	    context->current_attribute_number = i;
 #ifdef USE_PRETTYSRC
-	    if (!psrc_view) {
+	    if (psrc_view) {
+		attr_is_name = (BOOL) (attributes[i].type == HTMLA_ANAME);
+		attr_is_href = (BOOL) (attributes[i].type == HTMLA_HREF);
+	    } else
 #endif
+	    {
 	    context->present[i] = YES;
 	    FREE(context->value[i]);
 #ifdef USE_COLOR_STYLE
-#  ifdef USE_PRETTYSRC
+#   ifdef USE_PRETTYSRC
 	    current_is_class = IS_C(attributes[i]);
 #   else
 	    current_is_class = (!strcasecomp("class", s));
 #   endif
 	    CTRACE((tfp, "SGML: found attribute %s, %d\n", s, current_is_class));
 #endif
-
-#ifdef USE_PRETTYSRC
-	    } else {
-		 attr_is_name = (BOOL) (attributes[i].type == HTMLA_ANAME);
-		 attr_is_href = (BOOL) (attributes[i].type == HTMLA_HREF);
 	    }
-#endif
 	    return;
 	} /* if */
 
@@ -623,6 +624,27 @@ PRIVATE BOOL put_special_unicodes ARGS2(
     return YES;
 }
 
+#ifdef USE_PRETTYSRC
+PRIVATE void put_pretty_entity ARGS2(HTStream *, context, int, term)
+{
+    PSRCSTART(entity);
+    PUTC('&');
+    PUTS(entity_string);
+    if (term)
+	PUTC(term);
+    PSRCSTOP(entity);
+}
+
+PRIVATE void put_pretty_number ARGS1(HTStream *, context)
+{
+    PSRCSTART(entity);
+    PUTS( (context->isHex ? "&#x" : "&#") );
+    PUTS(entity_string);
+    PUTC(';');
+    PSRCSTOP(entity);
+}
+#endif /* USE_PRETTYSRC */
+
 /*	Handle entity
 **	-------------
 **
@@ -646,10 +668,8 @@ PRIVATE void handle_entity ARGS2(
 {
     UCode_t code;
     long uck = -1;
-    CONST char *p;
     CONST char *s = context->string->data;
 
-
     /*
     **	Handle all entities normally. - FM
     */
@@ -662,12 +682,7 @@ PRIVATE void handle_entity ARGS2(
 	if (put_special_unicodes(context, code)) {
 #ifdef USE_PRETTYSRC
 	    if (psrc_view) {
-		HTMLSRC_apply_markup(context,HTL_entity,START);
-		PUTC('&');
-		PUTS(entity_string);
-		if (term)
-		    PUTC(term);
-		HTMLSRC_apply_markup(context,HTL_entity,STOP);
+		put_pretty_entity(context, term);
 	    }
 #endif
 	    FoundEntity = TRUE;
@@ -683,9 +698,7 @@ PRIVATE void handle_entity ARGS2(
 	     uck >= LYlowest_eightbit[context->outUCLYhndl])) {
 #ifdef USE_PRETTYSRC
 	    if (psrc_view) {
-		HTMLSRC_apply_markup(context,HTL_entity,START);
-		PUTC('&'); PUTS(entity_string); if (term) PUTC(term);
-		HTMLSRC_apply_markup(context,HTL_entity,STOP);
+		put_pretty_entity(context, term);
 	    } else
 #endif
 	    PUTC(FROMASCII((char)uck));
@@ -701,16 +714,10 @@ PRIVATE void handle_entity ARGS2(
 					    context->outUCLYhndl, 0) >= 0)) {
 #ifdef USE_PRETTYSRC
 	    if (psrc_view) {
-		HTMLSRC_apply_markup(context,HTL_entity,START);
-		PUTC('&');
-		PUTS(entity_string);
-		if (term)
-		    PUTC(term);
-		HTMLSRC_apply_markup(context,HTL_entity,STOP);
+		put_pretty_entity(context, term);
 	    } else
 #endif
-	    for (p = replace_buf; *p; p++)
-		PUTC(*p);
+	    PUTS(replace_buf);
 	    FoundEntity = TRUE;
 	    return;
 	}
@@ -728,9 +735,7 @@ PRIVATE void handle_entity ARGS2(
 	      (putc_func_t*)(fake_put_character), code)): PUTUTF8(code) ) ) {
 
 	    if (psrc_view) {
-		HTMLSRC_apply_markup(context,HTL_entity,START);
-		PUTC('&'); PUTS(entity_string); if (term) PUTC(term);
-		HTMLSRC_apply_markup(context,HTL_entity,STOP);
+		put_pretty_entity(context, term);
 	    }
 
 	    FoundEntity = TRUE;
@@ -743,12 +748,7 @@ PRIVATE void handle_entity ARGS2(
 	if (code >= 32 && code < 127) {
 #ifdef USE_PRETTYSRC
 	    if (psrc_view) {
-		HTMLSRC_apply_markup(context,HTL_entity,START);
-		PUTC('&');
-		PUTS(entity_string);
-		if (term)
-		    PUTC(term);
-		HTMLSRC_apply_markup(context,HTL_entity,STOP);
+		put_pretty_entity(context, term);
 	    } else
 #endif
 
@@ -767,12 +767,7 @@ PRIVATE void handle_entity ARGS2(
 	    CTRACE((tfp, "handle_entity: Ignoring '%s'.\n", s));
 #ifdef USE_PRETTYSRC
 	    if (psrc_view) {
-		HTMLSRC_apply_markup(context,HTL_entity,START);
-		PUTC('&');
-		PUTS(entity_string);
-		if (term)
-		    PUTC(term);
-		HTMLSRC_apply_markup(context,HTL_entity,STOP);
+		put_pretty_entity(context, term);
 	    }
 #endif
 	    FoundEntity = TRUE;
@@ -786,12 +781,7 @@ PRIVATE void handle_entity ARGS2(
 	    CTRACE((tfp, "handle_entity: Ignoring '%s'.\n", s));
 #ifdef USE_PRETTYSRC
 	    if (psrc_view) {
-		HTMLSRC_apply_markup(context,HTL_entity,START);
-		PUTC('&');
-		PUTS(entity_string);
-		if (term)
-		    PUTC(term);
-		HTMLSRC_apply_markup(context,HTL_entity,STOP);
+		put_pretty_entity(context, term);
 	    }
 #endif
 	    FoundEntity = TRUE;
@@ -808,9 +798,7 @@ PRIVATE void handle_entity ARGS2(
 #endif
     CTRACE((tfp, "SGML: Unknown entity '%s' %ld %ld\n", s, (long)code, uck)); /* S/390 -- gil -- 0695 */
     PUTC('&');
-    for (p = s; *p; p++) {
-	PUTC(*p);
-    }
+    PUTS(s);
     if (term != '\0')
 	PUTC(term);
 #ifdef USE_PRETTYSRC
@@ -992,8 +980,6 @@ PRIVATE BOOL element_valid_within ARGS3(
 		(stacked_tag->tagclass & usecontained));
 }
 
-extern BOOL Old_DTD;
-
 typedef enum {
     close_NO	= 0,
     close_error = 1,
@@ -1034,7 +1020,7 @@ PRIVATE void do_close_stacked ARGS1(
 	e,
 	(char **)&context->include);
     context->element_stack = stacked->next;
-    FREE(stacked);
+    pool_free(stacked);
     context->no_lynx_specialcodes = context->element_stack ?
 	(context->element_stack->tag->flags & Tgf_nolyspcl) : NO;
 }
@@ -1179,7 +1165,7 @@ PRIVATE void end_element ARGS2(
 	    context->element_stack->tag = ALT_TAGP_OF_TAGNUM(e);
 	} else {
 	    context->element_stack = N->next;		/* Remove from stack */
-	    FREE(N);
+	    pool_free(N);
 	}
 	context->no_lynx_specialcodes = context->element_stack ?
 	    (context->element_stack->tag->flags & Tgf_nolyspcl) : NO;
@@ -1321,7 +1307,7 @@ PRIVATE void start_element ARGS1(
 		*/
 		CTRACE((tfp, "SGML: ***Faking SELECT end tag before <%s> start tag.\n",
 			    new_tag->name));
-		end_element(context, SGMLFindTag(context->dtd, "SELECT"));
+		end_element(context, SGMLFindUprTag(context->dtd, "SELECT"));
 	    } else {
 		/*
 		**  Ignore the start tag. - FM
@@ -1346,7 +1332,7 @@ PRIVATE void start_element ARGS1(
     if (status == HT_PARSER_OTHER_CONTENT)
 	new_tag = ALT_TAGP(new_tag);	/* this is only returned for OBJECT */
     if (new_tag->contents != SGML_EMPTY) {		/* i.e., tag not empty */
-	HTElement * N = (HTElement *)malloc(sizeof(HTElement));
+	HTElement * N = pool_get();
 	if (N == NULL)
 	    outofmem(__FILE__, "start_element");
 	N->next = context->element_stack;
@@ -1368,14 +1354,14 @@ PRIVATE void start_element ARGS1(
 **
 ** On entry,
 **	dtd	points to dtd structure including valid tag list
-**	string	points to name of tag in question
+**	string	points to name of uppercased tag in question
 **
 ** On exit,
 **	returns:
 **		NULL		tag not found
 **		else		address of tag structure in dtd
 */
-PUBLIC HTTag * SGMLFindTag ARGS2(
+PUBLIC HTTag * SGMLFindUprTag ARGS2(
 	CONST SGML_dtd*,	dtd,
 	CONST char *,		string)
 {
@@ -1385,7 +1371,7 @@ PUBLIC HTTag * SGMLFindTag ARGS2(
 	 high > low;
 	 diff < 0 ? (low = i+1) : (high = i)) {	 /* Binary search */
 	i = (low + (high-low)/2);
-	diff = AS_casecomp(dtd->tags[i].name, string);	/* Case insensitive */
+	diff = AS_cmp(dtd->tags[i].name, string);	/* Case sensitive */
 	if (diff == 0) {		/* success: found it */
 	    return &dtd->tags[i];
 	}
@@ -1399,6 +1385,28 @@ PUBLIC HTTag * SGMLFindTag ARGS2(
     return NULL;
 }
 
+/*		Find Tag in DTD tag list
+**		------------------------
+**
+** On entry,
+**	dtd	points to dtd structure including valid tag list
+**	string	points to name of tag in question
+**
+** On exit,
+**	returns:
+**		NULL		tag not found
+**		else		address of tag structure in dtd
+*/
+PUBLIC HTTag * SGMLFindTag ARGS2(
+	CONST SGML_dtd*,	dtd,
+	char *,			string)
+{
+    char * p = string;
+    for ( ; *p; p++)
+	*p = TOUPPER(*p);
+    return SGMLFindUprTag(dtd, string);
+}
+
 /*________________________________________________________________________
 **			Public Methods
 */
@@ -1430,7 +1438,7 @@ PRIVATE void SGML_free ARGS1(
 	cur = context->element_stack;
 	t = cur->tag;
 	context->element_stack = cur->next;	/* Remove from stack */
-	FREE(cur);
+	pool_free(cur);
 #ifdef USE_PRETTYSRC
 	if (!psrc_view) /* Don't actually call on target if viewing psrc - kw */
 #endif
@@ -1454,7 +1462,7 @@ PRIVATE void SGML_free ARGS1(
     FREE(context);
 
 #ifdef USE_PRETTYSRC
-    sgml_in_psrc_was_initialized =FALSE;
+    sgml_in_psrc_was_initialized = FALSE;
 #endif
 }
 
@@ -1485,7 +1493,7 @@ PRIVATE void SGML_abort ARGS2(
     while (context->element_stack) {
 	cur = context->element_stack;
 	context->element_stack = cur->next;	/* Remove from stack */
-	FREE(cur);
+	pool_free(cur);
     }
 
     /*
@@ -1497,9 +1505,8 @@ PRIVATE void SGML_abort ARGS2(
     FREE(context);
 
 #ifdef USE_PRETTYSRC
-    sgml_in_psrc_was_initialized =FALSE;
+    sgml_in_psrc_was_initialized = FALSE;
 #endif
-
 }
 
 
@@ -1533,7 +1540,6 @@ PRIVATE void SGML_character ARGS2(
     CONST SGML_dtd *dtd =	context->dtd;
     HTChunk	*string =	context->string;
     CONST char * EntityName;
-    char * p;
     HTTag * testtag = NULL;
     BOOLEAN chk;	/* Helps (?) walk through all the else ifs... */
     UCode_t clong, uck = 0; /* Enough bits for UCS4 ... */
@@ -1697,8 +1703,7 @@ PRIVATE void SGML_character ARGS2(
 	    c = replace_buf[0];
 	    if (c && replace_buf[1]) {
 		if (context->state == S_text) {
-		    for (p = replace_buf; *p; p++)
-			PUTC(*p);
+		    PUTS(replace_buf);
 		    return;
 		}
 		StrAllocCat(context->recover, replace_buf + 1);
@@ -1803,7 +1808,7 @@ top1:
     /*
     **	Handle character based on context->state.
     */
-    CTRACE2(TRACE_SGML, (tfp, "SGML before %s|%.*s|%c\n",
+    CTRACE2(TRACE_SGML, (tfp, "SGML before %s|%.*s|%c|\n",
 	    state_name(context->state),
 	    string->size,
 	    NonNull(string->data),
@@ -1897,7 +1902,7 @@ top1:
 	    if (testtag && testtag->contents == SGML_PCDATA) {
 		context->state = S_pcdata;
 	    } else if (testtag && (testtag->contents == SGML_LITTERAL
-	    			|| testtag->contents == SGML_CDATA)) {
+				|| testtag->contents == SGML_CDATA)) {
 		context->state = S_litteral;
 	    } else if (testtag && (testtag->contents == SGML_SCRIPT)) {
 		context->state = S_script;
@@ -2026,8 +2031,7 @@ top1:
 	    **	No further tests for validity - assume that whoever
 	    **	defined replacement strings knew what she was doing. - KW
 	    */
-	    for (p = replace_buf; *p; p++)
-		PUTC(*p);
+	    PUTS(replace_buf);
 	/*
 	**  If we're displaying UTF-8, try that now. - FM
 	*/
@@ -2050,15 +2054,13 @@ top1:
 	} else if (unsign_c > 160 && unsign_c < 256 &&
 		   !(PASSHI8BIT || HTCJK != NOCJK) &&
 		   !IncludesLatin1Enc) {
-	    int i;
 #ifdef USE_PRETTYSRC
 	    int psrc_view_backup = 0;
 #endif
 
 	    string->size = 0;
 	    EntityName = HTMLGetEntityName((int)(unsign_c - 160));
-	    for (i = 0; EntityName[i]; i++)
-		HTChunkPutc(string, EntityName[i]);
+	    HTChunkPuts(string, EntityName);
 	    HTChunkTerminate(string);
 #ifdef USE_PRETTYSRC
 	    /* we need to disable it temporary*/
@@ -2090,8 +2092,7 @@ top1:
 	**  already, but what the heck, try again. - FM
 	*/
 	} else if (context->T.output_utf8 && *context->utf_buf) {
-	    for (p = context->utf_buf; *p; p++)
-		PUTC(*p);
+	    PUTS(context->utf_buf);
 	    context->utf_buf_p = context->utf_buf;
 	    *(context->utf_buf_p) = '\0';
 #ifdef NOTDEFINED
@@ -2115,47 +2116,6 @@ top1:
 	} else if (TOASCII(UCH(c)) <	 /* S/390 -- gil -- 0997 */
 			LYlowest_eightbit[context->outUCLYhndl] ||
 		   (context->T.trans_from_uni && !HTPassEightBitRaw)) {
-#ifdef NOTUSED_FOTEMODS
-	    /*
-	    **	If we do not have the "7-bit approximations" as our
-	    **	output character set (in which case we did it already)
-	    **	seek a translation for that.  Otherwise, or if the
-	    **	translation fails, use UHHH notation. - FM
-	    */
-	    if ((chk = (context->outUCLYhndl !=
-			UCGetLYhndl_byMIME("us-ascii"))) &&
-		(uck = UCTransUniChar(unsign_c,
-				      UCGetLYhndl_byMIME("us-ascii")))
-				      >= ' ' && TOASCII(uck) < 127) {  /* S/390 -- gil -- 1008 */
-		/*
-		**  Got an ASCII character (yippey). - FM
-		*/
-		PUTC(((char)FROMASCII(TOASCII(uck) & 0xff)));
-	    } else if ((chk && uck == -4) &&
-		       (uck = UCTransUniCharStr(replace_buf,
-						60, clong,
-						UCGetLYhndl_byMIME("us-ascii"),
-						0) >= 0)) {
-		/*
-		**  Got a replacement string (yippey). - FM
-		*/
-		for (p = replace_buf; *p; p++)
-		    PUTC(*p);
-	    } else {
-#endif /* NOTUSED_FOTEMODS */
-		/*
-		**  Out of luck, so use the UHHH notation (ugh). - FM
-		*/
-			/* S/390 -- gil -- 1018 */
-			/* do not print UHHH for now
-		sprintf(replace_buf, "U%.2lX", TOASCII(unsign_c));
-		for (p = replace_buf; *p; p++) {
-		    PUTC(*p);
-		}
-			 */
-#ifdef NOTUSED_FOTEMODS
-	    }
-#endif /* NOTUSED_FOTEMODS */
 	/*
 	**  If we get to here, pass the character. - FM
 	*/
@@ -2188,7 +2148,9 @@ top1:
 			"SGML: Found PI in PCDATA, junking it until '>'\n"));
 #ifdef USE_PRETTYSRC
 		if (psrc_view) {
-		    PSRCSTART(abracket);PUTS("<?");PSRCSTOP(abracket);
+		    PSRCSTART(abracket);
+		    PUTS("<?");
+		    PSRCSTOP(abracket);
 		    context->seen_nonwhite_in_junk_tag = TRUE; /* show all */
 		}
 #endif
@@ -2248,7 +2210,9 @@ top1:
 		string->size > 1 && !testtag->name[string->size-2]) {
 #ifdef USE_PRETTYSRC
 		if (psrc_view) {
-		    PSRCSTART(abracket);PUTC('<');PUTC('/');PSRCSTOP(abracket);
+		    PSRCSTART(abracket);
+		    PUTS("</");
+		    PSRCSTOP(abracket);
 		    PSRCSTART(tag);
 		    strcpy(string->data,context->current_tag->name);
 		    if (tagname_transform != 1) {
@@ -2259,7 +2223,9 @@ top1:
 		    }
 		    PUTS(string->data);
 		    PSRCSTOP(tag);
-		    PSRCSTART(abracket);PUTC('>');PSRCSTOP(abracket);
+		    PSRCSTART(abracket);
+		    PUTC('>');
+		    PSRCSTOP(abracket);
 
 		    context->current_tag = NULL;
 		    string->size = 0;
@@ -2398,9 +2364,9 @@ top1:
 	    */
 #ifdef USE_PRETTYSRC
 	    if (psrc_view && FoundEntity && c == ';') {
-		HTMLSRC_apply_markup(context,HTL_entity, START);
+		PSRCSTART(entity);
 		PUTC(c);
-		HTMLSRC_apply_markup(context,HTL_entity, STOP);
+		PSRCSTOP(entity);
 	    }
 #endif
 	    if (!FoundEntity || c != ';')
@@ -2464,9 +2430,7 @@ top1:
 	    if (psrc_view)
 		PSRCSTART(badseq);
 #endif
-	    PUTC('&');
-	    PUTC('#');
-	    PUTC('x');
+	    PUTS("&#x");
 #ifdef USE_PRETTYSRC
 	    if (psrc_view)
 		PSRCSTOP(badseq);
@@ -2695,11 +2659,7 @@ top1:
 		    PUTC(FROMASCII((char)uck));
 #ifdef USE_PRETTYSRC
 		    } else {
-			PSRCSTART(entity);
-			PUTS( (context->isHex ? "&#x" : "&#") );
-			PUTS(entity_string);
-			PUTC(';');
-			PSRCSTOP(entity);
+			put_pretty_number(context);
 		    }
 #endif
 		} else if ((uck == -4 ||
@@ -2713,68 +2673,15 @@ top1:
 						    0) >= 0)) {
 #ifdef USE_PRETTYSRC
 		    if (psrc_view) {
-			PSRCSTART(entity);
-			PUTS( (context->isHex ? "&#x" : "&#") );
-			PUTS(entity_string);
-			PUTC(';');
-			PSRCSTOP(entity);
+			put_pretty_number(context);
 		    } else
 #endif
-		    for (p = replace_buf; *p; p++) {
-			PUTC(*p);
-		    }
+		    PUTS(replace_buf);
 		/*
 		**  If we're displaying UTF-8, try that now. - FM
 		*/
 		} else if (context->T.output_utf8 && PUTUTF8(code)) {
 		    ;  /* do nothing more */
-#ifdef NOTUSED_FOTEMODS
-		/*
-		**  If the value is greater than 255 and we do not
-		**  have the "7-bit approximations" as our output
-		**  character set (in which case we did it already)
-		**  seek a translation for that. - FM
-		*/
-		} else if ((chk = ((code > 255) &&
-				   context->outUCLYhndl !=
-				   UCGetLYhndl_byMIME("us-ascii"))) &&
-			   (uck = UCTransUniChar(code,
-				   UCGetLYhndl_byMIME("us-ascii")))
-				  >= ' ' && uck < 127) {
-		    /*
-		    **	Got an ASCII character (yippey). - FM
-		    */
-#ifdef USE_PRETTYSRC
-		    if (psrc_view) {
-			PSRCSTART(entity);
-			PUTS( (context->isHex ? "&#x" : "&#") );
-			PUTS(entity_string);
-			PUTC(';');
-			PSRCSTOP(entity);
-		    } else
-#endif
-		    PUTC(((char)FROMASCII(uck & 0xff)));
-/* =============== work in ASCII above here ===============  S/390 -- gil -- 1118 */
-		} else if ((chk && uck == -4) &&
-			   (uck = UCTransUniCharStr(replace_buf,
-						    60, code,
-						UCGetLYhndl_byMIME("us-ascii"),
-						    0) >= 0)) {
-		    /*
-		    **	Got a replacement string (yippey). - FM
-		    */
-#ifdef USE_PRETTYSRC
-		    if (psrc_view) {
-			PSRCSTART(entity);
-			PUTS( (context->isHex ? "&#x" : "&#") );
-			PUTS(entity_string);
-			PUTC(';');
-			PSRCSTOP(entity);
-		    } else
-#endif
-		    for (p = replace_buf; *p; p++)
-			PUTC(*p);
-#endif /* NOTUSED_FOTEMODS */
 		/*
 		**  Ignore 8205 (zwj),
 		**  8206 (lrm), and 8207 (rln), if we get to here. - FM
@@ -2839,11 +2746,11 @@ top1:
 			    PSRCSTART(badseq);
 			}
 #endif
-			PUTC('&');
-			PUTC('#');
 			if (context->isHex) {
-			    PUTC('x');
+			    PUTS("&#x");
 			    context->isHex = FALSE;
+			} else {
+			    PUTS("&#");
 			}
 			string->size--;
 			for (i = 0; i < string->size; i++)	/* recover */
@@ -2865,11 +2772,7 @@ top1:
 		    */
 #ifdef USE_PRETTYSRC
 		    if (psrc_view) {
-			PSRCSTART(entity);
-			PUTS( (context->isHex ? "&#x" : "&#") );
-			PUTS(entity_string);
-			PUTC(';');
-			PSRCSTOP(entity);
+			put_pretty_number(context);
 		    } else
 #endif
 		    PUTC(FROMASCII((char)code));
@@ -2881,8 +2784,7 @@ top1:
 		    EntityName = HTMLGetEntityName(code);
 		    if (EntityName && EntityName[0] != '\0') {
 			string->size = 0;
-			for (i = 0; EntityName[i]; i++)
-			    HTChunkPutc(string, EntityName[i]);
+			HTChunkPuts(string, EntityName);
 			HTChunkTerminate(string);
 			handle_entity(context, '\0');
 			/*
@@ -2901,11 +2803,11 @@ top1:
 			if (psrc_view)
 			    PSRCSTART(badseq);
 #endif
-			PUTC('&');
-			PUTC('#');
 			if (context->isHex) {
-			    PUTC('x');
+			    PUTS("&#x");
 			    context->isHex = FALSE;
+			} else {
+			    PUTS("&#");
 			}
 			string->size--;
 			for (i = 0; i < string->size; i++)	/* recover */
@@ -2947,16 +2849,16 @@ top1:
 		if (psrc_view)
 		    PSRCSTART(badseq);
 #endif
-		PUTC('&');
-		PUTC('#');
+		if (context->isHex) {
+		    PUTS("&#x");
+		    context->isHex = FALSE;
+		} else {
+		    PUTS("&#");
+		}
 #ifdef USE_PRETTYSRC
 		if (psrc_view)
 		    PSRCSTOP(badseq);
 #endif
-		if (context->isHex) {
-		    PUTC('x');
-		    context->isHex = FALSE;
-		}
 		if (context->recover == NULL) {
 		    StrAllocCopy(context->recover, string->data);
 		    context->recover_index = 0;
@@ -3068,7 +2970,9 @@ top1:
 		    CTRACE((tfp, "SGML: Found PI, junking it until '>'\n"));
 #ifdef USE_PRETTYSRC
 		    if (psrc_view) {
-			PSRCSTART(abracket);PUTS("<?");PSRCSTOP(abracket);
+			PSRCSTART(abracket);
+			PUTS("<?");
+			PSRCSTOP(abracket);
 			context->seen_nonwhite_in_junk_tag = TRUE; /*show all*/
 		    }
 #endif
@@ -3080,7 +2984,9 @@ top1:
 
 #ifdef USE_PRETTYSRC
 		if (psrc_view) {
-		    PSRCSTART(abracket);PUTC('<');PSRCSTOP(abracket);
+		    PSRCSTART(abracket);
+		    PUTC('<');
+		    PSRCSTOP(abracket);
 		    PSRCSTART(badtag);
 		    if (tagname_transform != 1) {
 			if (tagname_transform == 0)
@@ -3091,7 +2997,9 @@ top1:
 		    PUTS(string->data);
 		    if (c == '>' ) {
 			PSRCSTOP(badtag);
-			PSRCSTART(abracket);PUTC('>');PSRCSTOP(abracket);
+			PSRCSTART(abracket);
+			PUTC('>');
+			PSRCSTOP(abracket);
 		    } else {
 			PUTC(c);
 		    }
@@ -3112,7 +3020,9 @@ top1:
 
 #ifdef USE_PRETTYSRC
 	    if (psrc_view) {
-		PSRCSTART(abracket);PUTC('<');PSRCSTOP(abracket);
+		PSRCSTART(abracket);
+		PUTC('<');
+		PSRCSTOP(abracket);
 		if (t != context->unknown_tag)
 		    PSRCSTART(tag);
 		else
@@ -3591,10 +3501,12 @@ top1:
 		}
 		PUTS(string->data);
 		if (c == '=' ) PUTC('=');
-		if (context->current_attribute_number == INVALID)
-		    PSRCSTOP(badattr);
-		else
-		    PSRCSTOP(attrib);
+		if (c == '=' || c == '>') {
+		    if (context->current_attribute_number == INVALID)
+			PSRCSTOP(badattr);
+		    else
+			PSRCSTOP(attrib);
+		}
 		if (c == '>') {
 		    PSRCSTART(abracket);
 		    PUTC('>');
@@ -3778,7 +3690,7 @@ top1:
 	    if (psrc_view) {
 		/*PSRCSTART(attrval);*/
 		if (attr_is_name) {
-		    HTStartAnchor(context->target,string->data,NULL);
+		    HTStartAnchor(context->target,string->data, NULL);
 		    (*context->actions->end_element)(
 			context->target,
 			HTML_A,
@@ -3842,7 +3754,7 @@ top1:
 	    if (psrc_view) {
 		/*PSRCSTART(attrval);*/
 		if (attr_is_name) {
-		    HTStartAnchor(context->target,string->data,NULL);
+		    HTStartAnchor(context->target,string->data, NULL);
 		    (*context->actions->end_element)(
 			context->target,
 			HTML_A,
@@ -3922,8 +3834,7 @@ top1:
 #ifdef USE_PRETTYSRC
 		if (psrc_view) {
 		    PSRCSTART(abracket);
-		    PUTC('<');
-		    PUTC('/');
+		    PUTS("</");
 		    PSRCSTOP(abracket);
 		    PSRCSTART(badtag);
 		    if (tagname_transform != 1) {
@@ -3937,7 +3848,9 @@ top1:
 			PUTC(c);
 		    } else {
 			PSRCSTOP(badtag);
-			PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket);
+			PSRCSTART(abracket);
+			PUTC('>');
+			PSRCSTOP(abracket);
 		    }
 		    psrc_tagname_processed=TRUE;
 		}
@@ -4062,7 +3975,7 @@ top1:
 			    CTRACE((tfp, "SGML: ***Faking SELECT end tag before </%s> end tag.\n",
 					string->data));
 			    end_element(context,
-					SGMLFindTag(context->dtd, "SELECT"));
+					SGMLFindUprTag(context->dtd, "SELECT"));
 			    CTRACE((tfp, "SGML: End </%s>\n", string->data));
 
 #ifdef USE_PRETTYSRC
@@ -4121,8 +4034,7 @@ top1:
 #ifdef USE_PRETTYSRC
 	    if (psrc_view && !psrc_tagname_processed) {
 		PSRCSTART(abracket);
-		PUTC('<');
-		PUTC('/');
+		PUTS("</");
 		PSRCSTOP(abracket);
 		PSRCSTART(tag);
 		if (tagname_transform != 1) {
@@ -4131,7 +4043,8 @@ top1:
 		    else
 			LYUpperCase(string->data);
 		}
-		PUTS(string->data); PSRCSTOP(tag);
+		PUTS(string->data);
+		PSRCSTOP(tag);
 		if ( c != '>' ) {
 		    PSRCSTART(badtag);
 		    PUTC(c);
@@ -4331,7 +4244,7 @@ top1:
 #endif
 
     } /* switch on context->state */
-    CTRACE2(TRACE_SGML, (tfp, "SGML after  %s|%.*s|%c\n",
+    CTRACE2(TRACE_SGML, (tfp, "SGML after  %s|%.*s|%c|\n",
 	    state_name(context->state),
 	    string->size,
 	    NonNull(string->data),
diff --git a/WWW/Library/Implementation/SGML.h b/WWW/Library/Implementation/SGML.h
index 315b5ee1..9e84cf9f 100644
--- a/WWW/Library/Implementation/SGML.h
+++ b/WWW/Library/Implementation/SGML.h
@@ -250,13 +250,25 @@ Find a Tag by Name
    Returns a pointer to the tag within the DTD.
 
  */
-extern HTTag * SGMLFindTag PARAMS((
+extern HTTag * SGMLFindUprTag PARAMS((
 	CONST SGML_dtd *	dtd,
 	CONST char *		string));
 
 
 /*
 
+Find a Tag by Name
+
+   Returns a pointer to the tag within the DTD.
+
+ */
+extern HTTag * SGMLFindTag PARAMS((
+	CONST SGML_dtd *	dtd,
+	char *			string));
+
+
+/*
+
 Create an SGML parser
 
  */
@@ -276,7 +288,3 @@ extern HTStream * SGML_new PARAMS((
 extern CONST HTStreamClass SGMLParser;
 
 #endif	/* SGML_H */
-
-/*
-
-    */
diff --git a/WWW/Library/Implementation/www_tcp.h b/WWW/Library/Implementation/www_tcp.h
index b2aafd2b..11a4398f 100644
--- a/WWW/Library/Implementation/www_tcp.h
+++ b/WWW/Library/Implementation/www_tcp.h
@@ -549,11 +549,13 @@ extern int errno;
 #ifdef __DJGPP__
 #undef SELECT
 #define TCP_INCLUDES_DONE
-#define NO_IOCTL
+#undef  IOCTL
+#define IOCTL(s,cmd,arg) ioctlsocket(s,cmd,(char*)(arg))
 #define DECL_ERRNO
 #include <errno.h>
 #include <sys/types.h>
 #include <io.h>
+#include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <tcp.h>