about summary refs log tree commit diff stats
path: root/WWW/Library/Implementation
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>1997-05-25 00:16:10 -0400
committerThomas E. Dickey <dickey@invisible-island.net>1997-05-25 00:16:10 -0400
commit945e8eb6bb07f64aaca42207af3311220ff2e4ba (patch)
tree6afb50262b844dd069bd4f7234da68008c48677c /WWW/Library/Implementation
parente4409c408eedf320b8845cafdd62b664bec1afd8 (diff)
downloadlynx-snapshots-945e8eb6bb07f64aaca42207af3311220ff2e4ba.tar.gz
snapshot of project "lynx", label v2-7-1ac_0-28
Diffstat (limited to 'WWW/Library/Implementation')
-rw-r--r--WWW/Library/Implementation/HTAABrow.c340
-rw-r--r--WWW/Library/Implementation/HTAccess.c15
-rw-r--r--WWW/Library/Implementation/HTAnchor.c41
-rw-r--r--WWW/Library/Implementation/HTAnchor.h24
-rw-r--r--WWW/Library/Implementation/HTFTP.c2
-rw-r--r--WWW/Library/Implementation/HTFile.c4
-rw-r--r--WWW/Library/Implementation/HTML.h5
-rw-r--r--WWW/Library/Implementation/HTMLDTD.c663
-rw-r--r--WWW/Library/Implementation/HTMLDTD.h8
-rw-r--r--WWW/Library/Implementation/HTNews.c24
-rw-r--r--WWW/Library/Implementation/HTTCP.c33
-rw-r--r--WWW/Library/Implementation/HTTP.c186
-rw-r--r--WWW/Library/Implementation/HTTelnet.c4
-rw-r--r--WWW/Library/Implementation/HTUtils.h9
-rw-r--r--WWW/Library/Implementation/HTWAIS.c3
-rw-r--r--WWW/Library/Implementation/HTWSRC.c8
-rw-r--r--WWW/Library/Implementation/SGML.c303
-rw-r--r--WWW/Library/Implementation/SGML.h55
-rw-r--r--WWW/Library/Implementation/tcp.h24
19 files changed, 1439 insertions, 312 deletions
diff --git a/WWW/Library/Implementation/HTAABrow.c b/WWW/Library/Implementation/HTAABrow.c
index caf1cbd8..3be7d229 100644
--- a/WWW/Library/Implementation/HTAABrow.c
+++ b/WWW/Library/Implementation/HTAABrow.c
@@ -42,6 +42,9 @@
 **			otherwise HTUU_encode() reads uninitialized memory
 **			every now and then (not a real bug but not pretty).
 **			Corrected the formula for uuencode destination size.
+**
+** 28 Apr 1997	AJL	Do Proxy Authorisation.
+**
 ** BUGS:
 **
 **
@@ -61,6 +64,7 @@
 #include "LYLeaks.h"
 
 extern BOOL using_proxy;	/* Are we using an HTTP gateway? */
+extern BOOL auth_proxy;		/* Generate a proxy authorization - AJL */
 
 /*
 **  Local datatype definitions
@@ -124,6 +128,10 @@ PRIVATE char *current_docname	= NULL;	/* The document's name we are        */
                                         /* trying to access.		     */
 PRIVATE char *HTAAForwardAuth	= NULL;	/* Authorization: line to forward    */
                                         /* (used by gateway httpds)	     */
+PRIVATE HTAASetup *proxy_setup	= NULL;	/* Same as above, but for Proxy -AJL */
+PRIVATE char *proxy_hostname	= NULL;
+PRIVATE char *proxy_docname	= NULL;
+PRIVATE int proxy_portnumber	= 80;
 
 
 /*** HTAAForwardAuth for enabling gateway-httpds to forward Authorization ***/
@@ -583,7 +591,7 @@ PRIVATE char *compose_auth_string ARGS2(HTAAScheme,	scheme,
 	      	     setup->server->hostname : "??") + 40;
 	if (!(msg = (char*)calloc(1, sizeof(char) * len)))
 	    outofmem(__FILE__, "compose_auth_string");
-	if (using_proxy && setup->template) {
+	if ((!auth_proxy) && using_proxy && setup->template) {
 	    proxiedHost = HTParse(setup->template, "", PARSE_HOST);
 	    if (proxiedHost && *proxiedHost != '\0') {
 	        theHost = proxiedHost;
@@ -739,6 +747,8 @@ PRIVATE void free_HTAAGlobals NOARGS
     FREE(HTAA_composeAuthResult);
     FREE(current_hostname);
     FREE(current_docname);
+    FREE(proxy_hostname);
+    FREE(proxy_docname);
     FREE(compose_auth_stringResult);
     FREE(secret_key);
 }
@@ -799,79 +809,159 @@ PUBLIC char *HTAA_composeAuth ARGS3(CONST char *,	hostname,
 
     FREE(HTAA_composeAuthResult);	/* From previous call */
 
-    if (TRACE)
-	fprintf(stderr, 
-		"Composing Authorization for %s:%d/%s\n",
-		hostname, portnumber, docname);
+    if (auth_proxy) {
+        /*
+	**  Proxy Authorization required. - AJL
+	*/
 
-    if (current_portnumber != portnumber ||
-	!current_hostname || !current_docname ||
-	!hostname         || !docname         ||
-	0 != strcmp(current_hostname, hostname) ||
-	0 != strcmp(current_docname, docname)) {
+	if (TRACE)
+	    fprintf(stderr, 
+		    "Composing Proxy Authorization for %s:%d/%s\n",
+		    hostname, portnumber, docname);
+
+	if (proxy_portnumber != portnumber ||
+	    !proxy_hostname || !proxy_docname ||
+	    !hostname         || !docname         ||
+	    0 != strcmp(proxy_hostname, hostname) ||
+	    0 != strcmp(proxy_docname, docname)) {
+
+	    retry = NO;
+
+	    proxy_portnumber = portnumber;
+
+	    if (hostname)
+		StrAllocCopy(proxy_hostname, hostname);
+	    else
+		FREE(proxy_hostname);
+
+	    if (docname)
+		StrAllocCopy(proxy_docname, docname);
+	    else
+		FREE(proxy_docname);
+	} else {
+	    retry = YES;
+	}
 
-	retry = NO;
+	if (!proxy_setup || !retry)
+	    proxy_setup = HTAASetup_lookup(hostname, portnumber, docname);
 
-	current_portnumber = portnumber;
-	
-	if (hostname)
-	    StrAllocCopy(current_hostname, hostname);
-	else
-	    FREE(current_hostname);
-
-	if (docname)
-	    StrAllocCopy(current_docname, docname);
-	else
-	    FREE(current_docname);
-    } else {
-        retry = YES;
-    }
-    
-    if (!current_setup || !retry)
-	current_setup = HTAASetup_lookup(hostname, portnumber, docname);
+	if (!proxy_setup)
+	    return NULL;
 
-    if (!current_setup)
-	return NULL;
+    	switch (scheme = HTAA_selectScheme(proxy_setup)) {
+	  case HTAA_BASIC:
+	  case HTAA_PUBKEY:
+	    auth_string = compose_auth_string(scheme, proxy_setup);
+	    break;
+	  case HTAA_KERBEROS_V4:
+	    /* OTHER AUTHENTICATION ROUTINES ARE CALLED HERE */
+	  default:
+	    {
+		char msg[100];
+		sprintf(msg, "%s %s `%s'",
+			"This client doesn't know how to compose proxy authentication",
+			"information for scheme", HTAAScheme_name(scheme));
+		HTAlert(msg);
+		auth_string = NULL;
+	    }
+	} /* switch scheme */
 
+	proxy_setup->retry = NO;
 
-    switch (scheme = HTAA_selectScheme(current_setup)) {
-      case HTAA_BASIC:
-      case HTAA_PUBKEY:
-	auth_string = compose_auth_string(scheme, current_setup);
-	break;
-      case HTAA_KERBEROS_V4:
-	/* OTHER AUTHENTICATION ROUTINES ARE CALLED HERE */
-      default:
-	{
-	    char msg[100];
-	    sprintf(msg, "%s %s `%s'",
-		    "This client doesn't know how to compose authentication",
-		    "information for scheme", HTAAScheme_name(scheme));
-	    HTAlert(msg);
-	    auth_string = NULL;
+	if (!auth_string)
+	    /*
+	    **  Signal a failure. - FM
+	    */
+	    return NULL;  /* Added by marca. */
+	if (*auth_string == '\0') {
+	    /*
+	    **  Signal an abort. - FM
+	    */
+	    StrAllocCopy(HTAA_composeAuthResult, "");
+	    return(HTAA_composeAuthResult);
 	}
-    } /* switch scheme */
+	len = strlen(auth_string) + strlen((char *)HTAAScheme_name(scheme)) + 26;
+	if (!(HTAA_composeAuthResult = (char*)calloc(1, sizeof(char) * len)))
+	    outofmem(__FILE__, "HTAA_composeAuth");
+	strcpy(HTAA_composeAuthResult, "Proxy-Authorization: ");
 
-    current_setup->retry = NO;
+    } else {
+	/*
+	**  Normal WWW authorization.
+	*/
+	if (TRACE)
+	    fprintf(stderr, 
+		    "Composing Authorization for %s:%d/%s\n",
+		    hostname, portnumber, docname);
+
+	if (current_portnumber != portnumber ||
+	    !current_hostname || !current_docname ||
+	    !hostname         || !docname         ||
+	    0 != strcmp(current_hostname, hostname) ||
+	    0 != strcmp(current_docname, docname)) {
+
+	    retry = NO;
+
+	    current_portnumber = portnumber;
+
+	    if (hostname)
+		StrAllocCopy(current_hostname, hostname);
+	    else
+		FREE(current_hostname);
+
+	    if (docname)
+		StrAllocCopy(current_docname, docname);
+	    else
+		FREE(current_docname);
+	} else {
+	    retry = YES;
+	}
 
-    if (!auth_string)
-        /*
-	 *  Signal a failure. - FM
-	 */
-	return NULL;  /* Added by marca. */
-    if (*auth_string == '\0') {
-        /*
-	 *  Signal an abort. - FM
-	 */
-        StrAllocCopy(HTAA_composeAuthResult, "");
-	return(HTAA_composeAuthResult);
+	if (!current_setup || !retry)
+	    current_setup = HTAASetup_lookup(hostname, portnumber, docname);
+
+	if (!current_setup)
+	    return NULL;
+
+	switch (scheme = HTAA_selectScheme(current_setup)) {
+	  case HTAA_BASIC:
+	  case HTAA_PUBKEY:
+	    auth_string = compose_auth_string(scheme, current_setup);
+	    break;
+	  case HTAA_KERBEROS_V4:
+	    /* OTHER AUTHENTICATION ROUTINES ARE CALLED HERE */
+	  default:
+	    {
+		char msg[100];
+		sprintf(msg, "%s %s `%s'",
+			"This client doesn't know how to compose authentication",
+			"information for scheme", HTAAScheme_name(scheme));
+		HTAlert(msg);
+		auth_string = NULL;
+	    }
+	} /* switch scheme */
+
+	current_setup->retry = NO;
+
+	if (!auth_string)
+	    /*
+	    **  Signal a failure. - FM
+	    */
+	    return NULL;  /* Added by marca. */
+	if (*auth_string == '\0') {
+	    /*
+	    **  Signal an abort. - FM
+	    */
+	    StrAllocCopy(HTAA_composeAuthResult, "");
+	    return(HTAA_composeAuthResult);
+	}
+
+	len = strlen(auth_string) + strlen((char *)HTAAScheme_name(scheme)) + 20;
+	if (!(HTAA_composeAuthResult = (char*)calloc(1, sizeof(char) * len)))
+	    outofmem(__FILE__, "HTAA_composeAuth");
+	strcpy(HTAA_composeAuthResult, "Authorization: ");
     }
-    
-    len = strlen(auth_string) + strlen((char *)HTAAScheme_name(scheme)) + 20;
-    if (!(HTAA_composeAuthResult =
-    		(char*)calloc(1, sizeof(char) * len)))
-	outofmem(__FILE__, "HTAA_composeAuth");
-    strcpy(HTAA_composeAuthResult, "Authorization: ");
+
     strcat(HTAA_composeAuthResult, HTAAScheme_name(scheme));
     strcat(HTAA_composeAuthResult, " ");
     strcat(HTAA_composeAuthResult, auth_string);
@@ -943,8 +1033,11 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4(char *, start_of_headers,
 	    char *fieldname = HTNextField(&p);
 	    char *arg1 = HTNextField(&p);
 	    char *args = p;
-	    
-	    if (0==strcasecomp(fieldname, "WWW-Authenticate:")) {
+
+	    if ((auth_proxy &&
+		 0==strcasecomp(fieldname, "Proxy-Authenticate:")) ||
+	        (!auth_proxy &&
+		 0==strcasecomp(fieldname, "WWW-Authenticate:"))) {
 	        if (!(arg1 && *arg1 && args && *args)) {
 		    temp = (char *)calloc(1, strlen(line) +
 		    			     (arg1 ? strlen(arg1) : 0) +
@@ -976,11 +1069,14 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4(char *, start_of_headers,
 		else if (TRACE) {
 		    fprintf(stderr, "Unknown scheme `%s' %s\n",
 			    (arg1 ? arg1 : "(null)"),
-			    "in WWW-Authenticate: field");
+			    (auth_proxy ?
+			     "in Proxy-Authenticate: field" :
+			     "in WWW-Authenticate: field"));
 		}
 	    }
 
-	    else if (0==strcasecomp(fieldname, "WWW-Protection-Template:")) {
+	    else if (!auth_proxy &&
+		     0==strcasecomp(fieldname, "WWW-Protection-Template:")) {
 		if (TRACE)
 		    fprintf(stderr, "Protection template set to `%s'\n", arg1);
 		StrAllocCopy(template, arg1);
@@ -997,37 +1093,104 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4(char *, start_of_headers,
 
 
     /*
-    **  So should we retry with authorization
+    **  So should we retry with authorization?
     */
-    if (num_schemes == 0) {		/* No authentication valid */
+    if (auth_proxy) {
+	if (num_schemes == 0) {
+	    /*
+	    **  No proxy authentication valid
+	    */
+	    proxy_setup = NULL;
+	    return NO;
+	}
+        /*
+	**  Doing it for proxy.  -AJL
+	*/
+	if (proxy_setup && proxy_setup->server) {
+	    /* 
+	    **  We have already tried with proxy authorization.
+	    **  Either we don't have access or username or
+	    **  password was misspelled.
+	    **
+	    **  Update scheme-specific parameters
+	    **  (in case they have expired by chance).
+	    */
+	    HTAASetup_updateSpecifics(proxy_setup, scheme_specifics);
+
+	    if (NO == HTConfirm("Authorization failed.  Retry?")) {
+		proxy_setup = NULL;
+		return NO;
+	    } else {
+	        /*
+		**  Re-ask username+password (if misspelled).
+		*/
+		proxy_setup->retry = YES;
+		return YES;
+	    }
+	} else {
+	    /*
+	    **  proxy_setup == NULL, i.e. we have a
+	    **  first connection to a protected server or
+	    **  the server serves a wider set of documents
+	    **  than we expected so far.
+	    */
+	    HTAAServer *server = HTAAServer_lookup(proxy_hostname,
+						   proxy_portnumber);
+	    if (!server) {
+		server = HTAAServer_new(proxy_hostname,
+					proxy_portnumber);
+	    }
+	    if (!template)	/* Proxy matches everything  -AJL */
+		StrAllocCopy(template, "*");
+	    proxy_setup = HTAASetup_new(server, 
+					  template,
+					  valid_schemes,
+					  scheme_specifics);
+	    FREE(template);
+
+	    HTAlert("Proxy authentication required -- retrying");
+	    return YES;
+	}
+	/* Never reached */
+    }
+    /*
+    **  Normal WWW authorization.
+    */
+    if (num_schemes == 0) {
+	/*
+	**  No authentication valid.
+	*/
 	current_setup = NULL;
 	return NO;
     }
-
     if (current_setup && current_setup->server) {
-	/* So we have already tried with authorization.	*/
-	/* Either we don't have access or username or	*/
-	/* password was misspelled.			*/
-	    
-	/* Update scheme-specific parameters	*/
-	/* (in case they have expired by chance).	*/
+	/*
+	**  So we have already tried with WWW authorization.
+	**  Either we don't have access or username or
+	**  password was misspelled.
+	**
+	**  Update scheme-specific parameters
+	**  (in case they have expired by chance).
+	*/
 	HTAASetup_updateSpecifics(current_setup, scheme_specifics);
 
 	if (NO == HTConfirm("Authorization failed.  Retry?")) {
 	    current_setup = NULL;
 	    return NO;
-	} /* HTConfirm(...) == NO */
-	else { /* re-ask username+password (if misspelled) */
+	} else {
+	    /*
+	    **  Re-ask username+password (if misspelled).
+	    */
 	    current_setup->retry = YES;
 	    return YES;
-	} /* HTConfirm(...) == YES */
-    } /* if current_setup != NULL */
-
-    else { /* current_setup == NULL, i.e. we have a	 */
-	   /* first connection to a protected server or  */
-	   /* the server serves a wider set of documents */
-	   /* than we expected so far.                   */
-
+	}
+    } else {
+        /*
+	**  current_setup == NULL, i.e. we have a
+	**  first connection to a protected server or
+	**  the server serves a wider set of documents
+	**  than we expected so far.
+	*/
 	HTAAServer *server = HTAAServer_lookup(current_hostname,
 					       current_portnumber);
 	if (!server) {
@@ -1044,8 +1207,7 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4(char *, start_of_headers,
 
         HTAlert("Access without authorization denied -- retrying");
 	return YES;
-    } /* else current_setup == NULL */
-
+    }
     /* Never reached */
 }
 
diff --git a/WWW/Library/Implementation/HTAccess.c b/WWW/Library/Implementation/HTAccess.c
index 1f00a089..440cb1b1 100644
--- a/WWW/Library/Implementation/HTAccess.c
+++ b/WWW/Library/Implementation/HTAccess.c
@@ -602,6 +602,7 @@ PRIVATE BOOL HTLoadDocument ARGS4(
     char * address_to_load =  (char *)full_address;
     extern char LYforce_no_cache;		       /* from   GridText.c */
     extern char LYoverride_no_cache;		       /* from LYMainLoop.c */
+    extern char * HTLoadedDocumentURL NOPARAMS;		   /* in GridText.c */
     extern BOOL HText_hasNoCacheSet PARAMS((HText *text)); /* in GridText.c */
     extern BOOL reloading;
     extern char *redirecting_url;
@@ -693,6 +694,20 @@ PRIVATE BOOL HTLoadDocument ARGS4(
 	/*
 	**  Already loaded.  Check it it's OK to use it. - FM
 	*/
+#ifdef NOTUSED_FOTEMODS
+	/* not sure whether this is always the right thing to do,
+	 * and anyway, we have a far more complete (and complicated...)
+	 * way to prevent reloading on internal URL references now...
+	 * - kw
+	 */
+	if ((cp = strchr(address_to_load, '#')) != NULL) {
+	    *cp = '\0';
+	    if (!strcmp(address_to_load, HTLoadedDocumentURL()) &&
+	        strncasecomp(address_to_load, "LYNXIMGMAP:", 11))
+	        LYoverride_no_cache = TRUE;
+	    *cp = '#';
+	}
+#endif /* NOTUSED_FOTEMODS */
 	if (LYoverride_no_cache || !HText_hasNoCacheSet(text)) {
             if (TRACE)
 	        fprintf(stderr, "HTAccess: Document already in memory.\n");
diff --git a/WWW/Library/Implementation/HTAnchor.c b/WWW/Library/Implementation/HTAnchor.c
index 40032d8a..304e55c6 100644
--- a/WWW/Library/Implementation/HTAnchor.c
+++ b/WWW/Library/Implementation/HTAnchor.c
@@ -13,7 +13,7 @@
 **	(c) Copyright CERN 1991 - See Copyright.html
 */
 
-#define HASH_SIZE 101		/* Arbitrary prime. Memory/speed tradeoff */
+#define HASH_SIZE 8193		/* Arbitrary prime. Memory/speed tradeoff */
 
 #include "HTUtils.h"
 #include "tcp.h"
@@ -37,7 +37,7 @@
 /*
  *	This is the original function.  We'll use it again. - FM
  */ 
-PRIVATE int HASH_FUNCTION ARGS1(
+PUBLIC int HASH_FUNCTION ARGS1(
 	CONST char *,	cp_address)
 {
     int hash;
@@ -490,6 +490,11 @@ PRIVATE void deleteLinks ARGS1(
 	        me->parent != parent) {
 	        HTAnchor_delete(parent);
 	    }
+	    /* The link structure has to be deleted, too!
+	    ** That was missing, but this code probably never
+	    ** got exercised by Lynx.  - kw
+	    */
+	    FREE(target);
         }
 
         /*
@@ -647,6 +652,9 @@ PUBLIC BOOL HTAnchor_delete ARGS1(
     FREE(me->expires);
     FREE(me->last_modified);
     FREE(me->server);
+#ifdef USEHASH
+    FREE(me->style);
+#endif
  
     /*
      *  Remove ourselves from the hash table's list.
@@ -795,12 +803,41 @@ PUBLIC BOOL HTAnchor_isIndex ARGS1(
     return me ? me->isIndex : NO;
 }
 
+/*	Whether Anchor has been designated as an ISMAP link
+**	(normally by presence of an ISMAP attribute on A or IMG) - KW
+*/
+PUBLIC BOOL HTAnchor_isISMAPScript ARGS1(
+	HTAnchor *,	me)
+{
+    return me ? me->parent->isISMAPScript : NO;
+}
+
 PUBLIC BOOL HTAnchor_hasChildren ARGS1(
 	HTParentAnchor *,	me)
 {
     return me ? ! HTList_isEmpty(me->children) : NO;
 }
 
+#if defined(USEHASH)
+/*      Style handling.
+*/
+PUBLIC CONST char * HTAnchor_style ARGS1(
+        HTParentAnchor *,       me)
+{
+        return me ? me->style : NULL;
+}
+
+PUBLIC void HTAnchor_setStyle ARGS2(
+        HTParentAnchor *,       me,
+        CONST char *,           style)
+{
+    if (me) {
+        StrAllocCopy(me->style, style);
+    }
+}
+#endif
+
+
 /*	Title handling.
 */
 PUBLIC CONST char * HTAnchor_title ARGS1(
diff --git a/WWW/Library/Implementation/HTAnchor.h b/WWW/Library/Implementation/HTAnchor.h
index efa2a307..db875cac 100644
--- a/WWW/Library/Implementation/HTAnchor.h
+++ b/WWW/Library/Implementation/HTAnchor.h
@@ -98,6 +98,9 @@ struct _HTParentAnchor {
   char *        title;          /* Title of document */
   char *        owner;          /* Owner of document */
   char *        RevTitle;       /* TITLE in REV="made" or REV="owner" LINK */
+#ifdef USEHASH
+  char *	style;
+#endif
 
   HTList*       methods;        /* Methods available as HTAtoms */
   void *        protocol;       /* Protocol object */
@@ -150,6 +153,15 @@ 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")
+
+extern int HASH_FUNCTION PARAMS((
+	CONST char * 	cp_address));
+
 /*      Create new or find old sub-anchor
 **      ---------------------------------
 **
@@ -248,9 +260,21 @@ extern void HTAnchor_setPrompt PARAMS((
 extern BOOL HTAnchor_isIndex PARAMS((
 	HTParentAnchor *	me));
 
+extern BOOL HTAnchor_isISMAPScript PARAMS((
+	HTAnchor *		me));
+
 extern BOOL HTAnchor_hasChildren PARAMS((
 	HTParentAnchor *	me));
 
+#if defined(USEHASH)
+extern CONST char * HTAnchor_style PARAMS((
+	HTParentAnchor *	me));
+
+extern void HTAnchor_setStyle PARAMS((
+	HTParentAnchor *	me,
+	CONST char *		style));
+#endif
+
 /*      Title handling.
 */
 extern CONST char * HTAnchor_title PARAMS((
diff --git a/WWW/Library/Implementation/HTFTP.c b/WWW/Library/Implementation/HTFTP.c
index 8be44d44..dfca3a4f 100644
--- a/WWW/Library/Implementation/HTFTP.c
+++ b/WWW/Library/Implementation/HTFTP.c
@@ -1591,6 +1591,7 @@ PRIVATE void parse_ms_windows_dir_entry ARGS2(
  *      Format the name, date, and size from a WINDOWS_NT LIST line into
  *      the EntryInfo structure (assumes Chameleon NEWT format). - FM
  */
+#ifdef NOTDEFINED
 PRIVATE void parse_windows_nt_dir_entry ARGS2(
 	char *,		line,
 	EntryInfo *,	entry_info)
@@ -1708,6 +1709,7 @@ PRIVATE void parse_windows_nt_dir_entry ARGS2(
 			entry_info->size);
     return;
 } /* parse_windows_nt_dir_entry */
+#endif /* NOTDEFINED */
 
 /*
  * parse_cms_dir_entry() --
diff --git a/WWW/Library/Implementation/HTFile.c b/WWW/Library/Implementation/HTFile.c
index 40097a96..1565e629 100644
--- a/WWW/Library/Implementation/HTFile.c
+++ b/WWW/Library/Implementation/HTFile.c
@@ -100,6 +100,8 @@ typedef struct _HTSuffix {
 #define PUTS(s) (*target->isa->put_string)(target, s)
 #define START(e) (*target->isa->start_element)(target, e, 0, 0, 0)
 #define END(e) (*target->isa->end_element)(target, e, 0)
+#define MAYBE_END(e) if (HTML_dtd.tags[e].contents != SGML_EMPTY) \
+                        (*target->isa->end_element)(target, e, 0)
 #define FREE_TARGET (*target->isa->_free)(target)
 struct _HTStructured {
 	CONST HTStructuredClass *	isa;
@@ -684,7 +686,6 @@ PUBLIC HTFormat HTFileFormat ARGS2(
     extern char LYforce_HTML_mode;
 
     if (LYforce_HTML_mode) {
-        LYforce_HTML_mode = FALSE;
         return WWW_HTML;
     }
 
@@ -1987,6 +1988,7 @@ forget_multi:
 				PUTS(file_extra);
 				FREE(file_extra);
 			    }
+                            MAYBE_END(HTML_LI);
 #endif /* LONG_LIST */
 
 			    next_element = HTBTree_next(bt, next_element);
diff --git a/WWW/Library/Implementation/HTML.h b/WWW/Library/Implementation/HTML.h
index ed3aefee..6cdcc828 100644
--- a/WWW/Library/Implementation/HTML.h
+++ b/WWW/Library/Implementation/HTML.h
@@ -69,6 +69,7 @@ struct _HTStructured {
     char *			object_codetype;
     char *			object_name;
     HTChunk			option;		/* Grow by 128 */
+    BOOL			first_option;	/* First OPTION in SELECT? */
     char *			LastOptionValue;
     BOOL			LastOptionChecked;
     BOOL			select_disabled;
@@ -111,6 +112,8 @@ struct _HTStructured {
     BOOL			in_word;  /* Have just had a non-white char */
     stack_element 	stack[MAX_NESTING];
     stack_element 	*sp;		/* Style stack pointer */
+    BOOL		stack_overrun;	/* Was MAX_NESTING exceeded? */
+    int			skip_stack; /* flag to skip next style stack operation */
 
     /*
     **  Track if we are in an anchor, paragraph, address, base, etc.
@@ -119,6 +122,7 @@ struct _HTStructured {
     BOOL		inAPPLET;
     BOOL		inAPPLETwithP;
     BOOL		inBadBASE;
+    BOOL		inBadHREF;
     BOOL		inBadHTML;
     BOOL		inBASE;
     BOOL		inBoldA;
@@ -127,6 +131,7 @@ struct _HTStructured {
     BOOL		inCREDIT;
     BOOL		inFIG;
     BOOL		inFIGwithP;
+    BOOL		inFONT;
     BOOL		inFORM;
     BOOL		inLABEL;
     BOOL		inP;
diff --git a/WWW/Library/Implementation/HTMLDTD.c b/WWW/Library/Implementation/HTMLDTD.c
index 2639a461..54f14681 100644
--- a/WWW/Library/Implementation/HTMLDTD.c
+++ b/WWW/Library/Implementation/HTMLDTD.c
@@ -1101,129 +1101,545 @@ static attr ulist_attr[] = {			/* UL attributes */
 	{ 0 }	/* Terminate list */
 };
 
+/* From Peter Flynn's intro to the HTML Pro DTD:
+
+   %structure;
+
+   DIV, CENTER, H1 to H6, P, UL, OL, DL, DIR, MENU, PRE, XMP, LISTING, BLOCKQUOTE, BQ,
+   2    1       2     2   1  8   8   8   8    8     8    8    8        4           4
+   MULTICOL,?NOBR, FORM, TABLE, ADDRESS, FIG, BDO, NOTE, and FN; plus?WBR, LI, and LH
+   8 n      ?1 n   8     8      2        2    2    2         2      ?1 nE  4       4
+
+   %insertions;
+
+   Elements which usually contain special-purpose material, or no text material at all.
+
+   BASEFONT, APPLET, OBJECT, EMBED, SCRIPT, MAP, MARQUEE, HR, ISINDEX, BGSOUND, TAB,?IMG,
+   1 e?      2       2 l     1 e    2 l     8    4        4 E 1? E     1 E      ! E ?1 E
+   IMAGE, BR, plus NOEMBED, SERVER, SPACER, AUDIOSCOPE, and SIDEBAR; ?area
+   1 n    1 E        n        n       n       n               n       8 E
+
+   %text;
+
+   Elements within the %structure; which directly contain running text.
+
+   Descriptive or analytic markup: EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, Q, LANG, AU,
+                                   2   2       2    2     2     2    2    2     2  2 n   2
+   AUTHOR, PERSON, ACRONYM, ABBREV, INS, DEL, and SPAN
+   2       2 n     2        2       2    2        2
+   Visual markup:S, STRIKE, I, B, TT, U,?NOBR,?WBR, BR, BIG, SMALL, FONT, STYLE, BLINK, TAB,
+                 1  1       1  1  1   1  ?1 n ?1nE? 1 E  1   1      1     1 l    1      1 E?
+   BLACKFACE, LIMITTEXT, NOSMARTQUOTES, and SHADOW
+   1 n        1 n        1 n                1 n
+   Hypertext and graphics: A and?IMG
+                           8    ?8 E
+   Mathematical: SUB, SUP, and MATH
+                 4    4        4 l
+   Documentary: COMMENT, ENTITY, ELEMENT, and ATTRIB
+                4        4 n     4 n          4 n
+   %formula;
+ */
+
+/*	Extra element info
+**	------------------
+**
+**	Order and number of tags should match the tags_* tables
+**	further below and definitions in HTMLDTD.html.
+**
+**	The interspersed comments give the original Lynx tags[] entries
+**	for orientation, so they do not necessarily reflect what will
+**	be used with the T_* info (which is in tags_new[]).
+**
+**	An important design goal was that info for each tag should fit on
+**	one 80 character screen line :).  The price to pay is that it's
+**	a bit cryptic, to say the least...  - kw
+*/
+/*       1         2         3         4         5         6         7         8 */
+/*345678901234567890123456789012345678901234567890123456789012345678901234567890 */
+
+/*			self	contain	icont'n	contn'd	icont'd	canclos	omit */
+ /* { "A"	, a_attr,	HTML_A_ATTRIBUTES,	SGML_MIXED }, */
+#define T_A		0x0008,	0x0B007,0x0FF17,0x37787,0x77BA7,0x8604F,0x00004
+ /* { "ABBREV"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_ABBREV	0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00003,0x00000
+ /* { "ACRONYM"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_ACRONYM	0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00003,0x00000
+ /* { "ADDRESS"	, address_attr,	HTML_ADDRESS_ATTRIBUTES, SGML_MIXED }, */
+#define T_ADDRESS	0x0200,	0x0F14F,0x8FFFF,0x36680,0xB6FAF,0x80317,0x00000
+ /* { "APPLET"	, applet_attr,	HTML_APPLET_ATTRIBUTES, SGML_MIXED }, */
+#define T_APPLET	0x2000,	0x0B0CF,0x8FFFF,0x37F9F,0xB7FBF,0x8300F,0x00000
+ /* { "AREA"	, area_attr,	HTML_AREA_ATTRIBUTES,   SGML_EMPTY }, */
+#define T_AREA		0x8000,	0x00000,0x00000,0x08000,0x3FFFF,0x00F1F,0x00001
+ /* { "AU"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_AU		0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00003,0x00000
+ /* { "AUTHOR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_AUTHOR	0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00003,0x00000
+ /* { "B"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_B		0x0001, 0x8B04F,0xAFFFF,0xA778F,0xF7FBF,0x00001,0x00004
+ /* { "BANNER"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_BANNER	0x0200,	0x0FB8F,0x0FFFF,0x30000,0x30000,0x8031F,0x00000
+ /* { "BASE"	, base_attr,	HTML_BASE_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_BASE		0x40000,0x00000,0x00000,0x50000,0x50000,0x8000F,0x00001
+ /* { "BASEFONT", font_attr,	HTML_FONT_ATTRIBUTES,	SGML_EMPTY }, */
+#define	T_BASEFONT	0x1000,	0x00000,0x00000,0x377AF,0x37FAF,0x8F000,0x00001
+ /* { "BDO"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define	T_BDO		0x0100,	0x0B04F,0x8FFFF,0x36680,0xB6FAF,0x0033F,0x00000
+ /* { "BGSOUND"	, bgsound_attr,	HTML_BGSOUND_ATTRIBUTES, SGML_EMPTY }, */
+#define T_BGSOUND	0x1000,	0x00000,0x00000,0x777AF,0x77FAF,0x8730F,0x00001
+ /* { "BIG"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_BIG		0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00004
+ /* { "BLINK"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_BLINK		0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FAF,0x00001,0x00004
+ /* { "BLOCKQUOTE", bq_attr,	HTML_BQ_ATTRIBUTES,	SGML_MIXED }, */
+#define T_BLOCKQUOTE	0x0200,	0xAFBCF,0xAFFFF,0xB6680,0xB6FAF,0x8031F,0x00000
+ /* { "BODY"	, body_attr,	HTML_BODY_ATTRIBUTES,	SGML_MIXED }, */
+#define	T_BODY		0x20000,0x2FB8F,0x2FFFF,0x30000,0x30000,0xDFFFF,0x00003
+ /* { "BODYTEXT", bodytext_attr,HTML_BODYTEXT_ATTRIBUTES, SGML_MIXED }, */
+#define T_BODYTEXT	0x20000,0x0FB8F,0xAFFFF,0x30200,0xB7FAF,0x8F17F,0x00003
+ /* { "BQ"	, bq_attr,	HTML_BQ_ATTRIBUTES,	SGML_MIXED }, */
+#define T_BQ		0x0200,	0xAFBCF,0xAFFFF,0xB6680,0xB6FAF,0x8031F,0x00000
+ /* { "BR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_BR		0x1000, 0x00000,0x00000,0x377BF,0x77FBF,0x8101F,0x00001
+ /* { "CAPTION"	, caption_attr,	HTML_CAPTION_ATTRIBUTES, SGML_MIXED }, */
+#define	T_CAPTION	0x0100,	0x0B04F,0x8FFFF,0x06A00,0xB6FA7,0x8035F,0x00000
+ /* { "CENTER"	, div_attr,	HTML_DIV_ATTRIBUTES,	SGML_MIXED }, */
+#define T_CENTER	0x0200,	0x8FBCF,0x8FFFF,0xB6680,0xB6FA7,0x8071F,0x00000
+ /* { "CITE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_CITE		0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00002,0x00000
+ /* { "CODE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_CODE		0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00002,0x00000
+ /* { "COL"	, col_attr,	HTML_COL_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_COL		0x4000, 0x00000,0x00000,0x00820,0x36FA7,0x88F5F,0x00001
+ /* { "COLGROUP", col_attr,	HTML_COL_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_COLGROUP	0x0020, 0x04000,0x04000,0x00800,0x36FA7,0x8875F,0x00001
+ /* { "COMMENT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define	T_COMMENT	0x0004,	0x00000,0x00000,0xA77AF,0x7FFFF,0x00003,0x00000
+ /* { "CREDIT"	, credit_attr,	HTML_CREDIT_ATTRIBUTES,	SGML_MIXED }, */
+#define T_CREDIT	0x0100, 0x0B04F,0x8FFFF,0x06A00,0xB7FBF,0x8030F,0x00000
+ /* { "DD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_DD		0x0400,	0x0FBCF,0x8FFFF,0x00800,0xB6FFF,0x8071F,0x00001
+ /* { "DEL"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_DEL		0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00003,0x00000
+ /* { "DFN"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_DFN		0x0002, 0x8B0CF,0x8FFFF,0x8778F,0xF7FBF,0x00003,0x00000
+ /* { "DIR"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED }, */
+#define T_DIR		0x0800, 0x0B400,0x0F75F,0x37680,0x36FB7,0x84F7F,0x00000
+ /* { "DIV"	, div_attr,	HTML_DIV_ATTRIBUTES,	SGML_MIXED }, */
+#define T_DIV		0x0200,	0x8FB8F,0x8FFFF,0xB66A0,0xB7FFF,0x8031F,0x00004
+ /* { "DL"	, glossary_attr, HTML_DL_ATTRIBUTES,	SGML_MIXED }, */
+#define T_DL		0x0800,	0x0C480,0x8FFFF,0x36680,0xB7FB7,0x0075F,0x00000
+ /* { "DLC"	, glossary_attr, HTML_DL_ATTRIBUTES,	SGML_MIXED }, */
+#define T_DLC		0x0800,	0x0C480,0x8FFFF,0x36680,0xB7FB7,0x0075F,0x00000
+ /* { "DT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_DT		0x0400,	0x0B04F,0x0B1FF,0x00800,0x17FFF,0x8071F,0x00001
+ /* { "EM"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_EM		0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FAF,0x00003,0x00000
+ /* { "EMBED"	, embed_attr,	HTML_EMBED_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_EMBED		0x2000, 0x8F107,0x8FFF7,0xB6FBF,0xB7FBF,0x1FF7F,0x00001
+ /* { "FIELDSET", fieldset_attr,HTML_FIELDSET_ATTRIBUTES, SGML_MIXED }, */
+#define T_FIELDSET	0x0200,	0x0FB40,0x0FF5F,0x07787,0x37FF7,0x8805F,0x00000
+ /* { "FIG"	, fig_attr,	HTML_FIG_ATTRIBUTES,	SGML_MIXED }, */
+#define T_FIG		0x0200, 0x0FB00,0x8FFFF,0x36680,0xB6FBF,0x8834F,0x00000
+ /* { "FN"	, fn_attr,	HTML_FN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_FN		0x0200, 0x8FBCF,0x8FFFF,0xB6680,0xB7EBF,0x8114F,0x00000
+ /* { "FONT"	, font_attr,	HTML_FONT_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_FONT		0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00004
+ /* { "FORM"	, form_attr,	HTML_FORM_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_FORM		0x0080,	0x0FF6F,0x0FF7F,0x36E07,0x33F07,0x88DFF,0x00000
+ /* { "FRAME"	, frame_attr,	HTML_FRAME_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_FRAME		0x10000,0x00000,0x00000,0x10000,0x10000,0x9FFFF,0x00001
+ /* { "FRAMESET", frameset_attr,HTML_FRAMESET_ATTRIBUTES, SGML_MIXED }, */
+#define	T_FRAMESET	0x10000,0x90000,0x90000,0x90000,0x93000,0x9FFFF,0x00000
+ /* { "H1"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED }, */
+#define T_H1  		0x0100,	0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000
+ /* { "H2"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED }, */
+#define T_H2  		0x0100,	0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000
+ /* { "H3"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED }, */
+#define T_H3  		0x0100,	0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000
+ /* { "H4"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED }, */
+#define T_H4  		0x0100,	0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000
+ /* { "H5"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED }, */
+#define T_H5  		0x0100,	0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000
+ /* { "H6"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED }, */
+#define T_H6  		0x0100,	0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000
+ /* { "HEAD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_HEAD		0x40000,0x4F000,0x47000,0x10000,0x10000,0x9FFFF,0x00006
+ /* { "HR"	, hr_attr,	HTML_HR_ATTRIBUTES,	SGML_EMPTY }, */
+#define	T_HR		0x4000,	0x00000,0x00000,0x3FE80,0x3FFBF,0x87F37,0x00001
+ /* { "HTML"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_HTML		0x10000,0x7FB8F,0x7FFFF,0x00000,0x00000,0x1FFFF,0x00003
+#define T_HY		0x1000, 0x00000,0x00000,0x3779F,0x77FBF,0x8101F,0x00001
+ /* { "I"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_I		0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00004
+ /* { "IMG"     , img_attr,	HTML_IMG_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_IMG		0x1000,	0x00000,0x00000,0x3779F,0x37FBF,0x80000,0x00001
+ /* { "INPUT"   , input_attr,	HTML_INPUT_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_INPUT		0x0040,	0x00000,0x00000,0x03F87,0x37F87,0x8904F,0x00001
+ /* { "INS"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_INS		0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00003,0x00000
+ /* { "ISINDEX" , isindex_attr,	HTML_ISINDEX_ATTRIBUTES,SGML_EMPTY }, */
+#define T_ISINDEX	0x8000, 0x00000,0x00000,0x7778F,0x7FFAF,0x80007,0x00001
+ /* { "KBD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_KBD		0x0002, 0x00000,0x00000,0x2778F,0x77FBF,0x00003,0x00000
+ /* { "KEYGEN"	, keygen_attr,	HTML_KEYGEN_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_KEYGEN	0x0040,	0x00000,0x00000,0x07FB7,0x37FB7,0x80070,0x00001
+ /* { "LABEL"	, label_attr,	HTML_LABEL_ATTRIBUTES,	SGML_MIXED }, */
+#define T_LABEL		0x0020, 0x9FFFF,0x9FFFF,0x9FFFF,0x9FFFF,0x00007,0x00000
+ /* { "LH"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_LH		0x0400,	0x0BB7F,0x8FFFF,0x00800,0x97FFF,0x8071F,0x00001
+ /* { "LI"	, list_attr,	HTML_LI_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_LI		0x0400,	0x0BBFF,0x8FFFF,0x00800,0x97FFF,0x8071F,0x00001
+ /* { "LINK"	, link_attr,	HTML_LINK_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_LINK		0x8000, 0x00000,0x00000,0x50000,0x50000,0x0FF7F,0x00001
+ /* { "LISTING"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL }, */
+#define T_LISTING	0x0800, 0x00000,0x00000,0x36600,0x36F00,0x80F1F,0x00000
+ /* { "MAP"	, map_attr,	HTML_MAP_ATTRIBUTES,	SGML_MIXED }, */
+#define T_MAP		0x8000,	0x08000,0x08000,0x37FCF,0x37FBF,0x0071F,0x00000
+ /* { "MARQUEE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_MARQUEE	0x4000, 0x0000F,0x8F01F,0x37787,0xB7FA7,0x8301C,0x00000
+ /* { "MATH"	, math_attr,	HTML_MATH_ATTRIBUTES,	SGML_LITTERAL }, */
+#define T_MATH		0x0004,	0x0B05F,0x8FFFF,0x2778F,0xF7FBF,0x0001F,0x00000
+ /* { "MENU"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED }, */
+#define T_MENU		0x0800, 0x0B400,0x0F75F,0x17680,0x36FB7,0x88F7F,0x00000
+ /* { "META"	, meta_attr,	HTML_META_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_META		0x8000, 0x00000,0x00000,0x50000,0x50000,0x0FF7F,0x00001
+ /* { "NEXTID"  , nextid_attr,	1,			SGML_EMPTY }, */
+#define T_NEXTID	0x1000, 0x00000,0x00000,0x50000,0x1FFF7,0x00001,0x00001
+ /* { "NOFRAMES", gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define	T_NOFRAMES	0x20000,0x2FB8F,0x0FFFF,0x17000,0x17000,0x0CF5F,0x00000
+ /* { "NOTE"	, note_attr,	HTML_NOTE_ATTRIBUTES,	SGML_MIXED }, */
+#define T_NOTE		0x0200,	0x0BBAF,0x8FFFF,0x376B0,0xB7FFF,0x8031F,0x00000
+ /* { "OBJECT"	, object_attr,	HTML_OBJECT_ATTRIBUTES,	SGML_LITTERAL }, */
+#define	T_OBJECT	0x2000,	0x8FBCF,0x8FFFF,0xB679F,0xB6FBF,0x83F5F,0x00000
+ /* { "OL"	, olist_attr,	HTML_OL_ATTRIBUTES,	SGML_MIXED }, */
+#define T_OL		0x0800, 0x0C400,0x8FFFF,0x37680,0xB7FB7,0x88F7F,0x00000
+ /* { "OPTION"	, option_attr,	HTML_OPTION_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_OPTION	0x8000,	0x00000,0x00000,0x00040,0x37FFF,0x8031F,0x00001
+ /* { "OVERLAY"	, overlay_attr,	HTML_OVERLAY_ATTRIBUTES, SGML_EMPTY }, */
+#define T_OVERLAY	0x4000, 0x00000,0x00000,0x00200,0x37FBF,0x83F7F,0x00001
+ /* { "P"	, p_attr,	HTML_P_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_P   		0x0100,	0x0B04F,0x8FFFF,0x36680,0xB6FA7,0x80117,0x00001
+ /* { "PARAM"	, param_attr,	HTML_PARAM_ATTRIBUTES,	SGML_EMPTY }, */
+#define	T_PARAM		0x1000, 0x00000,0x00000,0x03000,0x17FFF,0x81777,0x00001
+ /* { "PLAINTEXT", gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL }, */
+#define T_PLAINTEXT	0x10000,0xFFFFF,0xFFFFF,0x90000,0x90000,0x3FFFF,0x00001
+ /* { "PRE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_PRE		0x0200,	0x0F04F,0x0F05E,0x36680,0x36FF0,0x8071E,0x00000
+ /* { "Q"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_Q		0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FAF,0x00003,0x00000
+ /* { "S"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_S		0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00000
+ /* { "SAMP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_SAMP		0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00002,0x00000
+ /* { "SCRIPT"	, script_attr,	HTML_SCRIPT_ATTRIBUTES,	SGML_LITTERAL }, */
+#define T_SCRIPT	0x2000,	0x00000,0x00000,0x57F8F,0x57FFF,0x87F5F,0x00000
+ /* { "SELECT"	, select_attr,	HTML_SELECT_ATTRIBUTES,	SGML_MIXED }, */
+#define T_SELECT	0x0040,	0x08000,0x08000,0x03FAF,0x13FBF,0x80F5F,0x00000
+#define T_SHY		0x1000, 0x00000,0x00000,0x3779F,0x77FBF,0x8101F,0x00001
+ /* { "SMALL"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_SMALL		0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00004
+ /* { "SPAN"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_SPAN		0x0002, 0x0B04F,0x0FFFF,0x2778F,0x77FBF,0x80003,0x00000
+ /* { "SPOT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_SPOT		0x0008,	0x00000,0x00000,0x3FFF7,0x3FFF7,0x00008,0x00001
+ /* { "STRIKE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_STRIKE	0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00000
+ /* { "STRONG"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_STRONG	0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FAF,0x00003,0x00000
+ /* { "STYLE"	, style_attr,	HTML_STYLE_ATTRIBUTES,	SGML_LITTERAL }, */
+#define T_STYLE		0x40000,0x00000,0x00000,0x7638F,0x76FAF,0x8001F,0x00000
+ /* { "SUB"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_SUB		0x0004,	0x8B05F,0x8FFFF,0x8779F,0xF7FBF,0x00007,0x00000
+ /* { "SUP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_SUP		0x0004, 0x8B05F,0x8FFFF,0x8779F,0xF7FBF,0x00007,0x00000
+ /* { "TAB"	, tab_attr,	HTML_TAB_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_TAB		0x1000,	0x00000,0x00000,0x3778F,0x57FAF,0x00001,0x00001
+ /* { "TABLE"	, table_attr,	HTML_TABLE_ATTRIBUTES,	SGML_MIXED }, */
+#define T_TABLE		0x0800, 0x0F1E0,0x8FFFF,0x36680,0xB6FA7,0x8C57F,0x00000
+ /* { "TBODY"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_TBODY		0x0020, 0x00020,0x8FFFF,0x00880,0xB7FB7,0x8C75F,0x00003
+ /* { "TD"	, td_attr,	HTML_TD_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_TD		0x0400, 0x0FBCF,0x8FFFF,0x00020,0xB7FB7,0x8C75F,0x00001
+ /* { "TEXTAREA", textarea_attr,HTML_TEXTAREA_ATTRIBUTES, SGML_LITTERAL }, */
+#define T_TEXTAREA	0x0040,	0x00000,0x00000,0x07F8F,0x33FBF,0x80F5F,0x00000
+ /* { "TEXTFLOW", bodytext_attr,HTML_BODYTEXT_ATTRIBUTES, SGML_MIXED }, */
+#define T_TEXTFLOW	0x20000,0x8FBFF,0x9FFFF,0x977B0,0xB7FB7,0x9B00F,0x00003
+ /* { "TFOOT"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_TFOOT		0x0020, 0x00020,0x8FFFF,0x00800,0xB7FB7,0x8CF5F,0x00001
+ /* { "TH"	, td_attr,	HTML_TD_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_TH		0x0400,	0x0FBCF,0x0FFFF,0x00020,0xB7FB7,0x8CF5F,0x00001
+ /* { "THEAD"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_THEAD		0x0020, 0x00020,0x8FFFF,0x00880,0xB7FB7,0x8CF5F,0x00001
+ /* { "TITLE", 	  gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_RCDATA }, */
+#define T_TITLE		0x40000,0x00000,0x00000,0x50000,0x50000,0x0031F,0x00004
+ /* { "TR"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY }, */
+#define T_TR		0x0020, 0x00400,0x8FFFF,0x00820,0xB7FB7,0x8C75F,0x00001
+ /* { "TT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define	T_TT		0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00000
+ /* { "U"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define	T_U		0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00004
+ /* { "UL"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED }, */
+#define T_UL		0x0800,	0x0C480,0x8FFFF,0x36680,0xB7FFF,0x8075F,0x00000
+ /* { "VAR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED }, */
+#define T_VAR		0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00000
+#define T_WBR		0x0001, 0x00000,0x00000,0x3778F,0x77FBF,0x8101F,0x00001
+ /* { "XMP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL }, */
+#define T_XMP		0x0800, 0x00000,0x00000,0x367E0,0x36FFF,0x0875F,0x00001
+
 /*	Elements
 **	--------
 **
 **	Must match definitions in HTMLDTD.html!
 **	Must be in alphabetical order.
 **
-**    Name, 	Attributes, 		content
+**  The T_* extra info is listed here, but it won't matter (is not used
+**  in SGML.c if New_DTD is not set).  This mainly simplifies comparison
+**  of the tags_old[] table (otherwise unchanged from original Lynx treatment)
+**  with the tags_new[] table below. - kw
+**
+**    Name, 	Attributes, 	No. of attributes,     content,   extra info...
 */
-static HTTag tags[HTML_ELEMENTS] = {
-    { "A"	, a_attr,	HTML_A_ATTRIBUTES,	SGML_MIXED },
-    { "ABBREV"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "ACRONYM"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "ADDRESS"	, address_attr,	HTML_ADDRESS_ATTRIBUTES, SGML_MIXED },
-    { "APPLET"	, applet_attr,	HTML_APPLET_ATTRIBUTES, SGML_MIXED },
-    { "AREA"	, area_attr,	HTML_AREA_ATTRIBUTES,   SGML_EMPTY },
-    { "AU"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "AUTHOR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "B"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "BANNER"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "BASE"	, base_attr,	HTML_BASE_ATTRIBUTES,	SGML_EMPTY },
-    { "BASEFONT", font_attr,	HTML_FONT_ATTRIBUTES,	SGML_EMPTY },
-    { "BDO"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "BGSOUND"	, bgsound_attr,	HTML_BGSOUND_ATTRIBUTES, SGML_EMPTY },
-    { "BIG"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "BLINK"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "BLOCKQUOTE", bq_attr,	HTML_BQ_ATTRIBUTES,	SGML_MIXED },
-    { "BODY"	, body_attr,	HTML_BODY_ATTRIBUTES,	SGML_MIXED },
-    { "BODYTEXT", bodytext_attr,HTML_BODYTEXT_ATTRIBUTES, SGML_MIXED },
-    { "BQ"	, bq_attr,	HTML_BQ_ATTRIBUTES,	SGML_MIXED },
-    { "BR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY },
-    { "CAPTION"	, caption_attr,	HTML_CAPTION_ATTRIBUTES, SGML_MIXED },
-    { "CENTER"	, div_attr,	HTML_DIV_ATTRIBUTES,	SGML_MIXED },
-    { "CITE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "CODE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "COL"	, col_attr,	HTML_COL_ATTRIBUTES,	SGML_EMPTY },
-    { "COLGROUP", col_attr,	HTML_COL_ATTRIBUTES,	SGML_EMPTY },
-    { "COMMENT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "CREDIT"	, credit_attr,	HTML_CREDIT_ATTRIBUTES,	SGML_MIXED },
-    { "DD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY },
-    { "DEL"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "DFN"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "DIR"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED },
-    { "DIV"	, div_attr,	HTML_DIV_ATTRIBUTES,	SGML_MIXED },
-    { "DL"	, glossary_attr, HTML_DL_ATTRIBUTES,	SGML_MIXED },
-    { "DLC"	, glossary_attr, HTML_DL_ATTRIBUTES,	SGML_MIXED },
-    { "DT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY },
-    { "EM"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "EMBED"	, embed_attr,	HTML_EMBED_ATTRIBUTES,	SGML_EMPTY },
-    { "FIELDSET", fieldset_attr,HTML_FIELDSET_ATTRIBUTES, SGML_MIXED },
-    { "FIG"	, fig_attr,	HTML_FIG_ATTRIBUTES,	SGML_MIXED },
-    { "FN"	, fn_attr,	HTML_FN_ATTRIBUTES,	SGML_MIXED },
-    { "FONT"	, font_attr,	HTML_FONT_ATTRIBUTES,	SGML_EMPTY },
-    { "FORM"	, form_attr,	HTML_FORM_ATTRIBUTES,	SGML_EMPTY },
-    { "FRAME"	, frame_attr,	HTML_FRAME_ATTRIBUTES,	SGML_EMPTY },
-    { "FRAMESET", frameset_attr,HTML_FRAMESET_ATTRIBUTES, SGML_MIXED },
-    { "H1"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED },
-    { "H2"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED },
-    { "H3"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED },
-    { "H4"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED },
-    { "H5"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED },
-    { "H6"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED },
-    { "HEAD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "HR"	, hr_attr,	HTML_HR_ATTRIBUTES,	SGML_EMPTY },
-    { "HTML"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "I"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "IMG"     , img_attr,	HTML_IMG_ATTRIBUTES,	SGML_EMPTY },
-    { "INPUT"   , input_attr,	HTML_INPUT_ATTRIBUTES,	SGML_EMPTY },
-    { "INS"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "ISINDEX" , isindex_attr,	HTML_ISINDEX_ATTRIBUTES,SGML_EMPTY },
-    { "KBD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "KEYGEN"	, keygen_attr,	HTML_KEYGEN_ATTRIBUTES,	SGML_EMPTY },
-    { "LABEL"	, label_attr,	HTML_LABEL_ATTRIBUTES,	SGML_MIXED },
-    { "LH"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY },
-    { "LI"	, list_attr,	HTML_LI_ATTRIBUTES,	SGML_EMPTY },
-    { "LINK"	, link_attr,	HTML_LINK_ATTRIBUTES,	SGML_EMPTY },
-    { "LISTING"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL },
-    { "MAP"	, map_attr,	HTML_MAP_ATTRIBUTES,	SGML_MIXED },
-    { "MARQUEE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "MATH"	, math_attr,	HTML_MATH_ATTRIBUTES,	SGML_LITTERAL },
-    { "MENU"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED },
-    { "META"	, meta_attr,	HTML_META_ATTRIBUTES,	SGML_EMPTY },
-    { "NEXTID"  , nextid_attr,	1,			SGML_EMPTY },
-    { "NOFRAMES", gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "NOTE"	, note_attr,	HTML_NOTE_ATTRIBUTES,	SGML_MIXED },
-    { "OBJECT"	, object_attr,	HTML_OBJECT_ATTRIBUTES,	SGML_LITTERAL },
-    { "OL"	, olist_attr,	HTML_OL_ATTRIBUTES,	SGML_MIXED },
-    { "OPTION"	, option_attr,	HTML_OPTION_ATTRIBUTES,	SGML_EMPTY },
-    { "OVERLAY"	, overlay_attr,	HTML_OVERLAY_ATTRIBUTES, SGML_EMPTY },
-    { "P"	, p_attr,	HTML_P_ATTRIBUTES,	SGML_EMPTY },
-    { "PARAM"	, param_attr,	HTML_PARAM_ATTRIBUTES,	SGML_EMPTY },
-    { "PLAINTEXT", gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL },
-    { "PRE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "Q"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "S"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "SAMP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "SCRIPT"	, script_attr,	HTML_SCRIPT_ATTRIBUTES,	SGML_LITTERAL },
-    { "SELECT"	, select_attr,	HTML_SELECT_ATTRIBUTES,	SGML_MIXED },
-    { "SMALL"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "SPAN"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "SPOT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY },
-    { "STRIKE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "STRONG"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "STYLE"	, style_attr,	HTML_STYLE_ATTRIBUTES,	SGML_LITTERAL },
-    { "SUB"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "SUP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "TAB"	, tab_attr,	HTML_TAB_ATTRIBUTES,	SGML_EMPTY },
-    { "TABLE"	, table_attr,	HTML_TABLE_ATTRIBUTES,	SGML_MIXED },
-    { "TBODY"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY },
-    { "TD"	, td_attr,	HTML_TD_ATTRIBUTES,	SGML_EMPTY },
-    { "TEXTAREA", textarea_attr,HTML_TEXTAREA_ATTRIBUTES, SGML_LITTERAL },
-    { "TEXTFLOW", bodytext_attr,HTML_BODYTEXT_ATTRIBUTES, SGML_MIXED },
-    { "TFOOT"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY },
-    { "TH"	, td_attr,	HTML_TD_ATTRIBUTES,	SGML_EMPTY },
-    { "THEAD"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY },
-    { "TITLE", 	  gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_RCDATA },
-    { "TR"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY },
-    { "TT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "U"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "UL"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED },
-    { "VAR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED },
-    { "XMP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL },
+static HTTag tags_old[HTML_ELEMENTS] = {
+    { "A"	, a_attr,	HTML_A_ATTRIBUTES,	SGML_EMPTY,T_A},
+    { "ABBREV"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_ABBREV},
+    { "ACRONYM"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_ACRONYM},
+    { "ADDRESS"	, address_attr,	HTML_ADDRESS_ATTRIBUTES, SGML_MIXED,T_ADDRESS},
+    { "APPLET"	, applet_attr,	HTML_APPLET_ATTRIBUTES, SGML_MIXED,T_APPLET},
+    { "AREA"	, area_attr,	HTML_AREA_ATTRIBUTES,   SGML_EMPTY,T_AREA},
+    { "AU"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_AU},
+    { "AUTHOR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_AUTHOR},
+    { "B"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_B},
+    { "BANNER"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_BANNER},
+    { "BASE"	, base_attr,	HTML_BASE_ATTRIBUTES,	SGML_EMPTY,T_BASE},
+    { "BASEFONT", font_attr,	HTML_FONT_ATTRIBUTES,	SGML_EMPTY,T_BASEFONT},
+    { "BDO"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_BDO},
+    { "BGSOUND"	, bgsound_attr,	HTML_BGSOUND_ATTRIBUTES, SGML_EMPTY,T_BGSOUND},
+    { "BIG"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_BIG},
+    { "BLINK"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_BLINK},
+    { "BLOCKQUOTE", bq_attr,	HTML_BQ_ATTRIBUTES,	SGML_MIXED,T_BLOCKQUOTE},
+    { "BODY"	, body_attr,	HTML_BODY_ATTRIBUTES,	SGML_MIXED,T_BODY},
+    { "BODYTEXT", bodytext_attr,HTML_BODYTEXT_ATTRIBUTES, SGML_MIXED,T_BODYTEXT},
+    { "BQ"	, bq_attr,	HTML_BQ_ATTRIBUTES,	SGML_MIXED,T_BQ},
+    { "BR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_BR},
+    { "CAPTION"	, caption_attr,	HTML_CAPTION_ATTRIBUTES, SGML_MIXED,T_CAPTION},
+    { "CENTER"	, div_attr,	HTML_DIV_ATTRIBUTES,	SGML_MIXED,T_CENTER},
+    { "CITE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_CITE},
+    { "CODE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_CODE},
+    { "COL"	, col_attr,	HTML_COL_ATTRIBUTES,	SGML_EMPTY,T_COL},
+    { "COLGROUP", col_attr,	HTML_COL_ATTRIBUTES,	SGML_EMPTY,T_COLGROUP},
+    { "COMMENT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_COMMENT},
+    { "CREDIT"	, credit_attr,	HTML_CREDIT_ATTRIBUTES,	SGML_MIXED,T_CREDIT},
+    { "DD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_DD},
+    { "DEL"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_DEL},
+    { "DFN"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_DFN},
+    { "DIR"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED,T_DIR},
+    { "DIV"	, div_attr,	HTML_DIV_ATTRIBUTES,	SGML_MIXED,T_DIV},
+    { "DL"	, glossary_attr, HTML_DL_ATTRIBUTES,	SGML_MIXED,T_DL},
+    { "DLC"	, glossary_attr, HTML_DL_ATTRIBUTES,	SGML_MIXED,T_DLC},
+    { "DT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_DT},
+    { "EM"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_EM},
+    { "EMBED"	, embed_attr,	HTML_EMBED_ATTRIBUTES,	SGML_EMPTY,T_EMBED},
+    { "FIELDSET", fieldset_attr,HTML_FIELDSET_ATTRIBUTES, SGML_MIXED,T_FIELDSET},
+    { "FIG"	, fig_attr,	HTML_FIG_ATTRIBUTES,	SGML_MIXED,T_FIG},
+    { "FN"	, fn_attr,	HTML_FN_ATTRIBUTES,	SGML_MIXED,T_FN},
+    { "FONT"	, font_attr,	HTML_FONT_ATTRIBUTES,	SGML_EMPTY,T_FONT},
+    { "FORM"	, form_attr,	HTML_FORM_ATTRIBUTES,	SGML_EMPTY,T_FORM},
+    { "FRAME"	, frame_attr,	HTML_FRAME_ATTRIBUTES,	SGML_EMPTY,T_FRAME},
+    { "FRAMESET", frameset_attr,HTML_FRAMESET_ATTRIBUTES, SGML_MIXED,T_FRAMESET},
+    { "H1"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H1},
+    { "H2"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H2},
+    { "H3"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H3},
+    { "H4"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H4},
+    { "H5"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H5},
+    { "H6"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H6},
+    { "HEAD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_HEAD},
+    { "HR"	, hr_attr,	HTML_HR_ATTRIBUTES,	SGML_EMPTY,T_HR},
+    { "HTML"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_HTML},
+    { "HY"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_HY},
+    { "I"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_I},
+    { "IMG"     , img_attr,	HTML_IMG_ATTRIBUTES,	SGML_EMPTY,T_IMG},
+    { "INPUT"   , input_attr,	HTML_INPUT_ATTRIBUTES,	SGML_EMPTY,T_INPUT},
+    { "INS"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_INS},
+    { "ISINDEX" , isindex_attr,	HTML_ISINDEX_ATTRIBUTES,SGML_EMPTY,T_ISINDEX},
+    { "KBD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_KBD},
+    { "KEYGEN"	, keygen_attr,	HTML_KEYGEN_ATTRIBUTES,	SGML_EMPTY,T_KEYGEN},
+    { "LABEL"	, label_attr,	HTML_LABEL_ATTRIBUTES,	SGML_MIXED,T_LABEL},
+    { "LH"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_LH},
+    { "LI"	, list_attr,	HTML_LI_ATTRIBUTES,	SGML_EMPTY,T_LI},
+    { "LINK"	, link_attr,	HTML_LINK_ATTRIBUTES,	SGML_EMPTY,T_LINK},
+    { "LISTING"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL,T_LISTING},
+    { "MAP"	, map_attr,	HTML_MAP_ATTRIBUTES,	SGML_MIXED,T_MAP},
+    { "MARQUEE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_MARQUEE},
+    { "MATH"	, math_attr,	HTML_MATH_ATTRIBUTES,	SGML_LITTERAL,T_MATH},
+    { "MENU"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED,T_MENU},
+    { "META"	, meta_attr,	HTML_META_ATTRIBUTES,	SGML_EMPTY,T_META},
+    { "NEXTID"  , nextid_attr,	1,			SGML_EMPTY,T_NEXTID},
+    { "NOFRAMES", gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_NOFRAMES},
+    { "NOTE"	, note_attr,	HTML_NOTE_ATTRIBUTES,	SGML_MIXED,T_NOTE},
+    { "OBJECT"	, object_attr,	HTML_OBJECT_ATTRIBUTES,	SGML_LITTERAL,T_OBJECT},
+    { "OL"	, olist_attr,	HTML_OL_ATTRIBUTES,	SGML_MIXED,T_OL},
+    { "OPTION"	, option_attr,	HTML_OPTION_ATTRIBUTES,	SGML_EMPTY,T_OPTION},
+    { "OVERLAY"	, overlay_attr,	HTML_OVERLAY_ATTRIBUTES, SGML_EMPTY,T_OVERLAY},
+    { "P"	, p_attr,	HTML_P_ATTRIBUTES,	SGML_EMPTY,T_P},
+    { "PARAM"	, param_attr,	HTML_PARAM_ATTRIBUTES,	SGML_EMPTY,T_PARAM},
+    { "PLAINTEXT", gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL,T_PLAINTEXT},
+    { "PRE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_PRE},
+    { "Q"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_Q},
+    { "S"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_S},
+    { "SAMP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_SAMP},
+    { "SCRIPT"	, script_attr,	HTML_SCRIPT_ATTRIBUTES,	SGML_LITTERAL,T_SCRIPT},
+    { "SELECT"	, select_attr,	HTML_SELECT_ATTRIBUTES,	SGML_MIXED,T_SELECT},
+    { "SHY"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_SHY},
+    { "SMALL"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_SMALL},
+    { "SPAN"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_SPAN},
+    { "SPOT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_SPOT},
+    { "STRIKE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_STRIKE},
+    { "STRONG"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_STRONG},
+    { "STYLE"	, style_attr,	HTML_STYLE_ATTRIBUTES,	SGML_LITTERAL,T_STYLE},
+    { "SUB"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_SUB},
+    { "SUP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_SUP},
+    { "TAB"	, tab_attr,	HTML_TAB_ATTRIBUTES,	SGML_EMPTY,T_TAB},
+    { "TABLE"	, table_attr,	HTML_TABLE_ATTRIBUTES,	SGML_MIXED,T_TABLE},
+    { "TBODY"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY,T_TBODY},
+    { "TD"	, td_attr,	HTML_TD_ATTRIBUTES,	SGML_EMPTY,T_TD},
+    { "TEXTAREA", textarea_attr,HTML_TEXTAREA_ATTRIBUTES, SGML_LITTERAL,T_TEXTAREA},
+    { "TEXTFLOW", bodytext_attr,HTML_BODYTEXT_ATTRIBUTES, SGML_MIXED,T_TEXTFLOW},
+    { "TFOOT"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY,T_TFOOT},
+    { "TH"	, td_attr,	HTML_TD_ATTRIBUTES,	SGML_EMPTY,T_TH},
+    { "THEAD"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY,T_THEAD},
+    { "TITLE", 	  gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_RCDATA,T_TITLE},
+    { "TR"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_EMPTY,T_TR},
+    { "TT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_TT},
+    { "U"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_U},
+    { "UL"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED,T_UL},
+    { "VAR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_VAR},
+    { "WBR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_WBR},
+    { "XMP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL,T_XMP},
 };
 
+static HTTag tags_new[HTML_ELEMENTS] = {
+    { "A"	, a_attr,	HTML_A_ATTRIBUTES,	SGML_MIXED,T_A},
+    { "ABBREV"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_ABBREV},
+    { "ACRONYM"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_ACRONYM},
+    { "ADDRESS"	, address_attr,	HTML_ADDRESS_ATTRIBUTES, SGML_MIXED,T_ADDRESS},
+    { "APPLET"	, applet_attr,	HTML_APPLET_ATTRIBUTES, SGML_MIXED,T_APPLET},
+    { "AREA"	, area_attr,	HTML_AREA_ATTRIBUTES,   SGML_EMPTY,T_AREA},
+    { "AU"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_AU},
+    { "AUTHOR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_AUTHOR},
+    { "B"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_B},
+    { "BANNER"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_BANNER},
+    { "BASE"	, base_attr,	HTML_BASE_ATTRIBUTES,	SGML_EMPTY,T_BASE},
+    { "BASEFONT", font_attr,	HTML_FONT_ATTRIBUTES,	SGML_EMPTY,T_BASEFONT},
+    { "BDO"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_BDO},
+    { "BGSOUND"	, bgsound_attr,	HTML_BGSOUND_ATTRIBUTES, SGML_EMPTY,T_BGSOUND},
+    { "BIG"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_BIG},
+    { "BLINK"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_BLINK},
+    { "BLOCKQUOTE", bq_attr,	HTML_BQ_ATTRIBUTES,	SGML_MIXED,T_BLOCKQUOTE},
+    { "BODY"	, body_attr,	HTML_BODY_ATTRIBUTES,	SGML_MIXED,T_BODY},
+    { "BODYTEXT", bodytext_attr,HTML_BODYTEXT_ATTRIBUTES, SGML_MIXED,T_BODYTEXT},
+    { "BQ"	, bq_attr,	HTML_BQ_ATTRIBUTES,	SGML_MIXED,T_BQ},
+    { "BR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_BR},
+    { "CAPTION"	, caption_attr,	HTML_CAPTION_ATTRIBUTES, SGML_MIXED,T_CAPTION},
+    { "CENTER"	, div_attr,	HTML_DIV_ATTRIBUTES,	SGML_MIXED,T_CENTER},
+    { "CITE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_CITE},
+    { "CODE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_CODE},
+    { "COL"	, col_attr,	HTML_COL_ATTRIBUTES,	SGML_EMPTY,T_COL},
+    { "COLGROUP", col_attr,	HTML_COL_ATTRIBUTES,	SGML_ELEMENT,T_COLGROUP},
+    { "COMMENT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_PCDATA,T_COMMENT},
+    { "CREDIT"	, credit_attr,	HTML_CREDIT_ATTRIBUTES,	SGML_MIXED,T_CREDIT},
+    { "DD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_DD},
+    { "DEL"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_DEL},
+    { "DFN"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_DFN},
+    { "DIR"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED,T_DIR},
+    { "DIV"	, div_attr,	HTML_DIV_ATTRIBUTES,	SGML_MIXED,T_DIV},
+    { "DL"	, glossary_attr, HTML_DL_ATTRIBUTES,	SGML_MIXED,T_DL},
+    { "DLC"	, glossary_attr, HTML_DL_ATTRIBUTES,	SGML_MIXED,T_DLC},
+    { "DT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_DT},
+    { "EM"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_EM},
+    { "EMBED"	, embed_attr,	HTML_EMBED_ATTRIBUTES,	SGML_EMPTY,T_EMBED},
+    { "FIELDSET", fieldset_attr,HTML_FIELDSET_ATTRIBUTES, SGML_MIXED,T_FIELDSET},
+    { "FIG"	, fig_attr,	HTML_FIG_ATTRIBUTES,	SGML_MIXED,T_FIG},
+    { "FN"	, fn_attr,	HTML_FN_ATTRIBUTES,	SGML_MIXED,T_FN},
+    { "FONT"	, font_attr,	HTML_FONT_ATTRIBUTES,	SGML_MIXED,T_FONT},
+    { "FORM"	, form_attr,	HTML_FORM_ATTRIBUTES,	SGML_MIXED,T_FORM},
+    { "FRAME"	, frame_attr,	HTML_FRAME_ATTRIBUTES,	SGML_EMPTY,T_FRAME},
+    { "FRAMESET", frameset_attr,HTML_FRAMESET_ATTRIBUTES, SGML_ELEMENT,T_FRAMESET},
+    { "H1"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H1},
+    { "H2"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H2},
+    { "H3"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H3},
+    { "H4"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H4},
+    { "H5"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H5},
+    { "H6"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H6},
+    { "HEAD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_HEAD},
+    { "HR"	, hr_attr,	HTML_HR_ATTRIBUTES,	SGML_EMPTY,T_HR},
+    { "HTML"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_HTML},
+    { "HY"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_HY},
+    { "I"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_I},
+    { "IMG"     , img_attr,	HTML_IMG_ATTRIBUTES,	SGML_EMPTY,T_IMG},
+    { "INPUT"   , input_attr,	HTML_INPUT_ATTRIBUTES,	SGML_EMPTY,T_INPUT},
+    { "INS"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_INS},
+    { "ISINDEX" , isindex_attr,	HTML_ISINDEX_ATTRIBUTES,SGML_EMPTY,T_ISINDEX},
+    { "KBD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_KBD},
+    { "KEYGEN"	, keygen_attr,	HTML_KEYGEN_ATTRIBUTES,	SGML_EMPTY,T_KEYGEN},
+    { "LABEL"	, label_attr,	HTML_LABEL_ATTRIBUTES,	SGML_MIXED,T_LABEL},
+    { "LH"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_LH},
+    { "LI"	, list_attr,	HTML_LI_ATTRIBUTES,	SGML_MIXED,T_LI},
+    { "LINK"	, link_attr,	HTML_LINK_ATTRIBUTES,	SGML_EMPTY,T_LINK},
+    { "LISTING"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL,T_LISTING},
+    { "MAP"	, map_attr,	HTML_MAP_ATTRIBUTES,	SGML_MIXED,T_MAP},
+    { "MARQUEE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_MARQUEE},
+    { "MATH"	, math_attr,	HTML_MATH_ATTRIBUTES,	SGML_LITTERAL,T_MATH},
+    { "MENU"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED,T_MENU},
+    { "META"	, meta_attr,	HTML_META_ATTRIBUTES,	SGML_EMPTY,T_META},
+    { "NEXTID"  , nextid_attr,	1,			SGML_EMPTY,T_NEXTID},
+    { "NOFRAMES", gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_NOFRAMES},
+    { "NOTE"	, note_attr,	HTML_NOTE_ATTRIBUTES,	SGML_MIXED,T_NOTE},
+    { "OBJECT"	, object_attr,	HTML_OBJECT_ATTRIBUTES,	SGML_LITTERAL,T_OBJECT},
+    { "OL"	, olist_attr,	HTML_OL_ATTRIBUTES,	SGML_MIXED,T_OL},
+    { "OPTION"	, option_attr,	HTML_OPTION_ATTRIBUTES,	SGML_PCDATA,T_OPTION},
+    { "OVERLAY"	, overlay_attr,	HTML_OVERLAY_ATTRIBUTES, SGML_PCDATA,T_OVERLAY},
+    { "P"	, p_attr,	HTML_P_ATTRIBUTES,	SGML_MIXED,T_P},
+    { "PARAM"	, param_attr,	HTML_PARAM_ATTRIBUTES,	SGML_EMPTY,T_PARAM},
+    { "PLAINTEXT", gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL,T_PLAINTEXT},
+    { "PRE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_PRE},
+    { "Q"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_Q},
+    { "S"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_S},
+    { "SAMP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_SAMP},
+    { "SCRIPT"	, script_attr,	HTML_SCRIPT_ATTRIBUTES,	SGML_LITTERAL,T_SCRIPT},
+    { "SELECT"	, select_attr,	HTML_SELECT_ATTRIBUTES,	SGML_ELEMENT,T_SELECT},
+    { "SHY"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_SHY},
+    { "SMALL"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_SMALL},
+    { "SPAN"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_SPAN},
+    { "SPOT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_SPOT},
+    { "STRIKE"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_STRIKE},
+    { "STRONG"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_STRONG},
+    { "STYLE"	, style_attr,	HTML_STYLE_ATTRIBUTES,	SGML_LITTERAL,T_STYLE},
+    { "SUB"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_SUB},
+    { "SUP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_SUP},
+    { "TAB"	, tab_attr,	HTML_TAB_ATTRIBUTES,	SGML_EMPTY,T_TAB},
+    { "TABLE"	, table_attr,	HTML_TABLE_ATTRIBUTES,	SGML_ELEMENT,T_TABLE},
+    { "TBODY"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_ELEMENT,T_TBODY},
+    { "TD"	, td_attr,	HTML_TD_ATTRIBUTES,	SGML_MIXED,T_TD},
+    { "TEXTAREA", textarea_attr,HTML_TEXTAREA_ATTRIBUTES, SGML_LITTERAL,T_TEXTAREA},
+    { "TEXTFLOW", bodytext_attr,HTML_BODYTEXT_ATTRIBUTES, SGML_MIXED,T_TEXTFLOW},
+    { "TFOOT"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_ELEMENT,T_TFOOT},
+    { "TH"	, td_attr,	HTML_TD_ATTRIBUTES,	SGML_MIXED,T_TH},
+    { "THEAD"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_ELEMENT,T_THEAD},
+    { "TITLE", 	  gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_PCDATA,T_TITLE},
+    { "TR"	, tr_attr,	HTML_TR_ATTRIBUTES,	SGML_MIXED,T_TR},
+    { "TT"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_TT},
+    { "U"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_U},
+    { "UL"	, ulist_attr,	HTML_UL_ATTRIBUTES,	SGML_MIXED,T_UL},
+    { "VAR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_VAR},
+    { "WBR"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_WBR},
+    { "XMP"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_LITTERAL,T_XMP},
+};
+
+/* Dummy space, will be filled with the contents of either tags_new
+   or tags_old on calling HTSwitchDTD - kw */
+
+static HTTag tags[HTML_ELEMENTS];
+
 PUBLIC CONST SGML_dtd HTML_dtd = {
 	tags,
 	HTML_ELEMENTS,
@@ -1235,6 +1651,25 @@ PUBLIC CONST SGML_dtd HTML_dtd = {
 #endif
 };
 
+/* This function fills the "tags" part of the HTML_dtd structure with
+   what we want to use, either tags_old or tags_new.  Note that it
+   has to be called at least once before HTML_dtd is used, otherwise
+   the HTML_dtd contents will be invalid!  This could be coded in a way
+   that would make an initialisation call unnecessary, but my C knowledge
+   is limited and I didn't want to list the whole tags_new table
+   twice... - kw */
+PUBLIC void HTSwitchDTD ARGS1(
+    BOOL,		new)
+{
+    if (TRACE)
+	fprintf(stderr,"HTMLDTD: Copying DTD element info of size %d, %d * %d\n",
+		new ? sizeof(tags_new) : sizeof(tags_old),
+		HTML_ELEMENTS, sizeof(HTTag));
+    if (new)
+	memcpy(tags, tags_new, HTML_ELEMENTS * sizeof(HTTag));
+    else
+	memcpy(tags, tags_old, HTML_ELEMENTS * sizeof(HTTag));
+}
 
 /*
 **	Utility Routine:  Useful for people building HTML objects.
diff --git a/WWW/Library/Implementation/HTMLDTD.h b/WWW/Library/Implementation/HTMLDTD.h
index ef6c5fbb..09b6936a 100644
--- a/WWW/Library/Implementation/HTMLDTD.h
+++ b/WWW/Library/Implementation/HTMLDTD.h
@@ -85,6 +85,7 @@ typedef enum _HTMLElement {
 	HTML_HEAD,
 	HTML_HR,
 	HTML_HTML,
+	HTML_HY,
         HTML_I,
 	HTML_IMG,
 	HTML_INPUT,
@@ -118,6 +119,7 @@ typedef enum _HTMLElement {
         HTML_SAMP,
 	HTML_SCRIPT,
 	HTML_SELECT,
+	HTML_SHY,
         HTML_SMALL,
 	HTML_SPAN,
 	HTML_SPOT,
@@ -141,9 +143,10 @@ typedef enum _HTMLElement {
         HTML_U,
 	HTML_UL,
         HTML_VAR,
+        HTML_WBR,
 	HTML_XMP } HTMLElement;
 
-#define HTML_ELEMENTS 112
+#define HTML_ELEMENTS 115
 
 /*
 
@@ -855,6 +858,9 @@ Attribute numbers
 
 extern CONST SGML_dtd HTML_dtd;
 
+extern void HTSwitchDTD PARAMS((
+    BOOL new));
+
 /*
 
 Start anchor element
diff --git a/WWW/Library/Implementation/HTNews.c b/WWW/Library/Implementation/HTNews.c
index 0de7fb71..b915e1e3 100644
--- a/WWW/Library/Implementation/HTNews.c
+++ b/WWW/Library/Implementation/HTNews.c
@@ -83,6 +83,8 @@ PRIVATE int	diagnostic;			/* level: 0=none 2=source */
 #define PUTS(s) (*targetClass.put_string)(target, s)
 #define START(e) (*targetClass.start_element)(target, e, 0, 0, 0)
 #define END(e) (*targetClass.end_element)(target, e, 0)
+#define MAYBE_END(e) if (HTML_dtd.tags[e].contents != SGML_EMPTY) \
+                        (*targetClass.end_element)(target, e, 0)
 
 PRIVATE void free_news_globals NOARGS
 {
@@ -834,6 +836,7 @@ PRIVATE int read_article NOARGS
 		PUTS(from);
 	    else
 		PUTS(from);
+	    MAYBE_END(HTML_DT);
 	    PUTC('\n');
 
 	    if (!replyto)
@@ -850,6 +853,7 @@ PRIVATE int read_article NOARGS
     	        PUTS(author_address(replyto));
      	    END(HTML_A);
 	    START(HTML_BR);
+	    MAYBE_END(HTML_DT);
 	    PUTC('\n');
 
 	    FREE(from);
@@ -863,6 +867,7 @@ PRIVATE int read_article NOARGS
 	    END(HTML_B);
             PUTC(' ');
 	    PUTS(date);
+	    MAYBE_END(HTML_DT);
 	    PUTC('\n');
 	    FREE(date);
 	}
@@ -874,6 +879,7 @@ PRIVATE int read_article NOARGS
 	    END(HTML_B);
             PUTC(' ');
 	    PUTS(organization);
+	    MAYBE_END(HTML_DT);
 	    PUTC('\n');
 	    FREE(organization);
 	}
@@ -897,8 +903,10 @@ PRIVATE int read_article NOARGS
 	    PUTS("Newsgroups:");
 	    END(HTML_B);
 	    PUTC('\n');
+	    MAYBE_END(HTML_DT);
 	    START(HTML_DD);
 	    write_anchors(newsgroups);
+	    MAYBE_END(HTML_DD);
 	    PUTC('\n');
 
 	    START(HTML_DT);
@@ -909,6 +917,7 @@ PRIVATE int read_article NOARGS
             start_anchor(href);
             PUTS("newsgroup(s)");
             END(HTML_A);
+	    MAYBE_END(HTML_DT);
 	    PUTC('\n');
 	}
 	FREE(newsgroups);
@@ -919,9 +928,11 @@ PRIVATE int read_article NOARGS
 	    START(HTML_B);
 	    PUTS("References:");
 	    END(HTML_B);
+	    MAYBE_END(HTML_DT);
 	    PUTC('\n');
 	    START(HTML_DD);
 	    write_anchors(references);
+	    MAYBE_END(HTML_DD);
 	    PUTC('\n');
 	    FREE(references);
 	}
@@ -996,7 +1007,7 @@ PRIVATE int read_article NOARGS
 		    char *l = line;
 		    char *p;
 
-		    while ((p = strstr(l, "rticle <")) != 0) {
+		    while ((p = strstr(l, "rticle <")) != NULL) {
 		        char *q  = strchr(p,'>');
 		        char *at = strchr(p, '@');
 		        if (q && at && at<q) {
@@ -1163,12 +1174,13 @@ PRIVATE int read_list ARGS1(char *, arg)
 	    if (TRACE)
 	        fprintf(stderr, "B %s", line);
 	    if (line[0] == '.') {
-		if (line[1] < ' ') {		/* End of article? */
+		if ((unsigned char)line[1] < ' ') {		/* End of article? */
 		    done = YES;
 		    break;
 		} else {			/* Line starts with dot */
 		    START(HTML_DT);
 		    PUTS(&line[1]);
+		    MAYBE_END(HTML_DT);
 		}
 	    } else if (line[0] == '#') {	/* Comment? */
 	        p = line;			/* Restart at beginning */
@@ -1194,9 +1206,11 @@ PRIVATE int read_list ARGS1(char *, arg)
 		    START(HTML_DT);
 		    write_anchor(line, line);
 		    listing++;
+		    MAYBE_END(HTML_DT);
 		    PUTC('\n');
     	            START(HTML_DD);
 		    PUTS(&line[i+1]); /* put description */
+		    MAYBE_END(HTML_DD);
 		} else {
 		    if ((head && strncasecomp(line, pattern, len)) ||
 		        (tail && (i < len ||
@@ -1206,6 +1220,7 @@ PRIVATE int read_list ARGS1(char *, arg)
 		    }
 		    START(HTML_DT);
 		    write_anchor(line, line);
+		    MAYBE_END(HTML_DT);
 		    listing++;
 		}
 	    } /* if not dot */
@@ -1216,6 +1231,7 @@ PRIVATE int read_list ARGS1(char *, arg)
         START(HTML_DT);
 	sprintf(line, "No matches for: %s", arg);
 	PUTS(line);
+	MAYBE_END(HTML_DT);
     }
     END(HTML_DLC);
     PUTC('\n');
@@ -1536,6 +1552,7 @@ PRIVATE int read_group ARGS3(
 		    PUTS(buffer);
 		    FREE(date);
 		}
+		MAYBE_END(HTML_LI);
 		/*
 		**  Indicate progress!   @@@@@@
 		*/
@@ -1563,6 +1580,7 @@ PRIVATE int read_group ARGS3(
 		END(HTML_I);
 		PUTC(' ');
 		PUTS(response_text);
+		MAYBE_END(HTML_LI);
 	    } /* Handle response to HEAD request */
 	} /* Loop over article */	    
     } /* If read headers */
@@ -1858,7 +1876,7 @@ PUBLIC int HTLoadNews ARGS4(
 	    if (TRACE)
 		fprintf(stderr,
 	      		"HTNews: Proxy command is '%.*s'\n",
-			(strlen(proxycmd) - 4), proxycmd);
+			(int)(strlen(proxycmd) - 4), proxycmd);
 	    strcat(command, "/");
 	    StrAllocCopy(ProxyHREF, NewsHREF);
 	    StrAllocCopy(NewsHREF, command);
diff --git a/WWW/Library/Implementation/HTTCP.c b/WWW/Library/Implementation/HTTCP.c
index 710005ab..b3c3b16e 100644
--- a/WWW/Library/Implementation/HTTCP.c
+++ b/WWW/Library/Implementation/HTTCP.c
@@ -784,6 +784,14 @@ PUBLIC int HTDoConnect ARGS4(
 	    else
 #endif /* SOCKS */
             ret = select(FD_SETSIZE, NULL, (void *)&writefds, NULL, &timeout);
+
+	   /*
+	   **  If we suspend, then it is possible that select will be 
+	   **  interrupted.  Allow for this possibility. - JED
+	   */
+	   if ((ret == -1) && (errno == EINTR))
+	     continue;
+
             /*
             **  Again according to the Sun and Motorola man pagse for connect:
             **     EALREADY            The socket is non-blocking and a  previ-
@@ -940,16 +948,25 @@ PUBLIC int HTDoRead ARGS3(
 	    return HT_INTERRUPTED;
 	}
 
-        timeout.tv_sec = 0;
-	timeout.tv_usec = 100000;
-        FD_ZERO(&readfds);
-        FD_SET(fildes, &readfds);
+	/*
+	**  If we suspend, then it is possible that select will be 
+	**  interrupted.  Allow for this possibility. - JED
+	*/
+        do {
+	    timeout.tv_sec = 0;
+	    timeout.tv_usec = 100000;
+	    FD_ZERO(&readfds);
+	    FD_SET(fildes, &readfds);
 #ifdef SOCKS
-	if (socks_flag)
-            ret = Rselect(FD_SETSIZE, (void *)&readfds, NULL, NULL, &timeout);
-	else
+	    if (socks_flag)
+	        ret = Rselect(FD_SETSIZE,
+			      (void *)&readfds, NULL, NULL, &timeout);
+	    else
 #endif /* SOCKS */
-        ret = select(FD_SETSIZE, (void *)&readfds, NULL, NULL, &timeout);
+		ret = select(FD_SETSIZE,
+			     (void *)&readfds, NULL, NULL, &timeout);
+	} while ((ret == -1) && (errno == EINTR));
+
         if (ret < 0) {
             return -1;
         } else if (ret > 0) {
diff --git a/WWW/Library/Implementation/HTTP.c b/WWW/Library/Implementation/HTTP.c
index e78870d6..e617b9c8 100644
--- a/WWW/Library/Implementation/HTTP.c
+++ b/WWW/Library/Implementation/HTTP.c
@@ -3,6 +3,7 @@
 ** Modified:
 ** 27 Jan 1994  PDM  Added Ari Luotonen's Fix for Reload when using proxy
 **                   servers.
+** 28 Apr 1997  AJL,FM Do Proxy Authorisation.
 */
 
 #include "HTUtils.h"
@@ -50,6 +51,7 @@ 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 auth_proxy = NO;	/* Generate a proxy authentication. - AJL */
 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? */
@@ -391,37 +393,94 @@ try_again:
 	}
 
 	/*
-	**  Add 'Cookie:' header, if applicable.
+	**  Add Authorization, Proxy-Authorization,
+	**  and/or Cookie headers, if applicable.
 	*/
 	if (using_proxy) {
 	    /*
-	    **  If it's not an HTTP or HTTPS document being proxied,
-	    **  forget about cookies.
+	    **  If we are using a proxy, first determine if
+	    **  we should include an Authorization header
+	    **  and/or Cookie header for the ultimate target
+	    **  of this request. - FM & AJL
 	    */
-	    if (!strncmp(docname, "http", 4)) {
-		char *host2 = NULL, *path2 = NULL;
-		int port = (strncmp(docname, "https", 5) ?
-					       HTTP_PORT : HTTPS_PORT);
-
-		host2 = HTParse(docname, "", PARSE_HOST);
-		path2 = HTParse(docname, "", PARSE_PATH|PARSE_PUNCTUATION);
-		if (host2) {
-		    if ((colon = strchr(host2, ':')) != NULL) {
-		        /*
-			**  Use non-default port number.
-			*/
-		        *colon = '\0';
-			colon++;
-			port = atoi(colon);
-		    }
+	    char *host2 = NULL, *path2 = NULL;
+	    int port2 = (strncmp(docname, "https", 5) ?
+					   HTTP_PORT : HTTPS_PORT);
+	    host2 = HTParse(docname, "", PARSE_HOST);
+	    path2 = HTParse(docname, "", PARSE_PATH|PARSE_PUNCTUATION);
+	    if (host2) {
+		if ((colon = strchr(host2, ':')) != NULL) {
+		    /* Use non-default port number */
+		    *colon = '\0';
+		    colon++;
+		    port2 = atoi(colon);
+		}
+	    }
+	    /*
+	    **  This composeAuth() does file access, i.e., for
+	    **  the ultimate target of the request. - AJL
+	    */
+	    auth_proxy = NO;
+	    if ((auth = HTAA_composeAuth(host2, port2, path2)) != NULL &&
+		*auth != '\0') {
+		/*
+		**  If auth is not NULL nor zero-length, it's
+		**  an Authorization header to be included. - FM
+		*/ 
+		sprintf(line, "%s%c%c", auth, CR, LF);
+		StrAllocCat(command, line);
+		if (TRACE)
+		    fprintf(stderr, "HTTP: Sending authorization: %s\n", auth);
+	    } else if (auth && *auth == '\0') {
+		/*
+		**  If auth is a zero-length string, the user either
+		**  cancelled or goofed at the username and password
+		**  prompt. - FM
+		*/
+		if (!(traversal || dump_output_immediately) &&
+			HTConfirm(
+			    "Proceed without a username and password?")) {
+		    show_401 = TRUE;
+		} else {
+		    if (traversal || dump_output_immediately)
+			HTAlert(
+			    "Can't proceed without a username and password.");
+		    FREE(command);
+		    FREE(hostname);
+		    FREE(docname);
+		    FREE(host2);
+		    FREE(path2);
+		    status = HT_NOT_LOADED;
+		    goto done;
 		}
-		cookie = LYCookie(host2, path2, port, secure);
-		FREE(host2);
-		FREE(path2);
+	    } else {
+		if (TRACE)
+		    fprintf(stderr,
+		    	    "HTTP: Not sending authorization (yet)\n");
+	    }
+	    /*
+	    **  Add 'Cookie:' header, if it's HTTP or HTTPS
+	    **  document being proxied.
+	    */
+	    if (!strncmp(docname, "http", 4)) {
+		cookie = LYCookie(host2, path2, port2, secure);
 	    }
+	    FREE(host2);
+	    FREE(path2);
+	    /*
+	    **  The next composeAuth() will be for the proxy. - AJL
+	    */
+	    auth_proxy = YES;
 	} else {
+	    /*
+	    **  Add cookie for a non-proxied request. - FM
+	    */
 	    cookie = LYCookie(hostname, abspath, portnumber, secure);
+	    auth_proxy = NO;
 	}
+	/*
+	**  If we do have a cookie set, add it to the request buffer. - FM
+	*/
 	if (cookie != NULL) {
 	    if (*cookie != '\0') {
 	        StrAllocCat(command, "Cookie: ");
@@ -434,16 +493,29 @@ try_again:
 	}
 	FREE(abspath);
 
-        if ((auth = HTAA_composeAuth(hostname, portnumber, docname)) != NULL &&
+	/*
+	**  If we are using a proxy, auth_proxy should be YES, and
+	**  we check here whether we want a Proxy-Authorization header
+	**  for it.  If we are not using a proxy, auth_proxy should
+	**  still be NO, and we check here for whether we want an
+	**  Authorization header. - FM & AJL
+	*/
+        if ((auth = HTAA_composeAuth(hostname,
+				     portnumber, docname)) != NULL &&
 	    *auth != '\0') {
 	    /*
 	    **  If auth is not NULL nor zero-length, it's
-	    **  an Authorization header to be included. - FM
+	    **  an Authorization or Proxy-Authorization
+	    **  header to be included. - FM
 	    */ 
             sprintf(line, "%s%c%c", auth, CR, LF);
             StrAllocCat(command, line);
 	    if (TRACE)
-                fprintf(stderr, "HTTP: Sending authorization: %s\n", auth);
+                fprintf(stderr,
+			(using_proxy ?
+			 "HTTP: Sending proxy authorization: %s\n" :
+			 "HTTP: Sending authorization: %s\n"),
+			auth);
 	} else if (auth && *auth == '\0') {
 	    /*
 	    **  If auth is a zero-length string, the user either
@@ -464,7 +536,10 @@ try_again:
 	    }
         } else {
 	    if (TRACE)
-                fprintf(stderr, "HTTP: Not sending authorization (yet)\n");
+                fprintf(stderr,
+			(using_proxy ?
+			 "HTTP: Not sending proxy authorization (yet).\n" :
+			 "HTTP: Not sending authorization (yet).\n"));
         }
         FREE(hostname);
         FREE(docname);
@@ -1229,6 +1304,7 @@ Cookie_continuation:
 		 *  to show the 401 body or restore the current
 		 *  document. - FM
 		 */
+		auth_proxy = NO;
 		if (show_401)
 		    break;
 		if (HTAA_shouldRetryWithAuth(start_of_data, length,
@@ -1271,17 +1347,55 @@ Cookie_continuation:
 
 	      case 407:
 	        /*
-		 *  Proxy Authentication Required.  We'll handle
-		 *  Proxy-Authenticate headers and retry with a
-		 *  Proxy-Authorization header, someday, but for
-		 *  now, apologized to the user and restore the
-		 *  current document. - FM
+		 *  Authorization for proxy server required.
+		 *  If we are not in fact using a proxy, or
+		 *  show_401 is set, proceed to showing the
+		 *  407 body.  Otherwise, if we can set up
+		 *  authorization based on the Proxy-Authenticate
+		 *  header, and the user provides a username and
+		 *  password, try again.  Otherwise, check whether
+		 *  to show the 401 body or restore the current
+		 *  document. - FM & AJL
 		 */
-	        HTAlert(
-		 "Proxy Authentication Required.  Sorry, not yet supported.");
-                HTTP_NETCLOSE(s, handle);
-	        status = HT_NO_DATA;
-	        goto done;
+		if (!using_proxy || show_401)
+		    break;
+		auth_proxy = YES;
+		if (HTAA_shouldRetryWithAuth(start_of_data, length,
+					     (void *)handle, s)) {
+ 		    extern char *authentication_info[2];
+
+                    HTTP_NETCLOSE(s, handle);
+                    if (dump_output_immediately && !authentication_info[0]) {
+                        fprintf(stderr,
+		      		"HTTP: Proxy authorization required.\n");
+                        fprintf(stderr,
+		      		"       Use the -auth=id:pw parameter.\n");
+                        status = HT_NO_DATA;
+                        goto clean_up;
+                    }
+
+                    if (TRACE) 
+                        fprintf(stderr, "%s %d %s\n",
+                              "HTTP: close socket", s,
+                              "to retry with Proxy Authorization");
+
+                    _HTProgress (
+		    	"Retrying with proxy authorization information.");
+		    FREE(line_buffer);
+		    FREE(line_kept_clean);
+                    goto try_again;
+                    break;
+		} else if (!(traversal || dump_output_immediately) &&
+		           HTConfirm("Show the 407 message body?")) {
+		    break;
+                } else {
+		    if (traversal || dump_output_immediately)
+		        HTAlert(
+	"Can't retry with proxy authorization!  Contact the server's WebMaster.");
+		    HTTP_NETCLOSE(s, handle);
+                    status = -1;
+                    goto clean_up;
+		}
 		break;
 
 	      case 408:
diff --git a/WWW/Library/Implementation/HTTelnet.c b/WWW/Library/Implementation/HTTelnet.c
index 99b91295..a09bc6d8 100644
--- a/WWW/Library/Implementation/HTTelnet.c
+++ b/WWW/Library/Implementation/HTTelnet.c
@@ -33,9 +33,9 @@
 #include "HTAlert.h"
 #if !defined (VMS) && !defined (_WINDOWS)
 #include "../../../userdefs.h"  /* for TELNET_COMMAND and RLOGIN_COMMAND */
-#endif /* not VMS or _WINDOWS */
+#endif /* not VMS */
 
-#ifdef _WINDOWS /* ../../.. doesn't work for me WB */
+#ifdef _WINDOWS /* ../../.. doesn't work for me */
 #include "userdefs.h"  /* for TELNET_COMMAND and RLOGIN_COMMAND */
 #endif
 
diff --git a/WWW/Library/Implementation/HTUtils.h b/WWW/Library/Implementation/HTUtils.h
index 2c5576b5..536dad08 100644
--- a/WWW/Library/Implementation/HTUtils.h
+++ b/WWW/Library/Implementation/HTUtils.h
@@ -115,9 +115,14 @@ SOLARIS 2
 #define HAVE_GETCWD 1
 #endif
 
+#ifndef USE_SLANG
 #ifndef NO_KEYPAD
 #define HAVE_KEYPAD 1
 #endif
+#ifndef NO_TTYTYPE
+#define HAVE_TTYTYPE 1
+#endif
+#endif /* USE_SLANG */
 
 #ifndef NO_PUTENV
 #define HAVE_PUTENV 1
@@ -127,10 +132,6 @@ SOLARIS 2
 #define HAVE_SIZECHANGE 1
 #endif
 
-#ifndef NO_TTYTYPE
-#define HAVE_TTYTYPE 1
-#endif
-
 #ifndef NO_UNISTD_H
 #define HAVE_UNISTD_H 1
 #endif
diff --git a/WWW/Library/Implementation/HTWAIS.c b/WWW/Library/Implementation/HTWAIS.c
index 264ce263..2bc4c4f6 100644
--- a/WWW/Library/Implementation/HTWAIS.c
+++ b/WWW/Library/Implementation/HTWAIS.c
@@ -107,6 +107,8 @@ PRIVATE char	line[2048];	/* For building strings to display */
 #define PUTS(s) (*target->isa->put_string)(target, s)
 #define START(e) (*target->isa->start_element)(target, e, 0, 0, 0)
 #define END(e) (*target->isa->end_element)(target, e, 0)
+#define MAYBE_END(e) if (HTML_dtd.tags[e].contents != SGML_EMPTY) \
+                        (*target->isa->end_element)(target, e, 0)
 #define FREE_TARGET (*target->isa->_free)(target)
 
 struct _HTStructured {
@@ -562,6 +564,7 @@ PRIVATE void display_search_response ARGS4(
 	    		head->Score,
 	    		head->Lines);
 		PUTS( line);
+	        MAYBE_END(HTML_LI);
       	    } /* next document header */
     	} /* if there were any document headers */
     
diff --git a/WWW/Library/Implementation/HTWSRC.c b/WWW/Library/Implementation/HTWSRC.c
index cca6394d..3d3647b3 100644
--- a/WWW/Library/Implementation/HTWSRC.c
+++ b/WWW/Library/Implementation/HTWSRC.c
@@ -39,6 +39,8 @@ struct _HTStructured {
 #define PUTS(s) (*me->target->isa->put_string)(me->target, s)
 #define START(e) (*me->target->isa->start_element)(me->target, e, 0, 0, 0)
 #define END(e) (*me->target->isa->end_element)(me->target, e, 0)
+#define MAYBE_END(e) if (HTML_dtd.tags[e].contents != SGML_EMPTY) \
+                        (*me->target->isa->end_element)(me->target, e, 0)
 
 
 /*	Here are the parameters which can be specified in a  source file
@@ -329,6 +331,7 @@ PRIVATE void WSRC_gen_html ARGS2(HTStream *, me, BOOL, source_file)
     if (source_file) {
 	START(HTML_DT);
 	PUTS("Access links");
+	MAYBE_END(HTML_DT);
 	START(HTML_DD);
 	if (me->par_value[PAR_IP_NAME] &&
 	    me->par_value[PAR_DATABASE_NAME]) {
@@ -365,20 +368,25 @@ PRIVATE void WSRC_gen_html ARGS2(HTStream *, me, BOOL, source_file)
 	    give_parameter(me, PAR_IP_NAME);
 	    give_parameter(me, PAR_DATABASE_NAME);
 	}
+	MAYBE_END(HTML_DD);
     
     } /* end if source_file */
     
     if (me->par_value[PAR_MAINTAINER]) {
 	START(HTML_DT);
 	PUTS("Maintainer");
+	MAYBE_END(HTML_DT);
 	START(HTML_DD);
 	PUTS(me->par_value[PAR_MAINTAINER]);
+	MAYBE_END(HTML_DD);
     }
     if (me->par_value[PAR_IP_NAME]) {
     	START(HTML_DT);
     	PUTS("Host");
+	MAYBE_END(HTML_DT);
     	START(HTML_DD);
     	PUTS(me->par_value[PAR_IP_NAME]);
+	MAYBE_END(HTML_DD);
     }
 
     END(HTML_DL);
diff --git a/WWW/Library/Implementation/SGML.c b/WWW/Library/Implementation/SGML.c
index 7cfbd68d..1ae3a8b1 100644
--- a/WWW/Library/Implementation/SGML.c
+++ b/WWW/Library/Implementation/SGML.c
@@ -8,6 +8,13 @@
 **	
 **	 6 Feb 93  Binary seraches used. Intreface modified.
 */
+
+/* Remove the following to disable the experimental HTML DTD parsing.
+   Currently only used in this source file. - kw */
+
+#define EXTENDED_HTMLDTD
+
+
 #include "HTUtils.h"
 #include "tcp.h"		/* For FROMASCII */
 
@@ -188,6 +195,12 @@ extern BOOL historical_comments;
 extern BOOL minimal_comments;
 extern BOOL soft_dquotes;
 
+#ifdef USE_COLOR_STYLE
+#include "AttrList.h"
+extern char class_string[TEMPSTRINGSIZE];
+int current_is_class=0;
+#endif
+
 /*	Handle Attribute
 **	----------------
 */
@@ -211,6 +224,11 @@ PRIVATE void handle_attribute_name ARGS2(
     	    context->current_attribute_number = i;
 	    context->present[i] = YES;
 	    FREE(context->value[i]);
+#ifdef USE_COLOR_STYLE
+	current_is_class=(!strcasecomp("class", s));
+	if (TRACE)
+		fprintf(stderr, "SGML: found attribute %s, %d\n", s, current_is_class);
+#endif
 	    return;
 	} /* if */
 	
@@ -232,6 +250,19 @@ PRIVATE void handle_attribute_value ARGS2(
 {
     if (context->current_attribute_number != INVALID) {
 	StrAllocCopy(context->value[context->current_attribute_number], s);
+#ifdef USE_COLOR_STYLE
+        if (current_is_class)
+        {
+                strncpy (class_string, s, TEMPSTRINGSIZE);
+                if (TRACE)
+                fprintf(stderr, "SGML: class is '%s'\n", s);
+        }
+        else
+        {
+                if (TRACE)
+                fprintf(stderr, "SGML: attribute value is '%s'\n", s);
+        }
+#endif
     } else {
         if (TRACE)
 	    fprintf(stderr, "SGML: Attribute value %s ignored\n", s);
@@ -506,6 +537,75 @@ PRIVATE void handle_sgmlatt ARGS1(
 }
 
 
+PRIVATE BOOL element_valid_within ARGS3(
+    HTTag *, 	new_tag,
+    HTTag *,	stacked_tag,
+    BOOL,	direct)
+{
+    TagClass usecontains, usecontained;
+    if (!stacked_tag || !new_tag)
+	return YES;
+    usecontains = (direct ? stacked_tag->contains : stacked_tag->icontains);
+    usecontained = (direct ? new_tag->contained : new_tag->icontained);
+    if (new_tag == stacked_tag)
+	return ((Tgc_same & usecontains) &&
+		(Tgc_same & usecontained));
+    else
+	return ((new_tag->tagclass & usecontains) &&
+		(stacked_tag->tagclass & usecontained));
+}
+
+#ifdef EXTENDED_HTMLDTD
+
+extern BOOL New_DTD;
+
+typedef enum {
+    close_NO	= 0,
+    close_error = 1,
+    close_valid	= 2,
+} canclose_t;
+
+PRIVATE canclose_t can_close ARGS2(
+    HTTag *, 	new_tag,
+    HTTag *,	stacked_tag)
+{
+    if (!stacked_tag)
+	return close_NO;
+    if (stacked_tag->flags & Tgf_endO)
+	return close_valid;
+    else if (new_tag == stacked_tag)
+	return ((Tgc_same & new_tag->canclose) ? close_error : close_NO);
+    else
+	return ((stacked_tag->tagclass & new_tag->canclose) ?
+		close_error : close_NO);
+}
+PRIVATE void do_close_stacked ARGS1(
+    HTStream *,	context)
+{
+    HTElement * stacked = context->element_stack;
+    if (!stacked)
+	return;			/* stack was empty */
+    (*context->actions->end_element)(
+        context->target,
+        stacked->tag - context->dtd->tags,
+        (char **)&context->include);
+    context->element_stack = stacked->next;
+    FREE(stacked);
+}
+PRIVATE int is_on_stack ARGS2(
+	HTStream *,	context,
+	HTTag *,	old_tag)
+{
+    HTElement * stacked = context->element_stack;
+    int i = 1;
+    for (; stacked; stacked = stacked->next, i++) {
+	if (stacked->tag == old_tag)
+	    return i;
+    }
+    return 0;
+}
+#endif /* EXTENDED_HTMLDTD */
+
 /*	End element
 **	-----------
 */
@@ -513,6 +613,57 @@ PRIVATE void end_element ARGS2(
 	HTStream *,	context,
 	HTTag *,	old_tag)
 {
+#ifdef EXTENDED_HTMLDTD
+
+    BOOL extra_action_taken = NO;
+    canclose_t canclose_check = close_valid;
+    int stackpos = is_on_stack(context, old_tag);
+
+    if (New_DTD) {
+	while (canclose_check != close_NO &&
+	       context->element_stack &&
+	       (stackpos > 1 || (!extra_action_taken && stackpos == 0))) {
+	    canclose_check = can_close(old_tag, context->element_stack->tag);
+	    if (canclose_check != close_NO) {
+		if (TRACE)
+		    fprintf(stderr, "SGML: End </%s> \t<- %s end </%s>\n",
+			    context->element_stack->tag->name,
+			    canclose_check == close_valid ? "supplied," : "forced by",
+			    old_tag->name);
+		do_close_stacked(context);
+		extra_action_taken = YES;
+		stackpos = is_on_stack(context, old_tag);
+	    } else {
+		if (TRACE)
+		    fprintf(stderr, "SGML: Still open %s \t<- invalid end </%s>\n",
+			    context->element_stack->tag->name,
+			    old_tag->name);
+		return;
+	    }
+	}
+
+	if (stackpos == 0 && old_tag->contents != SGML_EMPTY) {
+	    if (TRACE)
+		fprintf(stderr, "SGML: Still open %s, no open %s for </%s>\n",
+			context->element_stack ?
+			context->element_stack->tag->name : "none",
+			old_tag->name,
+			old_tag->name);
+	    return;
+	}
+	if (stackpos > 1) {
+	    if (TRACE)
+		fprintf(stderr, "SGML: Nesting <%s>...<%s> \t<- invalid end </%s>\n",
+			old_tag->name,
+			context->element_stack->tag->name,
+			old_tag->name);
+	    return;
+	}
+    }
+    /* Now let the old code deal with the rest... - kw */
+
+#endif /* EXTENDED_HTMLDTD */
+
     if (TRACE)
         fprintf(stderr, "SGML: End </%s>\n", old_tag->name);
     if (old_tag->contents == SGML_EMPTY) {
@@ -568,7 +719,73 @@ PRIVATE void start_element ARGS1(
 	HTStream *,	context)
 {
     HTTag * new_tag = context->current_tag;
+
+#ifdef EXTENDED_HTMLDTD
+
+    BOOL valid = YES;
+    BOOL direct_container = YES;
+    BOOL extra_action_taken = NO;
+    canclose_t canclose_check = close_valid;
+
+    if (New_DTD) {
+	while (context->element_stack &&
+	       (canclose_check == close_valid ||
+		(canclose_check == close_error &&
+		 new_tag == context->element_stack->tag)) &&
+	       !(valid = element_valid_within(new_tag, context->element_stack->tag,
+					      direct_container))) {
+	    canclose_check = can_close(new_tag, context->element_stack->tag);
+	    if (canclose_check != close_NO) {
+		if (TRACE)
+		    fprintf(stderr, "SGML: End </%s> \t<- %s start <%s>\n",
+			    context->element_stack->tag->name,
+			    canclose_check == close_valid ? "supplied," : "forced by",
+			    new_tag->name);
+		do_close_stacked(context);
+		extra_action_taken = YES;
+		if (canclose_check  == close_error)
+		    direct_container = NO;
+	    } else {
+		if (TRACE)
+		    fprintf(stderr, "SGML: Still open %s \t<- invalid start <%s>\n",
+			    context->element_stack->tag->name,
+			    new_tag->name);
+	    }
+	}
+
+	if (context->element_stack && !extra_action_taken &&
+	    canclose_check == close_NO && !valid && (new_tag->flags & Tgf_mafse)) {
+	    BOOL has_attributes = NO;
+	    int i = 0;
+	    for (; i< new_tag->number_of_attributes && !has_attributes; i++)
+		has_attributes = context->present[i];
+	    if (!has_attributes) {
+		if (TRACE)
+		    fprintf(stderr, "SGML: Still open %s, converting invalid <%s> to </%s>\n",
+			    context->element_stack->tag->name,
+			    new_tag->name,
+			    new_tag->name);
+		end_element(context, new_tag);
+		return;
+	    }
+	}
     
+	if (context->element_stack &&
+	    canclose_check == close_error && !(valid =
+					       element_valid_within(
+						   new_tag,
+						   context->element_stack->tag,
+						   direct_container))) {
+	    if (TRACE)
+		fprintf(stderr, "SGML: Still open %s \t<- invalid start <%s>\n",
+			context->element_stack->tag->name,
+			new_tag->name);
+	}
+    }
+    /* fall through to the old code - kw */
+
+#endif /* EXTENDED_HTMLDTD */
+
     if (TRACE)
         fprintf(stderr, "SGML: Start <%s>\n", new_tag->name);
     (*context->actions->start_element)(
@@ -677,6 +894,7 @@ PUBLIC void SGML_abort ARGS2(
 	HTError, 	e)
 {
     int i;
+    HTElement * cur;
 
     /*
     **  Abort the target. - FM
@@ -692,6 +910,15 @@ PUBLIC void SGML_abort ARGS2(
     FREE(context->csi);
 
     /*
+    **  Free stack memory if any elements were left open. - kw
+    */
+    while (context->element_stack) {
+        cur = context->element_stack;
+	context->element_stack = cur->next;	/* Remove from stack */
+	FREE(cur);
+    }
+
+    /*
     **  Free the strings and context structure. - FM
     */
     HTChunkFree(context->string);
@@ -901,6 +1128,8 @@ top1:
 	    		  (context->element_stack->tag->contents ==
 			  		SGML_MIXED ||
 			   context->element_stack->tag->contents ==
+			  		SGML_PCDATA ||
+			   context->element_stack->tag->contents ==
 			      		SGML_RCDATA)))) {
 	    /*
 	    **  Setting up for possible entity, without the leading '&'. - FM
@@ -1132,20 +1361,6 @@ top1:
 	    PUTC('#');
 	    context->state = S_text;
 	    goto top1;
-	} else if (unsign_c > 127 || isalnum((unsigned char)c)) {
-	    /*
-	    **  We have digit(s), but not a valid terminator,
-	    **  so recover the "&#" and digit(s) and recycle
-	    **  the character. - FM
-	    */
-	    int i;
-	    PUTC('&');
-	    PUTC('#');
-	    for (i = 0; i < string->size; i++)	/* recover */
-	       PUTC(string->data[i]);
-	    string->size = 0;
-	    context->state = S_text;
-	    goto top1;
 	} else {
 	    /*
 	    **  Terminate the numeric entity and try to handle it. - FM
@@ -1837,6 +2052,14 @@ top1:
 	    } else {
 		BOOL tag_OK = (c == '>' || WHITE(c));
 	        context->current_tag = t;
+#ifdef EXTENDED_HTMLDTD
+		/*
+		**  Just handle ALL end tags normally :-) - kw
+		*/
+		if (New_DTD) {
+		    end_element( context, context->current_tag);
+		} else
+#endif /* EXTENDED_HTMLDTD */
 		if (tag_OK &&
 		    (!strcasecomp(string->data, "DD") ||
 		     !strcasecomp(string->data, "DT") ||
@@ -1894,44 +2117,22 @@ top1:
 		    }
 		    break;
 		} else if (tag_OK &&
-			   !strcasecomp(string->data, "FONT")) {
-		    /*
-		    **  Treat a FONT end tag as a FONT start tag with
-		    **  a dummy END attribute.  It's too likely to be
-		    **  interdigited and mess up the parsing, so we've
-		    **  declared FONT as SGML_EMPTY and will handle the
-		    **  end tag in HTML_start_element. - FM
-		    */
-		    if (TRACE)
-		        fprintf(stderr,
-				"SGML: `</%s%c' found!  Treating as '<%s%c'.\n",
-				string->data, c, string->data, c);
-		    {
-		        int i;
-			for (i = 0;
-			     i < context->current_tag->number_of_attributes;
-			     i++) {
-			    context->present[i] = (i == HTML_FONT_END);
-			}
-		    }
-		    string->size = 0;
-		    context->current_attribute_number = INVALID;
-		    if (context->current_tag->name)
-			start_element(context);
-		    if (c != '>') {
-			context->state = S_junk_tag;
-		    } else {
-			context->state = S_text;
-		    }
-		    break;
-		} else if (tag_OK &&
-			   !strcasecomp(string->data, "FORM")) {
+			   (!strcasecomp(string->data, "A") ||
+			    !strcasecomp(string->data, "B") ||
+			    !strcasecomp(string->data, "BLINK") ||
+			    !strcasecomp(string->data, "CITE") ||
+			    !strcasecomp(string->data, "EM") ||
+			    !strcasecomp(string->data, "FONT") ||
+			    !strcasecomp(string->data, "FORM") ||
+			    !strcasecomp(string->data, "I") ||
+			    !strcasecomp(string->data, "STRONG") ||
+			    !strcasecomp(string->data, "U"))) {
 		    /*
-		    **  Handle a FORM end tag.  We declared FORM
-		    **  as SGML_EMPTY to prevent "expected tag
-		    **  substitution" and avoid throwing the
-		    **  HTML.c stack out of whack (Wow, what
-		    **  a hack! 8-). - FM
+		    **  Handle end tags for container elements declared
+		    **  as SGML_EMPTY to prevent "expected tag substitution"
+		    **  but still processed via HTML_end_element() in HTML.c
+		    **  with checks there to avoid throwing the HTML.c stack
+		    **  out of whack (Ugh, what a hack! 8-). - FM
 		    */
 		    if (TRACE)
 		        fprintf(stderr, "SGML: End </%s>\n", string->data);
diff --git a/WWW/Library/Implementation/SGML.h b/WWW/Library/Implementation/SGML.h
index 7ab47c82..2a9f985c 100644
--- a/WWW/Library/Implementation/SGML.h
+++ b/WWW/Library/Implementation/SGML.h
@@ -38,7 +38,8 @@ typedef enum _SGMLContent{
   SGML_CDATA,    /* character data. recognize </ only */
   SGML_RCDATA,   /* replaceable character data. recognize </ and &ref; */
   SGML_MIXED,    /* elements and parsed character data. recognize all markup */
-  SGML_ELEMENT   /* any data found will be returned as an error*/
+  SGML_ELEMENT,  /* any data found will be returned as an error*/
+  SGML_PCDATA    /* added - kw */
   } SGMLContent;
 
 
@@ -47,6 +48,50 @@ typedef struct {
                                 /* Could put type info in here */
 } attr;
 
+typedef enum _TagClass {
+    /* textflow */
+    Tgc_FONTlike	= 0x00001,/* S,STRIKE,I,B,TT,U,BIG,SMALL,STYLE,BLINK;BR,TAB */
+    Tgc_EMlike		= 0x00002, /* EM,STRONG,DFN,CODE,SAMP,KBD,VAR,CITE,Q,INS,DEL,SPAN,.. */
+    Tgc_MATHlike	= 0x00004, /* SUB,SUP,MATH,COMMENT */
+    Tgc_Alike		= 0x00008, /* A */
+    Tgc_formula		= 0x00010, /* not used until math is supported better... */
+    /* used for special structures: forms, tables,... */
+    Tgc_TRlike		= 0x00020,/* TR and similar */
+    Tgc_SELECTlike	= 0x00040,/* SELECT,INPUT,TEXTAREA(,...) */
+    /* structure */
+    Tgc_FORMlike	= 0x00080,/* FORM itself */
+    Tgc_Plike		= 0x00100, /* P,H1..H6,... structures containing text or
+				    insertion but not other structures */
+    Tgc_DIVlike		= 0x00200, /* ADDRESS,FIG,BDO,NOTE,FN,DIV,CENTER;FIG
+				    structures which can contain other structures */
+    Tgc_LIlike		= 0x00400, /* LH,LI,DT,DD;TH,TD structure-like, only valid
+				    within certain other structures */
+    Tgc_ULlike		= 0x00800, /* UL,OL,DL,DIR,MENU;TABLE;XMP,LISTING
+				    special in some way, cannot contain (parsed)
+				    text directly */
+    /* insertions */
+    Tgc_BRlike		= 0x01000,/* BR,IMG,TAB allowed in any text */
+    Tgc_APPLETlike	= 0x02000, /* APPLET,OBJECT,EMBED,SCRIPT */
+    Tgc_HRlike		= 0x04000, /* HR,MARQUEE can contain all kinds of things
+				    and/or are not allowed (?) in running text */
+    Tgc_MAPlike		= 0x08000, /* MAP,AREA some specials that never contain
+				    (directly or indirectly) other things than
+				    special insertions */
+    Tgc_outer		= 0x10000, /* HTML,FRAMESET,FRAME,PLAINTEXT; */
+    Tgc_BODYlike	= 0x20000, /* BODY,BODYTEXT,NOFRAMES,TEXTFLOW; */
+    Tgc_HEADstuff	= 0x40000, /* HEAD,BASE,STYLE,TITLE; */
+    /* special relations */
+    Tgc_same		= 0x80000
+} TagClass;
+
+/* Some more properties of tags (or rather, elements) and rules how
+   to deal with them. - kw */
+typedef enum _TagFlags {
+    Tgf_endO		= 0x00001, /* end tag can be Omitted */
+    Tgf_startO		= 0x00002, /* start tag can be Omitted */
+    Tgf_mafse   	= 0x00004  /* Make Attribute-Free Start-tag End instead
+				      (if found invalid) */
+} TagFlags;
 
 /*              A tag structure describes an SGML element.
 **              -----------------------------------------
@@ -68,6 +113,14 @@ struct _tag{
     attr *      attributes;             /* The list of acceptable attributes */
     int         number_of_attributes;   /* Number of possible attributes */
     SGMLContent contents;               /* End only on end tag @@ */
+    TagClass	tagclass,
+	contains,	/* which classes of elements this one can contain directly */
+	icontains,	/* which classes of elements this one can contain indirectly */
+	contained,	/* in which classes can this tag be contained ? */
+	icontained,	/* in which classes can this tag be indirectly contained ? */
+	canclose;	/* which classes of elements can this one close
+			   if something looks wrong ? */
+    TagFlags	flags;
 };
 
 
diff --git a/WWW/Library/Implementation/tcp.h b/WWW/Library/Implementation/tcp.h
index 7f38e545..f51dfc72 100644
--- a/WWW/Library/Implementation/tcp.h
+++ b/WWW/Library/Implementation/tcp.h
@@ -65,6 +65,8 @@ typedef struct sockaddr_in SockA;  /* See netinet/in.h */
 #define STDIO_H
 #endif /* !STDIO_H */
 
+#include <sys/types.h>
+
 #if HAVE_DIRENT_H
 # include <dirent.h>
 # define D_NAMLEN(dirent) strlen((dirent)->d_name)
@@ -612,6 +614,28 @@ Defaults
 #endif  /* TCP includes */
 
 /*
+
+ROUGH ESTIMATE OF MAX PATH LENGTH
+
+*/
+#ifndef HT_MAX_PATH
+#ifdef MAXPATHLEN
+#define HT_MAX_PATH MAXPATHLEN
+#else
+#ifdef PATH_MAX
+#define HT_MAX_PATH PATH_MAX
+#else
+#define HT_MAX_PATH 1024                        /* Any better ideas? */
+#endif
+#endif
+#endif /* HT_MAX_PATH */
+
+#if HT_MAX_PATH < 256
+#undef HT_MAX_PATH
+#define HT_MAX_PATH 256
+#endif
+
+/*
   MACROS FOR MANIPULATING MASKS FOR SELECT()
  */
 #ifdef SELECT