about summary refs log tree commit diff stats
path: root/WWW
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>1997-10-17 18:00:00 -0400
committerThomas E. Dickey <dickey@invisible-island.net>1997-10-17 18:00:00 -0400
commitcbcc3a1e1a82b01eea370bf7841e6b5f4d1e46c1 (patch)
tree2df907a422b75fb41590f113d3a0a3365bc667be /WWW
parent1d80538b4b84eadd223c7b61839b950389c2d49d (diff)
downloadlynx-snapshots-cbcc3a1e1a82b01eea370bf7841e6b5f4d1e46c1.tar.gz
snapshot of project "lynx", label v2-7-1ac_0-84
Diffstat (limited to 'WWW')
-rw-r--r--WWW/Library/Implementation/HTAccess.c62
-rw-r--r--WWW/Library/Implementation/HTAccess.h3
-rw-r--r--WWW/Library/Implementation/HTChunk.c37
-rw-r--r--WWW/Library/Implementation/HTChunk.h8
-rw-r--r--WWW/Library/Implementation/HTFTP.c104
-rw-r--r--WWW/Library/Implementation/HTFile.c3
-rw-r--r--WWW/Library/Implementation/HTFormat.c120
-rw-r--r--WWW/Library/Implementation/HTFormat.h11
-rw-r--r--WWW/Library/Implementation/HTMIME.c2
-rw-r--r--WWW/Library/Implementation/HTMLGen.c2
-rw-r--r--WWW/Library/Implementation/HTParse.c2
-rw-r--r--WWW/Library/Implementation/HTTP.c4
-rw-r--r--WWW/Library/Implementation/LYLeaks.h15
-rw-r--r--WWW/Library/Implementation/SGML.c235
-rw-r--r--WWW/Library/Implementation/SGML.h7
-rw-r--r--WWW/Library/Implementation/UCAux.h22
-rw-r--r--WWW/Library/Implementation/tcp.h30
-rw-r--r--WWW/Library/vms/descrip.mms3
-rw-r--r--WWW/Library/vms/libmake.com27
19 files changed, 559 insertions, 138 deletions
diff --git a/WWW/Library/Implementation/HTAccess.c b/WWW/Library/Implementation/HTAccess.c
index 816d64d2..2f21eaad 100644
--- a/WWW/Library/Implementation/HTAccess.c
+++ b/WWW/Library/Implementation/HTAccess.c
@@ -61,6 +61,8 @@
 #include "HText.h"	/* See bugs above */
 #include "HTAlert.h"
 #include "HTCJK.h"
+#include "UCMap.h"
+#include "LYGlobalDefs.h"
 
 #include "LYexit.h"
 #include "LYLeaks.h"
@@ -88,11 +90,14 @@ PRIVATE HTList * protocols = NULL; /* List of registered protocol descriptors */
 
 PUBLIC char *use_this_url_instead = NULL;
 
+PRIVATE int pushed_assume_LYhndl = -1; /* see LYUC* functions below - kw */
+PRIVATE char * pushed_assume_MIMEname = NULL;
 
 PRIVATE void free_protocols NOARGS
 {
     HTList_delete(protocols);
     protocols = NULL;
+    FREE(pushed_assume_MIMEname); /* shouldn't happen, just in case - kw */
 }
 
 /*	Register a Protocol.				HTRegisterProtocol()
@@ -241,11 +246,11 @@ PUBLIC BOOL override_proxy ARGS1(
         if (!strcmp("file", access) &&
 	    (!strcmp(Host, "localhost") ||
 #ifdef VMS
-             !strcasecomp(Host, HTHostName())))
+             !strcasecomp(Host, HTHostName())
 #else
-             !strcmp(Host, HTHostName())))
+             !strcmp(Host, HTHostName())
 #endif /* VMS */
-        {
+        )) {
 	    FREE(host);
 	    FREE(access);
 	    return YES;
@@ -524,6 +529,56 @@ PRIVATE int get_physical ARGS2(
     return HT_NO_ACCESS;
 }
 
+/*
+ *  Temporarily set the int UCLYhndl_for_unspec and string
+ *  UCLYhndl_for_unspec used for charset "assuming" to the values
+ *  implied by a HTParentAnchor's UCStages, after saving the current
+ *  values for later restoration. - kw
+ *  @@@ These functions may not really belong here, but where else?
+ *  I want the "pop" to occur as soon as possible after loading
+ *  has finished. - kw @@@   
+ */
+
+PUBLIC void LYUCPushAssumed ARGS1(
+    HTParentAnchor *,	anchor)
+{
+    int anchor_LYhndl = -1;
+    LYUCcharset * anchor_UCI = NULL;
+    if (anchor) {
+	anchor_LYhndl = HTAnchor_getUCLYhndl(anchor, UCT_STAGE_PARSER);
+	if (anchor_LYhndl >= 0)
+	    anchor_UCI = HTAnchor_getUCInfoStage(anchor,
+						 UCT_STAGE_PARSER);
+	if (anchor_UCI && anchor_UCI->MIMEname) {
+	    pushed_assume_LYhndl = anchor_LYhndl;
+	    UCLYhndl_for_unspec = anchor_LYhndl;
+	    pushed_assume_MIMEname = UCAssume_MIMEcharset;
+	    UCAssume_MIMEcharset = NULL;
+	    StrAllocCopy(UCAssume_MIMEcharset, anchor_UCI->MIMEname);
+	    return;
+	}
+    }
+    pushed_assume_LYhndl = -1;
+    FREE(pushed_assume_MIMEname);
+}
+/*
+ *  Restore the int UCLYhndl_for_unspec and string
+ *  UCLYhndl_for_unspec used for charset "assuming" from the values
+ *  saved by LYUCPushAssumed, if any. - kw
+ */
+PRIVATE int LYUCPopAssumed NOARGS
+{
+    if (pushed_assume_LYhndl >= 0) {
+	UCLYhndl_for_unspec = pushed_assume_LYhndl;
+	pushed_assume_LYhndl = -1;
+	FREE(UCAssume_MIMEcharset);
+	UCAssume_MIMEcharset = pushed_assume_MIMEname;
+	pushed_assume_MIMEname = NULL;
+	return UCLYhndl_for_unspec;
+    }
+    return -1;
+}
+
 /*	Load a document					HTLoad()
 **	---------------
 **
@@ -559,6 +614,7 @@ PRIVATE int HTLoad ARGS4(
     status= (*(p->load))(HTAnchor_physical(anchor),
     			anchor, format_out, sink);
     anchor->underway = FALSE;
+    LYUCPopAssumed();
     return status;
 }
 
diff --git a/WWW/Library/Implementation/HTAccess.h b/WWW/Library/Implementation/HTAccess.h
index d883e10f..2826d13a 100644
--- a/WWW/Library/Implementation/HTAccess.h
+++ b/WWW/Library/Implementation/HTAccess.h
@@ -316,6 +316,9 @@ For registering protocols supported by Lynx
 */
 extern void LYRegisterLynxProtocols NOARGS;
 
+extern void LYUCPushAssumed PARAMS((
+    HTParentAnchor *	anchor));
+
 #endif /* HTACCESS_H */
 /*
 
diff --git a/WWW/Library/Implementation/HTChunk.c b/WWW/Library/Implementation/HTChunk.c
index 64a7e0ba..497e5173 100644
--- a/WWW/Library/Implementation/HTChunk.c
+++ b/WWW/Library/Implementation/HTChunk.c
@@ -27,6 +27,27 @@ PUBLIC HTChunk * HTChunkCreate ARGS1 (int,grow)
     return ch;
 }
 
+/*	Create a chunk with a certain allocation unit and ensured size
+**	--------------
+*/
+PUBLIC HTChunk * HTChunkCreate2 ARGS2 (int,grow, size_t, needed)
+{
+    HTChunk * ch = (HTChunk *) calloc(1, sizeof(HTChunk));
+    if (ch == NULL)
+        outofmem(__FILE__, "HTChunkCreate2");
+
+    ch->growby = grow;
+    if (needed > 0) {
+	ch->allocated = needed-1 - ((needed-1) % ch->growby)
+	    + ch->growby; /* Round up */
+	ch->data = (char *)calloc(1, ch->allocated);
+	if (!ch->data)
+	    outofmem(__FILE__, "HTChunkCreate2 data");
+    }
+    ch->size = 0;
+    return ch;
+}
+
 
 /*	Clear a chunk of all data
 **	--------------------------
@@ -79,6 +100,22 @@ PUBLIC void HTChunkEnsure ARGS2 (HTChunk *,ch, int,needed)
         outofmem(__FILE__, "HTChunkEnsure");
 }
 
+PUBLIC void HTChunkPutb ARGS3 (HTChunk *,ch, CONST char *,b, int,l)
+{
+    int needed = ch->size + l;
+    if (l <= 0) return;
+    if (needed > ch->allocated) {
+	ch->allocated = needed-1 - ((needed-1) % ch->growby)
+	    + ch->growby; /* Round up */
+        ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated)
+			    : (char *)calloc(1, ch->allocated);
+	if (ch->data == NULL)
+	    outofmem(__FILE__, "HTChunkPutb");
+    }
+    memcpy(ch->data + ch->size, b, l);
+    ch->size += l;
+}
+
 #ifdef EXP_CHARTRANS
 
 #define PUTC(code) ch->data[ch->size++] = (char)(code)
diff --git a/WWW/Library/Implementation/HTChunk.h b/WWW/Library/Implementation/HTChunk.h
index c7308165..a5e89b31 100644
--- a/WWW/Library/Implementation/HTChunk.h
+++ b/WWW/Library/Implementation/HTChunk.h
@@ -47,6 +47,12 @@ Create new chunk
 
 extern HTChunk * HTChunkCreate PARAMS((int growby));
 
+/*
+ *  Like HTChunkCreate but with initial allocation - kw
+ *
+ */
+extern HTChunk * HTChunkCreate2 PARAMS((int growby, size_t needed));
+
 
 /*
 
@@ -118,6 +124,8 @@ Append a character to a  chunk
  */
 extern void HTChunkPutc PARAMS((HTChunk * ch, char c));
 
+extern void HTChunkPutb PARAMS((HTChunk * ch, CONST char *b, int l));
+
 #ifdef EXP_CHARTRANS
 extern void HTChunkPutUtf8Char PARAMS((HTChunk * ch, UCode_t code));
 
diff --git a/WWW/Library/Implementation/HTFTP.c b/WWW/Library/Implementation/HTFTP.c
index a3ad9de1..0e5b801b 100644
--- a/WWW/Library/Implementation/HTFTP.c
+++ b/WWW/Library/Implementation/HTFTP.c
@@ -162,7 +162,7 @@ extern char *personal_mail_address;
 */
 PRIVATE connection * connections = 0;	/* Linked list of connections */
 PRIVATE char response_text[LINE_LENGTH+1];/* Last response from NewsHost */
-PRIVATE connection * control;		/* Current connection */
+PRIVATE connection * control = NULL;		/* Current connection */
 PRIVATE int data_soc = -1;		/* Socket for data transfer =invalid */
 
 #define GENERIC_SERVER	   0
@@ -178,6 +178,7 @@ PRIVATE int data_soc = -1;		/* Socket for data transfer =invalid */
 #define MS_WINDOWS_SERVER 10
 #define MSDOS_SERVER      11
 #define APPLESHARE_SERVER 12
+#define NETPRESENZ_SERVER 13
 
 PRIVATE int     server_type = GENERIC_SERVER;   /* the type of ftp host */
 PRIVATE int     unsure_type = FALSE;            /* sure about the type? */
@@ -318,8 +319,13 @@ PRIVATE int close_connection ARGS1(
 {
     connection * scan;
     int status = NETCLOSE(con->socket);
-    if (TRACE)
+    if (TRACE) {
         fprintf(stderr, "HTFTP: Closing control socket %d\n", con->socket);
+#ifdef UNIX
+	if (status != 0)
+	    perror("HTFTP:close_connection");
+#endif
+    }
     con->socket = -1;
     if (connections == con) {
         connections = con->next;
@@ -336,6 +342,15 @@ PRIVATE int close_connection ARGS1(
     return -1;		/* very strange -- was not on list. */
 }
 
+PRIVATE void cleanup_ftp NOARGS
+{
+    if (control) {
+	if (control->socket != -1)
+	    close_connection(control);
+	FREE(control);
+    }
+}
+
 PRIVATE char *help_message_buffer = NULL;  /* global :( */
 
 PRIVATE void init_help_message_cache NOARGS
@@ -509,7 +524,8 @@ PRIVATE int set_mac_binary ARGS1(
         int,		server_type)
 {
     /* try to set mac binary mode */
-    if (server_type == APPLESHARE_SERVER) {
+    if (server_type == APPLESHARE_SERVER ||
+	server_type == NETPRESENZ_SERVER) {
 	/*
 	 *  Presumably E means "Enable"  - kw
 	 */
@@ -573,7 +589,8 @@ PRIVATE void get_ftp_pwd ARGS2(
 
         if ((*server_type == NCSA_SERVER) ||
             (*server_type == TCPC_SERVER) ||
-            (*server_type == PETER_LEWIS_SERVER))
+            (*server_type == PETER_LEWIS_SERVER) ||
+            (*server_type == NETPRESENZ_SERVER))
             set_mac_binary(*server_type);
     }
 }
@@ -593,8 +610,9 @@ PRIVATE void get_ftp_pwd ARGS2(
 **	It ensures that all connections are logged in if they exist.
 **	It ensures they have the port number transferred.
 */
-PRIVATE int get_connection ARGS1(
-	CONST char *,	arg)
+PRIVATE int get_connection ARGS2(
+	CONST char *,		arg,
+	HTParentAnchor *,	anchor)
 {
     int status;
     char * command;
@@ -603,15 +621,32 @@ PRIVATE int get_connection ARGS1(
     char * password=NULL;
     static char *user_entered_password=NULL;
     static char *last_username_and_host=NULL;
+    static BOOLEAN firstuse = TRUE;
 
-    /*
-    **  Allocate and init control struct.
-    */
-    con = (connection *)calloc(1, sizeof(connection));
-    
     if (!arg) return -1;		/* Bad if no name sepcified	*/
     if (!*arg) return -1;		/* Bad if name had zero length	*/
 
+    if (control) {
+	/*
+	**  Reuse this object - kw
+	*/
+	if (control->socket != -1)
+	    NETCLOSE(control->socket);
+	con = control;
+    } else {
+	/*
+	**  Allocate and init control struct.
+	*/
+	con = (connection *)calloc(1, sizeof(connection));
+	if (con == NULL)
+	    outofmem(__FILE__, "get_connection");
+	if (firstuse) {
+	    atexit(cleanup_ftp);
+	    firstuse = FALSE;
+	}
+    }
+    con->socket = -1;
+
 /* Get node name:
 */
     {
@@ -691,12 +726,15 @@ PRIVATE int get_connection ARGS1(
         }
 
       FREE(username);
+      if (control == con)
+	  control = NULL;
       FREE(con);
       return status;                    /* Bad return */
     }
 
     if (TRACE) 
- 	fprintf(stderr, "FTP connected, socket %ld\n", (long)con);
+ 	fprintf(stderr, "FTP connected, socket %d  control %ld\n",
+			con->socket, (long)con);
     control = con;		/* Current control connection */
 
     /* Initialise buffering for control connection */
@@ -719,7 +757,23 @@ PRIVATE int get_connection ARGS1(
         control->socket = -1;
         return HT_INTERRUPTED;
       }
+    server_type = GENERIC_SERVER;	/* reset */
     if (status == 2) {		/* Send username */
+	{
+	    char *cp;		/* look at greeting text */
+	    if (strlen(response_text) > 4) {
+		if ((cp = strstr(response_text, " awaits your command")) ||
+		    (cp = strstr(response_text, " ready."))) {
+		    *cp = '\0';
+		}
+		cp = response_text + 4;
+		if (!strncasecomp(cp, "NetPresenz", 10))
+		    server_type = NETPRESENZ_SERVER;
+	    } else {
+		cp = response_text;
+	    }
+	    StrAllocCopy(anchor->server, cp);
+	}
 	if (username && *username) {
 	    command = (char*)malloc(10+strlen(username)+2+1);
 	    if (command == NULL)
@@ -837,7 +891,8 @@ PRIVATE int get_connection ARGS1(
     if (TRACE) fprintf(stderr, "HTFTP: Logged in.\n");
 
     /** Check for host type **/
-    server_type = GENERIC_SERVER;	/* reset */
+    if (server_type != NETPRESENZ_SERVER)
+	server_type = GENERIC_SERVER;	/* reset */
     use_list = FALSE; 			/* reset */
     if ((status=response("SYST\r\n")) == 2) {
         /* we got a line -- what kind of server are we talking to? */
@@ -887,6 +942,13 @@ PRIVATE int get_connection ARGS1(
             get_ftp_pwd(&server_type, &use_list);
 	    unsure_type = TRUE;
 
+        } else if (server_type == NETPRESENZ_SERVER) { /* already set above */
+            use_list = TRUE;
+            set_mac_binary(server_type);
+	    if (TRACE)
+	        fprintf(stderr,
+	 	 	"HTFTP: Treating as NetPresenz (MACOS) server.\n");
+
         } else if (strncmp(response_text+4, "MACOS Peter's Server", 20) == 0) {
             server_type = PETER_LEWIS_SERVER;
             use_list = TRUE;
@@ -1924,6 +1986,7 @@ PRIVATE EntryInfo * parse_dir_entry ARGS2(
 	case MSDOS_SERVER:
         case WINDOWS_NT_SERVER:
         case APPLESHARE_SERVER:
+        case NETPRESENZ_SERVER:
 	    /*
 	    **  Check for EPLF output (local times).
 	    */
@@ -1937,6 +2000,11 @@ PRIVATE EntryInfo * parse_dir_entry ARGS2(
 	    */
             len = strlen(entry);
 	    if (*first) {
+		if (!strcmp(entry, "can not access directory .")) {
+		    /* don't reset *first, nothing real will follow - kw */
+		    entry_info->display=FALSE;
+		    return(entry_info);
+		}
 	        *first = FALSE;
                 if (!strncmp(entry, "total ", 6) ||
                     strstr(entry, "not available") != NULL) {
@@ -2462,7 +2530,9 @@ AgainForMultiNet:
 		 if (TRACE)
 		     fprintf(stderr, "Adding file to BTree: %s\n",
 		     		     entry_info->filename);
-	         HTBTree_add(bt, (EntryInfo *)entry_info); 
+	         HTBTree_add(bt, (EntryInfo *)entry_info);
+	    } else {
+		FREE(entry_info);
 	    }
 
 	}  /* next entry */
@@ -2532,13 +2602,15 @@ unload_btree:
 		free_entryinfo_struct_contents(entry_info);
 	    }
 	}
+	END(HTML_PRE);
 	FREE_TARGET;
 	HTBTreeAndObject_free(bt);
     }
 
     FREE(lastpath);
 
-    if (server_type == APPLESHARE_SERVER) {
+    if (server_type == APPLESHARE_SERVER ||
+	server_type == NETPRESENZ_SERVER) {
 	/*
 	 *  Without closing the data socket first,
 	 *  the response(NIL) below hangs... - kw
@@ -2590,7 +2662,7 @@ PUBLIC int HTFTPLoad ARGS4(
     server_type = GENERIC_SERVER;
 
     for (retry = 0; retry < 2; retry++) { /* For timed out/broken connections */
-	status = get_connection(name);
+	status = get_connection(name, anchor);
 	if (status < 0)
 	    return status;
 
diff --git a/WWW/Library/Implementation/HTFile.c b/WWW/Library/Implementation/HTFile.c
index 93553bcb..3ec307fc 100644
--- a/WWW/Library/Implementation/HTFile.c
+++ b/WWW/Library/Implementation/HTFile.c
@@ -743,7 +743,7 @@ PUBLIC HTFormat HTFileFormat ARGS3(
 #ifdef VMS
     char *semicolon = NULL;
 #endif /* VMS */
-    extern char LYforce_HTML_mode;
+    extern BOOLEAN LYforce_HTML_mode;
 
     if (pencoding)
 	*pencoding = NULL;
@@ -2370,6 +2370,7 @@ PUBLIC int HTLoadFile ARGS4(
 		}
 		return status;
 	    }  /* If succesfull open */
+	    FREE(localname);
 	}    /* scope of fp */
     }  /* local unix file system */    
 #endif /* !NO_UNIX_IO */
diff --git a/WWW/Library/Implementation/HTFormat.c b/WWW/Library/Implementation/HTFormat.c
index 3b33fb9a..2653833f 100644
--- a/WWW/Library/Implementation/HTFormat.c
+++ b/WWW/Library/Implementation/HTFormat.c
@@ -296,38 +296,29 @@ PRIVATE int half_match ARGS2(char *,trial_type, char *,target)
     return 0;
 }
 
-/*		Create a filter stack
-**		---------------------
+/*		Look up a presentation
+**		----------------------
 **
-**	If a wildcard match is made, a temporary HTPresentation
-**	structure is made to hold the destination format while the
-**	new stack is generated. This is just to pass the out format to
-**	MIME so far.  Storing the format of a stream in the stream might
-**	be a lot neater.
+**	If fill_in is NULL, only look for an exact match.
+**	If a wildcard match is made, *fill_in is used to store
+**	a possibly modified presentation, and a pointer to it is
+**	returned.  For an exact match, a pointer to the presentation
+**	in the HTPresentations list is returned.  Returns NULL if
+**	nothing found. - kw
 **
 */
-PUBLIC HTStream * HTStreamStack ARGS4(
+PRIVATE HTPresentation * HTFindPresentation ARGS3(
 	HTFormat,		rep_in,
 	HTFormat,		rep_out,
-	HTStream*,		sink,
-	HTParentAnchor*,	anchor)
+	HTPresentation*,	fill_in)
 {
     HTAtom * wildcard = HTAtom_for("*");
 
     if (TRACE)
         fprintf(stderr,
-		"HTFormat: Constructing stream stack for %s to %s\n",
+		"HTFormat: Looking up presentation for %s to %s\n",
 		HTAtom_name(rep_in), HTAtom_name(rep_out));
 		
-    /* don't return on WWW_SOURCE some people might like
-     * to make use of the source!!!!  LJM
-     *//*
-    if (rep_out == WWW_SOURCE || rep_out == rep_in)
-	return sink;  LJM */
-
-    if (rep_out == rep_in)
-        return sink;
-
     /* don't do anymore do it in the Lynx code at startup LJM */
     /* if (!HTPresentations) HTFormatInit(); */	/* set up the list */
     
@@ -346,10 +337,12 @@ PUBLIC HTStream * HTStreamStack ARGS4(
 	        if (pres->rep_out == rep_out) {
 		    if (TRACE)
 			fprintf(stderr,
-				"StreamStack: found exact match: %s\n",
+				"FindPresentation: found exact match: %s\n",
 				HTAtom_name(pres->rep));
-	    	    return (*pres->converter)(pres, anchor, sink);
+	    	    return pres;
 
+		} else if (!fill_in) {
+		    continue;
 		} else if (pres->rep_out == wildcard) {
 		    if (!strong_wildcard_match)
 		        strong_wildcard_match = pres;
@@ -360,6 +353,9 @@ PUBLIC HTStream * HTStreamStack ARGS4(
 				HTAtom_name(pres->rep));
 		}
 
+	    } else if (!fill_in) {
+		continue;
+
 	    } else if (half_match(HTAtom_name(pres->rep),
 					      HTAtom_name(rep_in))) {
 	        if (pres->rep_out == rep_out) {
@@ -397,20 +393,82 @@ PUBLIC HTStream * HTStreamStack ARGS4(
 		last_default_match;
 	
 	if (match) {
-	    HTPresentation temp;
-	    temp = *match;		/* Specific instance */
-	    temp.rep = rep_in;		/* yuk */
-	    temp.rep_out = rep_out;	/* yuk */
-	    if (TRACE)
-		fprintf(stderr,
-			"StreamStack: Using %s\n", HTAtom_name(temp.rep_out));
-	    return (*match->converter)(&temp, anchor, sink);
+	    *fill_in = *match;		/* Specific instance */
+	    fill_in->rep = rep_in;		/* yuk */
+	    fill_in->rep_out = rep_out;	/* yuk */
+	    return fill_in;
         }
     }
 
     return NULL;
 }
-	
+
+/*		Create a filter stack
+**		---------------------
+**
+**	If a wildcard match is made, a temporary HTPresentation
+**	structure is made to hold the destination format while the
+**	new stack is generated. This is just to pass the out format to
+**	MIME so far.  Storing the format of a stream in the stream might
+**	be a lot neater.
+**
+*/
+PUBLIC HTStream * HTStreamStack ARGS4(
+	HTFormat,		rep_in,
+	HTFormat,		rep_out,
+	HTStream*,		sink,
+	HTParentAnchor*,	anchor)
+{
+    HTPresentation temp;
+    HTPresentation *match;
+
+    if (TRACE)
+        fprintf(stderr,
+		"HTFormat: Constructing stream stack for %s to %s\n",
+		HTAtom_name(rep_in), HTAtom_name(rep_out));
+		
+    /* don't return on WWW_SOURCE some people might like
+     * to make use of the source!!!!  LJM
+     *//*
+    if (rep_out == WWW_SOURCE || rep_out == rep_in)
+	return sink;  LJM */
+
+    if (rep_out == rep_in)
+        return sink;
+
+    if ((match = HTFindPresentation(rep_in, rep_out, &temp))) {
+	if (match == &temp) {
+	    if (TRACE)
+		fprintf(stderr,
+			"StreamStack: Using %s\n", HTAtom_name(temp.rep_out));
+	} else {
+	    if (TRACE)
+		fprintf(stderr,
+			"StreamStack: found exact match: %s\n",
+			HTAtom_name(match->rep));
+	}
+	return (*match->converter)(match, anchor, sink);
+    } else {
+	return NULL;
+    }
+}
+
+/*		Put a presentation near start of list
+**		-------------------------------------
+**
+**	Look up a presentation (exact match only) and, if found, reorder
+**	it to the start of the HTPresentations list. - kw
+*/
+PUBLIC void HTReorderPresentation ARGS2(
+	HTFormat,		rep_in,
+	HTFormat,		rep_out)
+{
+    HTPresentation *match;
+    if ((match = HTFindPresentation(rep_in, rep_out, NULL))) {
+	HTList_removeObject(HTPresentations, match);
+	HTList_addObject(HTPresentations, match);
+    }
+}    
 /*		Find the cost of a filter stack
 **		-------------------------------
 **
diff --git a/WWW/Library/Implementation/HTFormat.h b/WWW/Library/Implementation/HTFormat.h
index b21a0ec3..80fb91dd 100644
--- a/WWW/Library/Implementation/HTFormat.h
+++ b/WWW/Library/Implementation/HTFormat.h
@@ -256,6 +256,17 @@ extern HTStream * HTStreamStack PARAMS((
         HTParentAnchor*         anchor));
 
 /*
+HTReorderPresentation: put presentation near head of list
+
+    Look up a presentation (exact match only) and, if found, reorder
+    it to the start of the HTPresentations list. - kw
+    */
+
+extern void HTReorderPresentation PARAMS((
+        HTFormat                format_in,
+        HTFormat                format_out));
+
+/*
 
 HTStackValue: Find the cost of a filter stack
 
diff --git a/WWW/Library/Implementation/HTMIME.c b/WWW/Library/Implementation/HTMIME.c
index 0d5c6fdd..67795a22 100644
--- a/WWW/Library/Implementation/HTMIME.c
+++ b/WWW/Library/Implementation/HTMIME.c
@@ -2096,7 +2096,7 @@ PUBLIC HTStream* HTMIMEConvert ARGS3(
     
     me = (HTStream *)calloc(1, sizeof(*me));
     if (me == NULL)
-        outofmem(__FILE__, "HTML_new");
+        outofmem(__FILE__, "HTMIME_new");
     me->isa	=	&HTMIME;       
     me->sink	=	sink;
     me->anchor	=	anchor;
diff --git a/WWW/Library/Implementation/HTMLGen.c b/WWW/Library/Implementation/HTMLGen.c
index ef5c2faa..7190d947 100644
--- a/WWW/Library/Implementation/HTMLGen.c
+++ b/WWW/Library/Implementation/HTMLGen.c
@@ -425,7 +425,7 @@ PRIVATE void PlainToHTML_abort ARGS2(
 */
 PRIVATE CONST HTStructuredClass HTMLGeneration = /* As opposed to print etc */
 {		
-	"text/html",
+	"HTMLGen",
 	HTMLGen_free,
 	HTMLGen_abort,
 	HTMLGen_put_character, 	HTMLGen_put_string, HTMLGen_write,
diff --git a/WWW/Library/Implementation/HTParse.c b/WWW/Library/Implementation/HTParse.c
index e69b77ad..3c5fafc5 100644
--- a/WWW/Library/Implementation/HTParse.c
+++ b/WWW/Library/Implementation/HTParse.c
@@ -799,7 +799,7 @@ PUBLIC void HTMake822Word ARGS1(
     	a = TOASCII(*p);
 	if ((a != '\t') && ((a & 127) < 32 ||
 			    ( a < 128 && ((crfc[a-32]) & 2))))
-	    *q++ = '\'';
+	    *q++ = '\\';
 	*q++ = *p;
 	if (a == '\n' || (a == '\r' && (TOASCII(*(p+1)) != '\n')))
 	    *q++ = ' ';
diff --git a/WWW/Library/Implementation/HTTP.c b/WWW/Library/Implementation/HTTP.c
index f4009328..2fc9145b 100644
--- a/WWW/Library/Implementation/HTTP.c
+++ b/WWW/Library/Implementation/HTTP.c
@@ -653,7 +653,7 @@ try_again:
     BOOL end_of_file = NO;
     int buffer_length = INIT_LINE_SIZE;
 
-    line_buffer = (char *) malloc(buffer_length * sizeof(char));
+    line_buffer = (char *) calloc(1, buffer_length * sizeof(char));
 
     do {/* Loop to read in the first line */
         /*
@@ -1119,7 +1119,7 @@ try_again:
 	       *  any, and then close the connection. - FM
 	       */
 	      while ((status = HTTP_NETREAD(s, line_buffer,
-	      				    INIT_LINE_SIZE,
+					    (INIT_LINE_SIZE - 1),
 					    handle)) > 0) {
 	          line_buffer[status] = '\0';
 		  StrAllocCat(line_kept_clean, line_buffer);
diff --git a/WWW/Library/Implementation/LYLeaks.h b/WWW/Library/Implementation/LYLeaks.h
index 4109be80..d7d47a01 100644
--- a/WWW/Library/Implementation/LYLeaks.h
+++ b/WWW/Library/Implementation/LYLeaks.h
@@ -130,6 +130,17 @@ AllocationList;
 #endif /* free */
 #define free(vp_alloced) LYLeakFree(vp_alloced, __FILE__, __LINE__)
 
+/*
+ *   Added the following two defines to track Lynx's frequent use
+ *   of those macros. - kw 1997-10-12
+ */
+#ifdef StrAllocCopy
+#undef StrAllocCopy
+#undef StrAllocCat
+#endif
+#define StrAllocCopy(dest, src) LYLeakSACopy (&(dest), src, __FILE__, __LINE__)
+#define StrAllocCat(dest, src)  LYLeakSACat  (&(dest), src, __FILE__, __LINE__)
+
 #endif /* LY_FIND_LEAKS && !NO_MEMORY_TRACKING */
 
 /*
@@ -145,5 +156,9 @@ PUBLIC void *LYLeakRealloc PARAMS((void *vp_alloced, size_t st_newbytes, CONST
 	char *cp_File, CONST short ssi_Line));
 PUBLIC void LYLeakFree PARAMS((void *vp_alloced, CONST char *cp_File, CONST
 	short ssi_Line));
+extern char * LYLeakSACopy PARAMS ((char **dest, CONST char *src, CONST char
+	*cp_File, CONST short ssi_Line));
+extern char * LYLeakSACat  PARAMS ((char **dest, CONST char *src, CONST char
+	*cp_File, CONST short ssi_Line));
 
 #endif /* __LYLEAKS_H */
diff --git a/WWW/Library/Implementation/SGML.c b/WWW/Library/Implementation/SGML.c
index 51434a66..2a210561 100644
--- a/WWW/Library/Implementation/SGML.c
+++ b/WWW/Library/Implementation/SGML.c
@@ -44,8 +44,6 @@ PUBLIC BOOL HTPassEightBitNum = FALSE;	/* Pass ^ numeric entities raw.	*/
 PUBLIC BOOL HTPassHighCtrlRaw = FALSE;	/* Pass 127-160,173,&#127; raw.	*/
 PUBLIC BOOL HTPassHighCtrlNum = FALSE;	/* Pass &#128;-&#159; raw.	*/
 
-extern BOOLEAN LYCheckForCSI PARAMS((HTParentAnchor *anchor, char **url));
-extern void LYDoCSI PARAMS((char *url, CONST char *comment, char **csi));
 
 /*	The State (context) of the parser
 **
@@ -118,8 +116,8 @@ struct _HTStream {
     LYUCcharset	*		htmlUCI;	/* anchor UCInfo for target */
     int				html_char_set;	/* feed it to target stream */
     char			utf_count;
-    long			utf_char;
-    char 			utf_buf[7];
+    UCode_t			utf_char;
+    char 			utf_buf[8];
     char *			utf_buf_p;
     UCTransParams		T;
     int			current_tag_charset; /* charset to pass attributes */
@@ -137,9 +135,9 @@ struct _HTStream {
 #ifdef EXP_CHARTRANS
 
 PRIVATE void set_chartrans_handling ARGS3(
-	HTStream *,	context,
-	HTParentAnchor *, anchor,
-	int,	chndl)
+	HTStream *,		context,
+	HTParentAnchor *,	anchor,
+	int,			chndl)
 {
     extern int current_char_set;
 
@@ -150,9 +148,9 @@ PRIVATE void set_chartrans_handling ARGS3(
 	if (chndl < 0)
 	    chndl = current_char_set;
 	HTAnchor_setUCInfoStage(anchor, chndl, UCT_STAGE_HTEXT,
-			    UCT_SETBY_DEFAULT);
+				UCT_SETBY_DEFAULT);
 	HTAnchor_setUCInfoStage(anchor, chndl, UCT_STAGE_STRUCTURED,
-			    UCT_SETBY_DEFAULT);
+				UCT_SETBY_DEFAULT);
 	context->htmlUCI = HTAnchor_getUCInfoStage(anchor,
 						   UCT_STAGE_STRUCTURED);
 	context->html_char_set = HTAnchor_getUCLYhndl(context->node_anchor,
@@ -178,7 +176,7 @@ PRIVATE void set_chartrans_handling ARGS3(
 }
 
 PRIVATE void change_chartrans_handling ARGS1(
-	HTStream *,	context)
+	HTStream *,		context)
 {
     int new_LYhndl = HTAnchor_getUCLYhndl(context->node_anchor,
 					  UCT_STAGE_PARSER);
@@ -301,22 +299,28 @@ PRIVATE void handle_attribute_value ARGS2(
 /* translate some Unicodes to Lynx special codes and output them. */
 PRIVATE BOOL put_special_unicodes ARGS2(
 	HTStream *,	context,
-	long, code)
+	UCode_t,	code)
 {
     if (code == 160) {
+	/*
+	**  Use Lynx special character for nbsp.
+	*/
 	PUTC(HT_NON_BREAK_SPACE);
-    } else  if (code==173) {
+    } else  if (code == 173) {
+	/*
+	**  Use Lynx special character for shy.
+	*/
 	PUTC(LY_SOFT_HYPHEN);
     } else if (code == 8194 || code == 8195 || code == 8201) {
-		        /*
-			**  ensp, emsp or thinsp.
-			*/
+	/*
+	**  Use Lynx special character for ensp, emsp or thinsp.
+	*/
 	PUTC(HT_EM_SPACE);
     } else if (code == 8211 || code == 8212) {
-		        /*
-			**  ndash or mdash.
-			*/
-			PUTC('-');
+	/*
+	**  Use ASCII hyphen for ndash/endash or mdash/emdash.
+	*/
+	PUTC('-');
     } else {
 	/*
 	**  Return NO if nothing done.
@@ -342,11 +346,11 @@ PRIVATE BOOL put_special_unicodes ARGS2(
 **	Modified SGML_character() so we only come here with terminator
 **	as '\0' and check a FoundEntity flag. -- Foteos Macrides
 **
-** Modified more (for use with CHARTRANS):
+** Modified more (for use with Lynx character translation code):
 */
 
 #ifdef EXP_CHARTRANS
-PRIVATE char replace_buf [61];        /* buffer for replacement strings */
+PRIVATE char replace_buf [64];        /* buffer for replacement strings */
 #endif
 
 PRIVATE BOOL FoundEntity = FALSE;
@@ -356,11 +360,9 @@ PRIVATE void handle_entity ARGS2(
 	char,		term)
 {
     CONST char ** entities = context->dtd->entity_names;
-#ifdef EXP_CHARTRANS
     CONST UC_entity_info * extra_entities = context->dtd->extra_entity_info;
     extern int current_char_set;
     int rc;
-#endif
     CONST char *s = context->string->data;
     int high, low, i, diff;
 
@@ -451,7 +453,7 @@ PRIVATE void handle_entity ARGS2(
     **  If entity string not found, display as text.
     */
     if (TRACE)
-	fprintf(stderr, "SGML: Unknown entity %s\n", s); 
+	fprintf(stderr, "SGML: Unknown entity '%s'\n", s); 
     PUTC('&');
     {
 	CONST char *p;
@@ -477,7 +479,7 @@ PRIVATE void handle_comment ARGS1(
 
     if (context->csi == NULL &&
         strncmp(s, "!--#", 4) == 0 &&
-        LYCheckForCSI(context->node_anchor, (char **)&context->url) == TRUE) {
+        LYCheckForCSI(context->target, (char **)&context->url) == TRUE) {
 	LYDoCSI(context->url, s, (char **)&context->csi);
     }
 
@@ -871,7 +873,7 @@ PUBLIC HTTag * SGMLFindTag ARGS2(
     int high, low, i, diff;
     for (low = 0, high=dtd->number_of_tags;
     	 high > low;
-	 diff < 0 ? (low = i+1) : (high = i)) {  /* Binary serach */
+	 diff < 0 ? (low = i+1) : (high = i)) {  /* Binary search */
 	i = (low + (high-low)/2);
 	diff = strcasecomp(dtd->tags[i].name, string);	/* Case insensitive */
 	if (diff == 0) {		/* success: found it */
@@ -1005,20 +1007,19 @@ PUBLIC void SGML_character ARGS2(
     HTChunk	*string = 	context->string;
     CONST char * EntityName;
     extern int current_char_set;
-    extern CONST char * LYchar_set_names[];
     extern CONST char * HTMLGetEntityName PARAMS((int i));
 
 #ifdef EXP_CHARTRANS
     extern int LYlowest_eightbit[];
     char * p;
     BOOLEAN chk;	/* Helps (?) walk through all the else ifs... */
-    long clong, uck;	/* Enough bits for UCS4 ... */
+    UCode_t clong, uck;	/* Enough bits for UCS4 ... */
     char c;
     char saved_char_in = '\0';
     /*
-    **  Now some fun with the preprocessor...
-    **  use copies for c an unsign_c == clong, so that we
-    **  can revert back to the unchanged c_in.
+    **  Now some fun with the preprocessor.
+    **  Use copies for c and unsign_c == clong, so that
+    **  we can revert back to the unchanged c_in. - KW
     */
 #define unsign_c clong
 
@@ -1035,9 +1036,9 @@ PUBLIC void SGML_character ARGS2(
 	/*
 	**  Combine UTF-8 into Unicode.
 	**  Incomplete characters silently ignored.
-	**  From Linux kernel's console.c.
+	**  From Linux kernel's console.c. - KW
 	*/
-	if((unsigned char)c > 0x7f) {
+	if ((unsigned char)c > 127) {
 	    if (context->utf_count > 0 && (c & 0xc0) == 0x80) {
 		context->utf_char = (context->utf_char << 6) | (c & 0x3f);
 		context->utf_count--;
@@ -1051,7 +1052,7 @@ PUBLIC void SGML_character ARGS2(
 		    goto top1;
 		} else {
 		    /*
-		    **  Wait for more.
+		    **  Wait for more. - KW
 		    */
 		    return;
 		}
@@ -1075,20 +1076,20 @@ PUBLIC void SGML_character ARGS2(
 		    context->utf_char = (c & 0x01);
 		} else {
 		    /*
-		    **  Garbage.
+		    **  Garbage. - KW
 		    */
 		    context->utf_count = 0;
 		    context->utf_buf_p = context->utf_buf;
 		    *(context->utf_buf_p) = '\0';
 		}
 		/*
-		**  Wait for more.
+		**  Wait for more. - KW
 		*/
 		return;
 	    }
 	} else {
 	    /*
-	    **  Got an ASCII char.
+	    **  Got an ASCII char. - KW
 	    */
 	    context->utf_count = 0;
 	    context->utf_buf_p = context->utf_buf;
@@ -1101,9 +1102,9 @@ PUBLIC void SGML_character ARGS2(
 	saved_char_in = c;
 
     if (context->T.trans_to_uni &&
-	(unsign_c >= 127 ||
-	    (unsign_c < 32 && unsign_c != 0 &&
-	     context->T.trans_C0_to_uni))) {
+	((unsign_c >= 127) ||
+	 (unsign_c < 32 && unsign_c != 0 &&
+	  context->T.trans_C0_to_uni))) {
 	clong = UCTransToUni(c, context->in_char_set);
 	if (clong > 0) {
 	    saved_char_in = c;
@@ -1233,7 +1234,7 @@ top1:
 	}
 	if (c == '&' && unsign_c < 127  &&
 	    (!context->element_stack ||
-			 (context->element_stack->tag  &&
+	     (context->element_stack->tag  &&
 	      (context->element_stack->tag->contents == SGML_MIXED ||
 	       context->element_stack->tag->contents == SGML_PCDATA ||
 	       context->element_stack->tag->contents == SGML_RCDATA)))) {
@@ -1276,7 +1277,7 @@ top1:
 	} else if (context->T.use_raw_char_in && saved_char_in) {
 	    /*
 	    **  Only if the original character is still in saved_char_in,
-	    **  otherwise we may be iterating from a goto top
+	    **  otherwise we may be iterating from a goto top. - KW
 	    */
 	    PUTC(saved_char_in);
 	    saved_char_in = '\0';
@@ -1305,10 +1306,15 @@ top1:
 					    0) >= 0)) { 
 	    /*
 	    **  No further tests for valididy - assume that whoever
-	    **  defined replacement strings knew what she was doing.
+	    **  defined replacement strings knew what she was doing. - KW
 	    */
-	      for (p=replace_buf; *p; p++)
+	    for (p = replace_buf; *p; p++)
 		PUTC(*p);
+	/*
+	**  If we're displaying UTF-8, try that now. - FM
+	*/
+	} else if (context->T.output_utf8 && PUTUTF8(clong)) {
+	    ; /* do nothing more */
 #endif /* EXP_CHARTRANS */
 
 	/*
@@ -1321,11 +1327,14 @@ top1:
 #define PASSHI8BIT HTPassEightBitRaw
 #else
 #define PASSHI8BIT (HTPassEightBitRaw || (context->T.do_8bitraw && !context->T.trans_from_uni))
+#define IncludesLatin1Enc(cs) \
+		(cs == 0 || \
+		 (context->htmlUCI && \
+		  (context->htmlUCI->enc & (UCT_CP_SUPERSETOF_LAT1))))
 #endif /* EXP_CHARTRANS */
 	} else if (unsign_c > 160 && unsign_c < 256 &&
 		   !(PASSHI8BIT || HTCJK != NOCJK) &&
-		   strncmp(LYchar_set_names[current_char_set],
-		   	   "ISO Latin 1", 11)) {
+		   !IncludesLatin1Enc(current_char_set)) {
 	    int i;
 	    int value;
 
@@ -1347,10 +1356,10 @@ top1:
 	    PUTC(c);
 	/*
 	**  If we get to here, and should have translated,
-	**  translation has failed so far.  
+	**  translation has failed so far. - KW
 	*/
 	} else if (context->T.output_utf8 && *context->utf_buf) {
-	    for (p=context->utf_buf; *p; p++)
+	    for (p = context->utf_buf; *p; p++)
 		PUTC(*p);
 	    context->utf_buf_p = context->utf_buf;
 	    *(context->utf_buf_p) = '\0';
@@ -1360,15 +1369,15 @@ top1:
 		   ((unsigned char)saved_char_in < 255)) {
 	    /*
 	    **  KOI8 special: strip high bit, gives (somewhat) readable
-	    **  ASCII or KOI7 - it was constructed that way!
+	    **  ASCII or KOI7 - it was constructed that way! - KW
 	    */
 	    PUTC((char)(saved_char_in & 0x7f));
 	    saved_char_in = '\0';
 	} else if ((unsigned char)c <
 			LYlowest_eightbit[context->html_char_set] ||
 		   (context->T.trans_from_uni && !HTPassEightBitRaw)) {
-	    sprintf(replace_buf,"U%.2lx",unsign_c);
-	    for (p=replace_buf; *p; p++)
+	    sprintf(replace_buf, "U%.2lX", unsign_c);
+	    for (p = replace_buf; *p; p++)
 		PUTC(*p);
 #endif /* EXP_CHARTRANS */
 	/*
@@ -1383,7 +1392,7 @@ top1:
     **  In litteral mode, waits only for specific end tag (for
     **  compatibility with old servers, and for Lynx). - FM
     */
-    case S_litteral :
+    case S_litteral:
 	HTChunkPutc(string, c);
 	if (TOUPPER(c) != ((string->size == 1) ?
 					   '/' :
@@ -1448,7 +1457,36 @@ top1:
 	    **  Terminate entity name and try to handle it. - FM
 	    */
 	    HTChunkTerminate(string);
-	    handle_entity(context, '\0');
+	    if (!strcmp(string->data, "zwnj") &&
+		(!context->element_stack ||
+		 (context->element_stack->tag  &&
+		  context->element_stack->tag->contents == SGML_MIXED))) {
+		/*
+		**  Handle zwnj (8204) as <WBR>. - FM
+		*/
+		char temp[8];
+
+		if (TRACE) {
+		    fprintf(stderr,
+		"SGML_character: Handling 'zwnj' entity as 'WBR' element.\n");
+		}
+		if (c != ';') {
+		    sprintf(temp, "<WBR>%c", c); 
+		} else {
+		    sprintf(temp, "<WBR>"); 
+		}
+		if (context->recover == NULL) {
+		    StrAllocCopy(context->recover, temp);
+		    context->recover_index = 0;
+		} else {
+		    StrAllocCat(context->recover, temp);
+		}
+		string->size = 0;
+		context->state = S_text;
+		break;
+	    } else {
+		handle_entity(context, '\0');
+	    }
 	    string->size = 0;
 	    context->state = S_text;
 	    /*
@@ -1518,6 +1556,46 @@ top1:
 	    HTChunkTerminate(string);
 	    if ((context->isHex ? sscanf(string->data, "%x", &value) :
 				  sscanf(string->data, "%d", &value)) == 1) {
+		/*
+		**  Check for special values. - FM
+		*/
+		if ((value == 8204) &&
+		    (!context->element_stack ||
+		     (context->element_stack->tag  &&
+		      context->element_stack->tag->contents == SGML_MIXED))) {
+		    /*
+		    **  Handle zwnj (8204) as <WBR>. - FM
+		    */
+		    char temp[8];
+
+		    if (TRACE) {
+		        fprintf(stderr,
+      "SGML_character: Handling '8204' (zwnj) reference as 'WBR' element.\n");
+		    }
+		    /*
+		    **  Include the terminator if it is not
+		    **  the standard semi-colon. - FM
+		    */
+		    if (c != ';') {
+			sprintf(temp, "<WBR>%c", c); 
+		    } else {
+			sprintf(temp, "<WBR>"); 
+		    }
+		    /*
+		    **  Add the replacement string to the
+		    **  recover buffer for processing. - FM
+		    */
+		    if (context->recover == NULL) {
+			StrAllocCopy(context->recover, temp);
+			context->recover_index = 0;
+		    } else {
+			StrAllocCat(context->recover, temp);
+		    }
+		    string->size = 0;
+		    context->isHex = FALSE;
+		    context->state = S_text;
+		    break;
+		}
 #ifdef EXP_CHARTRANS
 		if (value == 160 || value == 173) {
 		    /*
@@ -1546,13 +1624,13 @@ top1:
 		     uck >= LYlowest_eightbit[context->html_char_set])) {
 		    if (uck == 160 && current_char_set == 0) {
 			/*
-			**  Would only happen if some other unicode
+			**  Would only happen if some other Unicode
 			**  is mapped to Latin-1 160.
 			*/
 			PUTC(HT_NON_BREAK_SPACE);
 		    } else if (uck == 173 && current_char_set == 0) {
 			/*
-			**  Would only happen if some other unicode
+			**  Would only happen if some other Unicode
 			**  is mapped to Latin-1 173.
 			*/
 			PUTC(LY_SOFT_HYPHEN);
@@ -1593,13 +1671,13 @@ top1:
 		**  and the value:
 		**   (1) Is greater than 255 (but use ASCII characters
 		**	 for spaces or dashes).
-		**  (2) Is less than 32, and not valid or we don't
-		**	have HTCJK set.
-		**  (3) Is 127 and we don't have HTPassHighCtrlRaw or
-		**	HTCJK set.
-		**  (4) Is 128 - 159 and we don't have HTPassHighCtrlNum
-		**	set.
-		** - FM
+		**   (2) Is less than 32, and not valid or we don't
+		**	 have HTCJK set.
+		**   (3) Is 127 and we don't have HTPassHighCtrlRaw or
+		**	 HTCJK set.
+		**   (4) Is 128 - 159 and we don't have HTPassHighCtrlNum
+		**	 set.
+		**  - FM
 		*/
 		} else if ((value > 255) ||
 		    (value < 32 &&
@@ -1640,8 +1718,7 @@ top1:
 			goto top1;
 		    }
 		} else if (value < 161 || HTPassEightBitNum ||
-			   !strncmp(LYchar_set_names[current_char_set],
-			   	    "ISO Latin 1", 11)) {
+			   IncludesLatin1Enc(current_char_set)) {
 		    /*
 		    **  No conversion needed. - FM
 		    */
@@ -1696,6 +1773,7 @@ top1:
 		**  the "standard" semi-colon for HTML. - FM
 		*/
 		if (c != ';')
+
 		    goto top1;
 	    } else {
 	        /*
@@ -1814,7 +1892,7 @@ top1:
 	    */
 	    {
 	        int i;
-	        for (i=0; i< context->current_tag->number_of_attributes; i++)
+	        for (i = 0; i < context->current_tag->number_of_attributes; i++)
 	    	    context->present[i] = NO;
 	    }
 	    string->size = 0;
@@ -2188,13 +2266,18 @@ top1:
 	    else context->state = S_tag_gap;
 #ifdef EXP_CHARTRANS
 	} else if (context->T.decode_utf8 &&
-		*context->utf_buf) {
+		   *context->utf_buf) {
 	    HTChunkPuts(string, context->utf_buf);
 	    context->utf_buf_p = context->utf_buf;
 	    *(context->utf_buf_p) = '\0';
 	} else if (HTCJK == NOCJK && (context->T.output_utf8 ||
 				      context->T.trans_from_uni)) {
-	    HTChunkPutUtf8Char(string, clong);
+	    if (clong == 0xfffd && saved_char_in && HTPassEightBitRaw &&
+		(unsigned char)saved_char_in >= LYlowest_eightbit[current_char_set])
+		HTChunkPutUtf8Char(string,
+				   (0xf000 | (unsigned char)saved_char_in));
+	    else
+		HTChunkPutUtf8Char(string, clong);
 	} else if (saved_char_in && context->T.use_raw_char_in) {
 	    HTChunkPutc(string, saved_char_in);
 #endif /* EXP_CHARTRANS */
@@ -2218,13 +2301,18 @@ top1:
 	    HTChunkPutc(string, c);
 #ifdef EXP_CHARTRANS
 	} else if (context->T.decode_utf8 &&
-		*context->utf_buf) {
+		   *context->utf_buf) {
 	    HTChunkPuts(string, context->utf_buf);
 	    context->utf_buf_p = context->utf_buf;
 	    *(context->utf_buf_p) = '\0';
 	} else if (HTCJK == NOCJK && (context->T.output_utf8 ||
 				      context->T.trans_from_uni)) {
-	    HTChunkPutUtf8Char(string, clong);
+	    if (clong == 0xfffd && saved_char_in && HTPassEightBitRaw &&
+		(unsigned char)saved_char_in >= LYlowest_eightbit[current_char_set])
+		HTChunkPutUtf8Char(string,
+				   (0xf000 | (unsigned char)saved_char_in));
+	    else
+		HTChunkPutUtf8Char(string, clong);
 	} else if (saved_char_in && context->T.use_raw_char_in) {
 	    HTChunkPutc(string, saved_char_in);
 #endif /* EXP_CHARTRANS */
@@ -2252,13 +2340,18 @@ top1:
 	    HTChunkPutc(string, c);
 #ifdef EXP_CHARTRANS
 	} else if (context->T.decode_utf8 &&
-		*context->utf_buf) {
+		   *context->utf_buf) {
 	    HTChunkPuts(string, context->utf_buf);
 	    context->utf_buf_p = context->utf_buf;
 	    *(context->utf_buf_p) = '\0';
 	} else if (HTCJK == NOCJK && (context->T.output_utf8 ||
 				      context->T.trans_from_uni)) {
-	    HTChunkPutUtf8Char(string, clong);
+	    if (clong == 0xfffd && saved_char_in && HTPassEightBitRaw &&
+		(unsigned char)saved_char_in >= LYlowest_eightbit[current_char_set])
+		HTChunkPutUtf8Char(string,
+				   (0xf000 | (unsigned char)saved_char_in));
+	    else
+		HTChunkPutUtf8Char(string, clong);
 	} else if (saved_char_in && context->T.use_raw_char_in) {
 	    HTChunkPutc(string, saved_char_in);
 #endif /* EXP_CHARTRANS */
diff --git a/WWW/Library/Implementation/SGML.h b/WWW/Library/Implementation/SGML.h
index a3ea248a..0799c055 100644
--- a/WWW/Library/Implementation/SGML.h
+++ b/WWW/Library/Implementation/SGML.h
@@ -222,6 +222,13 @@ typedef struct _HTStructuredClass{
 }HTStructuredClass;
 
 /*
+  The following functions possibly should be generalised into
+  additional HTStructuredClass memebers. - kw
+  */
+extern BOOLEAN LYCheckForCSI PARAMS((HTStructured *target, char **url));
+extern void LYDoCSI PARAMS((char *url, CONST char *comment, char **csi));
+
+/*
 
 Find a Tag by Name
 
diff --git a/WWW/Library/Implementation/UCAux.h b/WWW/Library/Implementation/UCAux.h
index ffe0a652..a21521c4 100644
--- a/WWW/Library/Implementation/UCAux.h
+++ b/WWW/Library/Implementation/UCAux.h
@@ -1,9 +1,25 @@
 #ifndef UCAUX_H
 #define UCAUX_H
 
-extern BOOL UCCanUniTranslateFrom PARAMS((int from));
-extern BOOL UCCanTranslateUniTo PARAMS((int to));
-extern BOOL UCCanTranslateFromTo PARAMS((int from, int to));
+/*
+ *  A type for a "Translation Quality" (actually, Transcoding Quality).
+ *  This is a fuzzy concept since we are just looking at the charset
+ *  not what characters are actually there, so it's just a guess for
+ *  "common" cases.  TQ_NO must be 0 since callers of functions that
+ *  return this type may treat result as a boolean flag.
+ *  The functions returning this type could be improved to use more
+ *  knowledge from the translation tables.
+ */
+typedef enum {
+    TQ_NO	= 0,		/* must be 0 */
+    TQ_POOR	= 1,
+    TQ_GOOD	= 2,
+    TQ_EXCELLENT = 3
+} UCTQ_t;
+
+extern UCTQ_t UCCanUniTranslateFrom PARAMS((int from));
+extern UCTQ_t UCCanTranslateUniTo PARAMS((int to));
+extern UCTQ_t UCCanTranslateFromTo PARAMS((int from, int to));
 extern BOOL UCNeedNotTranslate PARAMS((int from, int to));
 
 struct _UCTransParams
diff --git a/WWW/Library/Implementation/tcp.h b/WWW/Library/Implementation/tcp.h
index d8c723fe..7dde5f34 100644
--- a/WWW/Library/Implementation/tcp.h
+++ b/WWW/Library/Implementation/tcp.h
@@ -329,6 +329,7 @@ extern char *vms_errno_string();
 #include "multinet_root:[multinet.include.arpa]inet.h"
 #include "multinet_root:[multinet.include]netdb.h"
 #include "multinet_root:[multinet.include.sys]ioctl.h"
+#define TCP_INCLUDES_DONE
 /*
 **  Uncomment this if you get compiler messages
 **  about struct timeval having no linkage. - FM
@@ -352,6 +353,7 @@ struct timeval {
 #include "dn"
 #include "dnetdb"
 /* #include "vms.h" */
+#define TCP_INCLUDES_DONE
 #endif /* DECNET */
 
 
@@ -369,6 +371,7 @@ struct timeval {
 #include <netdb.h>
 #include <ucx$inetdef.h>
 #endif /* TCPWARE */
+#define TCP_INCLUDES_DONE
 #endif /* UCX */
 
 
@@ -381,6 +384,7 @@ struct timeval {
 #include <inet.h>
 #include <netdb.h>
 #include "cmuip_root:[syslib]ioctl.h"
+#define TCP_INCLUDES_DONE
 #endif /* CMU_TCP */
 
 
@@ -394,6 +398,7 @@ struct timeval {
 #include <netdb.h>
 #include "socketshr_library:socketshr.h"
 #include "socketshr_library:ioctl.h"
+#define TCP_INCLUDES_DONE
 #endif /* SOCKETSHR_TCP */
 
 #ifdef WIN_TCP
@@ -407,10 +412,33 @@ struct timeval {
 #ifndef NO_IOCTL
 #include <ioctl.h>
 #endif /* !NO_IOCTL */
+#define TCP_INCLUDES_DONE
 #endif /* WIN_TCP */
 
-
+#ifndef TCP_INCLUDES_DONE
+#include <types.h>
+#include <errno.h>
+#include <time.h>
+#ifdef VMS_SOCKET_HEADERS
+/*
+**  Not all versions of VMS have the full set of headers
+**  for socket library functions, because the TCP/IP
+**  packages were layered products.  If we want these
+**  specifically, instead of those for the above packages,
+**  the module should be compiled with VMS_SOCKET_HEADERS
+**  defined instead of layered product definitions, above.
+**  If the module is not using socket library functions,
+**  none of the definitions need be used, and we include
+**  only the above three headers. - FM
+*/
+#include <socket.h>
+#include <in.h>
+#include <inet.h>
+#include <netdb.h>
+#include <ioctl.h>
+#endif /* VMS_SOCKET_HEADERS */
 #define TCP_INCLUDES_DONE
+#endif /* !TCP_INCLUDES_DONE */
 
 /*
 
diff --git a/WWW/Library/vms/descrip.mms b/WWW/Library/vms/descrip.mms
index d34fe347..216e6aee 100644
--- a/WWW/Library/vms/descrip.mms
+++ b/WWW/Library/vms/descrip.mms
@@ -177,7 +177,7 @@ CC = gcc
 
 MODULES = HTParse, HTAccess, HTTP, HTFile, HTBTree, HTFTP, HTTCP, HTString, -
 	SGML, HTMLDTD, HTChunk, HTPlain, HTWriter, HTMLGen, -
-	HTAtom, HTAnchor, HTStyle, HTList, HTAlert, HTRules, HTFormat, -
+	HTAtom, HTAnchor, HTStyle, HTList, HTRules, HTFormat, -
 	HTMIME, HTHistory, HTNews, HTGopher, HTTelnet, HTFinger, -
 	HTWSRC, HTAAUtil, HTAABrow, HTAAServ, HTAAFile, HTPasswd, HTGroup, -
 	HTACL, HTAuth, HTAAProt, HTAssoc, HTLex, HTUU, HTVMSUtils, getpass, -
@@ -219,7 +219,6 @@ clean :
 !HTPlain.obj :	HTPlain.c HTPlain.h HTStream.h
 !HTWriter.obj :	HTWriter.c HTWriter.h HTStream.h
 !HTMLGen.obj :	HTMLGen.c HTMLGen.h HTUtils.h HTMLDTD.h
-!HTAlert.obj :	HTAlert.c HTAlert.h HTUtils.h Version.make
 !HTRules.obj :	HTRules.c HTRules.h HTUtils.h Version.make
 !HTMIME.obj :	HTMIME.c HTMIME.h HTUtils.h HTList.h
 !HTTelnet.obj :	HTTelnet.c HTTelnet.h HTUtils.h
diff --git a/WWW/Library/vms/libmake.com b/WWW/Library/vms/libmake.com
index 7d812cfd..83ac1b4d 100644
--- a/WWW/Library/vms/libmake.com
+++ b/WWW/Library/vms/libmake.com
@@ -3,6 +3,9 @@ $!			LIBMAKE.COM
 $!
 $!   Command file to build the WWWLibrary on VMS systems.
 $!
+$!   08-Oct-1997	F.Macrides		macrides@sci.wfeb.edu
+$!	Added comments and minor tweaks for convenient addition of
+$!	compiler definitions and compiler and linker options.
 $!   26-Jul-1995	F.Macrides		macrides@sci.wfeb.edu
 $!	Adding support for GNUC.
 $!   03-May-1995	F.Macrides		macrides@sci.wfeb.edu
@@ -27,8 +30,19 @@ $!	Initial version, for WWWLibrary v2.14 with Lynx v2.1
 $!
 $ ON CONTROL_Y THEN GOTO CLEANUP
 $ ON ERROR THEN GOTO CLEANUP
-$ agent = 0
+$!
+$!	Compiler definitions can be added here as a comma separated
+$!	list with a lead comma, e.g., ",HAVE_FOO_H,DO_BLAH".  They
+$!	will apply only to the libwww-FM modules. - FM
+$!
 $ extra = ""
+$!
+$!	If no TCP/IP agent is specified (as the first argument),
+$!	prompt for a number from the list.   Note that the agent
+$!	must be the first argument if the debugger mode is to be
+$!	set via a second argument (see below). - FM
+$!
+$ agent = 0
 $ IF P1 .EQS. ""
 $ THEN
 $ 	write sys$output "Acceptable TCP/IP agents are"
@@ -50,10 +64,14 @@ $ if agent .eq. 5 .or. p1 .eqs. "SOCKETSHR_TCP" then transport = "SOCKETSHR_TCP"
 $ if agent .eq. 6 .or. p1 .eqs. "TCPWARE" then transport = "TCPWARE"
 $ if agent .eq. 7 .or. p1 .eqs. "DECNET" then transport = "DECNET"
 $!
-$ if transport .eqs. "TCPWARE" then extra = ",UCX"
+$ if transport .eqs. "TCPWARE" then extra = extra + ",UCX"
+$!
+$!	Compiler options can be specified here.  If there was
+$!	a second argument (with any value), then debugger mode
+$!	with no optimization will be specified as well. - FM
 $!
 $ cc_opts = ""
-$ if p2 .nes. "" then cc_opts = "/DEBUG/NOOPT"
+$ if p2 .nes. "" then cc_opts = cc_opts + "/DEBUG/NOOPT"
 $!
 $ IF f$trnlnm("VAXCMSG") .eqs. "DECC$MSG" .or. -
      f$trnlnm("DECC$CC_DEFAULT") .eqs. "/DECC" .or. -
@@ -80,7 +98,7 @@ $!
 $  v1 = 'f$verify(0)'
 $  Else
 $  if transport .eqs. "MULTINET" then -
-	extra = ",_DECC_V4_SOURCE,__SOCKET_TYPEDEFS"
+	extra = extra + ",_DECC_V4_SOURCE,__SOCKET_TYPEDEFS"
 $  v1 = f$verify(1)
 $!
 $ cc/decc/prefix=ansi /nomember 'cc_opts'-
@@ -142,7 +160,6 @@ $ cc [-.Implementation]HTAtom.c
 $ cc [-.Implementation]HTAnchor.c
 $ cc [-.Implementation]HTStyle.c
 $ cc [-.Implementation]HTList.c
-$ cc [-.Implementation]HTAlert.c
 $ cc [-.Implementation]HTRules.c
 $ cc [-.Implementation]HTFormat.c
 $ cc [-.Implementation]HTMIME.c