about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--CHANGES98
-rw-r--r--INSTALLATION32
-rw-r--r--WWW/Library/Implementation/HTDOS.c17
-rw-r--r--WWW/Library/Implementation/HTMLDTD.c2
-rw-r--r--WWW/Library/Implementation/HTString.c75
-rw-r--r--WWW/Library/Implementation/HTString.h2
-rw-r--r--WWW/Library/Implementation/HTTCP.c29
-rw-r--r--WWW/Library/Implementation/SGML.c11
-rw-r--r--WWW/Library/djgpp/CommonMakefile82
-rw-r--r--WWW/Library/djgpp/makefile.sla68
-rwxr-xr-xcfg_defs.sh53
-rwxr-xr-xcfg_edit.sh17
-rw-r--r--lynx.cfg3
-rw-r--r--lynx.man2
-rw-r--r--lynx_help/Lynx_users_guide.html4
-rw-r--r--lynx_help/keystrokes/alt_edit_help.html51
-rw-r--r--lynx_help/keystrokes/edit_help.html73
-rw-r--r--lynx_help/keystrokes/environments.html20
-rw-r--r--lynx_help/keystrokes/option_help.html89
-rw-r--r--makefile.in5
-rw-r--r--po/makefile.inn8
-rw-r--r--src/AttrList.h24
-rw-r--r--src/GridText.c30
-rw-r--r--src/HTAlert.c42
-rw-r--r--src/HTFWriter.c10
-rw-r--r--src/HTInit.c24
-rw-r--r--src/HTML.c186
-rw-r--r--src/LYBookmark.c103
-rw-r--r--src/LYCgi.c82
-rw-r--r--src/LYCharSets.c4
-rw-r--r--src/LYCharUtils.c20
-rw-r--r--src/LYDownload.c24
-rw-r--r--src/LYEdit.c25
-rw-r--r--src/LYEditmap.c14
-rw-r--r--src/LYGetFile.c6
-rw-r--r--src/LYGlobalDefs.h3
-rw-r--r--src/LYKeymap.c51
-rw-r--r--src/LYList.c2
-rw-r--r--src/LYMail.c14
-rw-r--r--src/LYMain.c75
-rw-r--r--src/LYMainLoop.c80
-rw-r--r--src/LYMainLoop.h1
-rw-r--r--src/LYNews.c4
-rw-r--r--src/LYOptions.c220
-rw-r--r--src/LYPrint.c1917
-rw-r--r--src/LYReadCFG.c12
-rw-r--r--src/LYShowInfo.c13
-rw-r--r--src/LYStrings.c17
-rw-r--r--src/LYStrings.h3
-rw-r--r--src/LYUtils.c88
-rw-r--r--src/LYUtils.h1
-rw-r--r--src/LYrcFile.c2
-rw-r--r--src/UCAuto.c43
-rw-r--r--src/UCdomap.c2
-rw-r--r--src/chrtrans/build-chrtrans.com2
-rw-r--r--src/chrtrans/caselower.h2
-rw-r--r--src/chrtrans/dmcs_uni.tbl31
-rw-r--r--src/chrtrans/iso15_uni.tbl216
-rw-r--r--src/chrtrans/makefile.dos2
-rw-r--r--src/chrtrans/makefile.in2
-rw-r--r--src/makefile.dos2
-rw-r--r--src/makefile.dsl2
-rw-r--r--src/makefile.in3
-rw-r--r--src/makefile.wsl2
-rw-r--r--userdefs.h4
65 files changed, 2390 insertions, 1761 deletions
diff --git a/CHANGES b/CHANGES
index 500d656f..22fbdc55 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,10 +1,92 @@
-Changes since Lynx 2.8.1 release
+Changes since Lynx 2.8 release
 ================================================================================
 
+1998-01-13 (2.8.2dev.13)
+* correct a missing trailing newline in caselower.h (this may be a problem
+  patching since 'diff' does not like that) - TD
+* fix off-by-one alignment download options (reported by LV) - IC
+* use HTSprintf/HTSprintf0 in UCAuto.c - TD
+* remove stop/start curses calls around UCChangeTerminalCodepage() in
+  GridText.c, since they are not necessary, and are a little distracting
+  when running Lynx in xterm - TD
+* correct handling in getfile() of ~/ expansion - KW
+* modify NSL_FORK logic to prevent child process from running any signal
+  handlers the parent may have installed - KW
+* The logic added to display_page for avoiding unnecessary screen redraw with
+  partial display (see 1998-12-03) is now disabled if enable_scrollback is set. 
+  Otherwise displayed pages could appear as empty (or with only the current
+  link drawn) - KW
+* Modify conditions under which screen style cache is reset (only relevant for
+  color style in combination with partial display) - KW
+* update the INSTALLATION file, reflecting the changes between the two DJGPP
+  versions of GCC in use.  Also, change optimization to -O2 in the other two
+  DOS makefiles - DK
+* add support for ISO 8859-15, i.e., "Latin 9", make corrections to DEC
+  Multinational character translations (patch by (Christian Weisgerber
+  <naddy@mips.rhein-neckar.de>)
+* modify po/makefile.inn to use mkdirs.sh rather than mkinstalldirs script
+  (reported by LV) - TD
+* modify print_help_and_exit() to print values for the simple options, i.e.,
+  toggle, integer and string, as part of "lynx -help" (request by
+  mattack@area.com) - TD
+* correct sense shown for Old_DTD variable in LYOptions.c (reported by DK).
+* correct order of params for non-Unix use of HTAddParam in LYBookmark.c
+  (reported by DK)
+1998-12-31
+* delete unused 'PREVAIL' color-style code from HTML.c, merge a couple of
+  sections of logic with TrimColorClass, and change Style_className to
+  a dynamically-allocated string - TD
+* modify fmt_tempname() to check for buffer overflow - TD
+* check/modify for potential buffer overflows:  HTAlert.c, LYBookMark.c,
+  LYKeymap.c, LYPrint.c (including splitting it up into functions) - TD
+* change GetOptValues to return status separately from the decoded value, in
+  case the options form is damaged (suggested by LP) - TD
+* add new function HTAddXpand to use in special case where Lynx is building
+  shell command using data from user's configuration, which should not be
+  quoted.  Use this in LYEdit.c to allow $EDITOR to be given as the editor
+  name (request by PG) - TD
+* add new function LYOpenTraceLog, to combine logic in LYMain.c and
+  LYMainLoop.c, including Lynx's version message - TD
+* fix some discrepancies between the code and the documentation (help files),
+  for the alternate line edit keybindings, that were first included in the
+  distribution somewhere around -dev.3, or so - KED
+* added a delete-to-beginning-of-line (for the alt bindings only), and a help
+  page that describes the alternate bindings - KED
+* improved description of "HTML error tolerance" - KW
+* Changes for handling lynxcgi:  handle failure of execve(), by showing the
+  system error and then _exit()ing the child process.  Make sure REQUEST_METHOD
+  is always set.  Added checks for EINTR and other errors from read() - KW
+* DOSPATH or EMX:  remove strange code dealing with root of local drive from
+  is_url() and HTDOS_name()/HTDOS_wwwname(), add right code at the earlier
+  stage in LYFillLocalFileURL() - LP (thanks KW)
+* Relax warning from HTAlert to HTUserMsg on REFRESH_URL_NOT_ABSOLUTE - LP
+* More tweaks on transfer rate calculation - LP
+* modify HTSACopy and HTSACat in case the source and destination are the same
+  pointer - TD
+* tested/removed redundant OS/2 EMX adjustement to filename from LYEdit.c - TD
+* optimized LYEdit.c by moving calls on HTSYS_name(filename) to a single place
+  near the top - LP
+* forms-based options menu:  prevent spoofing attempts from possible overruns
+  (e.g., user can doing 'e'dit in 'o'ptions and get coredump if
+  display_char_set gets an illegal number such as 50, or hang the keyboard with
+  illegal Line edit style) - LP
+* forms-based options menu:  add new logical section - Document Layout,
+  currently with "HTML error tolerance" (TagSoup/SortaSGML), "Pop-up for select
+  fields", "Show images" (no_alt/labels/links) and "Verbose images".  New
+  switches added for information purposes mostly, they duplicate hot keys but
+  not so hidden from user's view.  Documentation updated also.  (Oh yes, "Line
+  edit style" option is now available when we have a real choice >1) - LP
+* split cfg_defs.sh into two script based on revised script from PG - TD
+* minor fixes for toplevel makefile.in - PG
+* fixes for makefiles with gcc 2.8.1 using DJGPP 2.02 (do not use "-c -o"
+  combination, strip trailing blanks from makefile.sla, change optimization
+  level to -O2) - DK
+* rename New_DTD variable to Old_DTD, change logic for -tagsoup option to be
+  consistent with sense in lynx.cfg (reported by LP)
 1998-12-26 (2.8.2dev.12)
 * use HTSprintf0 in LYCgi.c - TD
 * add tab-completion on URL's, by using previously-entered strings for
-  matching (patch by Kari Davidsson <karid@loki.midheimar>) - TD
+  matching (patch by Kari Davidsson <karid@isholf.is>) - TD
 * add version number to trace log (patch by IC)
 * modify HTDOS_name to be consistent with HTVMS_name, which does not modify
   its parameter (reported by LP).  Also, modify HTDOS_name and HTDOS_wwwName
@@ -61,7 +143,7 @@ Changes since Lynx 2.8.1 release
   were received, although this is probably not necessary after all.  There is
   no difference any more w.r.t.  insertion into the list between cookies from
   the file and cookies from response headers - KW
-* use <= instead of < comparison when checking whether a cookie has expired - KW 
+* use <= instead of < comparison when checking whether a cookie has expired - KW
 * don't write expired cookies, cookies with discard attribute, or cookies
   without expiration date to persistent file - KW
 * don't call HTConfirmCookie for cookies read from file.  This doesn't change
@@ -71,9 +153,9 @@ Changes since Lynx 2.8.1 release
   unnecessary multiple atexit()'s - KW
 * write the cookie file even if we now have no cookies, if we have previously
   read cookies from the file.  The file should be updated if all cookies that
-  were in it are expired or superseded or deleted - KW 
+  were in it are expired or superseded or deleted - KW
 * when reading file cookies, set attributes in a way that (hopefully) makes
-  more sense than just ignoring them.  See comments in LYLoadCookies. 
+  more sense than just ignoring them.  See comments in LYLoadCookies.
   We are restricted a lot by the choice of a netscape-compatible cookie file
   format, some version 1 properties just cannot be stored in it AFAIK.  Some
   more tweaking in LYLoadCookies - KW
@@ -82,7 +164,7 @@ Changes since Lynx 2.8.1 release
   error - KW
 * some changes in what is displayed on Cookie Jar page:  FROM_FILE is a
   property of individual cookies, not of domains as previously.  Cookies from
-  file (which haven't been updated) are shown as "(from a previous session)". 
+  file (which haven't been updated) are shown as "(from a previous session)".
   Show expiration time ("Max.  Gobble Date") whenever we have one.  The state
   of the "discard" attribute is already displayed separately - KW
 * made color styles code work much better with TagSoup parsing mode.  A new
@@ -99,7 +181,7 @@ Changes since Lynx 2.8.1 release
 * split_line:  color style changes after the split position are moved to the
   correct position in the new line - KW
 * set TextAnchor's line_num in HText_beginInput, so that split_line can adjust
-  the input field's position properly if a split moves it to the next line. 
+  the input field's position properly if a split moves it to the next line.
   Should solve problem reported for www.lycos.com - KW
 * don't refuse to read from file-descriptor 0 in HTDoRead for Unix if it is not
   a tty.  The socket fd from HTDoConnect can be 0 if fd 0 was not open when
@@ -448,7 +530,7 @@ Changes since Lynx 2.8.1 release
 * misc documentation updates for the gettext/internationalization - LP
 * rename po/makefile.in.in to po/makefile.inn, and modify distclean rule to
   remove the remaining generated files - TD
-+ add preliminary changes from PG (pg@sweng.stortek.com) to support port to
+* add preliminary changes from PG (pg@sweng.stortek.com) to support port to
   OS/390, some ifdef'd with __MVS__, some with EBCDIC and NOT_ASCII.
 * modify LYCookie.c to accept cookies with no value, in case the site resets a
   cookie by nulling out the value (reported by Larry Virden) - BJP
diff --git a/INSTALLATION b/INSTALLATION
index d5395301..3f6d44a2 100644
--- a/INSTALLATION
+++ b/INSTALLATION
@@ -583,18 +583,26 @@ IV. Compile instructions -- Win32 (Windows95/NT)
 
 V. Compile instructions -- 386 DOS
 
-    Compiling for DOS with DJGPP is a multistep procedure.  First install
-    the c compiler and its libraries.  Update the distribution with the
-    patched lib.c, to take care of bug fixes.  It is available at:
-    "http://www.cartsys.com/eldredge/djgpp-patches.html".
-    DJGPP, as distributed from the usual DJGPP archives, will
-    not successfully compile lynx.  You need to "stubedit" your
-    "cc1.exe" file.  The following parameters have worked successfully:
-    minstack=800k, bufsize=64k.  To accomplish this, move to the
-    djgpp\bin directory and type the command:
-	"stubedit cc1.exe bufsize=64k minstack=800k".
-    Or do it interactively with the command: "stubedit cc1.exe".
-    (see "http://www.flora.org/lynx-dev/html/month0897/msg00145.html").
+    Compiling for DOS with DJGPP is a multistep procedure. First install
+    the c compiler and its libraries. If using DJGPP 2.01, update the
+    distribution with the patched lib.c, to take care of bug fixes. It is
+    available at: "http://www.cartsys.com/eldredge/djgpp-patches.html".
+    GCC 2.7.2.1, as distributed from the usual DJGPP archives, will not
+    successfully compile lynx. You need to "stubedit" your "cc1.exe" file.
+    The following parameters have worked successfully: minstack=800k,
+    bufsize=64k. To accomplish this, move to the djgpp\bin directory
+    and type the command:
+    	"stubedit cc1.exe bufsize=64k minstack=800k".
+    Or do it interactively with the command: "stubedit cc1.exe". (see
+    "http://www.flora.org/lynx-dev/html/month0897/msg00145.html").
+
+    If using DJGPP 2.02 and GCC 2.8.1, you may not need to "stubedit"
+    cc1.exe if you use -O2 optimization, since cc1.exe comes with
+    a 1536K stack. To compile with -O3 optimization, the stub
+    needs to be edited to give a larger stack. To do this go into
+    djgpp\lib\gcc-lib\djgpp\2.81 and either type the command:
+   	 "stubedit cc1.exe bufsize=63k minstack=2M",
+    or edit interactively with: "stubedit cc1.exe".
 
     Unpack the source code using a DOS program like UNZIP386.  If you are
     using PKUNZIP to unpack the .zip archive, you must use the -d command
diff --git a/WWW/Library/Implementation/HTDOS.c b/WWW/Library/Implementation/HTDOS.c
index f6697249..8b8231f0 100644
--- a/WWW/Library/Implementation/HTDOS.c
+++ b/WWW/Library/Implementation/HTDOS.c
@@ -38,10 +38,12 @@ char * HTDOS_wwwName ARGS1(char *, dosname)
     if(strlen(wwwname) > 3 && *cp_url == '/')
 	*cp_url = '\0';
 
+#ifdef NOTUSED
     if(*cp_url == ':') {
 	cp_url++;
-	*cp_url = '/';
+	*cp_url = '/';	/* terminate drive letter to survive */
     }
+#endif
 
     return(wwwname);
 }
@@ -65,19 +67,12 @@ char * HTDOS_name ARGS1(char *, wwwname)
 
     for (joe = 0; cp_url[joe] != '\0'; joe++)	{
 	if (cp_url[joe] == '/')	{
-	    cp_url[joe] = '\\';
+	    cp_url[joe] = '\\';	/* convert slashes to dos-style */
 	}
     }
 
-    /* Needed to surf the root of a local drive. */
-
-    if(strlen(cp_url) < 4) cp_url[2] = ':';
-    if(strlen(cp_url) == 3) strcpy(cp_url+3, "\\");
-    if(strlen(cp_url) == 4) strcpy(cp_url+4, ".");
-
-    if((strlen(cp_url) > 2) && (cp_url[1] == '|'))
-	cp_url[1] = ':';
-
+    /* pesky leading slash, rudiment from file://localhost/  */
+    /* the rest of path may be with or without drive letter  */
     if((cp_url[1] == '\\') || (cp_url[0]  != '\\')) {
 	result = cp_url;
     } else {
diff --git a/WWW/Library/Implementation/HTMLDTD.c b/WWW/Library/Implementation/HTMLDTD.c
index be390b3d..84ac15ee 100644
--- a/WWW/Library/Implementation/HTMLDTD.c
+++ b/WWW/Library/Implementation/HTMLDTD.c
@@ -1325,7 +1325,7 @@ static attr ulist_attr[] = {			/* UL attributes */
 **	Must be in alphabetical order.
 **
 **  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
+**  in SGML.c if Old_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
 **
diff --git a/WWW/Library/Implementation/HTString.c b/WWW/Library/Implementation/HTString.c
index 36d0ec64..fa037623 100644
--- a/WWW/Library/Implementation/HTString.c
+++ b/WWW/Library/Implementation/HTString.c
@@ -128,12 +128,16 @@ PUBLIC char * HTSACopy ARGS2(
 	char **,	dest,
 	CONST char *,	src)
 {
-    FREE(*dest);
-    if (src) {
-	*dest = (char *) malloc (strlen(src) + 1);
-	if (*dest == NULL)
-	    outofmem(__FILE__, "HTSACopy");
-	strcpy (*dest, src);
+    if (src != 0) {
+	if (src != *dest) {
+	    FREE(*dest);
+	    *dest = (char *) malloc (strlen(src) + 1);
+	    if (*dest == NULL)
+		outofmem(__FILE__, "HTSACopy");
+	    strcpy (*dest, src);
+	}
+    } else {
+	FREE(*dest);
     }
     return *dest;
 }
@@ -144,7 +148,7 @@ PUBLIC char * HTSACat ARGS2(
 	char **,	dest,
 	CONST char *,	src)
 {
-    if (src && *src) {
+    if (src && *src && (src != *dest)) {
 	if (*dest) {
 	    int length = strlen(*dest);
 	    *dest = (char *)realloc(*dest, length + strlen(src) + 1);
@@ -690,6 +694,55 @@ PRIVATE CONST char *HTAfterCommandArg ARGS2(
 }
 
 /*
+ * Like HTAddParam, but the parameter may be an environment variable, which we
+ * will expand and append.  Do this only for things like the command-verb,
+ * where we obtain the parameter from the user's configuration.  Any quoting
+ * required for the environment variable has to be done within its value, e.g.,
+ *
+ *	setenv EDITOR 'xvile -name "No such class"'
+ *
+ * This is useful only when we quote parameters, of course.
+ */
+#if USE_QUOTED_PARAMETER
+PUBLIC void HTAddXpand ARGS4(
+    char **,		result,
+    CONST char *,	command,
+    int,		number,
+    CONST char *,	parameter)
+{
+    if (*parameter != '$') {
+	HTAddParam (result, command, number, parameter);
+    } else if (number > 0) {
+	CONST char *last = HTAfterCommandArg(command, number - 1);
+	CONST char *next = last;
+
+	parameter = getenv(parameter+1);
+	if (parameter == 0)
+	    parameter = "";
+
+	if (number <= 1) {
+	    FREE(*result);
+	}
+
+	while (next[0] != 0) {
+	    if (HTIsParam(next)) {
+		if (next != last) {
+		    size_t len = (next - last)
+		    		+ ((*result != 0) ? strlen(*result) : 0);
+		    HTSACat(result, last);
+		    (*result)[len] = 0;
+		}
+		HTSACat(result, parameter);
+		CTRACE(tfp, "PARAM-EXP:%s\n", *result);
+		return;
+	    }
+	    next++;
+	}
+    }
+}
+#endif /* USE_QUOTED_PARAMETER */
+
+/*
  * Append string-parameter to a system command that we are constructing.  The
  * string is a complete parameter (which is a necessary assumption so we can
  * quote it properly).  We're given the index of the newest parameter we're
@@ -706,11 +759,11 @@ PUBLIC void HTAddParam ARGS4(
     int,		number,
     CONST char *,	parameter)
 {
-    CONST char *last = HTAfterCommandArg(command, number - 1);
-    CONST char *next = last;
-    char *quoted;
-
     if (number > 0) {
+	CONST char *last = HTAfterCommandArg(command, number - 1);
+	CONST char *next = last;
+	char *quoted;
+
 	if (number <= 1) {
 	    FREE(*result);
 	}
diff --git a/WWW/Library/Implementation/HTString.h b/WWW/Library/Implementation/HTString.h
index 5c093599..f6f3f99d 100644
--- a/WWW/Library/Implementation/HTString.h
+++ b/WWW/Library/Implementation/HTString.h
@@ -71,8 +71,10 @@ extern char * HTSprintf0 () GCC_PRINTFLIKE(2,3);
 
 #if USE_QUOTED_PARAMETER
 extern char *HTQuoteParameter PARAMS((CONST char *parameter));
+extern void HTAddXpand PARAMS((char ** result, CONST char * command, int number, CONST char * parameter));
 #else
 #define HTQuoteParameter(parameter) parameter	/* simplify ifdef'ing */
+#define HTAddXpand(result,command,number,parameter)  HTAddParam(result,command,number,parameter)
 #endif
 
 extern int HTCountCommandArgs PARAMS((CONST char * command));
diff --git a/WWW/Library/Implementation/HTTCP.c b/WWW/Library/Implementation/HTTCP.c
index 42821b4e..8733e997 100644
--- a/WWW/Library/Implementation/HTTCP.c
+++ b/WWW/Library/Implementation/HTTCP.c
@@ -20,6 +20,7 @@
 #include <HTParse.h>
 #include <HTAlert.h>
 #include <HTTCP.h>
+#include <LYGlobalDefs.h>	/* added for no_suspend */
 #include <LYUtils.h>
 
 #ifdef NSL_FORK
@@ -480,6 +481,34 @@ PUBLIC int HTParseInet ARGS2(
 		(void) signal(SIGTERM, quench);
 
 		/*
+		**  Also make sure the child does not run one of the
+		**  signal handlers that may have been installed by
+		**  Lynx if one of those signals occurs.  For example
+		**  we don't want the child to remove temp files on
+		**  ^C, let the parent deal with that. - kw
+		*/
+		(void) signal(SIGINT, quench);
+#ifndef NOSIGHUP
+		(void) signal(SIGHUP, quench);
+#endif /* NOSIGHUP */
+#ifdef SIGTSTP
+		if (no_suspend)
+		    (void) signal(SIGTSTP, SIG_IGN);
+		else
+		    (void) signal(SIGTSTP, SIG_DFL);
+#endif /* SIGTSTP */
+#ifdef SIGWINCH
+		(void) signal(SIGWINCH, SIG_IGN);
+#endif /* SIGWINCH */
+#ifndef __linux__
+#ifndef DOSPATH
+		signal(SIGBUS, SIG_DFL);
+#endif /* DOSPATH */
+#endif /* !__linux__ */
+		signal(SIGSEGV, SIG_DFL);
+		signal(SIGILL, SIG_DFL);
+
+		/*
 		**  Child won't use read side.  -BL
 		*/
 		close(pfd[0]);
diff --git a/WWW/Library/Implementation/SGML.c b/WWW/Library/Implementation/SGML.c
index fd15d5bf..efd5fdba 100644
--- a/WWW/Library/Implementation/SGML.c
+++ b/WWW/Library/Implementation/SGML.c
@@ -240,8 +240,7 @@ extern BOOL soft_dquotes;
 
 #ifdef USE_COLOR_STYLE
 #include <AttrList.h>
-extern char class_string[TEMPSTRINGSIZE];
-int current_is_class=0;
+static int current_is_class=0;
 #endif
 
 /*	Handle Attribute
@@ -614,7 +613,7 @@ PRIVATE BOOL element_valid_within ARGS3(
 		(stacked_tag->tagclass & usecontained));
 }
 
-extern BOOL New_DTD;
+extern BOOL Old_DTD;
 
 typedef enum {
     close_NO	= 0,
@@ -681,7 +680,7 @@ PRIVATE void end_element ARGS2(
     canclose_t canclose_check = close_valid;
     int stackpos = is_on_stack(context, old_tag);
 
-    if (New_DTD) {
+    if (!Old_DTD) {
 	while (canclose_check != close_NO &&
 	       context->element_stack &&
 	       (stackpos > 1 || (!extra_action_taken && stackpos == 0))) {
@@ -803,7 +802,7 @@ PRIVATE void start_element ARGS1(
     BOOL extra_action_taken = NO;
     canclose_t canclose_check = close_valid;
 
-    if (New_DTD) {
+    if (!Old_DTD) {
 	while (context->element_stack &&
 	       (canclose_check == close_valid ||
 		(canclose_check == close_error &&
@@ -2724,7 +2723,7 @@ top1:
 		/*
 		**  Just handle ALL end tags normally :-) - kw
 		*/
-		if (New_DTD) {
+		if (!Old_DTD) {
 		    end_element( context, context->current_tag);
 		} else
 #endif /* EXTENDED_HTMLDTD */
diff --git a/WWW/Library/djgpp/CommonMakefile b/WWW/Library/djgpp/CommonMakefile
index 82ec133d..bfa00d45 100644
--- a/WWW/Library/djgpp/CommonMakefile
+++ b/WWW/Library/djgpp/CommonMakefile
@@ -215,104 +215,104 @@ $(WWW)/Copyright.txt : $(WWW)/../Copyright.html
 #	Directory for object files
 
 $(LOB)/HTList.o : $(OE) $(CMN)HTList.c $(CMN)HTUtils.h $(CMN)HTList.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTList.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTList.c
 
 $(LOB)/HTAnchor.o : $(OE) $(CMN)HTAnchor.c $(CMN)HTUtils.h $(CMN)HTList.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTAnchor.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTAnchor.c
 
 $(LOB)/HTFormat.o : $(OE) $(CMN)HTFormat.c $(CMN)HTUtils.h $(CMN)HTList.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTFormat.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTFormat.c
 
 $(LOB)/HTMIME.o : $(OE) $(CMN)HTMIME.c $(CMN)HTUtils.h $(CMN)HTList.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTMIME.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTMIME.c
 
 $(LOB)/HTHistory.o : $(OE) $(CMN)HTHistory.c $(CMN)HTUtils.h $(CMN)HTList.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTHistory.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTHistory.c
 
 $(LOB)/HTDOS.o : $(OE) $(CMN)HTDOS.c $(CMN)HTUtils.h $(CMN)../../../userdefs.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTDOS.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTDOS.c
 
 $(LOB)/HTNews.o : $(OE) $(CMN)HTNews.c $(CMN)HTUtils.h $(CMN)HTList.h\
 	 $(CMN)HTMLDTD.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTNews.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTNews.c
 
 $(LOB)/HTGopher.o : $(OE) $(CMN)HTGopher.c $(CMN)HTUtils.h $(CMN)HTList.h \
 	 $(CMN)HTMLDTD.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTGopher.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTGopher.c
 
 $(LOB)/HTTelnet.o : $(OE) $(CMN)HTTelnet.c $(CMN)HTUtils.h $(CMN)HTTelnet.h $(CMN)../../../userdefs.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTTelnet.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTTelnet.c
 
 $(LOB)/HTFinger.o : $(OE) $(CMN)HTFinger.c $(CMN)HTUtils.h $(CMN)HTList.h \
 	$(CMN)HTMLDTD.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTFinger.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTFinger.c
 
 $(LOB)/HTStyle.o : $(OE) $(CMN)HTStyle.c $(CMN)HTUtils.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTStyle.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTStyle.c
 
 $(LOB)/HTAtom.o : $(OE) $(CMN)HTAtom.c $(CMN)HTUtils.h $(CMN)HTList.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTAtom.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTAtom.c
 
 $(LOB)/HTChunk.o : $(OE) $(CMN)HTChunk.c $(CMN)HTUtils.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTChunk.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTChunk.c
 
 $(LOB)/HTString.o : $(OE) $(CMN)HTString.c $(CMN)HTUtils.h $(CMN)Version.make
-	$(CC) -c -o $@ $(CFLAGS2) -DVC=\"$(VC)\" $(CMN)HTString.c
+	$(CC) -c  $(CFLAGS2) -DVC=\"$(VC)\" $(CMN)HTString.c
 
 $(LOB)/HTRules.o : $(OE) $(CMN)HTRules.c $(CMN)HTUtils.h $(CMN)Version.make \
 	 $(CMN)HTAAServ.h $(CMN)HTAAProt.h
-	$(CC) -c -o $@ $(CFLAGS2) -DVC=\"$(VC)\" $(CMN)HTRules.c
+	$(CC) -c  $(CFLAGS2) -DVC=\"$(VC)\" $(CMN)HTRules.c
 
 $(LOB)/SGML.o : $(OE) $(CMN)SGML.c $(CMN)HTUtils.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)SGML.c
+	$(CC) -c  $(CFLAGS2) $(CMN)SGML.c
 
 $(LOB)/HTMLGen.o : $(OE) $(CMN)HTMLGen.c $(CMN)HTUtils.h $(CMN)HTMLDTD.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTMLGen.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTMLGen.c
 
 $(LOB)/HTMLDTD.o : $(OE) $(CMN)HTMLDTD.c $(CMN)SGML.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTMLDTD.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTMLDTD.c
 
 $(LOB)/HTPlain.o : $(OE) $(CMN)HTPlain.c $(CMN)HTPlain.h $(CMN)HTStream.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTPlain.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTPlain.c
 
 $(LOB)/HTWAIS.o : $(OE) $(CMN)HTWAIS.c $(CMN)HTUtils.h $(CMN)HTList.h
-	$(CC) -c -o $@ $(CFLAGS2) $(WAISINC) $(CMN)HTWAIS.c
+	$(CC) -c  $(CFLAGS2) $(WAISINC) $(CMN)HTWAIS.c
 
 $(LOB)/HTWSRC.o : $(OE) $(CMN)HTWSRC.c $(CMN)HTUtils.h $(CMN)HTList.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTWSRC.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTWSRC.c
 
 $(LOB)/HTWriter.o : $(OE) $(CMN)HTWriter.c $(CMN)HTWriter.h $(CMN)HTStream.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTWriter.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTWriter.c
 
 
 #	Access Authorization
 
 $(LOB)/HTAAUtil.o : $(OE) $(CMN)HTAAUtil.c $(CMN)HTAAUtil.h \
 	 $(CMN)HTUtils.h $(CMN)HTString.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTAAUtil.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTAAUtil.c
 
 $(LOB)/HTAAFile.o : $(OE) $(CMN)HTAAFile.c $(CMN)HTAAFile.h \
 	 $(CMN)HTAAUtil.h $(CMN)HTUtils.h $(CMN)HTList.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTAAFile.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTAAFile.c
 
 $(LOB)/HTPasswd.o : $(OE) $(CMN)HTPasswd.c $(CMN)HTPasswd.h \
 	 $(CMN)HTAAUtil.h $(CMN)HTAAFile.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTPasswd.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTPasswd.c
 
 $(LOB)/HTGroup.o : $(OE) $(CMN)HTGroup.c $(CMN)HTGroup.h \
 	 $(CMN)HTAAUtil.h $(CMN)HTAAFile.h \
 	 $(CMN)HTAssoc.h $(CMN)HTLex.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTGroup.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTGroup.c
 
 $(LOB)/HTACL.o : $(OE) $(CMN)HTACL.c $(CMN)HTACL.h \
 	 $(CMN)HTAAUtil.h $(CMN)HTAAFile.h $(CMN)HTGroup.h \
 	 $(CMN)HTAssoc.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTACL.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTACL.c
 
 $(LOB)/HTAuth.o : $(OE) $(CMN)HTAuth.c $(CMN)HTAuth.h \
 	 $(CMN)HTAAUtil.h $(CMN)HTPasswd.h $(CMN)HTAAFile.h \
 	 $(CMN)HTAssoc.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTAuth.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTAuth.c
 
 $(LOB)/HTAAServ.o : $(OE) $(CMN)HTAAServ.c $(CMN)HTAAServ.h \
 	$(CMN)HTAAUtil.h $(CMN)HTAAFile.h $(CMN)HTPasswd.h \
@@ -320,52 +320,52 @@ $(LOB)/HTAAServ.o : $(OE) $(CMN)HTAAServ.c $(CMN)HTAAServ.h \
 	 $(CMN)HTUU.h $(CMN)HTParse.h $(CMN)HTList.h \
 	 $(CMN)HTUtils.h $(CMN)HTString.h $(CMN)HTRules.h \
 	 $(CMN)HTAAProt.h $(CMN)HTAssoc.h $(CMN)HTLex.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTAAServ.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTAAServ.c
 
 $(LOB)/HTAABrow.o : $(OE) $(CMN)HTAABrow.c $(CMN)HTAABrow.h \
 	 $(CMN)HTAAUtil.h $(CMN)HTUU.h \
 	 $(CMN)HTUtils.h $(CMN)HTString.h \
 	 $(CMN)HTParse.h $(CMN)HTList.h \
 	 $(CMN)HTAssoc.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTAABrow.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTAABrow.c
 
 $(LOB)/HTAAProt.o : $(OE) $(CMN)HTAAProt.c $(CMN)HTAAProt.h \
 	 $(CMN)HTUtils.h $(CMN)HTAAUtil.h $(CMN)HTAAFile.h \
 	 $(CMN)HTAssoc.h $(CMN)HTLex.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTAAProt.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTAAProt.c
 
 $(LOB)/HTAssoc.o : $(OE) $(CMN)HTAssoc.c $(CMN)HTAssoc.h \
 	$(CMN)HTUtils.h $(CMN)HTString.h $(CMN)HTList.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTAssoc.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTAssoc.c
 
 $(LOB)/HTLex.o : $(OE) $(CMN)HTLex.c $(CMN)HTLex.h $(CMN)HTUtils.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTLex.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTLex.c
 
 $(LOB)/HTUU.o : $(OE) $(CMN)HTUU.c $(CMN)HTUU.h $(CMN)HTUtils.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTUU.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTUU.c
 
 
 #	Communications & Files
 
 $(LOB)/HTTP.o : $(OE) $(CMN)HTTP.c $(CMN)HTUtils.h $(CMN)HTAABrow.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTTP.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTTP.c
 
 $(LOB)/HTTCP.o : $(OE) $(CMN)HTTCP.c $(CMN)HTUtils.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTTCP.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTTCP.c
 
 $(LOB)/HTFile.o : $(OE) $(CMN)HTFile.c $(CMN)HTUtils.h \
 	 $(CMN)HTMLDTD.h $(CMN)HTAAServ.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTFile.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTFile.c
 
 $(LOB)/HTBTree.o : $(OE) $(CMN)HTBTree.c $(CMN)HTUtils.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTBTree.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTBTree.c
 
 $(LOB)/HTFTP.o : $(OE) $(CMN)HTFTP.c $(CMN)HTUtils.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTFTP.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTFTP.c
 
 $(LOB)/HTAccess.o : $(OE)  $(CMN)HTAccess.c $(CMN)HTUtils.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTAccess.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTAccess.c
 
 $(LOB)/HTParse.o : $(OE) $(CMN)HTParse.c $(CMN)HTUtils.h
-	$(CC) -c -o $@ $(CFLAGS2) $(CMN)HTParse.c
+	$(CC) -c  $(CFLAGS2) $(CMN)HTParse.c
 
diff --git a/WWW/Library/djgpp/makefile.sla b/WWW/Library/djgpp/makefile.sla
index 8c974828..b3fe96e0 100644
--- a/WWW/Library/djgpp/makefile.sla
+++ b/WWW/Library/djgpp/makefile.sla
@@ -1,34 +1,34 @@
-#  Make WWW under unix for a.n.other unix system (bsd) 
-#   Use this as a template 
- 
-# For W3 distribution, machine type for subdirectories 
-WWW_MACH = djgpp 
- 
-# The ASIS repository's name for the machine we are on 
-#ASIS_MACH = hardware/os 
- 
-CFLAGS = -O3 -DUSE_SLANG -DUSE_ZLIB -DDOSPATH -DNOUSERS -DDEBUG -DDISP_PARTIAL \ 
--I../Implementation \ 
--I../../../djgpp/tcplib/include \ 
--I../../../djgpp/tcplib/include/tcp \ 
--I../../../src \ 
--I../../.. $(SLANGINC) 
-LFLAGS = 
-CC = gcc 
- 
-# Directory for installed binary: 
-!BINDIR = /usr/local/bin 
- 
-# Where is the W3 object library to be installed (not normally done)? 
-LIBDIR = $(WWW)/Library/Implementation/$(WWW_MACH) 
- 
-#_________________ OK if normal W3 distribution 
-# Where is the WWW source root? 
-WWW = ../.. 
- 
-#  Where should temporary (object) files go? 
-WTMP = ../.. 
- 
-include $(WWW)/Library/Implementation/Version.make 
-#include $(WWW)/Library/Implementation/CommonMakefile 
-include ./CommonMakefile 
+#  Make WWW under unix for a.n.other unix system (bsd)
+#   Use this as a template
+
+# For W3 distribution, machine type for subdirectories
+WWW_MACH = djgpp
+
+# The ASIS repository's name for the machine we are on
+#ASIS_MACH = hardware/os
+
+CFLAGS = -O3 -DUSE_SLANG -DUSE_ZLIB -DDOSPATH -DNOUSERS -DDEBUG -DDISP_PARTIAL \
+-I../Implementation \
+-I../../../djgpp/tcplib/include \
+-I../../../djgpp/tcplib/include/tcp \
+-I../../../src \
+-I../../.. $(SLANGINC)
+LFLAGS =
+CC = gcc
+
+# Directory for installed binary:
+!BINDIR = /usr/local/bin
+
+# Where is the W3 object library to be installed (not normally done)?
+LIBDIR = $(WWW)/Library/Implementation/$(WWW_MACH)
+
+#_________________ OK if normal W3 distribution
+# Where is the WWW source root?
+WWW = ../..
+
+#  Where should temporary (object) files go?
+WTMP = ../..
+
+include $(WWW)/Library/Implementation/Version.make
+#include $(WWW)/Library/Implementation/CommonMakefile
+include ./CommonMakefile
diff --git a/cfg_defs.sh b/cfg_defs.sh
index d20a77f7..4f8a0034 100755
--- a/cfg_defs.sh
+++ b/cfg_defs.sh
@@ -2,7 +2,9 @@
 # Translate the lynx_cfg.h and config.cache data into a table, useful for
 # display at runtime.
 
-cat <<EOF
+OUT=cfg_defs.h
+
+cat >$OUT <<EOF
 #ifndef CFG_DEFS_H
 #define CFG_DEFS_H 1
 
@@ -12,37 +14,14 @@ static CONST struct {
 } config_cache[] = {
 EOF
 
-# Empirical test for format of config.cache.
-#     I'd welcome a better touchstone.
-# Ideally, "configure" should generate a uniform format config.cache.
-#     -- gil
-case `grep '^ac_cv_func_' config.cache | head -1` in
-
-    # `set' quotes correctly as required by POSIX, so do not add quotes.
-  *{*'="'* )
- sed \
+sed \
 	-e '/^#/d'     \
-	-e 's/^.[^=]*_cv_/	{ "/' \
-	-e 's/=\${.*=/", /'	      \
-	-e 's/}$/ },/'	      \
-	config.cache | sort
-  ;;
-    # `set' does not quote correctly, so add quotes
-    #     ( cf. configure script's building config.cache )
-   * )
-sed	-e '/^#/d' \
-	-e 's/"/\\"/g' \
-	-e 's/=}$/=""}/' \
-	-e "s/'/\"/g" \
-	-e 's/^.[^=]*_cv_/	{ "/' \
-	-e 's/=${[^=]*="/", "/' \
-	-e 's/=${[^=]*=/", "/' \
-	-e 's/"}$/}/' \
-	-e 's/}$/" },/' \
-	config.cache | sort
-  ;; esac
+	-e 's/^.[^=]*_cv_//' \
+	-e 's/=\${.*=/=/'  \
+	-e 's/}$//'          \
+	config.cache | cfg_edit.sh >>$OUT
 
-cat <<EOF
+cat >>$OUT <<EOF
 };
 
 static CONST struct {
@@ -50,17 +29,15 @@ static CONST struct {
 	CONST char *value;
 } config_defines[] = {
 EOF
-fgrep	'#define' lynx_cfg.h |sort |
+fgrep	'#define' lynx_cfg.h |
 sed	-e 's@	@ @g' \
 	-e 's@  @ @g' \
-	-e 's@[ ]*#define @@' \
+	-e 's@^[ 	]*#define[ 	]*@@' \
 	-e 's@[ ]*/\*.*\*/@@' \
-	-e 's@"$@@' \
-	-e 's@"@@' \
-	-e 's@ @", "@' \
-	-e 's@^@	{ "@' \
-	-e 's@$@" },@'
-cat <<EOF
+	-e 's@[ 	][ 	]*@=@' \
+    | cfg_edit.sh >>$OUT
+
+cat >>$OUT <<EOF
 };
 
 #endif /* CFG_DEFS_H */
diff --git a/cfg_edit.sh b/cfg_edit.sh
new file mode 100755
index 00000000..6206c6c4
--- /dev/null
+++ b/cfg_edit.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+# Invoked from cfg_defs.sh as a filter
+# Strip leading and trailing whitespace
+# Escape any iternal '\'
+# Escape any iternal '"'
+# Entify any iternal '&', '<' or '>'
+# Append a '=' if none present'
+# Break into two strings at '='
+# Prefix ' { "' and suffix '" },'
+sort |
+sed	-e 's!^[ 	]*!!' -e 's![ 	]*$!!' \
+	-e 's!\\!\\\\!g'        \
+	-e 's!"!\\"!g'          \
+	-e 's!&!\&amp;!g' -e 's!<!\&lt;!g' -e 's!>!\&gt;!g' \
+	-e 's!^[^=]*$!&=!' \
+	-e 's!=!",	"!'     \
+	-e 's!^!	{ "!' -e 's!$!" },!'
diff --git a/lynx.cfg b/lynx.cfg
index 4f330475..458b56fc 100644
--- a/lynx.cfg
+++ b/lynx.cfg
@@ -220,6 +220,7 @@ DEFAULT_INDEX_FILE:http://www.ncsa.uiuc.edu/SDG/Software/Mosaic/MetaIndex.html
 #    ===========================        =========
 #    7 bit approximations (US-ASCII)    us-ascii
 #    Western (ISO-8859-1)               iso-8859-1
+#    Western (ISO-8859-15)              iso-8859-15
 #    Western (cp850)                    cp850
 #    Western (windows-1252)             windows-1252
 #    IBM PC US codepage (cp437)         cp437
@@ -1600,6 +1601,8 @@ MINIMAL_COMMENTS:TRUE
 #KEYMAP:^T:TRACE_TOGGLE	# Toggle tracing of browser operations
 #KEYMAP:*:IMAGE_TOGGLE	# Toggle inclusion of links for all images
 #KEYMAP:[:INLINE_TOGGLE	# Toggle pseudo-ALTs for inlines with no ALT string
+#*** Must be compiled with USE_EXTERNALS to enable EXTERN ***
+#KEYMAP:.:EXTERN	# Run external program with url
 #KEYMAP:0x00:DO_NOTHING	# Does nothing (ignore this key)
 
 # If TOGGLE_HELP is mapped, in novice mode the second help menu line
diff --git a/lynx.man b/lynx.man
index 0a7f02cf..50e6f13c 100644
--- a/lynx.man
+++ b/lynx.man
@@ -5,7 +5,7 @@
 .SH NAME
 lynx \- a general purpose distributed information browser for the World Wide Web
 .SH SYNOPSIS
-.B Lynx
+.B lynx
 [options] [path or URL]
 .PP
 use "lynx -help" to display a complete list of current options.
diff --git a/lynx_help/Lynx_users_guide.html b/lynx_help/Lynx_users_guide.html
index b6c1fab9..cc3f2fae 100644
--- a/lynx_help/Lynx_users_guide.html
+++ b/lynx_help/Lynx_users_guide.html
@@ -1218,7 +1218,7 @@ commands.
 	    create a log can be toggled on with the <em>-tlog</em> switch.
 	    Note that this ability is disabled in anonymous or validation
 	    accounts.
-   <dt><em>*</em>
+   <dt><A NAME="*-key"><em>*</em></A>
 	<dd>The '<em>*</em>' command toggles image_links mode on and off.
 	    When on, links will be created for all images, including inlines.
 	    If you have an image viewer mapped to the image's MIME type, you
@@ -1229,7 +1229,7 @@ commands.
 	    When on, the charset is assumed to match the selected character
 	    set and 8-bit characters are not reverse translated with respect
 	    to the ISO-8859-1 conversion tables.
-   <dt><em>[</em>
+   <dt><A NAME="[-key"><em>[</em></A>
 	<dd>The '<em>[</em>' command toggles pseudo_inlines mode on and off.
 	    When on, inline images which have no ALT string specified will
 	    have an <em>[INLINE]</em> pseudo-ALT string inserted in the Lynx
diff --git a/lynx_help/keystrokes/alt_edit_help.html b/lynx_help/keystrokes/alt_edit_help.html
new file mode 100644
index 00000000..a6da3002
--- /dev/null
+++ b/lynx_help/keystrokes/alt_edit_help.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html public "-//IETF//DTD HTML 3.0//EN">
+<html>
+<head>
+<title>Lynx Line Editor Alternate Key Binding</title>
+<link rev="made" href="mailto:lynx-dev@sig.net">
+</head>
+<body>
+<h1>+++ALTERNATE BINDINGS+++</h1>
+
+Lynx invokes a built-in <em>Line Editor</em> for entering strings in
+response to prompts, in forms, and for email messages if an external editor
+has not been defined.  Administrators can offer additional alternate key
+bindings by adding them in LYEditmap.c before compiling Lynx.  If available,
+they may be selected via the 'o'ptions menu, or by editing lineedit_mode in
+the '.lynxrc' file.
+
+<p>Note: setting emacs/vi keys ON has no effect on line-editor bindings.
+
+<p>This is the <em>Alternate Bindings</em> keymap:
+
+<p><pre>
+     ENTER  Input complete        -  RETURN
+     TAB    Input complete        -  TAB, Do
+     ABORT  Input cancelled       -  Ctrl-G, Ctrl-O, (Ctrl-C on some systems)
+     ERASE  Erase the line        -  Ctrl-U
+
+     BACK   Cursor back     char  -  Left-Arrow,  Ctrl-B
+     FORW   Cursor forward  char  -  Right-Arrow, Ctrl-F
+     BACKW  Cursor back     word  -  Ctrl-P
+     FORWW  Cursor forward  word  -  Ctrl-N
+     BOL    Go to begin of  line  -  Ctrl-A, Home, Find
+     EOL    Go to end   of  line  -  Ctrl-E, End,  Select
+
+     DELP   Delete prev     char  -  Ctrl-H, DELETE, Remove
+     DELN   Delete next [*] char  -  Ctrl-D
+     DELPW  Delete prev     word  -  Ctrl-R
+     DELNW  Delete next     word  -  Ctrl-T
+     DELBL  Delete to beg of line -  Ctrl-X
+     DELEL  Delete to end of line -  Ctrl-K
+
+     UPPER  Upper case the line   -  Ctrl-^
+     LOWER  Lower case the line   -  Ctrl-_
+
+     LKCMD  Invoke cmd prompt     -  Ctrl-V (in form text fields, only)
+
+[*] "next" means the character "under" a box or underline style cursor; it
+     means "to the immediate right of" an I-beam (between characters) type
+     cursor.
+</pre>
+</body>
+</html>
diff --git a/lynx_help/keystrokes/edit_help.html b/lynx_help/keystrokes/edit_help.html
index c58af9b2..d2a7c447 100644
--- a/lynx_help/keystrokes/edit_help.html
+++ b/lynx_help/keystrokes/edit_help.html
@@ -10,42 +10,45 @@
 Lynx invokes a built-in <em>Line Editor</em> for entering strings in
 response to prompts, in forms, and for email messages if an external editor
 has not been defined.  Administrators can offer alternate key bindings
-by adding them in LYEditmap.c before compiling Lynx.  If available, they may 
-be selected via the old-style 'o'ptions menu (see -forms_options command 
-line option), or by editing lineedit_mode in the .lynxrc file. 
- 
-<p>Note: setting emacs/vi keys ON has no effect on line-editor bindings. 
- 
-<p>This is the <em>Default Binding</em>: 
- 
-<p><pre> 
-     ENTER  Input complete        -  RETURN 
-     TAB    Input complete        -  TAB, Do 
-     ABORT  Input cancelled       -  Ctrl-G, Ctrl-O, Ctrl-C 
-     ERASE  Erase the line        -  Ctrl-U, Ctrl-X 
- 
-     BACK   Cursor back     char  -  Left-Arrow 
-     FORW   Cursor forward  char  -  Right-Arrow 
-     BACKW  Cursor back     word  -  Ctrl-P 
-     FORWW  Cursor forward  word  -  Ctrl-N 
-     BOL    Go to begin of  line  -  Ctrl-A, Home, Find 
-     EOL    Go to end   of  line  -  Ctrl-E, End,  Select 
- 
-     DELP   Delete prev     char  -  Ctrl-H, DELETE, Remove 
-     DELN   Delete next [*] char  -  Ctrl-D, Ctrl-R 
-     DELPW  Delete prev     word  -  Ctrl-B 
-     DELNW  Delete next     word  -  Ctrl-F 
-     DELEL  Delete to end of line -  Ctrl-\ 
- 
-     LOWER  Lower case the line   -  Ctrl-K 
-     UPPER  Upper case the line   -  Ctrl-T 
- 
-     LKCMD  Invoke cmd prompt     -  Ctrl-V (in form text fields, only) 
+by adding them in LYEditmap.c before compiling Lynx.  If available, they may
+be selected via the 'o'ptions menu, or by editing lineedit_mode in the
+'.lynxrc' file.
+
+<p>One such alternate key binding, which may be available on your system,
+is the <A HREF="alt_edit_help.html">Alternate Bindings</A> keymap.
+
+<p>Note: setting emacs/vi keys ON has no effect on line-editor bindings.
+
+<p>This is the <em>Default Binding</em> keymap:
+
+<p><pre>
+     ENTER  Input complete        -  RETURN
+     TAB    Input complete        -  TAB, Do
+     ABORT  Input cancelled       -  Ctrl-G, Ctrl-O, (Ctrl-C on some systems)
+     ERASE  Erase the line        -  Ctrl-U, Ctrl-X
+
+     BACK   Cursor back     char  -  Left-Arrow
+     FORW   Cursor forward  char  -  Right-Arrow
+     BACKW  Cursor back     word  -  Ctrl-P
+     FORWW  Cursor forward  word  -  Ctrl-N
+     BOL    Go to begin of  line  -  Ctrl-A, Home, Find
+     EOL    Go to end   of  line  -  Ctrl-E, End,  Select
+
+     DELP   Delete prev     char  -  Ctrl-H, DELETE, Remove
+     DELN   Delete next [*] char  -  Ctrl-D, Ctrl-R
+     DELPW  Delete prev     word  -  Ctrl-B
+     DELNW  Delete next     word  -  Ctrl-F
+     DELEL  Delete to end of line -  Ctrl-_
+
+     UPPER  Upper case the line   -  Ctrl-T
+     LOWER  Lower case the line   -  Ctrl-K
+
+     LKCMD  Invoke cmd prompt     -  Ctrl-V (in form text fields, only)
      SWMAP  Switch input keymap   -  Ctrl-^
- 
-[*] "next" means the character "under" a box or underline type cursor; it 
-     means "to the immediate right of" an I-beam type (between characters) 
-     cursor. 
+
+[*] "next" means the character "under" a box or underline style cursor; it
+     means "to the immediate right of" an I-beam (between characters) type
+     cursor.
 </pre>
 </body>
 </html>
diff --git a/lynx_help/keystrokes/environments.html b/lynx_help/keystrokes/environments.html
index c7d68eab..7a832e8a 100644
--- a/lynx_help/keystrokes/environments.html
+++ b/lynx_help/keystrokes/environments.html
@@ -7,20 +7,19 @@
 
 <em>ENVIRONMENT</em>
        In addition to various  "standard"  environment  variables
-       such  as HOME, PATH, USER, DISPLAY, TMPDIR, etc, Lynx utilizes
-       several Lynx-specific environment variables, <a href="#env">if they
-       exist</a>.
+       such as HOME, PATH, USER, DISPLAY, TMPDIR, etc, Lynx utilizes
+       several Lynx-specific environment variables, <a href="#env">if they exist</a>.
 
-       Others  may be created or modified by Lynx to pass data to
-       an external program, or  for  other  reasons.   These  are
+       Others may be created or modified by Lynx to pass data to
+       an external program, or for other reasons.  These are
        listed separately <a href="#setenv">below</a>.
 
-       See  also the sections on <a href="#cgi">SIMULATED CGI SUPPORT</a> and
+       See also the sections on <a href="#cgi">SIMULATED CGI SUPPORT</a> and
        <a href="#language">NATIVE LANGUAGE SUPPORT</a>, below.
 
        Note:  Not all environment variables apply to all types of
-       platforms  supported by Lynx, though most do.  Feedback on
-       platform dependencies is solicited. See also <a href="#dos">win32/dos</a> specific
+       platforms supported by Lynx, though most do.  Feedback on
+       platform dependencies is solicited.  See also <a href="#dos">win32/dos</a> specific
        variables.
 
 <a name="env"><em>
@@ -105,7 +104,7 @@ Environment Variables Used By Lynx:
                            the  form  PROTOCOL_proxy  (literally:
                            http_proxy,  ftp_proxy,  gopher_proxy,
                            etc), to "http://some.server.dom:port/".
-                           See <a href="#proxy">below</a> for details, and  examples.
+                           See <a href="#proxy">details and examples</a>.
 
        WWW_access_GATEWAY
                            Lynx still  supports  use  of  gateway
@@ -117,8 +116,7 @@ Environment Variables Used By Lynx:
                            discontinued.  Note that  you  do  not
                            include  a  terminal '/' for gateways,
                            but do for proxies specified by PROTOCOL_proxy
-                           environment variables.  See
-                           <a href="#proxy">below</a> for details.
+                           environment variables.  See <a href="#proxy">details</a>.
 
        WWW_HOME
                            This  variable,  if set, will override
diff --git a/lynx_help/keystrokes/option_help.html b/lynx_help/keystrokes/option_help.html
index c7b77225..594010d9 100644
--- a/lynx_help/keystrokes/option_help.html
+++ b/lynx_help/keystrokes/option_help.html
@@ -19,15 +19,20 @@ compiled in or chosen in `lynx.cfg':<P>
 <LI><A HREF="#EM">Emacs keys</A>
 <LI><A HREF="#LL">Execution links</A>
 <LI><A HREF="#KM">Keypad mode</A>
+<LI><A HREF="#LE">Line edit style</A>
 <LI><A HREF="#PM">Personal Mail Address</A>
-<LI><A HREF="#PU">Pop-ups for select fields</A>
 <LI><A HREF="#ST">Searching type</A>
 <LI><A HREF="#SC">Show color</A>
 <LI><A HREF="#CL">Show cursor for current link or option</A>
 <LI><A HREF="#UM">User Mode</A>
-<LI><A HREF="#VB">Verbose Images</A>
 <LI><A HREF="#VI">VI keys</A>
 <LI><A HREF="#DV">X DISPLAY variable</A></UL>
+<LI>Document Layout
+<UL>
+<LI><A HREF="#tagsoup">HTML error tolerance</A>
+<LI><A HREF="#PU">Pop-ups for select fields</A>
+<LI><A HREF="#SI">Show Images</A>
+<LI><A HREF="#VB">Verbose Images</A></UL>
 <LI>Bookmark Options
 <UL>
 <LI><A HREF="#MB">Multi-bookmarks</A>
@@ -47,9 +52,6 @@ compiled in or chosen in `lynx.cfg':<P>
 <LI><A HREF="#PC">Preferred Document Charset</A>
 <LI><A HREF="#PL">Preferred Document Language</A>
 <LI><A HREF="#UA">User Agent</A></UL>
-<LI> -- not in Options Form --
-<UL>
-<LI><A HREF="#LE">Line edit style</A></UL>
 </UL>
 
 <H1><A NAME="CK">Cookies</A></H1>
@@ -68,6 +70,7 @@ If set to 'ON' then the CTRL-P, CTRL-N, CTRL-F and CTRL-B keys will be mapped
 to up-arrow, down-arrow, right-arrow and left-arrow respectively.  Otherwise,
 they remain mapped to their configured bindings (normally UP_TWO lines,
 DOWN_TWO lines, NEXT_PAGE and PREV_PAGE respectively).
+<p>Note: setting emacs keys does not affect the line-editor bindings. 
 
 <H1><A NAME="LL">Execution links</A></H1>
 
@@ -82,6 +85,13 @@ see Lynx Navigation) and having every link numbered (numbered links)
 so that the links may be selected by numbers instead of moving to them
 with the arrow keys.  You can also number form fields.
 
+<H1><A NAME="LE">Line edit style</A></H1> 
+ 
+This allows you to set alternate key bindings for the built-in line editor, 
+if your system administrator has installed  
+<A HREF="alt_edit_help.html">Alternate Bindings</A>. 
+Otherwise, Lynx uses the <A HREF="edit_help.html">Default Binding</A>. 
+ 
 <H1><A NAME="PM">Personal Mail Address</A></H1>
 
 You may set your mail address here so that when mailing messages
@@ -157,6 +167,68 @@ for beginners.
 <dt><EM>Advanced</EM>: The URL is shown on the status line.
 </dl>
 
+<H1><A NAME="tagsoup">HTML error tolerance</A></H1>
+
+Lynx often has to deal with invalid HTML markup.  It always tries to 
+recover from errors, but there is no universally correct way for doing 
+this.  As a result, there are two parsing modes: 
+"<DFN>SortaSGML</DFN>" attempts to enforce valid nesting of most tags 
+at an earlier stage of processing, while "<DFN>TagSoup</DFN>" relies 
+more on the HTML rendering stage to mimic the behavior of some other 
+browsers. 
+You can also switch between these modes with the CTRL-V key, and the 
+default can be changed in lynx.cfg or with the -tagsoup command line 
+switch. 
+ 
+<P> 
+The "SortaSGML" mode will often appear to be more strict, and makes 
+some errors apparent that are otherwise unnoticeable.  One particular 
+difference is the handling of block elements or 
+&lt;li&gt;..&lt;/li&gt; inside &lt;a HREF="some.url"&gt;..&lt;/a&gt;. 
+Invalid nesting like this may turn anchors into hidden links which 
+cannot be easily followed, this is avoided in "TagSoup" mode.  See the 
+<a href="follow_help.html">help on following links by 
+number</a> for more information on hidden links.  Often pages may be 
+more readable in "TagSoup" mode, but sometimes the opposite is true. 
+Most documents with valid HTML, and documents with only minor errors, 
+should be rendered the same way in both modes. 
+ 
+<P> 
+If you are curious about what goes on behind the scenes, but find that 
+the information from the -trace switch is just too much, Lynx can be 
+started with the -preparsed switch; going into SOURCE mode ('\' key) 
+and toggling the parsing mode (with CTRL-V) should then show some of 
+the differences. 
+
+<!--
+LP's version - for reference - TD
+
+While the proper HTML markup should be canonical, badly nested HTML pages
+may be recovered in different ways.  There are two error recovery modes
+in Lynx: SortaSGML with the recovery at SGML stage and TagSoup mode
+with the recovery at HTML parsing stage, the latter gives more
+recovery and was the default in Lynx 2.7.2 and before,
+and the first may be useful for page validation purposes.
+One particular difference is known for &lt;li&gt;..&lt;/li&gt;
+or similar strong markup inside &lt;a HREF="some.url"&gt;..&lt;/a&gt;
+anchor text - those links are not reachable in SortaSGML
+(such markup should be placed outside &lt;a&gt;..&lt;/a&gt; indeed).
+Default recovery mode can also be switched with CTRL-V key,
+from lynx.cfg or command line switch.
+-->
+
+
+<H1><A NAME="SI">Show Images</A></H1>
+
+Text-based browser cannot show images directly, so we have a choice:
+ignore all images without ALT= text string (this is also switched by
+<A HREF="../Lynx_users_guide.html#[-key">'[' key</A>),
+show labels (see also "verbose images" for choice between [IMAGE] and filename),
+use links for every image to make it possible to download them
+(also switched by <A HREF="../Lynx_users_guide.html#*-key">'*' key</A>).
+Changing these settings will not be saved but could be made permanent
+by changing the respective settings in lynx.cfg.
+
 <H1><A NAME="VB">Verbose Images</A></H1>
 
 Controls whether or not Lynx replaces the [LINK], [INLINE] and [IMAGE] comments
@@ -170,6 +242,7 @@ If set to 'ON' then the lowercase h, j, k and l keys will be mapped
 to left-arrow, down-arrow, up-arrow and right-arrow respectively.
 <p>The uppercase H, J, K, and L keys remain mapped to their configured bindings
 (normally HELP, JUMP, KEYMAP and LIST, respectively).
+<p>Note: setting vi keys does not affect the line-editor bindings. 
 
 <H1><A NAME="DV">X DISPLAY variable</A></H1>
 
@@ -308,12 +381,6 @@ be prosecuted.  DO NOT misrepresent Lynx as Mozilla.  The Options Menu issues
 a warning about possible copyright infringement whenever the header is changed
 to one which does not include `Lynx' or `lynx'.
 
-<H1><A NAME="LE">Line edit style</A></H1>
-
-This allows you to set alternate key bindings for the built-in line editor,
-if your system administrator has installed alternates.
-Otherwise, Lynx uses the <A HREF="edit_help.html">Default Binding</A>.
-
 </BODY>
 </HTML>
 
diff --git a/makefile.in b/makefile.in
index f0314299..8b2bbb69 100644
--- a/makefile.in
+++ b/makefile.in
@@ -295,7 +295,6 @@ install-doc : $(docdir)
 	@echo Copying sample files
 	(cd $(srcdir) && tar cf - C[HO]* PROBLEMS README samples test ) | \
 			       ( cd $(docdir) && tar xf - )
-	-rm -f $(libdir)/lynx.tmp
 
 # HPUX 'sed' does not seem to like '=' as pattern delimiter.
 FIX_SED = tr '=' '%'
@@ -370,9 +369,9 @@ LYHelp.h : LYHelp.hin
 	@echo
 	@echo '**********************************************'
 
-cfg_defs.h : $(srcdir)/cfg_defs.sh
+cfg_defs.h : $(srcdir)/cfg_defs.sh config.cache lynx_cfg.h
 	@rm -f $@
-	$(SHELL) $(srcdir)/cfg_defs.sh >$@
+	PATH=$(srcdir):$$PATH $(SHELL) -c '$(srcdir)/cfg_defs.sh'
 
 install-cfg : $(libdir)
 	-mv -f $(libdir)/lynx.cfg $(libdir)/lynx.oldcfg
diff --git a/po/makefile.inn b/po/makefile.inn
index e7b2e666..e7b1250d 100644
--- a/po/makefile.inn
+++ b/po/makefile.inn
@@ -28,7 +28,7 @@ subdir = po
 
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
-MKINSTALLDIRS = $(top_srcdir)/@MKINSTALLDIRS@
+MKINSTALLDIRS = @MKINSTALLDIRS@
 
 CC = @CC@
 GENCAT = @GENCAT@
@@ -113,7 +113,7 @@ install-data-yes: all
 	if test -r $(MKINSTALLDIRS); then \
 	  $(MKINSTALLDIRS) $(datadir); \
 	else \
-	  $(top_srcdir)/mkinstalldirs $(datadir); \
+	  $(top_srcdir)/mkdirs.sh $(datadir); \
 	fi
 	@catalogs='$(CATALOGS)'; \
 	for cat in $$catalogs; do \
@@ -127,7 +127,7 @@ install-data-yes: all
 	  if test -r $(MKINSTALLDIRS); then \
 	    $(MKINSTALLDIRS) $$dir; \
 	  else \
-	    $(top_srcdir)/mkinstalldirs $$dir; \
+	    $(top_srcdir)/mkdirs.sh $$dir; \
 	  fi; \
 	  if test -r $$cat; then \
 	    $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
@@ -155,7 +155,7 @@ install-data-yes: all
 	  if test -r $(MKINSTALLDIRS); then \
 	    $(MKINSTALLDIRS) $(gettextsrcdir); \
 	  else \
-	    $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
+	    $(top_srcdir)/mkdirs.sh $(gettextsrcdir); \
 	  fi; \
 	  $(INSTALL_DATA) $(srcdir)/makefile.inn \
 			  $(gettextsrcdir)/makefile.inn; \
diff --git a/src/AttrList.h b/src/AttrList.h
index b58456ff..f7bb894c 100644
--- a/src/AttrList.h
+++ b/src/AttrList.h
@@ -4,8 +4,6 @@
 #include <HText.h>
 #include <HTMLDTD.h>
 
-#define TEMPSTRINGSIZE 256
-
 enum {
  ABS_OFF = 0,
  STACK_OFF = 0,
@@ -18,12 +16,12 @@ enum {
 enum {
  DSTYLE_LINK = HTML_A+STARTAT,
  DSTYLE_STATUS = HTML_ELEMENTS+STARTAT,
- DSTYLE_ALINK, /* active link */
- DSTYLE_NORMAL, /* default attributes */
-	DSTYLE_OPTION, 		/* option on the option screen */
-	DSTYLE_VALUE, 		/* value on the option screen */
-	DSTYLE_HIGH,
- DSTYLE_CANDY, /* possibly going to vanish */
+ DSTYLE_ALINK,		/* active link */
+ DSTYLE_NORMAL,		/* default attributes */
+ DSTYLE_OPTION, 	/* option on the option screen */
+ DSTYLE_VALUE, 		/* value on the option screen */
+ DSTYLE_HIGH,
+ DSTYLE_CANDY,		/* possibly going to vanish */
  DSTYLE_ELEMENTS
 };
 
@@ -48,14 +46,6 @@ typedef struct {
  int cattr; /* attributes to go with the color */
 } HTCharStyle;
 
-#ifdef NOT_USED
-
-typedef struct _linkedlist {
- char name[64];
- struct _linkedlist *next;
-} linked_list;
-#endif
-
 #define HText_characterStyle CTRACE(tfp,"HTC called from %s/%d\n",__FILE__,__LINE__);_internal_HTC
 
 #undef HText_characterStyle
@@ -63,6 +53,8 @@ typedef struct _linkedlist {
 
 #if defined(USE_COLOR_STYLE)
 extern void _internal_HTC PARAMS((HText * text, int style, int dir));
+#define TEMPSTRINGSIZE 256
+extern char class_string[TEMPSTRINGSIZE];
 #endif
 
 #endif
diff --git a/src/GridText.c b/src/GridText.c
index 2fee3cb9..e1100d00 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -1160,10 +1160,8 @@ PRIVATE void display_page ARGS3(
 	/*
 	 *  Currently implemented only for LINUX
 	 */
-	stop_curses();
 	UCChangeTerminalCodepage(current_char_set,
 				 &LYCharSet_UC[current_char_set]);
-	start_curses();
 #endif /* LINUX */
 #endif /* EXP_CHARTRANS_AUTOSWITCH */
     }
@@ -1180,8 +1178,13 @@ PRIVATE void display_page ARGS3(
     }
 
 #ifdef USE_COLOR_STYLE
+#ifdef DISP_PARTIAL
+    if (display_partial ||
+	line_number != text->first_lineno_last_disp_partial ||
+	line_number > text->last_lineno_last_disp_partial)
+#endif /* DISP_PARTIAL */
     LynxResetScreenCache();
-#endif
+#endif /* USE_COLOR_STYLE */
 
     text->top_of_screen = line_number;
     display_title(text);  /* will move cursor to top of screen */
@@ -1610,6 +1613,7 @@ PRIVATE void display_page ARGS3(
 #ifdef DISP_PARTIAL
     if (display_partial && display_flag &&
 	last_disp_partial >= text->top_of_screen &&
+	!enable_scrollback &&
 	!recent_sizechange) {	/*  really remember them if ok - kw  */
 	text->first_lineno_last_disp_partial = text->top_of_screen;
 	text->last_lineno_last_disp_partial = last_disp_partial;
@@ -2368,7 +2372,6 @@ PUBLIC void HText_appendCharacter ARGS2(
 	    CTRACE(tfp, "add(%c) %d/%d\n", ch,
 		   HTisDocumentSource(), HTOutputFormat != WWW_SOURCE);
 	}
-	FREE(special);
     } /* trace only */
 #endif /* DEBUG_APPCH */
 
@@ -3107,7 +3110,7 @@ PUBLIC void HText_endAnchor ARGS2(
 	     */
 	    i = a->extent;
 	}
-	j = (last->size - i);
+	k = j = (last->size - i);
 	while (j < last->size) {
 	    if (!IsSpecialAttrChar(last->data[j]) &&
 		!isspace((unsigned char)last->data[j]) &&
@@ -3146,11 +3149,12 @@ PUBLIC void HText_endAnchor ARGS2(
 	while (i == 0 &&
 	       (a->extent > CurBlankExtent ||
 		(a->extent == CurBlankExtent &&
+		 k == 0 &&
 		 prev != text->last_line &&
 		 (prev->size == 0 ||
 		  prev->data[prev->size - 1] == ']')))) {
 	    start = prev;
-	    j = prev->size - a->extent + CurBlankExtent;
+	    k = j = prev->size - a->extent + CurBlankExtent;
 	    if (j < 0) {
 		/*
 		 *  The anchor starts on a preceding line,
@@ -3175,7 +3179,8 @@ PUBLIC void HText_endAnchor ARGS2(
 	    }
 	    if (i == 0) {
 		if (a->extent > (CurBlankExtent + prev->size) ||
-		    (a->extent == CurBlankExtent + prev->size &&
+		    (a->extent == CurBlankExtent + (int)prev->size &&
+		     k == 0 &&
 		     prev->prev != text->last_line &&
 		     (prev->prev->size == 0 ||
 		      prev->prev->data[prev->prev->size - 1] == ']'))) {
@@ -4634,6 +4639,17 @@ PUBLIC BOOL HText_select ARGS1(
 	 */
 	if (text)
 	    text->page_has_target = NO;
+
+#ifdef DISP_PARTIAL
+	/* Reset these for the previous and current text. - kw */
+	text->first_lineno_last_disp_partial =
+	    text->last_lineno_last_disp_partial = -1;
+	if (HTMainText) {
+	    HTMainText->first_lineno_last_disp_partial =
+		HTMainText->last_lineno_last_disp_partial = -1;
+	}
+#endif /* DISP_PARTIAL */
+
 	/*
 	 *  Make this text the most current in the loaded texts list. - FM
 	 */
diff --git a/src/HTAlert.c b/src/HTAlert.c
index 7b44d086..f47c0251 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -111,8 +111,12 @@ PUBLIC void HTReadProgress ARGS2(
 	if (transfer_rate <= 0)    /* the very first time */
 	    transfer_rate = (bytes) / (now - first);   /* bytes/sec */
 
-	/* optimal refresh time: every 0.2 sec */
-	if ((bytes - bytes_last) > (transfer_rate / 5)) {
+	/*
+	 * Optimal refresh time:  every 0.2 sec, use interpolation.  Transfer
+	 * rate is not constant when we have partial content in a proxy, so
+	 * interpolation lies - will check every second at least for sure.
+	 */
+	if (((bytes - bytes_last) > (transfer_rate / 5)) || (now != last)) {
 
 	    bytes_last += (transfer_rate / 5);	/* until we got next second */
 
@@ -412,7 +416,6 @@ PUBLIC BOOL HTConfirmCookie ARGS4(
 	CONST char *,	name,
 	CONST char *,	value)
 {
-    char message[256];
     domain_entry *de;
     int ch, namelen, valuelen, space_free;
 
@@ -471,9 +474,11 @@ PUBLIC BOOL HTConfirmCookie ARGS4(
 	valuelen = (int)(percentage*(float)valuelen);
     }
     if(!LYAcceptAllCookies) {
-	sprintf(message, ADVANCED_COOKIE_CONFIRMATION,
-		server, namelen, name, valuelen, value);
+	char *message = 0;
+	HTSprintf(&message, ADVANCED_COOKIE_CONFIRMATION,
+		 server, namelen, name, valuelen, value);
 	_statusline(message);
+	free(message);
     }
     while (1) {
 	if(!LYAcceptAllCookies) {
@@ -542,9 +547,10 @@ PUBLIC int HTConfirmPostRedirect ARGS2(
 	CONST char *,	Redirecting_url,
 	int,		server_status)
 {
+    int result = -1;
     char *show_POST_url = NULL;
-    char StatusInfo[256];
-    char url[256];
+    char *StatusInfo = 0;
+    char *url = 0;
     int on_screen = 0;	/* 0 - show menu
 			 * 1 - show url
 			 * 2 - menu is already on screen */
@@ -576,16 +582,14 @@ PUBLIC int HTConfirmPostRedirect ARGS2(
 	}
     }
 
-    StatusInfo[254] = StatusInfo[255] = '\0';
-    url[254] = url[(LYcols < 250 ? LYcols-1 : 255)] = '\0';
     if (user_mode == NOVICE_MODE) {
 	on_screen = 2;
 	move(LYlines-2, 0);
-	sprintf(StatusInfo, SERVER_ASKED_FOR_REDIRECTION, server_status);
+	HTSprintf0(&StatusInfo, SERVER_ASKED_FOR_REDIRECTION, server_status);
 	addstr(StatusInfo);
 	clrtoeol();
 	move(LYlines-1, 0);
-	sprintf(url, "URL: %.*s",
+	HTSprintf0(&url, "URL: %.*s",
 		    (LYcols < 250 ? LYcols-6 : 250), Redirecting_url);
 	addstr(url);
 	clrtoeol();
@@ -595,7 +599,7 @@ PUBLIC int HTConfirmPostRedirect ARGS2(
 	    _statusline(PROCEED_OR_CANCEL);
 	}
     } else {
-	sprintf(StatusInfo, "%d %.*s",
+	HTSprintf0(&StatusInfo, "%d %.*s",
 			    server_status,
 			    251,
 			    ((server_status == 301) ?
@@ -604,7 +608,7 @@ PUBLIC int HTConfirmPostRedirect ARGS2(
 	StrAllocCopy(show_POST_url, LOCATION_HEADER);
 	StrAllocCat(show_POST_url, Redirecting_url);
     }
-    while (1) {
+    while (result < 0) {
 	int c;
 
 	switch (on_screen) {
@@ -622,7 +626,8 @@ PUBLIC int HTConfirmPostRedirect ARGS2(
 		**  with same method and POST content. - FM
 		*/
 		FREE(show_POST_url);
-		return 1;
+		result = 1;
+		break;
 
 	    case 7:
 	    case 'C':
@@ -630,7 +635,8 @@ PUBLIC int HTConfirmPostRedirect ARGS2(
 		**  Cancel request.
 		*/
 		FREE(show_POST_url);
-		return 0;
+		result = 0;
+		break;
 
 	    case 'U':
 		/*
@@ -651,7 +657,8 @@ PUBLIC int HTConfirmPostRedirect ARGS2(
 		    **	Treat as 303 (GET without content).
 		    */
 		    FREE(show_POST_url);
-		    return 303;
+		    result = 303;
+		    break;
 		}
 		/* fall through to default */
 
@@ -666,4 +673,7 @@ PUBLIC int HTConfirmPostRedirect ARGS2(
 		}
 	}
     }
+    FREE(StatusInfo);
+    FREE(url);
+    return (result);
 }
diff --git a/src/HTFWriter.c b/src/HTFWriter.c
index c1f82ef1..de3c6019 100644
--- a/src/HTFWriter.c
+++ b/src/HTFWriter.c
@@ -459,7 +459,7 @@ PUBLIC HTStream* HTSaveAndExecute ARGS3(
 	HTParentAnchor *,	anchor,
 	HTStream *,		sink)
 {
-    char fnam[256];
+    char fnam[LY_MAXPATH];
     CONST char *suffix;
     HTStream* me;
 
@@ -513,7 +513,7 @@ PUBLIC HTStream* HTSaveAndExecute ARGS3(
     } else {
 	/*
 	 *  Check for a suffix.
-	 *	Save the file under a suitably suffixed name.
+	 *  Save the file under a suitably suffixed name.
 	 */
 	if (!strcasecomp(pres->rep->name, "text/html")) {
 	    suffix = HTML_SUFFIX;
@@ -577,7 +577,7 @@ PUBLIC HTStream* HTSaveToFile ARGS3(
 	HTStream *,		sink)
 {
     HTStream * ret_obj;
-    char fnam[256];
+    char fnam[LY_MAXPATH];
     CONST char * suffix;
     char *cp;
     int c = 0;
@@ -802,8 +802,8 @@ PUBLIC HTStream* HTCompressed ARGS3(
     HTPresentation *Pres = NULL;
     int n, i;
     BOOL can_present = FALSE;
-    char fnam[256];
-    char temp[256];
+    char fnam[LY_MAXPATH];
+    char temp[LY_MAXPATH];	/* actually stores just a suffix */
     CONST char *suffix;
     char *uncompress_mask = NULL;
     char *compress_suffix = "";
diff --git a/src/HTInit.c b/src/HTInit.c
index ef0d284c..cad2f766 100644
--- a/src/HTInit.c
+++ b/src/HTInit.c
@@ -967,7 +967,9 @@ PRIVATE void HTGetWord ARGS4(
 PRIVATE int HTLoadExtensionsConfigFile ARGS1(
 	char *,		fn)
 {
-    char l[MAX_STRING_LEN],w[MAX_STRING_LEN],*ct;
+    char line[MAX_STRING_LEN];
+    char word[MAX_STRING_LEN];
+    char *ct;
     FILE *f;
     int count = 0;
 
@@ -978,24 +980,24 @@ PRIVATE int HTLoadExtensionsConfigFile ARGS1(
 	return count;
     }
 
-    while (!(HTGetLine(l,MAX_STRING_LEN,f))) {
-	HTGetWord(w, l, ' ', '\t');
-	if (l[0] == '\0' || w[0] == '#')
+    while (!(HTGetLine(line,sizeof(line),f))) {
+	HTGetWord(word, line, ' ', '\t');
+	if (line[0] == '\0' || word[0] == '#')
 	    continue;
-	ct = (char *)malloc(sizeof(char) * (strlen(w) + 1));
+	ct = (char *)malloc(sizeof(char) * (strlen(word) + 1));
 	if (!ct)
 	    outofmem(__FILE__, "HTLoadExtensionsConfigFile");
-	strcpy(ct,w);
+	strcpy(ct,word);
 	LYLowerCase(ct);
 
-	while(l[0]) {
-	    HTGetWord(w, l, ' ', '\t');
-	    if (w[0] && (w[0] != ' ')) {
-		char *ext = (char *)malloc(sizeof(char) * (strlen(w)+1+1));
+	while(line[0]) {
+	    HTGetWord(word, line, ' ', '\t');
+	    if (word[0] && (word[0] != ' ')) {
+		char *ext = (char *)malloc(sizeof(char) * (strlen(word)+1+1));
 	        if (!ext)
 	            outofmem(__FILE__, "HTLoadExtensionsConfigFile");
 
-		sprintf(ext, ".%s", w);
+		sprintf(ext, ".%s", word);
 		LYLowerCase(ext);
 
 		CTRACE (tfp, "SETTING SUFFIX '%s' to '%s'.\n", ext, ct);
diff --git a/src/HTML.c b/src/HTML.c
index cd7dac93..486b1b15 100644
--- a/src/HTML.c
+++ b/src/HTML.c
@@ -56,7 +56,6 @@
 #include <LYStyle.h>
 #undef SELECTED_STYLES
 #define pHText_changeStyle(X,Y,Z) {}
-char Style_className[16384];
 #endif
 
 #include <LYexit.h>
@@ -607,14 +606,42 @@ PUBLIC void HTML_write ARGS3(HTStructured *, me, CONST char*, s, int, l)
 
 #ifdef USE_COLOR_STYLE
 char class_string[TEMPSTRINGSIZE];
-char prevailing_class[TEMPSTRINGSIZE];
 #endif
 
 #ifdef USE_COLOR_STYLE
-    char myHash[128];
-    int hcode;
+static char *Style_className;
+static char myHash[128];
+static int hcode;
 #endif
 
+#ifdef USE_COLOR_STYLE
+PRIVATE void TrimColorClass ARGS1(char *, tagname)
+{
+    char *end, *start=NULL, *lookfrom;
+    char tmp[64];
+
+    sprintf(tmp, ";%.*s", (int) sizeof(tmp) - 3, tagname);
+    strtolower(tmp);
+
+    if ((lookfrom = Style_className) != 0) {
+	do {
+	    end = start;
+	    start = strstr(lookfrom, tmp);
+	    if (start)
+		lookfrom = start + 1;
+	}
+	while (start);
+	/* trim the last matching element off the end
+	** - should match classes here as well (rp)
+	*/
+	if (end)
+	    *end='\0';
+    }
+    hcode = hash_code(lookfrom && *lookfrom ? lookfrom : &tmp[1]);
+    CTRACE(tfp, "CSS:%s (trimmed %s)\n", Style_className, tmp);
+}
+#endif /* USE_COLOR_STYLE */
+
 /*	Start Element
 **	-------------
 */
@@ -664,55 +691,41 @@ PRIVATE void HTML_start_element ARGS6(
 
 /* this should be done differently */
 #if defined(USE_COLOR_STYLE)
-	strcat (Style_className, ";");
-	strcat (Style_className, HTML_dtd.tags[element_number].name);
-	strcpy (myHash, HTML_dtd.tags[element_number].name);
-	if (class_string[0])
-	{
-		strcat (Style_className, ".");
-		strcat (Style_className, class_string);
-		strcat (myHash, ".");
-		strcat (myHash, class_string);
-#ifdef PREVAIL
-		strcpy (prevailing_class, class_string);
-#endif
-	}
-#ifdef PREVAIL
-	else if (prevailing_class[0])
-	{
-		strcat (Style_className, ".");
-		strcat (Style_className, prevailing_class);
-		strcat (myHash, ".");
-		strcat (myHash, prevailing_class);
-	}
-#endif /* PREVAIL */
-	class_string[0]='\0';
-	strtolower(myHash);
-	hcode=hash_code(myHash);
-	strtolower(Style_className);
-
-	if (TRACE)
+    HTSprintf (&Style_className, ";%s", HTML_dtd.tags[element_number].name);
+    strcpy (myHash, HTML_dtd.tags[element_number].name);
+    if (class_string[0])
+    {
+	HTSprintf (&Style_className, ".%s", class_string);
+	strcat (myHash, ".");
+	strcat (myHash, class_string);
+    }
+    class_string[0] = '\0';
+    strtolower(myHash);
+    hcode = hash_code(myHash);
+    strtolower(Style_className);
+
+    if (TRACE)
+    {
+	fprintf(tfp, "CSSTRIM:%s -> %d", myHash, hcode);
+	if (hashStyles[hcode].code!=hcode)
 	{
-		fprintf(tfp, "CSSTRIM:%s -> %d", myHash, hcode);
-		if (hashStyles[hcode].code!=hcode)
-		{
-			char *rp=strrchr(myHash, '.');
-			fprintf(tfp, " (undefined) %s\n", myHash);
-			if (rp)
-			{
-				int hcd;
-				*rp='\0'; /* trim the class */
-				hcd = hash_code(myHash);
-				fprintf(tfp, "CSS:%s -> %d", myHash, hcd);
-				if (hashStyles[hcd].code!=hcd)
-					fprintf(tfp, " (undefined) %s\n", myHash);
-				else
-					fprintf(tfp, " ca=%d\n", hashStyles[hcd].color);
-			}
-		}
+	    char *rp=strrchr(myHash, '.');
+	    fprintf(tfp, " (undefined) %s\n", myHash);
+	    if (rp)
+	    {
+		int hcd;
+		*rp='\0'; /* trim the class */
+		hcd = hash_code(myHash);
+		fprintf(tfp, "CSS:%s -> %d", myHash, hcd);
+		if (hashStyles[hcd].code!=hcd)
+		    fprintf(tfp, " (undefined) %s\n", myHash);
 		else
-			fprintf(tfp, " ca=%d\n", hashStyles[hcode].color);
+		    fprintf(tfp, " ca=%d\n", hashStyles[hcd].color);
+	    }
 	}
+	else
+	    fprintf(tfp, " ca=%d\n", hashStyles[hcode].color);
+    }
 
     if (displayStyles[element_number + STARTAT].color > -2) /* actually set */
     {
@@ -5252,43 +5265,16 @@ PRIVATE void HTML_start_element ARGS6(
 #define REALLY_EMPTY(e) ((HTML_dtd.tags[e].contents == SGML_EMPTY) && \
 			 !(HTML_dtd.tags[e].flags & Tgf_nreie))
 
-	if (REALLY_EMPTY(element_number))
-	{
-		CTRACE(tfp, "STYLE:begin_element:ending EMPTY element style\n");
+    if (REALLY_EMPTY(element_number))
+    {
+	CTRACE(tfp, "STYLE:begin_element:ending EMPTY element style\n");
 #if !defined(USE_HASH)
 	HText_characterStyle(me->text, element_number+STARTAT, STACK_OFF);
 #else
 	HText_characterStyle(me->text, hcode, STACK_OFF);
 #endif /* USE_HASH */
-		{
-			char *end, *start=NULL, *lookfrom;
-			char tmp[64];
-			sprintf(tmp, ";%s", HTML_dtd.tags[element_number].name);
-			strtolower(tmp);
-
-			lookfrom = Style_className;
-			do
-			{
-				end = start;
-				start = strstr(lookfrom, tmp);
-				if (start)
-				    lookfrom = start + 1;
-			}
-			while (start);
-			if (end)
-				*end='\0';
-
-#if defined(PREVAIL)
-			start=strrchr(Style_className, '.');
-			if (start)
-				strcpy(prevailing_class, (start+1));
-			else
-				strcpy(prevailing_class, "");
-#endif
-
-			CTRACE(tfp, "CSS:%s (trimmed %s, SGML_EMPTY)\n", Style_className, tmp);
-		}
-	}
+	TrimColorClass(HTML_dtd.tags[element_number].name);
+    }
 #endif /* USE_COLOR_STYLE */
 }
 
@@ -6627,29 +6613,7 @@ End_Object:
 
     } /* switch */
 #ifdef USE_COLOR_STYLE
-    {
-	char *end, *start=NULL, *lookfrom;
-	char tmp[64];
-	sprintf(tmp, ";%s", HTML_dtd.tags[element_number].name);
-	strtolower(tmp);
-
-	lookfrom = Style_className;
-	do
-	{
-	    end = start;
-	    start = strstr(lookfrom, tmp);
-	    if (start)
-		lookfrom = start + 1;
-	}
-	while (start);
-/* trim the last matching element off the end
-** - should match classes here as well (rp)
-*/
-	if (end)
-	    *end='\0';
-	hcode = hash_code(lookfrom && *lookfrom ? lookfrom : &tmp[1]);
-	CTRACE(tfp, "CSS:%s (trimmed %s, END_ELEMENT)\n", Style_className, tmp);
-    }
+    TrimColorClass(HTML_dtd.tags[element_number].name);
 
     if (!REALLY_EMPTY(element_number))
     {
@@ -6659,15 +6623,6 @@ End_Object:
 #else
 	HText_characterStyle(me->text, hcode, STACK_OFF);
 #endif /* USE_HASH */
-#if defined(PREVAIL)
-	/* reset the prevailing class to the previous one */
-	{
-		char *dot=strrchr(Style_className,'.');
-		LYstrncpy(prevailing_class,
-			  dot ? (dot+1) : "",
-			  (TEMPSTRINGSIZE - 1));
-	}
-#endif
     }
 #endif /* USE_COLOR_STYLE */
 }
@@ -7234,9 +7189,8 @@ PUBLIC HTStructured* HTML_new ARGS3(
     me->comment_end = NULL;
 
 #ifdef USE_COLOR_STYLE
-    Style_className[0] = '\0';
+    FREE(Style_className);
     class_string[0] = '\0';
-    prevailing_class[0] = '\0';
 #endif
 
 #ifdef NOTUSED_FOTEMODS
diff --git a/src/LYBookmark.c b/src/LYBookmark.c
index 1a400ed3..612e5984 100644
--- a/src/LYBookmark.c
+++ b/src/LYBookmark.c
@@ -25,6 +25,18 @@ PUBLIC char *MBM_A_subdescript[MBM_V_MAXFILES+1];
 PRIVATE BOOLEAN is_mosaic_hotlist = FALSE;
 PRIVATE char * convert_mosaic_bookmark_file PARAMS((char *filename_buffer));
 
+PRIVATE void
+show_bookmark_not_defined NOARGS
+{
+    char *string_buffer = 0;
+
+    HTSprintf0(&string_buffer,
+	    BOOKMARK_FILE_NOT_DEFINED,
+	    key_for_func(LYK_OPTIONS));
+    LYMBM_statusline(string_buffer);
+    free(string_buffer);
+}
+
 /*
  *  Tries to open a bookmark file for reading, which may be
  *  the default, or based on offering the user a choice from
@@ -41,8 +53,8 @@ PRIVATE char * convert_mosaic_bookmark_file PARAMS((char *filename_buffer));
 PUBLIC char * get_bookmark_filename ARGS1(
 	char **,	URL)
 {
-    static char filename_buffer[256];
-    char string_buffer[256];
+    static char filename_buffer[LY_MAXPATH];
+    char string_buffer[BUFSIZ];
     FILE *fp;
     int MBM_tmp;
 
@@ -57,10 +69,7 @@ PUBLIC char * get_bookmark_filename ARGS1(
 	 */
 	return("");
     if (MBM_tmp == -1) {
-	sprintf(string_buffer,
-		BOOKMARK_FILE_NOT_DEFINED,
-		key_for_func(LYK_OPTIONS));
-	HTAlert(string_buffer);
+	show_bookmark_not_defined();
 	/*
 	 *  Space flags an undefined selection. - FMG
 	 */
@@ -80,7 +89,6 @@ PUBLIC char * get_bookmark_filename ARGS1(
     /*
      *	Seek it in the home path. - FM
      */
-    filename_buffer[255] = '\0';
     LYAddPathToHome(filename_buffer,
 		    sizeof(filename_buffer),
 		    BookmarkPage);
@@ -100,7 +108,7 @@ success:
      *	We now have the file open.
      *	Check if it is a mosaic hotlist.
      */
-    if (fgets(string_buffer, 255, fp) &&
+    if (fgets(string_buffer, sizeof(string_buffer)-1, fp) &&
 	!strncmp(string_buffer, "ncsa-xmosaic-hotlist-format-1", 29)) {
 	char *newname;
 	/*
@@ -127,7 +135,7 @@ success:
 PRIVATE char * convert_mosaic_bookmark_file ARGS1(
 	char *, 	filename_buffer)
 {
-    static char newfile[256];
+    static char newfile[LY_MAXPATH];
     FILE *fp, *nfp;
     char buf[BUFSIZ];
     int line = -2;
@@ -191,8 +199,8 @@ PUBLIC void save_bookmark_link ARGS2(
     BOOLEAN first_time = FALSE;
     char *filename;
     char *bookmark_URL = NULL;
-    char filename_buffer[256];
-    char string_buffer[256];
+    char filename_buffer[LY_MAXPATH];
+    char string_buffer[BUFSIZ];
     char *Address = NULL;
     char *Title = NULL;
     int i, c;
@@ -261,7 +269,6 @@ PUBLIC void save_bookmark_link ARGS2(
     /*
      *	Allow user to change the title. - FM
      */
-    string_buffer[sizeof(string_buffer)-1] = '\0';
     do {
 	LYstrncpy(string_buffer, title, sizeof(string_buffer)-1);
 	convert_to_spaces(string_buffer, FALSE);
@@ -414,12 +421,12 @@ PUBLIC void remove_bookmark_link ARGS2(
     char filename_buffer[NAM$C_MAXRSS+12];
     char newfile[NAM$C_MAXRSS+12];
 #else
-    char filename_buffer[256];
-    char newfile[256];
+    char filename_buffer[LY_MAXPATH];
+    char newfile[LY_MAXPATH];
     struct stat stat_buf;
     mode_t mode;
 #endif /* VMS */
-    char homepath[256];
+    char homepath[LY_MAXPATH];
 
     CTRACE(tfp, "remove_bookmark_link: deleting link number: %d\n", cur);
 
@@ -514,19 +521,9 @@ PUBLIC void remove_bookmark_link ARGS2(
      *	it is writable by the current process.
      *	Changed to copy  1998-04-26 -- gil
      */
-    {	char buffer[3072];
-
-	sprintf(buffer, "%s %s %s && %s %s",
-	    COPY_PATH, newfile, filename_buffer,
-	    RM_PATH, newfile);
-
-	CTRACE(tfp, "remove_bookmark_link: %s\n", buffer);
-	if( LYSystem( buffer ) ) {
-	    HTAlert(BOOKTEMP_COPY_FAIL);
-	} else {
-	    return;
-	}
-    }
+    if (LYCopyFile(newfile, filename_buffer) == 0) 
+	return;
+    HTAlert(BOOKTEMP_COPY_FAIL);
 #else  /* !UNIX */
     if (rename(newfile, filename_buffer) != -1) {
 	HTSYS_purge(filename_buffer);
@@ -544,9 +541,14 @@ PUBLIC void remove_bookmark_link ARGS2(
 	if (errno == EXDEV)
 #endif /* WINDOWS */
 	{
-	    char buffer[2048];
-	    sprintf(buffer, "%s %s %s", MV_PATH, newfile, filename_buffer);
+	    static CONST char MV_FMT[] = "%s %s %s";
+	    char *buffer = 0;
+	    HTAddParam(&buffer, MV_FMT, 1, MV_PATH);
+	    HTAddParam(&buffer, MV_FMT, 2, newfile);
+	    HTAddParam(&buffer, MV_FMT, 3, filename_buffer);
+	    HTEndParam(&buffer, MV_FMT, 3);
 	    LYSystem(buffer);
+	    FREE(buffer);
 	    return;
 	}
 #endif /* !VMS */
@@ -658,8 +660,6 @@ PUBLIC int select_menu_multi_bookmarks NOARGS
 {
     int c, MBM_tmp_count, MBM_allow;
     int MBM_screens, MBM_from, MBM_to, MBM_current;
-    char string_buffer[256];
-    char shead_buffer[256];
 
     /*
      *	If not enabled, pick the "default" (0).
@@ -702,12 +702,6 @@ PUBLIC int select_menu_multi_bookmarks NOARGS
 	HTAlert(MULTIBOOKMARKS_SMALL);
 	return (-2);
     }
-    /*
-     *	Load the bad choice message buffer.
-     */
-    sprintf(string_buffer,
-	    BOOKMARK_FILE_NOT_DEFINED,
-	    key_for_func(LYK_OPTIONS));
 
     MBM_screens = (MBM_V_MAXFILES/MBM_allow)+1; /* int rounds off low. */
 
@@ -733,9 +727,11 @@ draw_bookmark_choices:
     move(1, 5);
     lynx_start_h1_color ();
     if (MBM_screens > 1) {
-	sprintf(shead_buffer,
+	char *shead_buffer = 0;
+	HTSprintf0(&shead_buffer,
 		MULTIBOOKMARKS_SHEAD_MASK, MBM_current, MBM_screens);
 	addstr(shead_buffer);
+	free(shead_buffer);
     } else {
 	addstr(MULTIBOOKMARKS_SHEAD);
     }
@@ -837,8 +833,7 @@ get_bookmark_choice:
     if (c < 0 || c > MBM_V_MAXFILES) {
 	goto get_bookmark_choice;
     } else if (!MBM_A_subbookmark[c]) {
-	LYMBM_statusline(string_buffer);
-	sleep(AlertSecs);
+	show_bookmark_not_defined();
 	LYMBM_statusline(MULTIBOOKMARKS_SAVE);
 	goto get_bookmark_choice;
     } else {
@@ -948,9 +943,8 @@ PRIVATE  BOOLEAN have8bit ARGS1(CONST char *, Title)
 PRIVATE  char* title_convert8bit ARGS1(CONST char *, Title)
 {
     CONST char *p = Title;
-    char temp[256];
     char *p0;
-    char *q = temp;
+    char *q;
     char *comment = NULL;
     char *ncr     = NULL;
     char *buf = NULL;
@@ -958,25 +952,24 @@ PRIVATE  char* title_convert8bit ARGS1(CONST char *, Title)
     int charset_out = UCGetLYhndl_byMIME("us-ascii");
 
     for ( ; *p; p++) {
-	LYstrncpy(q, p, 1);
-	if ((unsigned char)*q <= 127) {
-	    StrAllocCat(comment, q);
-	    StrAllocCat(ncr, q);
+	char temp[2];
+	LYstrncpy(temp, p, sizeof(temp)-1);
+	if ((unsigned char)*temp <= 127) {
+	    StrAllocCat(comment, temp);
+	    StrAllocCat(ncr, temp);
 	} else {
-	    int uck;
 	    long unicode;
-	    char replace_buf [10], replace_buf2 [10];
+	    char replace_buf [32];
 
-	    uck = UCTransCharStr(replace_buf, sizeof(replace_buf), *q,
-				  charset_in, charset_out, YES);
-	    if (uck >0)
+	    if (UCTransCharStr(replace_buf, sizeof(replace_buf), *temp,
+				  charset_in, charset_out, YES) > 0)
 		StrAllocCat(comment, replace_buf);
 
-	    unicode = UCTransToUni( *q, charset_in);
+	    unicode = UCTransToUni( *temp, charset_in);
 
 	    StrAllocCat(ncr, "&#");
-	    sprintf(replace_buf2, "%ld", unicode);
-	    StrAllocCat(ncr, replace_buf2);
+	    sprintf(replace_buf, "%ld", unicode);
+	    StrAllocCat(ncr, replace_buf);
 	    StrAllocCat(ncr, ";");
 	}
     }
diff --git a/src/LYCgi.c b/src/LYCgi.c
index e939d308..7cd4a4af 100644
--- a/src/LYCgi.c
+++ b/src/LYCgi.c
@@ -67,6 +67,18 @@ PRIVATE char *post_len;
 
 PRIVATE void add_environment_value PARAMS((char *env_value));
 
+#define PERROR(msg) CTRACE(tfp, "LYNXCGI: %s: %s\n", msg, LYStrerror(errno))
+
+#ifdef HAVE_STRERROR
+#define LYStrerror(n) strerror(n)
+#else
+PRIVATE char *LYStrerror ARGS1(int, code)
+{
+    static char temp[80];
+    sprintf(temp, "System errno is %d.\r\n", code);
+    return temp;
+}
+#endif /* HAVE_STRERROR */
 
 /*
  * Simple routine for expanding the environment array and adding a value to
@@ -178,16 +190,14 @@ PRIVATE int LYLoadCGI ARGS4(
 		*cp = '\0';
 		statrv = 999;	/* force new stat()  - kw */
 	    } else {
-		if (TRACE)
-		    perror("LYNXCGI: strrchr(pgm_buff, '/') returned NULL");
+		PERROR("strrchr(pgm_buff, '/') returned NULL");
 	    	break;
 	    }
         }
 
 	if (statrv < 0) {
 	    /* Did not find PATH_INFO data */
-	    if (TRACE)
-		perror("LYNXCGI: stat() of pgm_buff failed");
+	    PERROR("stat() of pgm_buff failed");
 	} else {
 	    /* Found PATH_INFO data.  Strip it off of pgm and into path_info. */
 	    StrAllocCopy(path_info, pgm+strlen(pgm_buff));
@@ -205,9 +215,7 @@ PRIVATE int LYLoadCGI ARGS4(
 	 *  backing up were stat()able. - kw
 	 */
 	HTAlert(gettext("Unable to access cgi script"));
-	if (TRACE) {
-	    perror("LYNXCGI: stat() failed");
-	}
+	PERROR("stat() failed");
 	status = -4;
 
     } else if (!(S_ISREG(stat_buf.st_mode) &&
@@ -323,16 +331,12 @@ PRIVATE int LYLoadCGI ARGS4(
 
 	} else if (anAnchor->post_data && pipe(fd1) < 0) {
 	    HTAlert(CONNECT_SET_FAILED);
-	    if (TRACE) {
-		perror("LYNXCGI: pipe() failed");
-	    }
+	    PERROR("pipe() failed");
 	    status = -3;
 
 	} else if (pipe(fd2) < 0) {
 	    HTAlert(CONNECT_SET_FAILED);
-	    if (TRACE) {
-		perror("LYNXCGI: pipe() failed");
-	    }
+	    PERROR("pipe() failed");
 	    close(fd1[0]);
 	    close(fd1[1]);
 	    status = -3;
@@ -354,6 +358,8 @@ PRIVATE int LYLoadCGI ARGS4(
 			LYNX_NAME, LYNX_VERSION);
 		add_environment_value(server_software);
 	    }
+	    fflush(stdout);
+	    fflush(stderr);
 
 	    if ((pid = fork()) > 0) { /* The good, */
 		int chars, total_chars;
@@ -382,9 +388,7 @@ PRIVATE int LYLoadCGI ARGS4(
 			    if (errno == ERESTARTSYS)
 				continue;
 #endif /* ERESTARTSYS */
-			    if (TRACE) {
-				perror("LYNXCGI: write() of POST data failed");
-			    }
+			    PERROR("write() of POST data failed");
 			    break;
 			}
 			CTRACE(tfp, "LYNXCGI: Wrote %d bytes of POST data.\n",
@@ -402,11 +406,34 @@ PRIVATE int LYLoadCGI ARGS4(
 		}
 
 		HTReadProgress(total_chars = 0, 0);
-		while((chars = read(fd2[0], buf, sizeof(buf))) > 0) {
+		while((chars = read(fd2[0], buf, sizeof(buf))) != 0) {
+		    if (chars < 0) {
+#ifdef EINTR
+			if (errno == EINTR)
+			    continue;
+#endif /* EINTR */
+#ifdef ERESTARTSYS
+			if (errno == ERESTARTSYS)
+			    continue;
+#endif /* ERESTARTSYS */
+			PERROR("read() of CGI output failed");
+			break;
+		    }
 		    HTReadProgress(total_chars += chars, 0);
 		    CTRACE(tfp, "LYNXCGI: Rx: %.*s\n", chars, buf);
 		    (*target->isa->put_block)(target, buf, chars);
 		}
+
+		if (chars < 0 && total_chars == 0) {
+		    status = HT_NOT_LOADED;
+		    (*target->isa->_abort)(target, NULL);
+		    target = NULL;
+		} else if (chars != 0) {
+		    status = HT_PARTIAL_CONTENT;
+		} else {
+		    status = HT_LOADED;
+		}
+
 #if !HAVE_WAITPID
 		while (wait(&wstatus) != pid)
 		    ; /* do nothing */
@@ -424,12 +451,12 @@ PRIVATE int LYLoadCGI ARGS4(
 		}
 #endif /* !HAVE_WAITPID */
 		close(fd2[0]);
-		status = HT_LOADED;
 
 	    } else if (pid == 0) { /* The Bad, */
 		char **argv = NULL;
 		int argv_cnt = 3; /* name, one arg and terminator */
 		char **cur_argv = NULL;
+		int exec_errno;
 
 		/* Set up output pipe */
 		close(fd2[0]);
@@ -497,7 +524,7 @@ PRIVATE int LYLoadCGI ARGS4(
 		    /* Data for a get/search form */
 		    if (is_www_index) {
 			add_environment_value("REQUEST_METHOD=SEARCH");
-		    } else if (!anAnchor->isHEAD) {
+		    } else if (!anAnchor->isHEAD && !anAnchor->post_data) {
 			add_environment_value("REQUEST_METHOD=GET");
 		    }
 
@@ -523,6 +550,8 @@ PRIVATE int LYLoadCGI ARGS4(
 			}
 			cp++;
 		    }
+		} else if (!anAnchor->isHEAD && !anAnchor->post_data) {
+		    add_environment_value("REQUEST_METHOD=GET");
 		}
 		*cur_argv = NULL;	/* Terminate argv */
 		argv[0] = pgm;
@@ -557,15 +586,20 @@ PRIVATE int LYLoadCGI ARGS4(
 		/* End WebSter Mods  -jkt */
 
 		execve(argv[0], argv, env);
-		if (TRACE) {
-		    perror("LYNXCGI: execve failed");
+		exec_errno = errno;
+		PERROR("execve failed");
+		printf("Content-Type: text/plain\r\n\r\n");
+		if (!anAnchor->isHEAD) {
+		    printf("exec of %s failed", pgm);
+		    printf(": %s.\r\n", LYStrerror(exec_errno));
 		}
+		fflush(stdout);
+		fflush(stderr);
+		_exit(1);
 
 	    } else {	/* and the Ugly */
 		HTAlert(CONNECT_FAILED);
-		if (TRACE) {
-		    perror("LYNXCGI: fork() failed");
-		}
+		PERROR("fork() failed");
 		status = HT_NO_DATA;
 		close(fd1[0]);
 		close(fd1[1]);
diff --git a/src/LYCharSets.c b/src/LYCharSets.c
index dafda5b8..10708495 100644
--- a/src/LYCharSets.c
+++ b/src/LYCharSets.c
@@ -328,6 +328,7 @@ PUBLIC CONST char * SevenBitApproximations[] = {
  */
 PUBLIC CONST char ** LYCharSets[MAXCHARSETS]={
 	ISO_Latin1,		/* ISO Latin 1		*/
+	SevenBitApproximations, /* ISO 8859-15 (Latin 9)*/
 	SevenBitApproximations, /* DosLatin1 (cp850)	*/
 	SevenBitApproximations, /* WinLatin1 (cp1252)	*/
 	SevenBitApproximations, /* DosLatinUS (cp437)	*/
@@ -350,6 +351,7 @@ PUBLIC CONST char ** LYCharSets[MAXCHARSETS]={
  */
 PUBLIC CONST char * LYchar_set_names[MAXCHARSETS + 1]={
 	"Western (ISO-8859-1)",
+	"Western (ISO-8859-15)",
 	"Western (cp850)",
 	"Western (windows-1252)",
 	"IBM PC US codepage (cp437)",
@@ -391,6 +393,7 @@ PUBLIC LYUCcharset LYCharSet_UC[MAXCHARSETS]=
   /*
    *  Placeholders for Unicode tables. - FM
    */
+  {-1,"iso-8859-15",   UCT_ENC_8BIT,0,0,0,     UCT_R_8BIT,UCT_R_ASCII},
   {-1,"cp850",         UCT_ENC_8BIT,0,
                        UCT_REP_SUPERSETOF_LAT1,
                        0,                      UCT_R_8BIT,UCT_R_ASCII},
@@ -439,6 +442,7 @@ PUBLIC LYUCcharset LYCharSet_UC[MAXCHARSETS]=
  */
 PUBLIC int LYlowest_eightbit[MAXCHARSETS]={
 	160,	/* ISO Latin 1		*/
+	160,	/* ISO 8859-15 (Latin 9)*/
 	128,	/* DosLatin1 (cp850)	*/
 	130,	/* WinLatin1 (cp1252)	*/
 	128,	/* DosLatinUS (cp437)	*/
diff --git a/src/LYCharUtils.c b/src/LYCharUtils.c
index d29fde06..54bac073 100644
--- a/src/LYCharUtils.c
+++ b/src/LYCharUtils.c
@@ -334,7 +334,7 @@ PUBLIC void LYFillLocalFileURL ARGS2(
     }
 
 #if defined(DOSPATH) || defined(__EMX__)
-    if (*(*href+1) == ':') {
+    if (isalpha(*(*href)) && (*(*href+1) == ':'))  {
 	/*
 	 * If it's a local DOS path beginning with drive letter,
 	 * add file://localhost/ prefix and go ahead.
@@ -342,6 +342,18 @@ PUBLIC void LYFillLocalFileURL ARGS2(
 	StrAllocCopy(temp, *href);
 	LYLocalFileToURL (href, temp);
     }
+
+    /* use below: strlen("file://localhost/") = 17 */
+    if (!strncmp(*href, "file://localhost/", 17)
+	  && (strlen(*href) == 19)
+	  && isalpha(*(*href+17))
+	  && (*(*href+18) == ':')) {
+	/*
+	 * Terminate DOS drive letter with a slash to surf root successfully.
+	 * Here seems a proper place to do so.
+	 */
+	StrAllocCat(*href, "/");
+    }
 #endif /* DOSPATH */
 
     /*
@@ -353,9 +365,9 @@ PUBLIC void LYFillLocalFileURL ARGS2(
 #ifdef VMS
 	temp2 = HTVMS_wwwName(getenv("PATH"));
 #else
-	char curdir[DIRNAMESIZE];
+	char curdir[LY_MAXPATH];
 #if HAVE_GETCWD
-	getcwd (curdir, DIRNAMESIZE);
+	getcwd (curdir, sizeof(curdir));
 #else
 	getwd (curdir);
 #endif /* NO_GETCWD */
@@ -2888,7 +2900,7 @@ PUBLIC void LYHandleMETA ARGS4(
 		     *	but this is a Netscapism, so don't
 		     *	expect the author to know that. - FM
 		     */
-		    HTAlert(REFRESH_URL_NOT_ABSOLUTE);
+		    HTUserMsg(REFRESH_URL_NOT_ABSOLUTE);
 		    /*
 		     *	Use the document's address
 		     *	as the base. - FM
diff --git a/src/LYDownload.c b/src/LYDownload.c
index d15dc1d3..3b813265 100644
--- a/src/LYDownload.c
+++ b/src/LYDownload.c
@@ -22,10 +22,7 @@
  *  LYNXDOWNLOAD://Method=<#>/File=<STRING>/SugFile=<STRING>
  */
 #ifdef VMS
-#define COPY_COMMAND "copy/nolog/noconf %s %s"
 PUBLIC BOOLEAN LYDidRename = FALSE;
-#else
-#define COPY_COMMAND "%s %s %s"
 #endif /* VMS */
 
 PRIVATE char LYValidDownloadFile[LY_MAXPATH] = "\0";
@@ -264,14 +261,7 @@ check_recall:
 	     *	Failed.  Use spawned COPY_COMMAND. - FM
 	     */
 	    CTRACE(tfp, "         FAILED!\n");
-	    HTAddParam(&the_command, COPY_COMMAND, 1, file);
-	    HTAddParam(&the_command, COPY_COMMAND, 2, buffer);
-	    HTEndParam(&the_command, COPY_COMMAND, 2);
-	    CTRACE(tfp, "command: %s\n", the_command);
-	    stop_curses();
-	    LYSystem(the_command);
-	    FREE(the_command);
-	    start_curses();
+	    LYCopyFile(file, buffer);
 	} else {
 	    /*
 	     *	We don't have the temporary file (it was renamed to
@@ -283,16 +273,8 @@ check_recall:
 	chmod(buffer, HIDE_CHMOD);
 #else /* Unix: */
 
-	HTAddParam(&the_command, COPY_COMMAND, 1, COPY_PATH);
-	HTAddParam(&the_command, COPY_COMMAND, 2, file);
-	HTAddParam(&the_command, COPY_COMMAND, 3, buffer);
-	HTEndParam(&the_command, COPY_COMMAND, 3);
+	LYCopyFile(file, buffer);
 
-	CTRACE(tfp, "command: %s\n", the_command);
-	stop_curses();
-	LYSystem(the_command);
-	FREE(the_command);
-	start_curses();
 #if defined(UNIX)
 	LYRelaxFilePermissions(buffer);
 #endif /* defined(UNIX) */
@@ -539,7 +521,7 @@ PUBLIC int LYdownload_options ARGS2(
 	if (!lynx_edit_mode)
 #endif /* DIRED_SUPPORT */
 	fprintf(fp0,
-		"  <a href=\"LYNXDOWNLOAD://Method=-1/File=%s/SugFile=%s%s\">%s</a>\n",
+		"   <a href=\"LYNXDOWNLOAD://Method=-1/File=%s/SugFile=%s%s\">%s</a>\n",
 		data_file,
 		(lynx_save_space ? lynx_save_space : ""),
 		sug_filename,
diff --git a/src/LYEdit.c b/src/LYEdit.c
index 772e4fa3..acd3cffb 100644
--- a/src/LYEdit.c
+++ b/src/LYEdit.c
@@ -77,16 +77,11 @@ PUBLIC int edit_current_file ARGS3(
 #endif /* !VMS */
 	filename = HTParse(newfile, "", PARSE_PATH+PARSE_PUNCTUATION);
 	HTUnEscape(filename);
-#if defined (DOSPATH) || defined (__EMX__)
-	if (strlen(filename) > 1) {	/* FIXME: why do we need to do this? */
-	    int n;
-	    for (n = 0; (filename[n] = filename[n+1]) != 0; n++)
-		;
-	}
-#endif
-	if ((fp = fopen(HTSYS_name(filename), "r")) == NULL)
+	StrAllocCopy(filename, HTSYS_name(filename));
+	if ((fp = fopen(filename, "r")) == NULL)
 	{
 	    HTAlert(COULD_NOT_ACCESS_FILE);
+	    CTRACE(tfp, "filename: '%s'\n", filename);
 	    goto done;
 	}
 #if !defined (VMS) && !defined (DOSPATH) && !defined (__EMX__)
@@ -98,7 +93,7 @@ PUBLIC int edit_current_file ARGS3(
     /*
      *  Don't allow editing if user lacks append access.
      */
-    if ((fp = fopen(HTSYS_name(filename), "a")) == NULL)
+    if ((fp = fopen(filename, "a")) == NULL)
     {
 	HTUserMsg(NOAUTH_TO_EDIT_FILE);
 	goto done;
@@ -127,20 +122,20 @@ PUBLIC int edit_current_file ARGS3(
     if (editor_can_position() && *position) {
 #ifdef VMS
 	format = "%s %s -%s";
-	HTAddParam(&command, format, params++, editor);
-	HTAddParam(&command, format, params++, HTVMS_name("", filename));
+	HTAddXpand(&command, format, params++, editor);
+	HTAddParam(&command, format, params++, filename);
 	HTAddParam(&command, format, params++, position);
 	HTEndParam(&command, format, params);
 #else
 	format = "%s +%s %s";
-	HTAddParam(&command, format, params++, editor);
+	HTAddXpand(&command, format, params++, editor);
 	HTAddParam(&command, format, params++, position);
-	HTAddParam(&command, format, params++, HTSYS_name(filename));
+	HTAddParam(&command, format, params++, filename);
 	HTEndParam(&command, format, params);
 #endif
     } else {
-	HTAddParam(&command, format, params++, editor);
-	HTAddParam(&command, format, params++, HTSYS_name(filename));
+	HTAddXpand(&command, format, params++, editor);
+	HTAddParam(&command, format, params++, filename);
 	HTEndParam(&command, format, params);
     }
 
diff --git a/src/LYEditmap.c b/src/LYEditmap.c
index a7e50807..e9912a06 100644
--- a/src/LYEditmap.c
+++ b/src/LYEditmap.c
@@ -33,7 +33,7 @@ LYE_UPPER,      LYE_ERASE,      LYE_LKCMD,      LYE_NOP,
 LYE_ERASE,      LYE_NOP,        LYE_NOP,        LYE_NOP,
 /* ^X           ^Y              ^Z              ESC     */
 
-LYE_NOP,        LYE_NOP,        LYE_SWMAP,      LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_SWMAP,      LYE_DELEL,
 /* ^\           ^]              ^^              ^_      */
 
 /* sp .. RUBOUT                                         */
@@ -110,15 +110,17 @@ LYE_NOP,        LYE_TAB,        LYE_BOL,        LYE_EOL,
 /* F1           Do key          Find key        Select key  */
 
 LYE_NOP,        LYE_DELP,       LYE_NOP,        LYE_NOP,
-/* Insert key   Remove key      MOUSE_KEY       DO_NOTHING         */
+/* Insert key   Remove key      MOUSE_KEY       DO_NOTHING  */
 };
 
 /*
  * Add your favorite key bindings HERE
  */
 
-/* 01 */ /* Default except that  ^F=cursor-forward  and  ^B=cursor-backward */
-/*    */
+/* KED-01 */ /* Default except: ^B=cursor-backward,  ^F=cursor-forward,   */
+             /*                 ^K=delete-to-EOL,    ^X=delete-to-BOL,    */
+             /*                 ^R=delete-prev-word, ^T=delete-next-word, */
+             /*                 ^^=upper-case-line,  ^_=lower-case-line   */
 
 #ifdef EXP_ALT_BINDINGS
 PRIVATE char BetterEditBinding[]={
@@ -141,7 +143,7 @@ LYE_BACKW,      LYE_NOP,        LYE_DELPW,      LYE_NOP,
 LYE_DELNW,      LYE_ERASE,      LYE_LKCMD,      LYE_NOP,
 /* ^T           ^U              ^V              ^W      */
 
-LYE_ERASE,      LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_DELBL,      LYE_NOP,        LYE_NOP,        LYE_NOP,
 /* ^X           ^Y              ^Z              ESC     */
 
 LYE_NOP,        LYE_NOP,        LYE_UPPER,      LYE_LOWER,
@@ -221,7 +223,7 @@ LYE_NOP,        LYE_TAB,        LYE_BOL,        LYE_EOL,
 /* F1           Do key          Find key        Select key  */
 
 LYE_NOP,        LYE_DELP,       LYE_NOP,        LYE_NOP,
-/* Insert key   Remove key      DO_NOTHING      ...         */
+/* Insert key   Remove key      MOUSE_KEY       DO_NOTHING  */
 };
 #endif
 
diff --git a/src/LYGetFile.c b/src/LYGetFile.c
index b0c6968d..7fe1df76 100644
--- a/src/LYGetFile.c
+++ b/src/LYGetFile.c
@@ -603,8 +603,10 @@ Try_Redirected_URL:
 			    *cp1 = '\0';
 			    cp1 += 2;
 			    StrAllocCopy(temp, doc->address);
-			    LYAddHtmlSep(&temp);
-			    StrAllocCat(temp, wwwName(Home_Dir()));
+			    StrAllocCopy(cp, wwwName(Home_Dir()));
+			    if (!LYIsHtmlSep(*cp))
+				LYAddHtmlSep(&temp);
+			    StrAllocCat(temp, cp);
 			    if ((cp2 = strchr(cp1, '/')) != NULL) {
 				LYTrimRelFromAbsPath(cp2);
 				StrAllocCat(temp, cp2);
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index 40752064..4000b353 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -96,7 +96,6 @@ extern BOOLEAN LYUseNoviceLineTwo;  /* True if TOGGLE_HELP is not mapped */
 extern char star_string[MAX_LINE + 1]; /* from GridText.c */
 #define STARS(n) \
  ((n) >= MAX_LINE ? star_string : &star_string[(MAX_LINE-1)] - (n))
-#define DIRNAMESIZE 256
 
 #define SHOW_COLOR_UNKNOWN	(-1)
 #define SHOW_COLOR_NEVER  0
@@ -326,7 +325,7 @@ extern BOOLEAN no_externals; 		/* don't allow the use of externals */
 extern BOOLEAN LYNoISMAPifUSEMAP;	/* Omit ISMAP link if MAP present? */
 extern int LYHiddenLinks;
 
-extern BOOL New_DTD;
+extern BOOL Old_DTD;
 
 #define MBM_V_MAXFILES  25		/* Max number of sub-bookmark files */
 /*
diff --git a/src/LYKeymap.c b/src/LYKeymap.c
index 852799e9..338fb202 100644
--- a/src/LYKeymap.c
+++ b/src/LYKeymap.c
@@ -673,12 +673,12 @@ PRIVATE char *pretty ARGS1 (int, c)
 	return buf;
 }
 
-PRIVATE BOOL format_binding ARGS3(
-	char *,			buf,
+PRIVATE char * format_binding ARGS2(
 	unsigned short *,	table,
 	int,			i)
 {
     unsigned the_key = table[i];
+    char *buf = 0;
     char *formatted;
 
     if (the_key != 0
@@ -686,23 +686,24 @@ PRIVATE BOOL format_binding ARGS3(
      && revmap[the_key].name != 0
      && revmap[the_key].doc != 0
      && (formatted = pretty(i-1)) != 0) {
-	sprintf(buf, "%-12s%-14s%s\n", formatted,
+	HTSprintf0(&buf, "%-12s%-14s%s\n", formatted,
 		revmap[the_key].name,
 		revmap[the_key].doc);
-	return TRUE;
+	return buf;
     }
-    return FALSE;
+    return 0;
 }
 
-PRIVATE void print_binding ARGS3(HTStream *, target, char *, buf, int, i)
+PRIVATE void print_binding ARGS2(HTStream *, target, int, i)
 {
+    char *buf;
 #if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
     if (prev_lynx_edit_mode && !no_dired_support &&
-        format_binding(buf, key_override, i)) {
+        (buf = format_binding(key_override, i)) != 0) {
 	(*target->isa->put_block)(target, buf, strlen(buf));
     } else
 #endif /* DIRED_SUPPORT && OK_OVERRIDE */
-    if (format_binding(buf, keymap, i)) {
+    if ((buf = format_binding(keymap, i)) != 0) {
 	(*target->isa->put_block)(target, buf, strlen(buf));
     }
 }
@@ -715,7 +716,7 @@ PRIVATE int LYLoadKeymap ARGS4 (
 {
     HTFormat format_in = WWW_HTML;
     HTStream *target;
-    char buf[256];
+    char *buf = 0;
     int i;
 
     /*
@@ -723,29 +724,29 @@ PRIVATE int LYLoadKeymap ARGS4 (
      */
     target = HTStreamStack(format_in, format_out, sink, anAnchor);
     if (!target || target == NULL) {
-	sprintf(buf, CANNOT_CONVERT_I_TO_O,
-		     HTAtom_name(format_in), HTAtom_name(format_out));
+	HTSprintf0(&buf, CANNOT_CONVERT_I_TO_O,
+			 HTAtom_name(format_in), HTAtom_name(format_out));
 	HTAlert(buf);
+	FREE(buf);
 	return(HT_NOT_LOADED);
     }
     anAnchor->no_cache = TRUE;
 
-    sprintf(buf, "<head>\n<title>%s</title>\n</head>\n<body>\n",
-    		  CURRENT_KEYMAP_TITLE);
+    HTSprintf0(&buf, "<head>\n<title>%s</title>\n</head>\n<body>\n",
+		     CURRENT_KEYMAP_TITLE);
     (*target->isa->put_block)(target, buf, strlen(buf));
-    sprintf(buf, "<h1>%s (%s)%s<a href=\"%s%s\">%s</a></h1>\n",
+    HTSprintf0(&buf, "<h1>%s (%s)%s<a href=\"%s%s\">%s</a></h1>\n",
 	LYNX_NAME, LYNX_VERSION,
 	HELP_ON_SEGMENT,
 	helpfilepath, CURRENT_KEYMAP_HELP, CURRENT_KEYMAP_TITLE);
     (*target->isa->put_block)(target, buf, strlen(buf));
-    sprintf(buf, "<pre>\n");
+    HTSprintf0(&buf, "<pre>\n");
     (*target->isa->put_block)(target, buf, strlen(buf));
 
     for (i = 'a'+1; i <= 'z'+1; i++) {
-	print_binding(target, buf, i);
+	print_binding(target, i);
 	if (keymap[i - ' '] != keymap[i]) {
-	    print_binding(target, buf,
-			  i-' ');  /* uppercase mapping is different */
+	    print_binding(target, i-' ');  /* uppercase mapping is different */
 	}
     }
     for (i = 1; i < KEYMAP_SIZE; i++) {
@@ -754,14 +755,15 @@ PRIVATE int LYLoadKeymap ARGS4 (
 	 */
 	if ((i >= 0400 || i <= ' ' || !isalpha(i-1)) &&
 	    strcmp(revmap[keymap[i]].name, "PIPE")) {
-	    print_binding(target, buf, i);
+	    print_binding(target, i);
 	}
     }
 
-    sprintf(buf,"</pre>\n</body>\n");
+    HTSprintf0(&buf,"</pre>\n</body>\n");
     (*target->isa->put_block)(target, buf, strlen(buf));
 
     (*target->isa->_free)(target);
+    FREE(buf);
     return(HT_LOADED);
 }
 
@@ -940,16 +942,15 @@ PUBLIC int lookup_keymap ARGS1(
 PUBLIC char *key_for_func ARGS1 (
 	int,	func)
 {
-    static char buf[512];
+    static char *buf;
     int i;
     char *formatted;
 
-    buf[0] = '\0';
     if ((i = LYReverseKeymap(func)) >= 0) {
-	if (*buf)
-	    strcat(buf, " or ");
 	formatted = pretty(i);
-	strcat(buf, formatted != 0 ? formatted : "?");
+	StrAllocCopy(buf, formatted != 0 ? formatted : "?");
+    } else if (buf == 0) {
+	StrAllocCopy(buf, "");
     }
     return buf;
 }
diff --git a/src/LYList.c b/src/LYList.c
index 140d7894..e53f51e8 100644
--- a/src/LYList.c
+++ b/src/LYList.c
@@ -51,7 +51,7 @@ PUBLIC int showlist ARGS2(
 {
     int cnt;
     int refs, hidden_links;
-    static char tempfile[256];
+    static char tempfile[LY_MAXPATH];
     FILE *fp0;
     char *Address = NULL, *Title = NULL, *cp = NULL;
     BOOLEAN intern_w_post = FALSE;
diff --git a/src/LYMail.c b/src/LYMail.c
index 3f483194..5bb717b6 100644
--- a/src/LYMail.c
+++ b/src/LYMail.c
@@ -68,14 +68,14 @@ PUBLIC void mailform ARGS4(
     char cmd[512];
     int len, i, ch;
 #if defined(VMS) || defined(DOSPATH)
-    char my_tmpfile[256];
+    char my_tmpfile[LY_MAXPATH];
     char *command = NULL;
 #ifdef VMS
     char *address_ptr1, *address_ptr2;
     BOOLEAN first = TRUE;
 #endif
     BOOLEAN isPMDF = FALSE;
-    char hdrfile[256];
+    char hdrfile[LY_MAXPATH];
     FILE *hfd;
 
     if (!strncasecomp(system_mail, "PMDF SEND", 9)) {
@@ -596,14 +596,14 @@ PUBLIC void mailmsg ARGS4(
     char *searchpart = NULL;
     char cmd[512], *cp, *cp0, *cp1;
 #if defined(VMS) || defined(DOSPATH)
-    char my_tmpfile[256];
+    char my_tmpfile[LY_MAXPATH];
     char *command = NULL;
 #ifdef VMS
     char *address_ptr1, *address_ptr2;
     BOOLEAN first = TRUE;
 #endif
     BOOLEAN isPMDF = FALSE;
-    char hdrfile[256];
+    char hdrfile[LY_MAXPATH];
     FILE *hfd;
 
     CTRACE(tfp, "mailmsg(%d, \"%s\", \"%s\", \"%s\")\n", cur,
@@ -868,9 +868,9 @@ PUBLIC void reply_by_mail ARGS3(
     char *temp = NULL;
     int i, len;
     int c = 0;	/* user input */
-    char my_tmpfile[256], cmd[512];
+    char my_tmpfile[LY_MAXPATH], cmd[512];
 #ifdef DOSPATH
-    char tmpfile2[256];
+    char tmpfile2[LY_MAXPATH];
 #endif
 #if defined(DOSPATH) || defined(VMS)
     char *command = NULL;
@@ -883,7 +883,7 @@ PUBLIC void reply_by_mail ARGS3(
     char *address_ptr1 = NULL, *address_ptr2 = NULL;
     BOOLEAN first = TRUE;
     BOOLEAN isPMDF = FALSE;
-    char hdrfile[256];
+    char hdrfile[LY_MAXPATH];
     FILE *hfd;
 
     CTRACE(tfp, "reply_by_mail(\"%s\", \"%s\", \"%s\")\n",
diff --git a/src/LYMain.c b/src/LYMain.c
index 9204b984..29a675fd 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -349,7 +349,7 @@ PUBLIC char *XLoadImageCommand = NULL;	/* Default image viewer for X */
 PUBLIC BOOLEAN LYNoISMAPifUSEMAP = FALSE; /* Omit ISMAP link if MAP present? */
 PUBLIC int LYHiddenLinks = HIDDENLINKS_SEPARATE; /* Show hidden links? */
 
-PUBLIC BOOL New_DTD = YES;
+PUBLIC BOOL Old_DTD = NO;
 PUBLIC FILE *LYTraceLogFP = NULL;		/* Pointer for TRACE log  */
 PUBLIC char *LYTraceLogPath = NULL;		/* Path for TRACE log	   */
 PUBLIC BOOLEAN LYUseTraceLog = USE_TRACE_LOG;	/* Use a TRACE log?	   */
@@ -592,7 +592,7 @@ PUBLIC int main ARGS2(
     char *temp = NULL;
     char *cp;
     FILE *fp;
-    char filename[256];
+    char filename[LY_MAXPATH];
     BOOL LYGetStdinArgs = FALSE;
 
 #ifdef    NOT_ASCII  /* S/390 -- gil -- 2002 */
@@ -914,7 +914,7 @@ PUBLIC int main ARGS2(
 	}
     }
     if (LYGetStdinArgs == TRUE) {
-	char buf[1025];
+	char buf[LINESIZE];
 
 	while (fgets(buf, sizeof(buf) - 1, stdin)) {
 	    int j;
@@ -1099,32 +1099,7 @@ PUBLIC int main ARGS2(
      *	Set up the TRACE log path, and logging if appropriate. - FM
      */
     LYAddPathToHome(LYTraceLogPath = malloc(LY_MAXPATH), LY_MAXPATH, "Lynx.trace");
-
-    if (TRACE && LYUseTraceLog) {
-	/*
-	 *  If we can't open it for writing, give up.
-	 *  Otherwise, on VMS close it, delete it and any
-	 *  versions from previous sessions so they don't
-	 *  accumulate, and open it again. - FM
-	 */
-	if ((LYTraceLogFP = LYNewTxtFile(LYTraceLogPath)) == NULL) {
-	    WWW_TraceFlag = FALSE;
-	    fprintf(stderr, "%s\n", TRACELOG_OPEN_FAILED);
-	    exit(-1);
-	}
-#ifdef VMS
-	LYCloseTracelog();
-	HTSYS_remove(LYTraceLogPath);
-	if ((LYTraceLogFP = LYNewTxtFile(LYTraceLogPath)) == NULL) {
-	    WWW_TraceFlag = FALSE;
-	    printf("%s\n", TRACELOG_OPEN_FAILED);
-	    exit(-1);
-	}
-#endif /* VMS */
-	fflush(stdout);
-	fflush(stderr);
-	fprintf(tfp, "\t\t%s\n\n", LYNX_TRACELOG_TITLE);
-    }
+    LYOpenTraceLog();
 
     /*
      *	If TRACE is on, indicate whether the
@@ -1317,7 +1292,7 @@ PUBLIC int main ARGS2(
      */
     read_rc();
 
-    HTSwitchDTD(New_DTD);
+    HTSwitchDTD(!Old_DTD);
 
     /*
      *	Check for a save space path in the environment.
@@ -2474,7 +2449,7 @@ static int tagsoup_fun ARGS3(
 	char **,		argv GCC_UNUSED,
 	char *,			next_arg GCC_UNUSED)
 {
-    HTSwitchDTD(New_DTD = NO);
+    HTSwitchDTD(!(Old_DTD = YES));
     return 0;
 }
 
@@ -2977,9 +2952,10 @@ treated '>' as a co-terminator for double-quotes and tags"
    {NULL}
 };
 
-static void print_help_strings ARGS2(
+static void print_help_strings ARGS3(
 	CONST char *,	name,
-	CONST char *,	help)
+	CONST char *,	help,
+	CONST char *,	value)
 {
     int pad;
     int c;
@@ -3003,7 +2979,7 @@ static void print_help_strings ARGS2(
     }
 
     if (strchr (help, '\n') == 0) {
-	fprintf (stdout, "%s\n", help);
+	fprintf (stdout, "%s", help);
     } else {
 	while ((c = *help) != 0) {
 	    if (c == '\n') {
@@ -3021,8 +2997,10 @@ static void print_help_strings ARGS2(
 	    help++;
 	    first--;
 	}
-	fputc ('\n', stdout);
     }
+    if (value)
+	printf(" (%s)", value);
+    fputc ('\n', stdout);
 }
 
 static void print_help_and_exit ARGS1(int, exit_status)
@@ -3037,10 +3015,31 @@ static void print_help_and_exit ARGS1(int, exit_status)
     fprintf (stdout, gettext("Options are:\n"));
     print_help_strings("",
 "receive the arguments from stdin (enclose\n\
-in double-quotes (\"-\") on VMS)");
+in double-quotes (\"-\") on VMS)", NULL);
 
-    for (p = Arg_Table; p->name != 0; p++)
-	print_help_strings(p->name, p->help_string);
+    for (p = Arg_Table; p->name != 0; p++) {
+	char temp[LINESIZE], *value = temp;
+	ParseUnion *q = (ParseUnion *)(&(p->value));
+	switch (p->type & ARG_TYPE_MASK) {
+	    case TOGGLE_ARG:
+	    case SET_ARG:
+	    case UNSET_ARG:
+		sprintf(temp, "%s", *(q->set_value) ? "on" : "off");
+		break;
+	    case INT_ARG:
+		sprintf(temp, "%d", *(q->int_value));
+		break;
+	    case STRING_ARG:
+		if ((value = *(q->str_value)) != 0
+		 && !*value)
+		    value = 0;
+		break;
+	    default:
+		value = 0;
+		break;
+	}
+	print_help_strings(p->name, p->help_string, value);
+    }
 
     SetOutputMode( O_BINARY );
 
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index 0994de49..0ad66d59 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -138,7 +138,39 @@ PUBLIC FILE *TraceFP NOARGS
 PRIVATE void TracelogOpenFailed NOARGS
 {
     WWW_TraceFlag = FALSE;
-    HTUserMsg(TRACELOG_OPEN_FAILED);
+    if (LYCursesON) {
+	HTUserMsg(TRACELOG_OPEN_FAILED);
+    } else {
+	fprintf(stderr, "%s\n", TRACELOG_OPEN_FAILED);
+	exit(-1);
+    }
+}
+
+PUBLIC BOOLEAN LYOpenTraceLog NOARGS
+{
+    if (TRACE && LYUseTraceLog && LYTraceLogFP == NULL) {
+	/*
+	 * If we can't open it for writing, give up.  Otherwise, on VMS close
+	 * it, delete it and any versions from previous sessions so they don't
+	 * accumulate, and open it again.  - FM
+	 */
+	if ((LYTraceLogFP = LYNewTxtFile(LYTraceLogPath)) == NULL) {
+	    TracelogOpenFailed();
+	    return FALSE;
+	}
+#ifdef VMS
+	LYCloseTracelog();
+	HTSYS_remove(LYTraceLogPath);
+	if ((LYTraceLogFP = LYNewTxtFile(LYTraceLogPath)) == NULL) {
+	    TracelogOpenFailed();
+	    return FALSE;
+	}
+#endif /* VMS */
+	fflush(stdout);
+	fflush(stderr);
+	fprintf(tfp, "\t\t%s (%s)\n\n", LYNX_TRACELOG_TITLE, LYNX_VERSION);
+    }
+    return TRUE;
 }
 
 PUBLIC void LYCloseTracelog NOARGS
@@ -2130,12 +2162,9 @@ new_cmd:  /*
 	    newdoc.line = curdoc.line;
 	    newdoc.link = curdoc.link;
 #endif /* NO_ASSUME_SAME_DOC */
-	    if (New_DTD)
-		New_DTD = NO;
-	    else
-		New_DTD = YES;
-	    HTSwitchDTD(New_DTD);
-	    HTUserMsg(New_DTD ? USING_DTD_1 : USING_DTD_0);
+	    Old_DTD = !Old_DTD;
+	    HTSwitchDTD(!Old_DTD);
+	    HTUserMsg(Old_DTD ? USING_DTD_0 : USING_DTD_1);
 	    break;
 
 #ifdef NOT_DONE_YET
@@ -4980,40 +5009,9 @@ check_add_bookmark_to_self:
 #endif /* DIRED_SUPPORT */
 
 	case LYK_TRACE_TOGGLE:	/*  Toggle TRACE mode. */
-	    if (WWW_TraceFlag)
-		WWW_TraceFlag = FALSE;
-	    else
-		WWW_TraceFlag = TRUE;
-
-	    if (TRACE && LYUseTraceLog && LYTraceLogFP == NULL) {
-		/*
-		 *  We haven't yet started a TRACE log for this
-		 *  session.  If we can't open the file with write
-		 *  access, turn off TRACE and give up.  Otherwise,
-		 *  on VMS we'll close it and delete it and any
-		 *  log file from a previous session, so they don't
-		 *  accumulate, and then open it again, including
-		 *  "shr=get" to overcome open file locking when
-		 *  attempting to read the log via the TRACE_LOG
-		 *  command. - FM
-		 */
-		if ((LYTraceLogFP = LYNewTxtFile(LYTraceLogPath)) == NULL) {
-		    TracelogOpenFailed();
-		    break;
-		}
-#ifdef VMS
-		LYCloseTracelog();
-		HTSYS_remove(LYTraceLogPath);
-		if ((LYTraceLogFP = LYNewTxtFile(LYTraceLogPath)) == NULL) {
-		    TracelogOpenFailed();
-		    break;
-		}
-#endif /* VMS */
-		fprintf(tfp, "\t\t%s (%s)\n\n",
-			     LYNX_TRACELOG_TITLE,
-			     LYNX_VERSION);
-	    }
-	    HTUserMsg(WWW_TraceFlag ? TRACE_ON : TRACE_OFF);
+	    WWW_TraceFlag = ! WWW_TraceFlag;
+	    if (LYOpenTraceLog())
+		HTUserMsg(WWW_TraceFlag ? TRACE_ON : TRACE_OFF);
 	    break;
 
 	case LYK_TRACE_LOG:	/*  View TRACE log. */
diff --git a/src/LYMainLoop.h b/src/LYMainLoop.h
index 25d7b133..82480992 100644
--- a/src/LYMainLoop.h
+++ b/src/LYMainLoop.h
@@ -3,6 +3,7 @@
 
 #include <HTUtils.h>
 
+extern BOOLEAN LYOpenTraceLog NOPARAMS;
 extern void LYCloseTracelog NOPARAMS;
 extern int mainloop NOPARAMS;
 
diff --git a/src/LYNews.c b/src/LYNews.c
index 890e4156..e7f11d2d 100644
--- a/src/LYNews.c
+++ b/src/LYNews.c
@@ -46,9 +46,9 @@ PUBLIC char *LYNewsPost ARGS2(
     CONST char *kp = NULL;
     int c = 0;  /* user input */
     FILE *fd = NULL;
-    char my_tempfile[256];
+    char my_tempfile[LY_MAXPATH];
     FILE *fc = NULL;
-    char CJKfile[256];
+    char CJKfile[LY_MAXPATH];
     char *postfile = NULL;
     char *NewsGroups = NULL;
     char *org = NULL;
diff --git a/src/LYOptions.c b/src/LYOptions.c
index 7b76c618..ed8dab58 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -3279,7 +3279,6 @@ static OptValues search_type_values[] = {
 	{ FALSE,	    "Case insensitive",  "case_insensitive" },
 	{ TRUE, 	    "Case sensitive",	 "case_sensitive" },
 	{ 0, 0, 0 }};
-static char * select_popups_string	= "select_popups";
 #if defined(USE_SLANG) || defined(COLOR_CURSES)
 static char * show_color_string		= "show_color";
 static OptValues show_color_values[] = {
@@ -3296,10 +3295,30 @@ static OptValues user_mode_values[] = {
 	{ INTERMEDIATE_MODE,	"Intermediate", "Intermediate" },
 	{ ADVANCED_MODE,	"Advanced",	"Advanced" },
 	{ 0, 0, 0 }};
-static char * verbose_images_string	= "verbose_images";
 static char * vi_keys_string		= "vi_keys";
 
 /*
+ * Document Layout
+ */
+static char * DTD_recovery_string      = "DTD";
+static OptValues DTD_type_values[] = {
+	/* Old_DTD variable */
+	{ TRUE, 	    "relaxed (TagSoup mode)",	 "tagsoup" },
+	{ FALSE, 	    "strict (SortaSGML mode)",	 "sortasgml" },
+	{ 0, 0, 0 }};
+static char * select_popups_string     = "select_popups";
+static char * images_string            = "images";
+static char * images_ignore_all_string  = "ignore";
+static char * images_use_label_string   = "as labels";
+static char * images_use_links_string   = "as links";
+static char * verbose_images_string    = "verbose_images";
+static OptValues verbose_images_type_values[] = {
+	/* verbose_img variable */
+	{ FALSE,	    "OFF",		 "OFF" },
+	{ TRUE, 	    "show filename",	 "ON" },
+	{ 0, 0, 0 }};
+
+/*
  * Bookmark Options
  */
 static char * mbm_advanced_string	= "ADVANCED";
@@ -3376,16 +3395,19 @@ PRIVATE void PutOptValues ARGS3(
     }
 }
 
-PRIVATE int GetOptValues ARGS2(
+PRIVATE BOOLEAN GetOptValues ARGS3(
 	OptValues *,	table,
-	char *, 	value)
+	char *, 	value,
+	int *,		result)
 {
     while (table->LongName != 0) {
-	if (!strcmp(value, table->HtmlName))
-	    return table->value;
+	if (!strcmp(value, table->HtmlName)) {
+	    *result = table->value;
+	    return TRUE;
+	}
 	table++;
     }
-    return -1;
+    return FALSE;
 }
 
 /*
@@ -3488,7 +3510,8 @@ PRIVATE PostPair * break_data ARGS1(
  * Security:  some options are disabled in gen_options() under certain
  * conditions.  We *should* duplicate the same conditions here in postoptions()
  * to prevent user with a limited access from editing HTML options code
- * manually and submit it to access the restricted items.  - LP
+ * manually (e.g., doing 'e'dit in 'o'ptions) and submit it to access the
+ * restricted items. Prevent spoofing attempts from index overrun. - LP
  */
 
 PUBLIC int postoptions ARGS1(
@@ -3496,6 +3519,7 @@ PUBLIC int postoptions ARGS1(
 {
     PostPair *data = 0;
     int i;
+    int code;
     BOOLEAN save_all = FALSE;
     int display_char_set_old = current_char_set;
     BOOLEAN raw_mode_old = LYRawMode;
@@ -3567,8 +3591,9 @@ PUBLIC int postoptions ARGS1(
 	}
 
 	/* Emacs keys: ON/OFF */
-	if (!strcmp(data[i].tag, emacs_keys_string)) {
-	    if ((emacs_keys = GetOptValues(bool_values, data[i].value))) {
+	if (!strcmp(data[i].tag, emacs_keys_string)
+	 && GetOptValues(bool_values, data[i].value, &code)) {
+	    if ((emacs_keys = code) != FALSE) {
 		set_emacs_keys();
 	    } else {
 		reset_emacs_keys();
@@ -3577,8 +3602,8 @@ PUBLIC int postoptions ARGS1(
 
 	/* Execution links: SELECT */
 #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
-	if (!strcmp(data[i].tag, exec_links_string)) {
-	    int code = GetOptValues(exec_links_values, data[i].value);
+	if (!strcmp(data[i].tag, exec_links_string)
+	 && GetOptValues(exec_links_values, data[i].value, &code)) {
 #ifndef NEVER_ALLOW_REMOTE_EXEC
 	    local_exec = (code == EXEC_ALWAYS);
 #endif /* !NEVER_ALLOW_REMOTE_EXEC */
@@ -3588,18 +3613,28 @@ PUBLIC int postoptions ARGS1(
 
 	/* Keypad Mode: SELECT */
 	if (!strcmp(data[i].tag, keypad_mode_string)) {
-	    keypad_mode = GetOptValues(keypad_mode_values, data[i].value);
+	    GetOptValues(keypad_mode_values, data[i].value, &keypad_mode);
 	}
 
 	/* Line edit style: SELECT */
 	if (!strcmp(data[i].tag, lineedit_style_string)) {
-	    current_lineedit = atoi(data[i].value);
+	    int newval = atoi(data[i].value);
+	    int j;
+	    /* prevent spoofing attempt */
+	    for (j = 0; LYLineeditNames[j]; j++) {
+	       if (j==newval)  current_lineedit = newval;
+	    }
 	}
 
 #ifdef EXP_KEYBOARD_LAYOUT
 	/* Keyboard layout: SELECT */
 	if (!strcmp(data[i].tag, kblayout_string)) {
-	    current_layout = atoi(data[i].value);
+	    int newval = atoi(data[i].value);
+	    int j;
+	    /* prevent spoofing attempt */
+	    for (j = 0; LYKbLayoutNames[j]; j++) {
+	       if (j==newval)  current_layout = newval;
+	    }
 	}
 #endif /* EXP_KEYBOARD_LAYOUT */
 
@@ -3610,19 +3645,28 @@ PUBLIC int postoptions ARGS1(
 	}
 
 	/* Search Type: SELECT */
-	if (!strcmp(data[i].tag, search_type_string)) {
-	    case_sensitive = GetOptValues(search_type_values, data[i].value);
+	if (!strcmp(data[i].tag, search_type_string)
+	 && GetOptValues(search_type_values, data[i].value, &code)) {
+	    case_sensitive = code;
+	}
+
+	/* HTML error tolerance: SELECT */
+	if (!strcmp(data[i].tag, DTD_recovery_string)
+	 && GetOptValues(DTD_type_values, data[i].value, &code)) {
+	    Old_DTD = code;
+	    HTSwitchDTD(!Old_DTD);
 	}
 
 	/* Select Popups: ON/OFF */
-	if (!strcmp(data[i].tag, select_popups_string)) {
-	    LYSelectPopups = GetOptValues(bool_values, data[i].value);
+	if (!strcmp(data[i].tag, select_popups_string)
+	 && GetOptValues(bool_values, data[i].value, &code)) {
+	    LYSelectPopups = code;
 	}
 
 #if defined(USE_SLANG) || defined(COLOR_CURSES)
 	/* Show Color: SELECT */
-	if (!strcmp(data[i].tag, show_color_string)) {
-	    LYShowColor = GetOptValues(show_color_values, data[i].value);
+	if (!strcmp(data[i].tag, show_color_string)
+	 && GetOptValues(show_color_values, data[i].value, &LYShowColor)) {
 	    LYChosenShowColor = LYShowColor;
 	    if (CurrentShowColor != LYShowColor) {
 		lynx_force_repaint();
@@ -3635,13 +3679,14 @@ PUBLIC int postoptions ARGS1(
 #endif /* USE_SLANG || COLOR_CURSES */
 
 	/* Show Cursor: ON/OFF */
-	if (!strcmp(data[i].tag, show_cursor_string)) {
-	    LYShowCursor = GetOptValues(bool_values, data[i].value);
+	if (!strcmp(data[i].tag, show_cursor_string)
+	 && GetOptValues(bool_values, data[i].value, &code)) {
+	    LYShowCursor = code;
 	}
 
 	/* User Mode: SELECT */
-	if (!strcmp(data[i].tag, user_mode_string)) {
-	    user_mode = GetOptValues(user_mode_values, data[i].value);
+	if (!strcmp(data[i].tag, user_mode_string)
+	 && GetOptValues(user_mode_values, data[i].value, &user_mode)) {
 	    if (user_mode == NOVICE_MODE) {
 		display_lines = (LYlines - 4);
 	    } else {
@@ -3649,16 +3694,31 @@ PUBLIC int postoptions ARGS1(
 	    }
 	}
 
+	/* Show Images: SELECT */
+	if (!strcmp(data[i].tag, images_string)) {
+	    if (!strcmp(data[i].value, images_ignore_all_string)) {
+		pseudo_inline_alts = FALSE;
+		clickable_images = FALSE;
+	    } else if (!strcmp(data[i].value, images_use_label_string)) {
+		pseudo_inline_alts = TRUE;
+		clickable_images = FALSE;
+	    } else if (!strcmp(data[i].value, images_use_links_string)) {
+		clickable_images = TRUE;
+	    }
+	}
+
 	/* Verbose Images: ON/OFF */
-	if (!strcmp(data[i].tag, verbose_images_string)) {
-	    verbose_img = GetOptValues(bool_values, data[i].value);
+	if (!strcmp(data[i].tag, verbose_images_string)
+        && GetOptValues(verbose_images_type_values, data[i].value, &code)) {
+	   verbose_img = code;
 	}
 
 	/* VI Keys: ON/OFF */
-	if (!strcmp(data[i].tag, vi_keys_string)) {
-	    if ((vi_keys = GetOptValues(bool_values, data[i].value))) {
+	if (!strcmp(data[i].tag, vi_keys_string)
+	 && GetOptValues(bool_values, data[i].value, &code)) {
+	    if ((vi_keys = code) != FALSE) {
 		set_vi_keys();
-	    } else if (!strcmp(data[i].value, off_string)) {
+	    } else {
 		reset_vi_keys();
 	    }
 	}
@@ -3686,13 +3746,14 @@ PUBLIC int postoptions ARGS1(
 
 	/* Assume Character Set: SELECT */
 	if (!strcmp(data[i].tag, assume_char_set_string)) {
-	    int newval;
+	    int newval = UCGetLYhndl_byMIME(data[i].value);
 
-	    newval = UCGetLYhndl_byMIME(data[i].value);
-	    if ((raw_mode_old &&
-		 newval != safeUCGetLYhndl_byMIME(UCAssume_MIMEcharset))
-	       || (!raw_mode_old &&
-		   newval != UCLYhndl_for_unspec)) {
+	    if (newval >= 0
+	     && ((raw_mode_old &&
+		     newval != safeUCGetLYhndl_byMIME(UCAssume_MIMEcharset))
+	      || (!raw_mode_old &&
+		     newval != UCLYhndl_for_unspec)
+		)) {
 
 		UCLYhndl_for_unspec = newval;
 		StrAllocCopy(UCAssume_MIMEcharset, data[i].value);
@@ -3702,31 +3763,38 @@ PUBLIC int postoptions ARGS1(
 
 	/* Display Character Set: SELECT */
 	if (!strcmp(data[i].tag, display_char_set_string)) {
-           current_char_set = atoi(data[i].value);
+	    int newval = atoi(data[i].value);
+	    int j;
+	    /* prevent spoofing attempt */
+	    for (j = 0; LYchar_set_names[j]; j++) {
+		if (j==newval)	current_char_set = newval;
+	    }
 	}
 
 	/* Raw Mode: ON/OFF */
-	if (!strcmp(data[i].tag, raw_mode_string)) {
-           LYRawMode = GetOptValues(bool_values, data[i].value);
+	if (!strcmp(data[i].tag, raw_mode_string)
+        && GetOptValues(bool_values, data[i].value, &code)) {
+	   LYRawMode = code;
 	}
 
 	/*
 	 * ftp sort: SELECT
 	 */
 	if (!strcmp(data[i].tag, ftp_sort_string)) {
-	    HTfileSortMethod = GetOptValues(ftp_sort_values, data[i].value);
+	    GetOptValues(ftp_sort_values, data[i].value, &HTfileSortMethod);
 	}
 
 #ifdef DIRED_SUPPORT
 	/* Local Directory Sort: SELECT */
 	if (!strcmp(data[i].tag, dired_sort_string)) {
-	    dir_list_style = GetOptValues(dired_values, data[i].value);
+	    GetOptValues(dired_values, data[i].value, &dir_list_style);
 	}
 #endif /* DIRED_SUPPORT */
 
 	/* Show dot files: ON/OFF */
-	if (!strcmp(data[i].tag, show_dotfiles_string) && (!no_dotfiles)) {
-	    show_dotfiles = GetOptValues(bool_values, data[i].value);
+	if (!strcmp(data[i].tag, show_dotfiles_string) && (!no_dotfiles)
+	 && GetOptValues(bool_values, data[i].value, &code)) {
+	    show_dotfiles = code;
 	}
 
 	/* Preferred Document Character Set: INPUT */
@@ -3945,14 +4013,16 @@ PUBLIC int gen_options ARGS1(
     EndSelect(fp0);
 
     /* Line edit style: SELECT */
-    PutLabel(fp0, "Line edit style");
-    BeginSelect(fp0, lineedit_style_string);
-    for (i = 0; LYLineeditNames[i]; i++) {
-	char temp[16];
-	sprintf(temp, "%d", i);
-	PutOption(fp0, i==current_lineedit, temp, LYLineeditNames[i]);
+    if (LYLineeditNames[1]) { /* well, at least 2 line edit styles available */
+	PutLabel(fp0, "Line edit style");
+	BeginSelect(fp0, lineedit_style_string);
+	for (i = 0; LYLineeditNames[i]; i++) {
+	    char temp[16];
+	    sprintf(temp, "%d", i);
+	    PutOption(fp0, i==current_lineedit, temp, LYLineeditNames[i]);
+	}
+	EndSelect(fp0);
     }
-    EndSelect(fp0);
 
 #ifdef EXP_KEYBOARD_LAYOUT
     /* Keyboard layout: SELECT */
@@ -3971,12 +4041,6 @@ PUBLIC int gen_options ARGS1(
     PutTextInput(fp0, mail_address_string,
 		NOTEMPTY(personal_mail_address), text_len, "");
 
-    /* Select Popups: ON/OFF */
-    PutLabel(fp0, gettext("Popups for select fields"));
-    BeginSelect(fp0, select_popups_string);
-    PutOptValues(fp0, LYSelectPopups, bool_values);
-    EndSelect(fp0);
-
     /* Search Type: SELECT */
     PutLabel(fp0, gettext("Searching type"));
     BeginSelect(fp0, search_type_string);
@@ -4039,24 +4103,54 @@ PUBLIC int gen_options ARGS1(
     PutOptValues(fp0, user_mode, user_mode_values);
     EndSelect(fp0);
 
-    /* Verbose Images: ON/OFF */
-    PutLabel(fp0, gettext("Verbose images"));
-    BeginSelect(fp0, verbose_images_string);
-    PutOptValues(fp0, verbose_img, bool_values);
-    EndSelect(fp0);
-
     /* VI Keys: ON/OFF */
     PutLabel(fp0, gettext("VI keys"));
     BeginSelect(fp0, vi_keys_string);
     PutOptValues(fp0, vi_keys, bool_values);
     EndSelect(fp0);
 
-
     /* X Display: INPUT */
     PutLabel(fp0, gettext("X Display"));
     PutTextInput(fp0, x_display_string, NOTEMPTY(x_display), text_len, "");
 
     /*
+     * Document Layout
+     */
+    fprintf(fp0,"\n  <em>%s</em>\n", gettext("Document Layout"));
+
+    /* HTML error tolerance: SELECT */
+    PutLabel(fp0, gettext("HTML error tolerance"));
+    BeginSelect(fp0, DTD_recovery_string);
+    PutOptValues(fp0, Old_DTD, DTD_type_values);
+    EndSelect(fp0);
+
+    /* Select Popups: ON/OFF */
+    PutLabel(fp0, gettext("Popups for select fields"));
+    BeginSelect(fp0, select_popups_string);
+    PutOptValues(fp0, LYSelectPopups, bool_values);
+    EndSelect(fp0);
+
+    /* Show Images: SELECT */
+    PutLabel(fp0, gettext("Show images"));
+    BeginSelect(fp0, images_string);
+    PutOption(fp0, !pseudo_inline_alts && !clickable_images,
+       images_ignore_all_string,
+       images_ignore_all_string);
+    PutOption(fp0, pseudo_inline_alts && !clickable_images,
+       images_use_label_string,
+       images_use_label_string);
+    PutOption(fp0, clickable_images,
+       images_use_links_string,
+       images_use_links_string);
+    EndSelect(fp0);
+
+    /* Verbose Images: ON/OFF */
+    PutLabel(fp0, gettext("Verbose images"));
+    BeginSelect(fp0, verbose_images_string);
+    PutOptValues(fp0, verbose_img, verbose_images_type_values);
+    EndSelect(fp0);
+
+    /*
      * Bookmark Options
      */
     fprintf(fp0,"\n  <em>%s</em>\n", gettext("Bookmark Options"));
diff --git a/src/LYPrint.c b/src/LYPrint.c
index dbdd7f5a..21e0989d 100644
--- a/src/LYPrint.c
+++ b/src/LYPrint.c
@@ -18,6 +18,9 @@
 
 #include <LYLeaks.h>
 
+#define CancelPrint(msg) HTInfoMsg(msg); goto done
+#define CannotPrint(msg) HTAlert(msg); goto done
+
 /*
  *  printfile prints out the current file minus the links and targets
  *  to a variety of places
@@ -101,46 +104,925 @@ PRIVATE void set_environ ARGS3(
 #endif
 }
 
-PUBLIC int printfile ARGS1(
+PRIVATE char *suggested_filename ARGS1(
 	document *,	newdoc)
 {
-    static char tempfile[LY_MAXPATH];
-    char *the_command = 0;
-    char buffer[LINESIZE];
-    char filename[LINESIZE];
-    char user_response[256];
-    int lines_in_file = 0;
-    int printer_number = 0;
-    int pages = 0;
-    int type = 0, c = 0;
-    BOOLEAN Lpansi = FALSE;
-    FILE *outfile_fp;
-    char *cp = NULL;
-    lynx_printer_item_type *cur_printer;
-    char *sug_filename = NULL;
-    char *link_info = NULL;
-    DocAddress WWWDoc;
-    int pagelen = 0;
-    int ch, recall;
-    int FnameTotal;
-    int FnameNum;
-    BOOLEAN FirstRecall = TRUE;
-    char *content_base = NULL, *content_location = NULL;
+    char *cp, *sug_filename = 0;
+
+    /*
+     *	Load the suggested filename string. - FM
+     */
+    if (HText_getSugFname() != 0)
+	StrAllocCopy(sug_filename, HText_getSugFname()); /* must be freed */
+    else
+	StrAllocCopy(sug_filename, newdoc->address); /* must be freed */
+    /*
+     *	Strip any gzip or compress suffix, if present. - FM
+     */
+    cp = NULL;
+    if (strlen(sug_filename) > 3) {
+	cp = (char *)&sug_filename[(strlen(sug_filename) - 3)];
+	if ((*cp == '.' || *cp == '-' || *cp == '_') &&
+	    !strcasecomp((cp + 1), "gz")) {
+	    *cp = '\0';
+	} else {
+	    cp = NULL;
+	}
+    }
+    if ((cp == NULL) && strlen(sug_filename) > 2) {
+	cp = (char *)&sug_filename[(strlen(sug_filename) - 2)];
+	if ((*cp == '.' || *cp == '-' || *cp == '_') &&
+	    !strcasecomp((cp + 1), "Z")) {
+	    *cp = '\0';
+	}
+    }
+    return sug_filename;
+}
+
+PRIVATE void SetupFilename ARGS2(
+	char *,		filename,
+	char *,		sug_filename)
+{
     HTFormat format;
     HTAtom *encoding;
-    BOOL use_mime, use_cte, use_type;
+    char *cp;
+
+    LYstrncpy(filename, sug_filename, LY_MAXPATH-1);  /* add suggestion info */
+    /* make the sug_filename conform to system specs */
+    change_sug_filename(filename);
+    if (!(HTisDocumentSource())
+     && (cp = strrchr(filename, '.')) != NULL
+     && (cp - filename) < LY_MAXPATH-5) {
+	format = HTFileFormat(filename, &encoding, NULL);
+	if (!strcasecomp(format->name, "text/html") ||
+	    !IsUnityEnc(encoding)) {
+	    strcpy(cp, ".txt");
+	}
+    }
+}
+
+#define FN_INIT 0
+#define FN_READ 1
+#define FN_DONE 2
+#define FN_QUIT 3
+
+PRIVATE int RecallFilename ARGS4(
+	char *,		filename,
+	BOOLEAN *,	first,
+	int *,		now,
+	int *,		total)
+{
+    int ch;
+    char *cp;
+    int recall;
+
+    /*
+     * Set up the sug_filenames recall buffer.
+     */
+    if (*now < 0) {
+	*total = (sug_filenames ? HTList_count(sug_filenames) : 0);
+	*now = *total;
+    }
+    recall = ((*total >= 1) ? RECALL : NORECALL);
+
+    if ((ch = LYgetstr(filename, VISIBLE, LY_MAXPATH, recall)) < 0 ||
+	*filename == '\0' || ch == UPARROW || ch == DNARROW) {
+	if (recall && ch == UPARROW) {
+	    if (*first) {
+		*first = FALSE;
+		/*
+		 * Use the last Fname in the list.  - FM
+		 */
+		*now = 0;
+	    } else {
+		/*
+		 * Go back to the previous Fname in the list.  - FM
+		 */
+		*now += 1;
+	    }
+	    if (*now >= *total) {
+		/*
+		 * Reset the *first flag, and use sug_file or a blank.  -
+		 * FM
+		 */
+		*first = TRUE;
+		*now = *total;
+		_statusline(FILENAME_PROMPT);
+		return FN_INIT;
+	    } else if ((cp = (char *)HTList_objectAt(
+					    sug_filenames,
+					    *now)) != NULL) {
+		LYstrncpy(filename, cp, LY_MAXPATH-1);
+		if (*total == 1) {
+		    _statusline(EDIT_THE_PREV_FILENAME);
+		} else {
+		    _statusline(EDIT_A_PREV_FILENAME);
+		}
+		return FN_READ;
+	    }
+	} else if (recall && ch == DNARROW) {
+	    if (*first) {
+		*first = FALSE;
+		/*
+		 * Use the first Fname in the list. - FM
+		 */
+		*now = *total - 1;
+	    } else {
+		/*
+		 * Advance to the next Fname in the list. - FM
+		 */
+		*now -= 1;
+	    }
+	    if (*now < 0) {
+		/*
+		 * Set the *first flag, and use sug_file or a blank.  - FM
+		 */
+		*first = TRUE;
+		*now = *total;
+		_statusline(FILENAME_PROMPT);
+		return FN_INIT;
+	    } else if ((cp = (char *)HTList_objectAt(
+					    sug_filenames,
+					    *now)) != NULL) {
+		LYstrncpy(filename, cp, LY_MAXPATH-1);
+		if (*total == 1) {
+		    _statusline(EDIT_THE_PREV_FILENAME);
+		} else {
+		    _statusline(EDIT_A_PREV_FILENAME);
+		}
+		return FN_READ;
+	    }
+	}
+
+	/*
+	 * Save cancelled.
+	 */
+	HTInfoMsg(SAVE_REQUEST_CANCELLED);
+	return FN_QUIT;
+    }
+    return FN_DONE;
+}
+
+PRIVATE BOOLEAN confirm_by_pages ARGS3(
+	char *,		prompt,
+	int,		lines_in_file,
+	int,		lines_per_page)
+{
+    int pages = lines_in_file/(lines_per_page+1);
+    int c;
+
+    /* count fractional pages ! */
+    if ((lines_in_file % (LYlines+1)) > 0)
+	pages++;
+
+    if (pages > 4) {
+	char *msg = 0;
+
+	HTSprintf0(&msg, prompt, pages);
+	_statusline(msg);
+	free(msg);
+
+	c = LYgetch();
+#ifdef VMS
+	if (HadVMSInterrupt) {
+	    HadVMSInterrupt = FALSE;
+	    HTInfoMsg(PRINT_REQUEST_CANCELLED);
+	    return FALSE;
+	}
+#endif /* VMS */
+	if (c == RTARROW || c == 'y' || c== 'Y' || c == '\n' || c == '\r') {
+	    addstr("   Ok...");
+	} else {
+	    HTInfoMsg(PRINT_REQUEST_CANCELLED);
+	    return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+PRIVATE void send_file_to_file ARGS3(
+	document *,	newdoc,
+	char *,		content_base,
+	char *,		sug_filename)
+{
+    BOOLEAN FirstRecall = TRUE;
+    BOOLEAN use_cte;
     CONST char *disp_charset;
-    char *subject = NULL;   /* print-to-email */
+    FILE *outfile_fp;
+    char buffer[LY_MAXPATH];
+    char filename[LY_MAXPATH];
+    int FnameNum = -1;
+    int FnameTotal;
+    int c = 0;
+
+    _statusline(FILENAME_PROMPT);
+retry:
+    SetupFilename(filename, sug_filename);
+    if (lynx_save_space
+     && (strlen(lynx_save_space) + strlen(filename)) < sizeof(filename)) {
+	strcpy(buffer, lynx_save_space);
+	strcat(buffer, filename);
+	strcpy(filename, buffer);
+    }
+check_recall:
+    switch (RecallFilename(filename, &FirstRecall, &FnameNum, &FnameTotal)) {
+	case FN_INIT:
+	    goto retry;
+	case FN_READ:
+	    goto check_recall;
+	case FN_QUIT:
+	    goto done;
+	default:
+	    break;
+    }
+
+    if (!LYValidateFilename(buffer, filename)) {
+	CancelPrint(SAVE_REQUEST_CANCELLED);
+    }
+
+    /*
+     * See if it already exists.
+     */
+    switch (LYValidateOutput(buffer)) {
+    case 'Y':
+	break;
+    case 'N':
+	_statusline(NEW_FILENAME_PROMPT);
+	FirstRecall = TRUE;
+	FnameNum = FnameTotal;
+	goto retry;
+    default:
+	goto done;
+    }
+
+    /*
+     * See if we can write to it.
+     */
+    CTRACE(tfp, "LYPrint: filename is %s, action is `%c'\n", buffer, c);
+
+#if HAVE_POPEN
+    if (*buffer == '|') {
+	if (no_shell) {
+	    HTUserMsg(SPAWNING_DISABLED);
+	    FirstRecall = TRUE;
+	    FnameNum = FnameTotal;
+	    goto retry;
+	} else if ((outfile_fp = popen(buffer+1, "w")) == NULL) {
+	    CTRACE(tfp, "LYPrint: errno is %d\n", errno);
+	    HTAlert(CANNOT_WRITE_TO_FILE);
+	    _statusline(NEW_FILENAME_PROMPT);
+	    FirstRecall = TRUE;
+	    FnameNum = FnameTotal;
+	    goto retry;
+	}
+    } else
+#endif
+    if ((outfile_fp = (TOUPPER(c) == 'A'
+	    ? LYAppendToTxtFile(buffer)
+	    : LYNewTxtFile(buffer))) == NULL) {
+	CTRACE(tfp, "LYPrint: errno is %d\n", errno);
+	HTAlert(CANNOT_WRITE_TO_FILE);
+	_statusline(NEW_FILENAME_PROMPT);
+	FirstRecall = TRUE;
+	FnameNum = FnameTotal;
+	goto retry;
+    }
+
+    if (LYPrependBaseToSource && HTisDocumentSource()) {
+	/*
+	 * Added the document's base as a BASE tag to the top of the file.  May
+	 * create technically invalid HTML, but will help get any partial or
+	 * relative URLs resolved properly if no BASE tag is present to replace
+	 * it.  - FM
+	 *
+	 * Add timestamp (last reload).
+	 */
+
+	fprintf(outfile_fp,
+		"<!-- X-URL: %s -->\n", newdoc->address);
+	if (HText_getDate() != NULL)
+	     fprintf(outfile_fp,
+		"<!-- Date: %s -->\n", HText_getDate());
+	fprintf(outfile_fp,
+		"<BASE HREF=\"%s\">\n", content_base);
+    }
+
+    if (LYPrependCharsetToSource && HTisDocumentSource()) {
+	/*
+	 * Added the document's charset as a META CHARSET tag to the top of the
+	 * file.  May create technically invalid HTML, but will help to resolve
+	 * properly the document converted via chartrans:  printed document
+	 * correspond to a display charset and we *should* override both
+	 * assume_local_charset and original document's META CHARSET (if any).
+	 *
+	 * Currently, if several META CHARSETs are found Lynx uses the first
+	 * only, and it is opposite to BASE where the original BASE in the
+	 * <HEAD> overrides ones from the top.
+	 *
+	 * As in print-to-email we write charset only if the document has 8-bit
+	 * characters, and we have no CJK or an unofficial "x-" charset.
+	 */
+	use_cte = HTLoadedDocumentEightbit();
+	disp_charset = LYCharSet_UC[current_char_set].MIMEname;
+	if (!use_cte || LYHaveCJKCharacterSet ||
+	    strncasecomp(disp_charset, "x-", 2) == 0) {
+	} else {
+	    fprintf(outfile_fp,
+		    "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=%s\">\n\n",
+		    disp_charset);
+	}
+    }
+
+    print_wwwfile_to_fd(outfile_fp,0);
+    if (keypad_mode)
+	printlist(outfile_fp,FALSE);
+
+#if HAVE_POPEN
+    if (LYIsPipeCommand(buffer))
+	pclose(outfile_fp);
+    else
+#endif
+    fclose(outfile_fp);
+#ifdef VMS
+    if (0 == strncasecomp(buffer, "sys$disk:", 9)) {
+	if (0 == strncmp((buffer+9), "[]", 2)) {
+	    HTAddSugFilename(buffer+11);
+	} else {
+	    HTAddSugFilename(buffer+9);
+	}
+    } else {
+	HTAddSugFilename(buffer);
+    }
+#else
+    HTAddSugFilename(buffer);
+#endif /* VMS */
+
+done:
+    return;
+}
+
+PRIVATE void send_file_to_mail ARGS3(
+	document *,	newdoc,
+	char *,		content_base,
+	char *,		content_location)
+{
     static BOOLEAN first_mail_preparsed = TRUE;
+
 #ifdef VMS
-    BOOLEAN isPMDF = FALSE;
-    char hdrfile[LY_MAXPATH];
+    BOOLEAN isPMDF = !strncasecomp(system_mail, "PMDF SEND", 9);
     FILE *hfd;
+    char hdrfile[LY_MAXPATH];
+    char my_temp[LY_MAXPATH];
+#endif
+#ifdef DOSPATH
+    char my_temp[LY_MAXPATH];
+#endif
+
+    BOOL use_cte;
+    BOOL use_mime;
+    BOOL use_type;
+    CONST char *disp_charset;
+    FILE *outfile_fp;
+    char *buffer;
+    char *subject = NULL;
+    char user_response[LINESIZE];
+    int c;
+
+    if (LYPreparsedSource && first_mail_preparsed &&
+	HTisDocumentSource()) {
+	_statusline(CONFIRM_MAIL_SOURCE_PREPARSED);
+	c = 0;
+	while (TOUPPER(c)!='Y' && TOUPPER(c)!='N' && c != 7 && c != 3)
+	    c = LYgetch();
+#ifdef VMS
+	if (HadVMSInterrupt) {
+	    HadVMSInterrupt = FALSE;
+	    CancelPrint(MAIL_REQUEST_CANCELLED);
+	}
+#endif /* VMS */
+	if (c == RTARROW || c == 'y' || c== 'Y' || c == '\n' || c == '\r') {
+	    addstr("   Ok...");
+	    first_mail_preparsed = FALSE;
+	} else	{
+	    CancelPrint(MAIL_REQUEST_CANCELLED);
+	}
+    }
+
+    _statusline(MAIL_ADDRESS_PROMPT);
+    LYstrncpy(user_response, personal_mail_address, sizeof(user_response)-1);
+    if (LYgetstr(user_response, VISIBLE, sizeof(user_response), NORECALL) < 0 ||
+	*user_response == '\0') {
+	CancelPrint(MAIL_REQUEST_CANCELLED);
+    }
+
+    /*
+     * Determine which mail headers should be sent.  Use Content-Type and
+     * MIME-Version headers only if needed.  We need them if we are mailing
+     * HTML source, or if we have 8-bit characters and will be sending
+     * Content-Transfer-Encoding to indicate this.  We will append a charset
+     * parameter to the Content-Type if we do not have an "x-" charset, and we
+     * will include the Content-Transfer-Encoding only if we are appending the
+     * charset parameter, because indicating an 8-bit transfer without also
+     * indicating the charset can cause problems with many mailers.  - FM & KW
+     */
+    disp_charset = LYCharSet_UC[current_char_set].MIMEname;
+    use_cte = HTLoadedDocumentEightbit();
+    if (!(use_cte && strncasecomp(disp_charset, "x-", 2))) {
+	disp_charset = NULL;
+	use_cte = FALSE;
+    }
+    use_type =  (disp_charset || HTisDocumentSource());
+
+    /*
+     * Use newdoc->title as a subject instead of sug_filename:  MORE readable
+     * and 8-bit letters shouldn't be a problem - LP
+     */
+    /* change_sug_filename(sug_filename); */
+   subject = subject_translate8bit(newdoc->title);
+
+   if (newdoc->isHEAD) {
+	   /*
+	    * Special case for mailing HEAD responce:  this is rather technical
+	    * information, show URL.
+	    */
+	   FREE(subject);
+	   StrAllocCopy(subject, "HEAD  ");
+	   StrAllocCat(subject, newdoc->address);
+    }
+
+#ifdef VMS
+    if (strchr(user_response,'@') && !strchr(user_response,':') &&
+       !strchr(user_response,'%') && !strchr(user_response,'"')) {
+	char *temp = 0;
+	HTSprintf0(&temp, mail_adrs, user_response);
+	LYstrncpy(user_response, temp, sizeof(user_response)-1);
+	FREE(temp);
+    }
+
+    outfile_fp = LYOpenTemp(my_temp,
+			    (HTisDocumentSource())
+				    ? HTML_SUFFIX
+				    : ".txt",
+			    "w");
+    if (outfile_fp == NULL) {
+	CannotPrint(UNABLE_TO_OPEN_TEMPFILE);
+    }
+
+    if (isPMDF) {
+	if ((hfd = LYOpenTemp(hdrfile, ".txt", "w")) == NULL) {
+	    CannotPrint(UNABLE_TO_OPEN_TEMPFILE);
+	}
+	if (use_type) {
+	    fprintf(hfd, "Mime-Version: 1.0\n");
+	    if (use_cte) {
+		fprintf(hfd, "Content-Transfer-Encoding: 8bit\n");
+	    }
+	}
+	if (HTisDocumentSource()) {
+	    /*
+	     * Add Content-Type, Content-Location, and Content-Base headers for
+	     * HTML source.  - FM
+	     */
+	    fprintf(hfd, "Content-Type: text/html");
+	    if (disp_charset != NULL) {
+		fprintf(hfd, "; charset=%s\n", disp_charset);
+	    } else {
+		fprintf(hfd, "\n");
+	    }
+	    fprintf(hfd, "Content-Base: %s\n", content_base);
+	    fprintf(hfd, "Content-Location: %s\n", content_location);
+	} else {
+	    /*
+	     * Add Content-Type:  text/plain if we have 8-bit characters and a
+	     * valid charset for non-source documents.  - FM
+	     */
+	    if (disp_charset != NULL) {
+		fprintf(hfd,
+			"Content-Type: text/plain; charset=%s\n",
+			disp_charset);
+	    }
+	}
+	/*
+	 *	X-URL header. - FM
+	 */
+	fprintf(hfd, "X-URL: %s\n", newdoc->address);
+    }
+
+    /*
+     *  Write the contents to a temp file.
+     */
+    if (LYPrependBaseToSource && HTisDocumentSource()) {
+	/*
+	 * Added the document's base as a BASE tag to the top of the message
+	 * body.  May create technically invalid HTML, but will help get any
+	 * partial or relative URLs resolved properly if no BASE tag is present
+	 * to replace it.  - FM
+	 */
+	fprintf(outfile_fp,
+		"<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
+		newdoc->address, content_base);
+    } else if (!isPMDF) {
+	fprintf(outfile_fp, "X-URL: %s\n\n", newdoc->address);
+    }
+    print_wwwfile_to_fd(outfile_fp, 0);
+    if (keypad_mode)
+	printlist(outfile_fp, FALSE);
+    LYCloseTempFP(outfile_fp);
+
+    if (isPMDF) {
+	/*
+	 * For PMDF, put the subject in the header file and close it.  - FM
+	 */
+	fprintf(hfd, "Subject: %.70s\n\n", subject);
+	LYCloseTempFP(hfd);
+	/*
+	 * Now set up the command.  - FM
+	 */
+	HTSprintf0(&buffer,
+		"%s %s %s,%s %s",
+		system_mail,
+		system_mail_flags,
+		hdrfile,
+		my_temp,
+		user_response);
+    } else {
+	/*
+	 * For "generic" VMS MAIL, include the subject in the command.  - FM
+	 */
+	remove_quotes(subject);
+	HTSprintf0(&buffer,
+		"%s %s/subject=\"%.70s\" %s %s",
+		system_mail,
+		system_mail_flags,
+		subject,
+		my_temp,
+		user_response);
+    }
+
+    stop_curses();
+    printf(MAILING_FILE);
+    LYSystem(buffer);
+    sleep(AlertSecs);
+    start_curses();
+    if (isPMDF)
+	LYRemoveTemp(hdrfile);
+    LYRemoveTemp(my_temp);
+#else /* Unix or DOS */
+
+#ifdef DOSPATH
+    outfile_fp = LYOpenTemp(my_temp, ".txt", "w");
+#else
+    HTSprintf0(&buffer, "%s %s", system_mail, system_mail_flags);
+    outfile_fp = popen(buffer, "w");
+#endif
+    if (outfile_fp == NULL) {
+	CannotPrint(MAIL_REQUEST_FAILED);
+    }
+
+    /*
+     * Determine which mail headers should be sent.  Use Content-Type and
+     * MIME-Version headers only if needed.  We need them if we are mailing
+     * HTML source, or if we have 8-bit characters and will be sending
+     * Content-Transfer-Encoding to indicate this.
+     *
+     * Send Content-Transfer-Encoding only if the document has 8-bit
+     * characters.  Send a charset parameter only if the document has 8-bit
+     * characters and we seem to have a valid charset.  - kw
+     */
+    use_cte = HTLoadedDocumentEightbit();
+    disp_charset = LYCharSet_UC[current_char_set].MIMEname;
+    /*
+     * Don't send a charset if we have a CJK character set selected, since it
+     * may not be appropriate for mail...  Also don't use an unofficial "x-"
+     * charset.  - kw
+     */
+    if (!use_cte || LYHaveCJKCharacterSet ||
+	strncasecomp(disp_charset, "x-", 2) == 0) {
+	disp_charset = NULL;
+    }
+#ifdef NOTDEFINED
+    /*  Enable this if indicating an 8-bit transfer without
+     *  also indicating the charset causes problems. - kw */
+    if (use_cte && !disp_charset)
+	use_cte = FALSE;
+#endif /* NOTDEFINED */
+    use_type = (disp_charset || HTisDocumentSource());
+    use_mime = (use_cte || use_type);
+
+    if (use_mime) {
+	fprintf(outfile_fp, "Mime-Version: 1.0\n");
+	if (use_cte) {
+	    fprintf(outfile_fp, "Content-Transfer-Encoding: 8bit\n");
+	}
+    }
+
+    if (HTisDocumentSource()) {
+	/*
+	 * Add Content-Type, Content-Location, and Content-Base headers for
+	 * HTML source.  - FM
+	 */
+	fprintf(outfile_fp, "Content-Type: text/html");
+	if (disp_charset != NULL) {
+	    fprintf(outfile_fp, "; charset=%s\n", disp_charset);
+	} else {
+	    fprintf(outfile_fp, "\n");
+	}
+    } else {
+	/*
+	 * Add Content-Type:  text/plain if we have 8-bit characters and a
+	 * valid charset for non-source documents.  - KW
+	 */
+	if (disp_charset != NULL) {
+	    fprintf(outfile_fp,
+		    "Content-Type: text/plain; charset=%s\n",
+		    disp_charset);
+	}
+    }
+    /*
+     * If we are using MIME headers, add content-base and content-location if
+     * we have them.  This will always be the case if the document is source. 
+     * - kw
+     */
+    if (use_mime) {
+	if (content_base)
+	    fprintf(outfile_fp, "Content-Base: %s\n", content_base);
+	if (content_location)
+	    fprintf(outfile_fp, "Content-Location: %s\n", content_location);
+    }
+
+    /*
+     *  Add the To, Subject, and X-URL headers. - FM
+     */
+    fprintf(outfile_fp, "To: %s\nSubject: %s\n", user_response, subject);
+    fprintf(outfile_fp, "X-URL: %s\n\n", newdoc->address);
+
+    if (LYPrependBaseToSource && HTisDocumentSource()) {
+	/*
+	 * Added the document's base as a BASE tag to the top of the message
+	 * body.  May create technically invalid HTML, but will help get any
+	 * partial or relative URLs resolved properly if no BASE tag is present
+	 * to replace it.  - FM
+	 */
+	fprintf(outfile_fp,
+		"<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
+		newdoc->address, content_base);
+    }
+    print_wwwfile_to_fd(outfile_fp, 0);
+    if (keypad_mode)
+	printlist(outfile_fp, FALSE);
+
+#ifdef DOSPATH
+    HTSprintf0(&buffer, "%s -t \"%s\" -F %s", system_mail, user_response, my_temp);
+    LYCloseTempFP(outfile_fp);	/* Close the tmpfile. */
+    stop_curses();
+    printf("%s\n\n$ %s\n\n%s", gettext("Sending"), buffer, PLEASE_WAIT);
+    LYSystem(buffer);
+    sleep(MessageSecs);
+    start_curses();
+    LYRemoveTemp(my_temp); /* Delete the tmpfile. */
+#else
+    pclose(outfile_fp);
+#endif
+#endif /* VMS */
+
+done:
+    FREE(buffer);
+    FREE(subject);
+    return;
+}
+
+PRIVATE void send_file_to_printer ARGS4(
+	document *,	newdoc,
+	char *,		content_base,
+	char *,		sug_filename,
+	int,		printer_number)
+{
+    BOOLEAN FirstRecall = TRUE;
+    FILE *outfile_fp;
+    char *the_command = 0;
+    char my_file[LY_MAXPATH];
+    char my_temp[LY_MAXPATH];
+    int FnameTotal, FnameNum = -1;
+    lynx_printer_item_type *cur_printer;
 
-    if (!strncasecomp(system_mail, "PMDF SEND", 9)) {
-	isPMDF = TRUE;
+    outfile_fp = LYOpenTemp(my_temp,
+			    (HTisDocumentSource())
+				    ? HTML_SUFFIX
+				    : ".txt",
+			    "w");
+    if (outfile_fp == NULL) {
+	CannotPrint(FILE_ALLOC_FAILED);
     }
+
+    if (LYPrependBaseToSource && HTisDocumentSource()) {
+	/*
+	 * Added the document's base as a BASE tag to the top of the file.  May
+	 * create technically invalid HTML, but will help get any partial or
+	 * relative URLs resolved properly if no BASE tag is present to replace
+	 * it.  - FM
+	 */
+	fprintf(outfile_fp,
+		"<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
+		newdoc->address, content_base);
+    }
+    print_wwwfile_to_fd(outfile_fp, 0);
+    if (keypad_mode)
+	printlist(outfile_fp, FALSE);
+
+    LYCloseTempFP(outfile_fp);
+
+    /* find the right printer number */
+    {
+	int count=0;
+	for (cur_printer = printers;
+	     count < printer_number;
+	     count++, cur_printer = cur_printer->next)
+	    ; /* null body */
+    }
+
+    /*
+     * Commands have the form "command %s [%s] [etc]" where %s is the filename
+     * and the second optional %s is the suggested filename.
+     */
+    if (cur_printer->command == NULL) {
+	CannotPrint(PRINTER_MISCONF_ERROR);
+    }
+
+    /*
+     * Check for two '%s' and ask for the second filename argument if there
+     * is.
+     */
+    if (HTCountCommandArgs (cur_printer->command) >= 2) {
+	_statusline(FILENAME_PROMPT);
+again:
+	SetupFilename(my_file, sug_filename);
+check_again:
+	switch (RecallFilename(my_file, &FirstRecall, &FnameNum, &FnameTotal)) {
+	    case FN_INIT:
+		goto again;
+	    case FN_READ:
+		goto check_again;
+	    case FN_QUIT:
+		goto done;
+	    default:
+		break;
+	}
+
+	if (no_dotfiles || !show_dotfiles) {
+	    if (*LYPathLeaf(my_file) == '.') {
+		HTAlert(FILENAME_CANNOT_BE_DOT);
+		_statusline(NEW_FILENAME_PROMPT);
+		FirstRecall = TRUE;
+		FnameNum = FnameTotal;
+		goto again;
+	    }
+	}
+	/*
+	 * Cancel if the user entered "/dev/null" on Unix, or an "nl:" path
+	 * (case-insensitive) on VMS.  - FM
+	 */
+#ifdef VMS
+	if (!strncasecomp(my_file, "nl:", 3) ||
+	    !strncasecomp(my_file, "/nl/", 4))
+#else
+	if (!strcmp(my_file, "/dev/null"))
 #endif /* VMS */
+	{
+	    CancelPrint(PRINT_REQUEST_CANCELLED);
+	}
+	HTAddSugFilename(my_file);
+    }
+
+    HTAddParam (&the_command, cur_printer->command, 1, my_temp);
+    HTAddParam (&the_command, cur_printer->command, 2, my_file);
+    HTEndParam (&the_command, cur_printer->command, 2);
+
+    /*
+     * Move the cursor to the top of the screen so that output from system'd
+     * commands don't scroll up the screen.
+     */
+    move(1,1);
+
+    stop_curses();
+    CTRACE(tfp, "command: %s\n", the_command);
+    printf(PRINTING_FILE);
+    /*
+     * Set various bits of document information as environment variables, for
+     * use by external print scripts/etc.  On UNIX, We assume there are values,
+     * and leave NULL value checking up to the external PRINTER:  cmd/script -
+     * KED
+     */
+    SET_ENVIRON(LYNX_PRINT_TITLE,   HText_getTitle(),        "No Title");
+    SET_ENVIRON(LYNX_PRINT_URL,     newdoc->address,         "No URL");
+    SET_ENVIRON(LYNX_PRINT_DATE,    HText_getDate(),         "No Date");
+    SET_ENVIRON(LYNX_PRINT_LASTMOD, HText_getLastModified(), "No LastMod");
+
+    LYSystem(the_command);
+    FREE(the_command);
+    LYRemoveTemp(my_temp);
+
+    /*
+     * Remove the various LYNX_PRINT_xxxx logicals.  - KED
+     * [could use unsetenv(), but it's not portable]
+     */
+    SET_ENVIRON(LYNX_PRINT_TITLE,   "", "");
+    SET_ENVIRON(LYNX_PRINT_URL,     "","");
+    SET_ENVIRON(LYNX_PRINT_DATE,    "", "");
+    SET_ENVIRON(LYNX_PRINT_LASTMOD, "", "");
+
+    fflush(stdout);
+#ifndef VMS
+    signal(SIGINT, cleanup_sig);
+#endif /* !VMS */
+    sleep(MessageSecs);
+    start_curses();
+
+done:
+    return;
+}
+
+PRIVATE void send_file_to_screen ARGS3(
+	document *,	newdoc,
+	char *,		content_base,
+	BOOLEAN,	Lpansi)
+{
+    FILE *outfile_fp;
+    char prompt[80];
+
+    if (Lpansi) {
+	_statusline(CHECK_PRINTER);
+    } else {
+	_statusline(PRESS_RETURN_TO_BEGIN);
+    }
+
+    *prompt = '\0';
+    if (LYgetstr(prompt, VISIBLE, sizeof(prompt), NORECALL) < 0) {
+	CancelPrint(PRINT_REQUEST_CANCELLED);
+    }
+
+    outfile_fp = stdout;
+
+    stop_curses();
+#ifndef VMS
+    signal(SIGINT, SIG_IGN);
+#endif /* !VMS */
+
+    if (LYPrependBaseToSource && HTisDocumentSource()) {
+	/*
+	 * Added the document's base as a BASE tag to the top of the file.  May
+	 * create technically invalid HTML, but will help get any partial or
+	 * relative URLs resolved properly if no BASE tag is present to replace
+	 * it.  - FM
+	 */
+	fprintf(outfile_fp,
+		"<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
+		newdoc->address, content_base);
+    }
+    if (Lpansi)
+	printf("\033[5i");
+    print_wwwfile_to_fd(outfile_fp, 0);
+    if (keypad_mode)
+	printlist(outfile_fp, FALSE);
+
+#ifdef VMS
+    if (HadVMSInterrupt) {
+	HadVMSInterrupt = FALSE;
+	start_curses();
+	CancelPrint(PRINT_REQUEST_CANCELLED);
+    }
+#endif /* VMS */
+    if (Lpansi) {
+	printf("\n\014");	/* Form feed */
+	printf("\033[4i");
+	Lpansi = FALSE;
+    } else {
+	fprintf(stdout,"\n\n%s", PRESS_RETURN_TO_FINISH);
+	LYgetch();  /* grab some user input to pause */
+#ifdef VMS
+	HadVMSInterrupt = FALSE;
+#endif /* VMS */
+    }
+    fflush(stdout);  /* refresh to screen */
+    start_curses();
+
+done:
+    return;
+}
+
+PUBLIC int printfile ARGS1(
+	document *,	newdoc)
+{
+    BOOLEAN Lpansi = FALSE;
+    DocAddress WWWDoc;
+    char *content_base = NULL;
+    char *content_location = NULL;
+    char *cp = NULL;
+    char *link_info = NULL;
+    char *sug_filename = NULL;
+    int lines_in_file = 0;
+    int pagelen = 0;
+    int printer_number = 0;
+    int type = 0;
 
     /*
      *	Extract useful info from URL.
@@ -195,34 +1077,7 @@ PUBLIC int printfile ARGS1(
 	}
     }
 
-    /*
-     *	Load the suggested filename string. - FM
-     */
-    if (HText_getSugFname() != 0)
-	StrAllocCopy(sug_filename, HText_getSugFname()); /* must be freed */
-    else
-	StrAllocCopy(sug_filename, newdoc->address); /* must be freed */
-    /*
-     *	Strip any gzip or compress suffix, if present. - FM
-     */
-    cp = NULL;
-    if (strlen(sug_filename) > 3) {
-	cp = (char *)&sug_filename[(strlen(sug_filename) - 3)];
-	if ((*cp == '.' || *cp == '-' || *cp == '_') &&
-	    !strcasecomp((cp + 1), "gz")) {
-	    *cp = '\0';
-	} else {
-	    cp = NULL;
-	}
-    }
-    if ((cp == NULL) && strlen(sug_filename) > 2) {
-	cp = (char *)&sug_filename[(strlen(sug_filename) - 2)];
-	if ((*cp == '.' || *cp == '-' || *cp == '_') &&
-	    !strcasecomp((cp + 1), "Z")) {
-	    *cp = '\0';
-	}
-    }
-    cp = NULL;
+    sug_filename = suggested_filename(newdoc);
 
     /*
      *	Get the number of lines in the file.
@@ -238,7 +1093,6 @@ PUBLIC int printfile ARGS1(
 	cp += 6;
 
 	lines_in_file = atoi(cp);
-	pages = lines_in_file/66;
     }
 
     /*
@@ -272,919 +1126,32 @@ PUBLIC int printfile ARGS1(
     }
 
     /*
-     *	Set up the sug_filenames recall buffer.
-     */
-    FnameTotal = (sug_filenames ? HTList_count(sug_filenames) : 0);
-    recall = ((FnameTotal >= 1) ? RECALL : NORECALL);
-    FnameNum = FnameTotal;
-
-    /*
      *	Act on the request. - FM
      */
     switch (type) {
 
 	case TO_FILE:
-		_statusline(FILENAME_PROMPT);
-	retry:	strcpy(filename, sug_filename);  /* add suggestion info */
-		/* make the sug_filename conform to system specs */
-		change_sug_filename(filename);
-		if (!(HTisDocumentSource()) &&
-		    (cp = strrchr(filename, '.')) != NULL) {
-		    format = HTFileFormat(filename, &encoding, NULL);
-		    if (!strcasecomp(format->name, "text/html") ||
-			!IsUnityEnc(encoding)) {
-			*cp = '\0';
-			strcat(filename, ".txt");
-		    }
-		}
-		if (lynx_save_space && *lynx_save_space) {
-		    strcpy(buffer, lynx_save_space);
-		    strcat(buffer, filename);
-		    strcpy(filename, buffer);
-		}
-	check_recall:
-		if ((ch = LYgetstr(filename, VISIBLE,
-				   sizeof(filename), recall)) < 0 ||
-		    *filename == '\0' || ch == UPARROW || ch == DNARROW) {
-		    if (recall && ch == UPARROW) {
-			if (FirstRecall) {
-			    FirstRecall = FALSE;
-			    /*
-			     *	Use the last Fname in the list. - FM
-			     */
-			    FnameNum = 0;
-			} else {
-			    /*
-			     *	Go back to the previous Fname
-			     *	in the list. - FM
-			     */
-			    FnameNum++;
-			}
-			if (FnameNum >= FnameTotal) {
-			    /*
-			     *	Reset the FirstRecall flag,
-			     *	and use sug_file or a blank. - FM
-			     */
-			    FirstRecall = TRUE;
-			    FnameNum = FnameTotal;
-			    _statusline(FILENAME_PROMPT);
-			    goto retry;
-			} else if ((cp = (char *)HTList_objectAt(
-							sug_filenames,
-							FnameNum)) != NULL) {
-			    strcpy(filename, cp);
-			    if (FnameTotal == 1) {
-				_statusline(EDIT_THE_PREV_FILENAME);
-			    } else {
-				_statusline(EDIT_A_PREV_FILENAME);
-			    }
-			    goto check_recall;
-			}
-		    } else if (recall && ch == DNARROW) {
-			if (FirstRecall) {
-			    FirstRecall = FALSE;
-			    /*
-			     * Use the first Fname in the list. - FM
-			     */
-			    FnameNum = FnameTotal - 1;
-			} else {
-			    /*
-			     * Advance to the next Fname in the list. - FM
-			     */
-			    FnameNum--;
-			}
-			if (FnameNum < 0) {
-			    /*
-			     *	Set the FirstRecall flag,
-			     *	and use sug_file or a blank. - FM
-			     */
-			    FirstRecall = TRUE;
-			    FnameNum = FnameTotal;
-			    _statusline(FILENAME_PROMPT);
-			    goto retry;
-			} else if ((cp = (char *)HTList_objectAt(
-							sug_filenames,
-							FnameNum)) != NULL) {
-			    strcpy(filename, cp);
-			    if (FnameTotal == 1) {
-				_statusline(EDIT_THE_PREV_FILENAME);
-			    } else {
-				_statusline(EDIT_A_PREV_FILENAME);
-			    }
-			    goto check_recall;
-			}
-		    }
-
-		    /*
-		     *	Save cancelled.
-		     */
-		    HTInfoMsg(SAVE_REQUEST_CANCELLED);
-		    break;
-		}
-
-		if (!LYValidateFilename(buffer, filename)) {
-		    HTInfoMsg(SAVE_REQUEST_CANCELLED);
-		    break;
-		}
-
-		/*
-		 *  See if it already exists.
-		 */
-		switch (LYValidateOutput(buffer)) {
-		case 'Y':
-		    break;
-		case 'N':
-		    _statusline(NEW_FILENAME_PROMPT);
-		    FirstRecall = TRUE;
-		    FnameNum = FnameTotal;
-		    goto retry;
-		default:
-		    goto done;
-		}
-
-		/*
-		 *  See if we can write to it.
-		 */
-		CTRACE(tfp, "LYPrint: filename is %s, action is `%c'\n", buffer, c);
-
-#if HAVE_POPEN
-		if (*buffer == '|') {
-		    if (no_shell) {
-			HTUserMsg(SPAWNING_DISABLED);
-			FirstRecall = TRUE;
-			FnameNum = FnameTotal;
-			goto retry;
-		    } else if ((outfile_fp = popen(buffer+1, "w")) == NULL) {
-			CTRACE(tfp, "LYPrint: errno is %d\n", errno);
-			HTAlert(CANNOT_WRITE_TO_FILE);
-			_statusline(NEW_FILENAME_PROMPT);
-			FirstRecall = TRUE;
-			FnameNum = FnameTotal;
-			goto retry;
-		    }
-		} else
-#endif
-		if ((outfile_fp = (TOUPPER(c) == 'A'
-			? LYAppendToTxtFile(buffer)
-			: LYNewTxtFile(buffer))) == NULL) {
-		    CTRACE(tfp, "LYPrint: errno is %d\n", errno);
-		    HTAlert(CANNOT_WRITE_TO_FILE);
-		    _statusline(NEW_FILENAME_PROMPT);
-		    FirstRecall = TRUE;
-		    FnameNum = FnameTotal;
-		    goto retry;
-		}
-
-		if (LYPrependBaseToSource && HTisDocumentSource()) {
-		    /*
-		     *	Added the document's base as a BASE tag
-		     *	to the top of the file.  May create
-		     *	technically invalid HTML, but will help
-		     *	get any partial or relative URLs resolved
-		     *	properly if no BASE tag is present to
-		     *	replace it. - FM
-		     *
-		     *  Add timestamp (last reload).
-		     */
-
-		    fprintf(outfile_fp,
-			    "<!-- X-URL: %s -->\n", newdoc->address);
-		    if (HText_getDate() != NULL)
-			 fprintf(outfile_fp,
-			    "<!-- Date: %s -->\n", HText_getDate());
-		    fprintf(outfile_fp,
-			    "<BASE HREF=\"%s\">\n", content_base);
-		}
-
-		if (LYPrependCharsetToSource && HTisDocumentSource()) {
-		    /*
-		     *	Added the document's charset as a META CHARSET tag
-		     *	to the top of the file.  May create
-		     *	technically invalid HTML, but will help to resolve
-		     *	properly the document converted via chartrans:
-		     *	printed document correspond to a display charset
-		     *	and we *should* override both assume_local_charset
-		     *	and original document's META CHARSET (if any).
-		     *
-		     *	Currently, if several META CHARSETs are found Lynx uses
-		     *	the first only, and it is opposite to BASE where the
-		     *	original BASE in the <HEAD> overrides ones from the
-		     *	top.
-		     *
-		     *	As in print-to-email we write charset only if the
-		     *	document has 8-bit characters, and we have no CJK or an
-		     *	unofficial "x-" charset.
-		     */
-		     use_cte = HTLoadedDocumentEightbit();
-		     disp_charset = LYCharSet_UC[current_char_set].MIMEname;
-		     if (!use_cte || LYHaveCJKCharacterSet ||
-			  strncasecomp(disp_charset, "x-", 2) == 0) {
-		     } else {
-			fprintf(outfile_fp,
-				"<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=%s\">\n\n",
-				disp_charset);
-			}
-		}
-
-		print_wwwfile_to_fd(outfile_fp,0);
-		if (keypad_mode)
-		    printlist(outfile_fp,FALSE);
-
-#if HAVE_POPEN
-		if (LYIsPipeCommand(buffer))
-		    pclose(outfile_fp);
-		else
-#endif
-		fclose(outfile_fp);
-#ifdef VMS
-		if (0 == strncasecomp(buffer, "sys$disk:", 9)) {
-		    if (0 == strncmp((buffer+9), "[]", 2)) {
-			HTAddSugFilename(buffer+11);
-		    } else {
-			HTAddSugFilename(buffer+9);
-		    }
-		} else {
-		    HTAddSugFilename(buffer);
-		}
-#else
-		HTAddSugFilename(buffer);
-#endif /* VMS */
-		break;
+	    send_file_to_file(newdoc, content_base, sug_filename);
+	    break;
 
 	case MAIL:
-	    if (LYPreparsedSource && first_mail_preparsed &&
-		HTisDocumentSource()) {
-		_statusline(CONFIRM_MAIL_SOURCE_PREPARSED);
-		c = 0;
-		while (TOUPPER(c)!='Y' && TOUPPER(c)!='N' &&
-		       c != 7 && c != 3)
-		    c = LYgetch();
-#ifdef VMS
-		if (HadVMSInterrupt) {
-		    HadVMSInterrupt = FALSE;
-		    HTInfoMsg(MAIL_REQUEST_CANCELLED);
-		    break;
-		}
-#endif /* VMS */
-		if (c == RTARROW || c == 'y' || c== 'Y'
-		    || c == '\n' || c == '\r') {
-		    addstr("   Ok...");
-		    first_mail_preparsed = FALSE;
-		} else	{
-		    HTInfoMsg(MAIL_REQUEST_CANCELLED);
-		    break;
-		}
-	    }
-
-		_statusline(MAIL_ADDRESS_PROMPT);
-		strcpy(user_response, (personal_mail_address ?
-				       personal_mail_address : ""));
-		if (LYgetstr(user_response, VISIBLE,
-			     sizeof(user_response), NORECALL) < 0 ||
-		    *user_response == '\0') {
-		    HTInfoMsg(MAIL_REQUEST_CANCELLED);
-		    break;
-		}
-
-		/*
-		 *  Determine which mail headers should be sent.
-		 *  Use Content-Type and MIME-Version headers only
-		 *  if needed.	We need them if we are mailing HTML
-		 *  source, or if we have 8-bit characters and will
-		 *  be sending Content-Transfer-Encoding to indicate
-		 *  this.  We will append a charset parameter to the
-		 *  Content-Type if we do not have an "x-" charset,
-		 *  and we will include the Content-Transfer-Encoding
-		 *  only if we are appending the charset parameter,
-		 *  because indicating an 8-bit transfer without also
-		 *  indicating the charset can cause problems with
-		 *  many mailers. - FM & KW
-		 */
-		disp_charset = LYCharSet_UC[current_char_set].MIMEname;
-		use_cte = HTLoadedDocumentEightbit();
-		if (!(use_cte && strncasecomp(disp_charset, "x-", 2))) {
-		    disp_charset = NULL;
-		    use_cte = FALSE;
-		}
-		use_type =  (disp_charset || HTisDocumentSource());
-
-		/*
-		 *  Use newdoc->title as a subject instead of sug_filename:
-		 *  MORE readable and 8-bit letters shouldn't be a problem - LP
-		 */
-		/* change_sug_filename(sug_filename); */
-	       subject = subject_translate8bit(newdoc->title);
-
-	       if (newdoc->isHEAD) {
-		       /*
-			* Special case for mailing HEAD responce:
-			* this is rather technical information, show URL.
-			*/
-		       FREE(subject);
-		       StrAllocCopy(subject, "HEAD  ");
-		       StrAllocCat(subject, newdoc->address);
-		}
-
-#ifdef VMS
-		if (strchr(user_response,'@') && !strchr(user_response,':') &&
-		   !strchr(user_response,'%') && !strchr(user_response,'"')) {
-		    sprintf(filename, mail_adrs, user_response);
-		    strcpy(user_response, filename);
-		}
-
-		LYRemoveTemp(tempfile);
-		outfile_fp = LYOpenTemp(tempfile,
-					(HTisDocumentSource())
-						? HTML_SUFFIX
-						: ".txt",
-					"w");
-		if (outfile_fp == NULL) {
-		    HTAlert(UNABLE_TO_OPEN_TEMPFILE);
-		    break;
-		}
-
-		if (isPMDF) {
-		    if ((hfd = LYOpenTemp(hdrfile, ".txt", "w")) == NULL) {
-			HTAlert(UNABLE_TO_OPEN_TEMPFILE);
-			break;
-		    }
-		    if (use_type) {
-			fprintf(hfd, "Mime-Version: 1.0\n");
-			if (use_cte) {
-			    fprintf(hfd,
-				    "Content-Transfer-Encoding: 8bit\n");
-			}
-		    }
-		    if (HTisDocumentSource()) {
-			/*
-			 *  Add Content-Type, Content-Location, and
-			 *  Content-Base headers for HTML source. - FM
-			 */
-			fprintf(hfd, "Content-Type: text/html");
-			if (disp_charset != NULL) {
-			    fprintf(hfd,
-				    "; charset=%s\n",
-				    disp_charset);
-			} else {
-			    fprintf(hfd, "\n");
-			}
-			fprintf(hfd,
-				"Content-Base: %s\n",
-				content_base);
-			fprintf(hfd,
-				"Content-Location: %s\n",
-				content_location);
-		    } else {
-			/*
-			 *  Add Content-Type: text/plain if we have 8-bit
-			 *  characters and a valid charset for non-source
-			 *  documents. - FM
-			 */
-			if (disp_charset != NULL) {
-			    fprintf(hfd,
-				    "Content-Type: text/plain; charset=%s\n",
-				    disp_charset);
-			}
-		    }
-		    /*
-		     *	X-URL header. - FM
-		     */
-		    fprintf(hfd, "X-URL: %s\n", newdoc->address);
-		}
-
-		/*
-		 *  Write the contents to a temp file.
-		 */
-		if (LYPrependBaseToSource && HTisDocumentSource()) {
-		    /*
-		     *	Added the document's base as a BASE tag to
-		     *	the top of the message body.  May create
-		     *	technically invalid HTML, but will help
-		     *	get any partial or relative URLs resolved
-		     *	properly if no BASE tag is present to
-		     *	replace it. - FM
-		     */
-		    fprintf(outfile_fp,
-			    "<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
-			    newdoc->address, content_base);
-		} else if (!isPMDF) {
-		    fprintf(outfile_fp, "X-URL: %s\n\n", newdoc->address);
-		}
-		print_wwwfile_to_fd(outfile_fp, 0);
-		if (keypad_mode)
-		    printlist(outfile_fp, FALSE);
-		LYCloseTempFP(outfile_fp);
-
-		if (isPMDF) {
-		    /*
-		     *	For PMDF, put the subject in the
-		     *	header file and close it. - FM
-		     */
-		    fprintf(hfd, "Subject: %.70s\n\n", subject);
-		    LYCloseTempFP(hfd);
-		    /*
-		     *	Now set up the command. - FM
-		     */
-		    sprintf(buffer,
-			    "%s %s %s,%s %s",
-			    system_mail,
-			    system_mail_flags,
-			    hdrfile,
-			    tempfile,
-			    user_response);
-		} else {
-		    /*
-		     *	For "generic" VMS MAIL, include
-		     *	the subject in the command. - FM
-		     */
-		    remove_quotes(subject);
-		    sprintf(buffer,
-			    "%s %s/subject=\"%.70s\" %s %s",
-			    system_mail,
-			    system_mail_flags,
-			    subject,
-			    tempfile,
-			    user_response);
-		}
-
-		stop_curses();
-		printf(MAILING_FILE);
-		LYSystem(buffer);
-		sleep(AlertSecs);
-		start_curses();
-		if (isPMDF)
-		    LYRemoveTemp(hdrfile);
-#else /* Unix or DOS */
-
-#ifdef DOSPATH
-		outfile_fp = LYOpenTemp(tempfile, ".txt", "w");
-#else
-		sprintf(buffer, "%s %s", system_mail, system_mail_flags);
-		outfile_fp = popen(buffer, "w");
-#endif
-		if (outfile_fp == NULL) {
-		    HTAlert(MAIL_REQUEST_FAILED);
-		    break;
-		}
-
-		/*
-		 *  Determine which mail headers should be sent.
-		 *  Use Content-Type and MIME-Version headers only
-		 *  if needed.	We need them if we are mailing HTML
-		 *  source, or if we have 8-bit characters and will
-		 *  be sending Content-Transfer-Encoding to indicate
-		 *  this.
-		 *
-		 *  Send Content-Transfer-Encoding only if the document
-		 *  has 8-bit characters.  Send a charset parameter only
-		 *  if the document has 8-bit characters and we we seem
-		 *  to have a valid charset.  - kw
-		 */
-		use_cte = HTLoadedDocumentEightbit();
-		disp_charset = LYCharSet_UC[current_char_set].MIMEname;
-		/*
-		 *  Don't send a charset if we have a CJK character set
-		 *  selected, since it may not be appropriate for mail...
-		 *  Also don't use an unofficial "x-" charset. - kw
-		 */
-		if (!use_cte || LYHaveCJKCharacterSet ||
-		    strncasecomp(disp_charset, "x-", 2) == 0) {
-		    disp_charset = NULL;
-		}
-#ifdef NOTDEFINED
-		/*  Enable this if indicating an 8-bit transfer without
-		 *  also indicating the charset causes problems. - kw */
-		if (use_cte && !disp_charse)
-		    use_cte = FALSE;
-#endif /* NOTDEFINED */
-		use_type =  (disp_charset || HTisDocumentSource());
-		use_mime = (use_cte || use_type);
-
-		if (use_mime) {
-		    fprintf(outfile_fp, "Mime-Version: 1.0\n");
-		    if (use_cte) {
-			fprintf(outfile_fp,
-				"Content-Transfer-Encoding: 8bit\n");
-		    }
-		}
-
-		if (HTisDocumentSource()) {
-		    /*
-		     *	Add Content-Type, Content-Location, and
-		     *	Content-Base headers for HTML source. - FM
-		     */
-		    fprintf(outfile_fp, "Content-Type: text/html");
-		    if (disp_charset != NULL) {
-			fprintf(outfile_fp, "; charset=%s\n",
-					    disp_charset);
-		    } else {
-			fprintf(outfile_fp, "\n");
-		    }
-		} else {
-		    /*
-		     *	Add Content-Type: text/plain if we have 8-bit
-		     *	characters and a valid charset for non-source
-		     *	documents. - KW
-		     */
-		    if (disp_charset != NULL) {
-			fprintf(outfile_fp,
-				"Content-Type: text/plain; charset=%s\n",
-				disp_charset);
-		    }
-		}
-		/*
-		 *  If we are using MIME headers, add content-base and
-		 *  content-location if we have them.  This will always
-		 *  be the case if the document is source. - kw
-		 */
-		if (use_mime) {
-		    if (content_base)
-			fprintf(outfile_fp, "Content-Base: %s\n",
-				content_base);
-		    if (content_location)
-			fprintf(outfile_fp, "Content-Location: %s\n",
-				content_location);
-		}
-
-		/*
-		 *  Add the To, Subject, and X-URL headers. - FM
-		 */
-		fprintf(outfile_fp, "To: %s\nSubject: %s\n",
-				     user_response, subject);
-		fprintf(outfile_fp, "X-URL: %s\n\n", newdoc->address);
-		if (LYPrependBaseToSource && HTisDocumentSource()) {
-		    /*
-		     *	Added the document's base as a BASE tag to
-		     *	the top of the message body.  May create
-		     *	technically invalid HTML, but will help
-		     *	get any partial or relative URLs resolved
-		     *	properly if no BASE tag is present to
-		     *	replace it. - FM
-		     */
-		    fprintf(outfile_fp,
-			    "<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
-			    newdoc->address, content_base);
-		}
-		print_wwwfile_to_fd(outfile_fp, 0);
-		if (keypad_mode)
-		    printlist(outfile_fp, FALSE);
-
-#ifdef DOSPATH
-		sprintf(buffer, "%s -t \"%s\" -F %s", system_mail, user_response, tempfile);
-		LYCloseTempFP(outfile_fp);	/* Close the tmpfile. */
-		stop_curses();
-		printf("%s\n\n$ %s\n\n%s", gettext("Sending"), buffer, PLEASE_WAIT);
-		LYSystem(buffer);
-		sleep(MessageSecs);
-		start_curses();
-		LYRemoveTemp(tempfile); /* Delete the tmpfile. */
-#else
-		pclose(outfile_fp);
-#endif
-#endif /* VMS */
-		break;
+	    send_file_to_mail(newdoc, content_base, content_location);
+	    break;
 
 	case TO_SCREEN:
-		pages = lines_in_file/(LYlines+1);
-		/* count fractional pages ! */
-		if ((lines_in_file % (LYlines+1)) > 0)
-		    pages++;
-		if (pages > 4) {
-		    sprintf(filename, CONFIRM_LONG_SCREEN_PRINT, pages);
-		    _statusline(filename);
-		    c = LYgetch();
-#ifdef VMS
-		    if (HadVMSInterrupt) {
-			HadVMSInterrupt = FALSE;
-			HTInfoMsg(PRINT_REQUEST_CANCELLED);
-			break;
-		    }
-#endif /* VMS */
-		    if (c == RTARROW || c == 'y' || c== 'Y'
-			 || c == '\n' || c == '\r') {
-			addstr("   Ok...");
-		    } else {
-			HTInfoMsg(PRINT_REQUEST_CANCELLED);
-			break;
-		    }
-		}
-
-		if (Lpansi) {
-		      _statusline(CHECK_PRINTER);
-		} else	{
-		      _statusline(PRESS_RETURN_TO_BEGIN);
-		}
-		*filename = '\0';
-		if (LYgetstr(filename, VISIBLE,
-			     sizeof(filename), NORECALL) < 0) {
-		      HTInfoMsg(PRINT_REQUEST_CANCELLED);
-		      break;
-		}
-
-		outfile_fp = stdout;
-
-		stop_curses();
-#ifndef VMS
-		signal(SIGINT, SIG_IGN);
-#endif /* !VMS */
-
-		if (LYPrependBaseToSource && HTisDocumentSource()) {
-		    /*
-		     *	Added the document's base as a BASE tag
-		     *	to the top of the file.  May create
-		     *	technically invalid HTML, but will help
-		     *	get any partial or relative URLs resolved
-		     *	properly if no BASE tag is present to
-		     *	replace it. - FM
-		     */
-		    fprintf(outfile_fp,
-			    "<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
-			    newdoc->address, content_base);
-		}
-		if (Lpansi)
-		    printf("\033[5i");
-		print_wwwfile_to_fd(outfile_fp, 0);
-		if (keypad_mode)
-		    printlist(outfile_fp, FALSE);
-
-#ifdef VMS
-		if (HadVMSInterrupt) {
-		     HadVMSInterrupt = FALSE;
-		     start_curses();
-		     break;
-		}
-#endif /* VMS */
-		if (Lpansi) {
-		     printf("\n\014");	/* Form feed */
-		     printf("\033[4i");
-		     Lpansi = FALSE;
-		} else {
-		     fprintf(stdout,"\n\n%s", PRESS_RETURN_TO_FINISH);
-		     LYgetch();  /* grab some user input to pause */
-#ifdef VMS
-		     HadVMSInterrupt = FALSE;
-#endif /* VMS */
-		}
-		fflush(stdout);  /* refresh to screen */
-		start_curses();
-		break;
+	    if (confirm_by_pages(CONFIRM_LONG_SCREEN_PRINT, lines_in_file, LYlines))
+		send_file_to_screen(newdoc, content_base, Lpansi);
+	    break;
 
 	case PRINTER:
-		pages = lines_in_file/pagelen;
-		/* count fractional pages ! */
-		if ((lines_in_file % pagelen) > 0)
-		    pages++;
-		if (pages > 4) {
-		    sprintf(filename, CONFIRM_LONG_PAGE_PRINT, pages);
-		    _statusline(filename);
-		    c=LYgetch();
-#ifdef VMS
-		    if (HadVMSInterrupt) {
-			HadVMSInterrupt = FALSE;
-			HTInfoMsg(PRINT_REQUEST_CANCELLED);
-			break;
-		    }
-#endif /* VMS */
-		    if (c == RTARROW || c == 'y' || c== 'Y'
-			 || c == '\n' || c == '\r') {
-			addstr("   Ok...");
-		    } else  {
-			HTInfoMsg(PRINT_REQUEST_CANCELLED);
-			break;
-		    }
-		}
-
-		LYRemoveTemp(tempfile);
-		outfile_fp = LYOpenTemp(tempfile,
-					(HTisDocumentSource())
-						? HTML_SUFFIX
-						: ".txt",
-					"w");
-		if (outfile_fp == NULL) {
-		    HTAlert(FILE_ALLOC_FAILED);
-		    break;
-		}
-
-		if (LYPrependBaseToSource && HTisDocumentSource()) {
-		    /*
-		     *	Added the document's base as a BASE tag
-		     *	to the top of the file.  May create
-		     *	technically invalid HTML, but will help
-		     *	get any partial or relative URLs resolved
-		     *	properly if no BASE tag is present to
-		     *	replace it. - FM
-		     */
-		    fprintf(outfile_fp,
-			    "<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
-			    newdoc->address, content_base);
-		}
-		print_wwwfile_to_fd(outfile_fp, 0);
-		if (keypad_mode)
-		    printlist(outfile_fp, FALSE);
-
-		LYCloseTempFP(outfile_fp);
-
-		/* find the right printer number */
-		{
-		    int count=0;
-		    for (cur_printer = printers;
-			 count < printer_number;
-			 count++, cur_printer = cur_printer->next)
-			; /* null body */
-		}
-
-		/*
-		 *  Commands have the form "command %s [%s] [etc]"
-		 *  where %s is the filename and the second optional
-		 *  %s is the suggested filename.
-		 */
-		if (cur_printer->command != NULL) {
-		    /*
-		     *	Check for two '%s' and ask for the second filename
-		     *	argument if there is.
-		     */
-		    if (HTCountCommandArgs (cur_printer->command) >= 2) {
-			_statusline(FILENAME_PROMPT);
-		again:	strcpy(filename, sug_filename);
-			change_sug_filename(filename);
-			if (!(HTisDocumentSource()) &&
-			    (cp = strrchr(filename, '.')) != NULL) {
-			    format = HTFileFormat(filename, &encoding, NULL);
-			    if (!strcasecomp(format->name, "text/html") ||
-				!IsUnityEnc(encoding)) {
-				*cp = '\0';
-				strcat(filename, ".txt");
-			    }
-			}
-		check_again:
-			if ((ch = LYgetstr(filename, VISIBLE,
-					   sizeof(filename), recall)) < 0 ||
-			    *filename == '\0' ||
-			    ch == UPARROW || ch == DNARROW) {
-			    if (recall && ch == UPARROW) {
-				if (FirstRecall) {
-				    FirstRecall = FALSE;
-				    /*
-				     *	Use the last Fname in the list. - FM
-				     */
-				    FnameNum = 0;
-				} else {
-				    /*
-				     *	Go back to the previous Fname
-				     *	in the list. - FM
-				     */
-				    FnameNum++;
-				}
-				if (FnameNum >= FnameTotal) {
-				    /*
-				     *	Reset the FirstRecall flag,
-				     *	and use sug_file or a blank. - FM
-				     */
-				    FirstRecall = TRUE;
-				    FnameNum = FnameTotal;
-				    _statusline(FILENAME_PROMPT);
-				    goto again;
-				} else if ((cp = (char *)HTList_objectAt(
-							sug_filenames,
-							FnameNum)) != NULL) {
-				    strcpy(filename, cp);
-				    if (FnameTotal == 1) {
-					_statusline(EDIT_THE_PREV_FILENAME);
-				    } else {
-					_statusline(EDIT_A_PREV_FILENAME);
-				    }
-				    goto check_again;
-				}
-			    } else if (recall && ch == DNARROW) {
-				if (FirstRecall) {
-				    FirstRecall = FALSE;
-				    /*
-				     *	Use the first Fname in the list. - FM
-				     */
-				    FnameNum = FnameTotal - 1;
-				} else {
-				    /*
-				     *	Advance to the next Fname
-				     *	in the list. - FM
-				     */
-				    FnameNum--;
-				}
-				if (FnameNum < 0) {
-				    /*
-				     *	Set the FirstRecall flag,
-				     *	and use sug_file or a blank. - FM
-				     */
-				    FirstRecall = TRUE;
-				    FnameNum = FnameTotal;
-				    _statusline(FILENAME_PROMPT);
-				    goto again;
-				} else if ((cp = (char *)HTList_objectAt(
-							sug_filenames,
-							FnameNum)) != NULL) {
-				    strcpy(filename, cp);
-				    if (FnameTotal == 1) {
-					_statusline(EDIT_THE_PREV_FILENAME);
-				    } else {
-					_statusline(EDIT_A_PREV_FILENAME);
-				    }
-				    goto check_again;
-				}
-			    }
-
-			    /*
-			     *	Printer cancelled.
-			     */
-			    HTInfoMsg(PRINT_REQUEST_CANCELLED);
-			    break;
-			}
-
-			if (no_dotfiles || !show_dotfiles) {
-			    if (*LYPathLeaf(filename) == '.') {
-				HTAlert(FILENAME_CANNOT_BE_DOT);
-				_statusline(NEW_FILENAME_PROMPT);
-				FirstRecall = TRUE;
-				FnameNum = FnameTotal;
-				goto again;
-			    }
-			}
-			/*
-			 *  Cancel if the user entered "/dev/null" on Unix,
-			 *  or an "nl:" path (case-insensitive) on VMS. - FM
-			 */
-#ifdef VMS
-			if (!strncasecomp(filename, "nl:", 3) ||
-			    !strncasecomp(filename, "/nl/", 4))
-#else
-			if (!strcmp(filename, "/dev/null"))
-#endif /* VMS */
-			{
-			    HTInfoMsg(PRINT_REQUEST_CANCELLED);
-			    break;
-			}
-			HTAddSugFilename(filename);
-		    }
-
-		    HTAddParam (&the_command, cur_printer->command, 1, tempfile);
-		    HTAddParam (&the_command, cur_printer->command, 2, filename);
-		    HTEndParam (&the_command, cur_printer->command, 2);
-
-		} else {
-		    HTAlert(PRINTER_MISCONF_ERROR);
-		    break;
-		}
-
-		/*
-		 *  Move the cursor to the top of the screen so that
-		 *  output from system'd commands don't scroll up
-		 *  the screen.
-		 */
-		move(1,1);
-
-		stop_curses();
-		CTRACE(tfp, "command: %s\n", the_command);
-		printf(PRINTING_FILE);
-		/*
-		 * Set various bits of document information as environment
-		 * variables, for use by external print scripts/etc.  On UNIX,
-		 * We assume there are values, and leave NULL value checking
-		 * up to the external PRINTER:  cmd/script - KED
-		 */
-		SET_ENVIRON(LYNX_PRINT_TITLE,
-			    HText_getTitle(),
-			    "No Title");
-		SET_ENVIRON(LYNX_PRINT_URL,
-			    newdoc->address,
-			    "No URL");
-		SET_ENVIRON(LYNX_PRINT_DATE,
-			    HText_getDate(),
-			    "No Date");
-		SET_ENVIRON(LYNX_PRINT_LASTMOD,
-			    HText_getLastModified(),
-			    "No LastMod");
-
-		LYSystem(the_command);
-		FREE(the_command);
-		/*
-		 * Remove the various LYNX_PRINT_xxxx logicals.  - KED
-		 * [could use unsetenv(), but it's not portable]
-		 */
-		SET_ENVIRON(LYNX_PRINT_TITLE,   "", "");
-		SET_ENVIRON(LYNX_PRINT_URL,     "","");
-		SET_ENVIRON(LYNX_PRINT_DATE,    "", "");
-		SET_ENVIRON(LYNX_PRINT_LASTMOD, "", "");
+	    if (confirm_by_pages(CONFIRM_LONG_PAGE_PRINT, lines_in_file, pagelen))
+		send_file_to_printer(newdoc, content_base, sug_filename, printer_number);
+	    break;
 
-		fflush(stdout);
-#ifndef VMS
-		signal(SIGINT, cleanup_sig);
-#endif /* !VMS */
-		sleep(MessageSecs);
-		start_curses();
     } /* end switch */
 
-done:
     FREE(link_info);
     FREE(sug_filename);
-    FREE(subject);
     FREE(content_base);
     FREE(content_location);
     return(NORMAL);
@@ -1225,11 +1192,10 @@ PRIVATE int remove_quotes ARGS1(
 PRIVATE char* subject_translate8bit ARGS1(char *, source)
 {
     CONST char *p = source;
-    char temp[256];
-    char *q = temp;
+    char temp[2];
     char *target = NULL;
 
-    int charset_in, charset_out, uck;
+    int charset_in, charset_out;
     char replace_buf [10];
 
     int i = outgoing_mail_charset;  /* from lynx.cfg, -1 by default */
@@ -1245,14 +1211,13 @@ PRIVATE char* subject_translate8bit ARGS1(char *, source)
     }
 
     for ( ; *p; p++) {
-	LYstrncpy(q, p, 1);
-	if ((unsigned char)*q <= 127) {
-	    StrAllocCat(target, q);
+	LYstrncpy(temp, p, sizeof(temp)-1);
+	if ((unsigned char)*temp <= 127) {
+	    StrAllocCat(target, temp);
 	} else {
-	    uck = UCTransCharStr(replace_buf, sizeof(replace_buf), *q,
-				 charset_in, charset_out, YES);
-	    if (uck >0)
-	    StrAllocCat(target, replace_buf);
+	    if (UCTransCharStr(replace_buf, sizeof(replace_buf), *temp,
+				charset_in, charset_out, YES) > 0)
+		StrAllocCat(target, replace_buf);
 	}
     }
 
@@ -1275,21 +1240,20 @@ PUBLIC int print_options ARGS3(
 	char **,	printed_url,
 	int,		lines_in_file)
 {
-    static char tempfile[LY_MAXPATH];
-    char buffer[LINESIZE];
+    static char my_temp[LY_MAXPATH];
+    char *buffer = 0;
     int count;
     int pages;
     FILE *fp0;
     lynx_printer_item_type *cur_printer;
 
-
-    LYRemoveTemp(tempfile);
-    if ((fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w")) == NULL) {
+    LYRemoveTemp(my_temp);
+    if ((fp0 = LYOpenTemp(my_temp, HTML_SUFFIX, "w")) == NULL) {
 	HTAlert(UNABLE_TO_OPEN_PRINTOP_FILE);
 	return(-1);
     }
 
-    LYLocalFileToURL(newfile, tempfile);
+    LYLocalFileToURL(newfile, my_temp);
 
     BeginInternalPage(fp0, PRINT_OPTIONS_TITLE, PRINT_OPTIONS_HELP);
 
@@ -1297,13 +1261,14 @@ PUBLIC int print_options ARGS3(
 
     /*  pages = lines_in_file/66 + 1; */
     pages = (lines_in_file+65)/66;
-    sprintf(buffer, "   <em>%s</em> %s\n   <em>%s</em> %d\n   <em>%s</em> %d %s %s\n",
+    HTSprintf0(&buffer, "   <em>%s</em> %s\n   <em>%s</em> %d\n   <em>%s</em> %d %s %s\n",
 	    gettext("Document:"), *printed_url,
 	    gettext("Number of lines:"), lines_in_file,
 	    gettext("Number of pages:"), pages,
 	    (pages > 1 ? gettext("pages") : gettext("page")),
 	    gettext("(approximately)"));
     fputs(buffer, fp0);
+    FREE(buffer);
 
     if (no_print || no_disk_save || child_lynx || no_mail)
 	fprintf(fp0, "   <em>%s</em>\n", gettext("Some print functions have been disabled!"));
@@ -1322,10 +1287,10 @@ PUBLIC int print_options ARGS3(
 	fprintf(fp0,"   <em>%s</em>\n", gettext("Save to disk disabled"));
     }
     if (child_lynx == FALSE && no_mail == FALSE && local_host_only == FALSE)
-	 fprintf(fp0,
-		 "   <a href=\"LYNXPRINT://MAIL_FILE/lines=%d\">%s</a>\n",
-		 lines_in_file,
-		 gettext("Mail the file"));
+	fprintf(fp0,
+		"   <a href=\"LYNXPRINT://MAIL_FILE/lines=%d\">%s</a>\n",
+		lines_in_file,
+		gettext("Mail the file"));
 
 #ifndef DOSPATH
     fprintf(fp0,
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index 1978fa4a..2143d53d 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -661,10 +661,12 @@ static int lynxcgi_environment_fun ARGS1(
 static int lynx_sig_file_fun ARGS1(
 	char *, 	value)
 {
-    if (LYPathOffHomeOK(value, 256)) {
-	StrAllocCopy(LynxSigFile, value);
-	LYAddPathToHome(value, 256, LynxSigFile);
-	StrAllocCopy(LynxSigFile, value);
+    char temp[LY_MAXPATH];
+    LYstrncpy(temp, value, sizeof(temp)-1);
+    if (LYPathOffHomeOK(temp, sizeof(temp))) {
+	StrAllocCopy(LynxSigFile, temp);
+	LYAddPathToHome(temp, sizeof(temp), LynxSigFile);
+	StrAllocCopy(LynxSigFile, temp);
 	CTRACE(tfp, "LYNX_SIG_FILE set to '%s'\n", LynxSigFile);
     } else {
 	CTRACE(tfp, "LYNX_SIG_FILE '%s' is bad. Ignoring.\n", LYNX_SIG_FILE);
@@ -945,7 +947,7 @@ static Config_Type Config_Table [] =
      PARSE_FUN("system_editor", CONF_FUN, system_editor_fun),
      PARSE_STR("system_mail", CONF_STR, system_mail),
      PARSE_STR("system_mail_flags", CONF_STR, system_mail_flags),
-     PARSE_SET("tagsoup", CONF_BOOL, New_DTD),
+     PARSE_SET("tagsoup", CONF_BOOL, Old_DTD),
 #ifdef EXEC_LINKS
      PARSE_DEF("trusted_exec", CONF_ADD_TRUSTED, EXEC_PATH),
 #endif
diff --git a/src/LYShowInfo.c b/src/LYShowInfo.c
index f72d5755..962a7329 100644
--- a/src/LYShowInfo.c
+++ b/src/LYShowInfo.c
@@ -25,10 +25,7 @@
 #if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO)
 #define HAVE_CFG_DEFS_H
 
-#define PutDefs(table, N) \
-	fprintf(fp0, "%-35s %s\n", \
-		     table[N].name, \
-		     (table[N].value != 0) ? table[N].value : "")
+#define PutDefs(table, N) fprintf(fp0, "%-35s %s\n", table[N].name, table[N].value)
 
 /*
  *  Compile-time definitions info, returns local url
@@ -291,7 +288,7 @@ PUBLIC int showinfo ARGS4(
     StrAllocCopy(Title, doc->title);
     LYEntify(&Title, TRUE);
     fprintf(fp0, "<dt><em>%s</em> %s%s\n",
-    		 gettext("Linkname:"),
+		 gettext("Linkname:"),
 		 Title, (doc->isHEAD ? " (HEAD)" : ""));
 
     StrAllocCopy(Address, doc->address);
@@ -301,7 +298,7 @@ PUBLIC int showinfo ARGS4(
 
     if (HTLoadedDocumentCharset()) {
 	fprintf(fp0, "<dt><em>&nbsp;%s</em> %s\n",
-	             gettext("Charset:"),
+		     gettext("Charset:"),
 		     HTLoadedDocumentCharset());
     } else {
       LYUCcharset * p_in = HTAnchor_getUCInfoStage(HTMainAnchor,
@@ -346,7 +343,7 @@ PUBLIC int showinfo ARGS4(
 	    gettext("size:"), size_of_file, gettext("lines"));
 
     fprintf(fp0, "<dt>&nbsp;&nbsp;&nbsp;&nbsp;<em>%s</em> %s%s%s\n",
-    		 gettext("mode:"),
+		 gettext("mode:"),
 		 (lynx_mode == FORMS_LYNX_MODE ?
 				  gettext("forms mode") : gettext("normal")),
 		 (doc->safe ? gettext(", safe") : ""),
@@ -370,7 +367,7 @@ PUBLIC int showinfo ARGS4(
 		char *enctype = links[doc->link].form->submit_enctype;
 
 		fprintf(fp0, "<dt>&nbsp;&nbsp;<em>%s</em> %s\n",
-		             gettext("Method:"),
+			     gettext("Method:"),
 			     (method == URL_POST_METHOD) ? "POST" :
 			     (method == URL_MAIL_METHOD) ? "(email)" :
 							   "GET");
diff --git a/src/LYStrings.c b/src/LYStrings.c
index 71e50e28..4b37c0dd 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -297,7 +297,11 @@ PUBLIC char *LYstrncpy ARGS3(
 	int,		n)
 {
     char *val;
-    int len = strlen(src);
+    int len;
+
+    if (src == 0)
+	src = "";
+    len = strlen(src);
 
     if (n < 0)
 	n = 0;
@@ -1836,6 +1840,17 @@ PUBLIC int LYEdit1 ARGS4(
 	}
 	break;
 
+    case LYE_DELBL:
+	/*
+	 *  Delete from current cursor position back to BOL.
+	 */
+	{
+	    int pos0 = Pos;
+	    while (pos0--)
+		LYEdit1(edit, 0, LYE_DELP, FALSE);
+	}
+	break;
+
     case LYE_DELEL:
 	/*
 	 *  Delete from current cursor position thru EOL.
diff --git a/src/LYStrings.h b/src/LYStrings.h
index 3d5d9a83..e4683b38 100644
--- a/src/LYStrings.h
+++ b/src/LYStrings.h
@@ -155,7 +155,8 @@ typedef struct _EditFieldData {
 
 #define LYE_AIX   (LYE_LKCMD +1)  /* Hex 97                */
 
-#define LYE_DELEL (LYE_AIX   +1)  /* Delete thru EOL       */
+#define LYE_DELBL (LYE_AIX   +1)  /* Delete back to BOL    */
+#define LYE_DELEL (LYE_DELBL +1)  /* Delete thru EOL       */
 
 #define LYE_SWMAP (LYE_DELEL +1)  /* Switch input keymap   */
 
diff --git a/src/LYUtils.c b/src/LYUtils.c
index 0591a895..07d427bd 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -90,6 +90,12 @@ extern int BSDselect PARAMS((int nfds, fd_set * readfds, fd_set * writefds,
 #endif /* __FreeBSD__ || __bsdi__ */
 #endif /* !UTMP_FILE */
 
+#ifdef VMS
+#define COPY_COMMAND "copy/nolog/noconf %s %s"
+#else
+#define COPY_COMMAND "%s %s %s"
+#endif /* VMS */
+
 extern HTkcode kanji_code;
 extern BOOLEAN LYHaveCJKCharacterSet;
 extern HTCJKlang HTCJK;
@@ -1818,7 +1824,8 @@ PUBLIC void statusline ARGS1(
      *	character set selected, otherwise, strip any escapes.  Also,
      *	make sure text is not longer than the statusline window. - FM
      */
-    max_length = ((LYcols - 2) < 256) ? (LYcols - 2) : 255;
+    max_length = ((LYcols - 2) < sizeof(buffer))
+		? (LYcols - 2) : sizeof(buffer)-1;
     if ((text[0] != '\0') &&
 	(LYHaveCJKCharacterSet)) {
 	/*
@@ -2476,12 +2483,6 @@ PUBLIC int is_url ARGS1(
     if (LYIsHtmlSep(*cp))
 	return(0);
 
-#if defined (DOSPATH) || defined (__EMX__) /* sorry! */
-    if (strncmp(cp, "file:///", 8) && strlen(cp) == 19 &&
-	cp[strlen(cp)-1] == ':')
-	StrAllocCat(cp,"/");
-#endif
-
     if (compare_type(cp, "news:", 5)) {
 	return(NEWS_URL_TYPE);
 
@@ -2769,8 +2770,8 @@ PUBLIC BOOLEAN inlocaldomain NOARGS
 		return(TRUE);
 #ifdef LINUX
 /* Linux fix to check for local user. J.Cullen 11Jul94		*/
-		if ((n > 0) && (strlen(me.ut_host) == 0))
-			return(TRUE);
+	    if ((n > 0) && (strlen(me.ut_host) == 0))
+		return(TRUE);
 #endif /* LINUX */
 
     } else {
@@ -3220,22 +3221,21 @@ PUBLIC void change_sug_filename ARGS1(
 }
 
 /*
- * Construct a temporary-filename
+ * Construct a temporary-filename.  Assumes result is LY_MAXPATH chars long.
  */
-PRIVATE char *fmt_tempname ARGS3(
+PRIVATE int fmt_tempname ARGS3(
 	char *, 	result,
 	CONST char *, 	prefix,
 	CONST char *,	suffix)
 {
     static unsigned counter;
-    char *leaf;
+    char leaf[LY_MAXPATH];
+    int code;
 
     if (prefix == 0)
 	prefix = "";
     if (suffix == 0)
 	suffix = "";
-    strcpy(result, prefix);
-    leaf = result + strlen(result);
     counter++;
 #ifdef FNAMES_8_3
     /*
@@ -3257,8 +3257,18 @@ PRIVATE char *fmt_tempname ARGS3(
 #else
     sprintf(leaf, "L%u-%uTMP%s", (unsigned)getpid(), counter, suffix);
 #endif
+    /*
+     * Someone could have configured the temporary pathname to be too long.
+     */
+    if ((strlen(prefix) + strlen(leaf)) < LY_MAXPATH) {
+	sprintf(result, "%s%s", prefix, leaf);
+	code = TRUE;
+    } else {
+	sprintf(result, "%.*s", LY_MAXPATH-1, leaf);
+	code = FALSE;
+    }
     CTRACE(tfp, "-> '%s'\n", result);
-    return result;
+    return (code);
 }
 
 /*
@@ -3727,7 +3737,7 @@ PUBLIC void LYConvertToURL ARGS1(
 		StrAllocCat(*AllocatedString, fragment);
 		fragment = NULL;
 	    }
-	} else if ((NULL != getcwd(dir_name, 255, 0)) &&
+	} else if ((NULL != getcwd(dir_name, sizeof(dir_name)-1, 0)) &&
 		   0 == chdir(old_string)) {
 	    /*
 	     * Probably a directory.  Try converting that.
@@ -3736,7 +3746,7 @@ PUBLIC void LYConvertToURL ARGS1(
 	    if (fragment != NULL) {
 		*fragment = '#';
 	    }
-	    if (NULL != getcwd(dir_name, 255, 0)) {
+	    if (NULL != getcwd(dir_name, sizeof(dir_name)-1, 0)) {
 		/*
 		 * Yup, we got it!
 		 */
@@ -3831,8 +3841,8 @@ have_VMS_URL:
 	    /*
 	     *	They want .
 	     */
-	    char curdir[DIRNAMESIZE];
-	    getcwd (curdir, DIRNAMESIZE);
+	    char curdir[LY_MAXPATH];
+	    getcwd (curdir, sizeof(curdir));
 	    StrAllocCopy(temp, wwwName(curdir));
 	    StrAllocCat(*AllocatedString, temp);
 	    FREE(temp);
@@ -3862,11 +3872,11 @@ have_VMS_URL:
 	    /*
 	     *	Create a full path to the current default directory.
 	     */
-	    char curdir[DIRNAMESIZE];
+	    char curdir[LY_MAXPATH];
 	    char *temp2 = NULL;
 	    BOOL is_local = FALSE;
 #if HAVE_GETCWD
-	    getcwd (curdir, DIRNAMESIZE);
+	    getcwd (curdir, sizeof(curdir));
 #else
 	    getwd (curdir);
 #endif /* NO_GETCWD */
@@ -3878,7 +3888,7 @@ have_VMS_URL:
 	    if (old_string[1] != ':' && old_string[1] != '|') {
 		StrAllocCopy(temp, wwwName(curdir));
 		LYAddHtmlSep(&temp);
-		LYstrncpy(curdir, temp, (DIRNAMESIZE - 1));
+		LYstrncpy(curdir, temp, (sizeof(curdir) - 1));
 		StrAllocCat(temp, old_string);
 	    } else {
 		curdir[0] = '\0';
@@ -5633,7 +5643,8 @@ PUBLIC FILE *LYOpenTemp ARGS3(
     }
 
     do {
-	(void) fmt_tempname(result, lynx_temp_space, suffix);
+	if (!fmt_tempname(result, lynx_temp_space, suffix))
+	    return 0;
 	if (txt) {
 	    switch (wrt) {
 	    case 'w':
@@ -5689,7 +5700,9 @@ PUBLIC FILE *LYOpenScratch ARGS2(
     FILE *fp;
     LY_TEMP *p;
 
-    (void) fmt_tempname(result, prefix, HTML_SUFFIX);
+    if (!fmt_tempname(result, prefix, HTML_SUFFIX))
+	return 0;
+
     if ((fp = LYNewTxtFile (result)) != 0) {
 	if ((p = (LY_TEMP *)calloc(1, sizeof(LY_TEMP))) != 0) {
 	    p->next = ly_temp;
@@ -6123,7 +6136,7 @@ PUBLIC void LYAddHtmlSep ARGS1(
  * to it.  This only applies to HTML paths.
  */
 PUBLIC void LYAddHtmlSep0 ARGS1(
-	char *,	path)
+	char *,		path)
 {
     size_t len;
 
@@ -6135,6 +6148,31 @@ PUBLIC void LYAddHtmlSep0 ARGS1(
 }
 
 /*
+ * Copy a file
+ */
+PUBLIC int LYCopyFile ARGS2(
+	char *,		src,
+	char *,		dst)
+{
+    int code;
+    char *the_command = 0;
+
+    HTAddParam(&the_command, COPY_COMMAND, 1, COPY_PATH);
+    HTAddParam(&the_command, COPY_COMMAND, 2, src);
+    HTAddParam(&the_command, COPY_COMMAND, 3, dst);
+    HTEndParam(&the_command, COPY_COMMAND, 3);
+
+    CTRACE(tfp, "command: %s\n", the_command);
+    stop_curses();
+    code = LYSystem(the_command);
+    start_curses();
+
+    FREE(the_command);
+
+    return code;
+}
+
+/*
  * Invoke a shell command
  */
 PUBLIC int LYSystem ARGS1(
diff --git a/src/LYUtils.h b/src/LYUtils.h
index 4264fe91..21a2875e 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -67,6 +67,7 @@ extern char *strip_trailing_slash PARAMS((char * my_dirname));
 extern char *wwwName PARAMS((CONST char *pathname));
 extern int HTCheckForInterrupt NOPARAMS;
 extern int LYCheckForProxyURL PARAMS((char *filename));
+extern int LYCopyFile PARAMS((char *src, char *dst));
 extern int LYOpenInternalPage PARAMS((FILE **fp0, char **newfile));
 extern int LYSystem PARAMS((char *command));
 extern int LYValidateOutput PARAMS((char * filename));
diff --git a/src/LYrcFile.c b/src/LYrcFile.c
index c79b4727..d3540ec8 100644
--- a/src/LYrcFile.c
+++ b/src/LYrcFile.c
@@ -19,7 +19,7 @@
 
 PUBLIC void read_rc NOPARAMS
 {
-    char line_buffer[256];
+    char line_buffer[LINESIZE];
     char rcfile[LY_MAXPATH];
     FILE *fp;
     char *cp, *cp2;
diff --git a/src/UCAuto.c b/src/UCAuto.c
index bac25ab3..903944e2 100644
--- a/src/UCAuto.c
+++ b/src/UCAuto.c
@@ -37,9 +37,9 @@ typedef enum {
     GN_Blat1, GN_0decgraf, GN_Ucp437, GN_Kuser, GN_dunno, GN_dontCare
 } TTransT_t;
 
-static char T_font_fn[100] = "\0";
-static char T_umap_fn[100] = "\0";
-static char T_setfont_cmd[200] = "\0";
+static char *T_font_fn = NULL;
+static char *T_umap_fn = NULL;
+
 #define SETFONT "setfont"
 #define NOOUTPUT "2>/dev/null >/dev/null"
 
@@ -48,37 +48,38 @@ PRIVATE void call_setfont ARGS3(
 	char *, 	fnsuffix,
 	char *, 	umap)
 {
-    if (font && *font && umap && *umap &&
-	!strcmp(font, T_font_fn) && !strcmp(umap, T_umap_fn)) {
+    char *T_setfont_cmd = NULL;
+
+    if ((font && T_font_fn && !strcmp(font, T_font_fn))
+     && (umap && T_umap_fn && !strcmp(umap, T_umap_fn))) {
 	/*
 	 *  No need to repeat.
 	 */
 	return;
     }
     if (font)
-	strcpy(T_font_fn, font);
+	StrAllocCopy(T_font_fn, font);
     if (umap)
-	strcpy(T_umap_fn, umap);
+	StrAllocCopy(T_umap_fn, umap);
 
     if (!*fnsuffix)
 	fnsuffix = "";
 
     if (umap &&*umap && font && *font) {
-	sprintf(T_setfont_cmd, "%s %s%s -u %s %s",
+	HTSprintf0(&T_setfont_cmd, "%s %s%s -u %s %s",
 		SETFONT, font, fnsuffix,	umap,	NOOUTPUT);
     } else if (font && *font) {
-	sprintf(T_setfont_cmd, "%s %s%s %s",
+	HTSprintf0(&T_setfont_cmd, "%s %s%s %s",
 		SETFONT, font, fnsuffix,		NOOUTPUT);
     } else if (umap && *umap) {
-	sprintf(T_setfont_cmd, "%s -u %s %s",
+	HTSprintf0(&T_setfont_cmd, "%s -u %s %s",
 		SETFONT,			umap,	NOOUTPUT);
-    } else {
-	*T_setfont_cmd = '\0';
     }
 
-    if (*T_setfont_cmd) {
+    if (T_setfont_cmd) {
 	CTRACE(tfp, "Executing setfont: '%s'\n", T_setfont_cmd);
 	LYSystem(T_setfont_cmd);
+	FREE(T_setfont_cmd);
     }
 }
 
@@ -124,7 +125,8 @@ PUBLIC void UCChangeTerminalCodepage ARGS2(
     TGen_state_t Utf = Dunno;
     TGen_state_t HasUmap = Dunno;
 
-    char tmpbuf1[100], tmpbuf2[20];
+    char *tmpbuf1 = NULL;
+    char *tmpbuf2 = NULL;
 
     /*
      *	Restore the original character set.
@@ -137,13 +139,14 @@ PUBLIC void UCChangeTerminalCodepage ARGS2(
 
 	    if (have_font) {
 		if (have_umap) {
-		    sprintf(tmpbuf1, "%s %s -u %s %s",
+		    HTSprintf0(&tmpbuf1, "%s %s -u %s %s",
 			    SETFONT, old_font, old_umap, NOOUTPUT);
 		} else {
-		    sprintf(tmpbuf1, "%s %s %s",
+		    HTSprintf0(&tmpbuf1, "%s %s %s",
 			    SETFONT, old_font, NOOUTPUT);
 		}
 		LYSystem(tmpbuf1);
+		FREE(tmpbuf1);
 	    }
 
 	    remove(old_font);
@@ -158,9 +161,10 @@ PUBLIC void UCChangeTerminalCodepage ARGS2(
     } else if (lastcs < 0 && old_umap == 0 && old_font == 0) {
 	old_umap = tempnam((char *)0, "umap");
 	old_font = tempnam((char *)0, "font");
-	sprintf(tmpbuf1, "%s -o %s -ou %s %s",
+	HTSprintf0(&tmpbuf1, "%s -o %s -ou %s %s",
 		SETFONT, old_font, old_umap, NOOUTPUT);
 	LYSystem(tmpbuf1);
+	FREE(tmpbuf1);
     }
 
     name = p->MIMEname;
@@ -223,12 +227,13 @@ PUBLIC void UCChangeTerminalCodepage ARGS2(
 	HasUmap = Is_Set;
 	Utf = Is_Unset;
     } else if (!strncmp(name, "iso-8859-", 9)) {
-	sprintf(tmpbuf1, "iso0%s", &name[9]);
-	sprintf(tmpbuf2, "iso0%s%s", &name[9],".uni");
+	HTSprintf0(&tmpbuf1, "iso0%s", &name[9]);
+	HTSprintf0(&tmpbuf2, "iso0%s%s", &name[9],".uni");
 	/*
 	 *  "setfont iso0N.f16 -u iso0N.uni"
 	 */
 	call_setfont(tmpbuf1, SUFF1, tmpbuf2);
+	FREE(tmpbuf2);
 	TransT = GN_Kuser;
 	HasUmap = Is_Set;
 	Utf = Is_Unset;
diff --git a/src/UCdomap.c b/src/UCdomap.c
index 711b60a9..cf89b4cf 100644
--- a/src/UCdomap.c
+++ b/src/UCdomap.c
@@ -58,6 +58,7 @@
 #include <iso08_uni.h>		/* ISO 8859-8 Hebrew	*/
 #include <iso09_uni.h>		/* ISO 8859-9 (Latin 5) */
 #include <iso10_uni.h>		/* ISO 8859-10		*/
+#include <iso15_uni.h>		/* ISO 8859-15 (Latin 9)*/
 #include <koi8r_uni.h>		/* KOI8-R Cyrillic	*/
 #include <mac_uni.h>		/* Macintosh (8 bit)	*/
 #include <mnem2_suni.h> 	/* RFC 1345 Mnemonic	*/
@@ -2013,6 +2014,7 @@ PUBLIC void UCInit NOARGS
  */
 
     UC_CHARSET_SETUP_iso_8859_1;	  /* ISO Latin 1	  */
+    UC_CHARSET_SETUP_iso_8859_15;	  /* ISO 8859-15 (Latin 9)*/
     UC_CHARSET_SETUP_cp850;		  /* DosLatin1 (cp850)	  */
     UC_CHARSET_SETUP_windows_1252;	  /* WinLatin1 (cp1252)   */
     UC_CHARSET_SETUP_cp437;		  /* DosLatinUS (cp437)   */
diff --git a/src/chrtrans/build-chrtrans.com b/src/chrtrans/build-chrtrans.com
index 1694df14..cb015d18 100644
--- a/src/chrtrans/build-chrtrans.com
+++ b/src/chrtrans/build-chrtrans.com
@@ -140,6 +140,8 @@ $ define/user sys$output 'CHRwhere'iso09_uni.h	!ISO 8859-9 (Latin 5)
 $ makeuctb iso09_uni.tbl
 $ define/user sys$output 'CHRwhere'iso10_uni.h	!ISO 8859-10
 $ makeuctb iso10_uni.tbl
+$ define/user sys$output 'CHRwhere'iso15_uni.h	!ISO 8859-15
+$ makeuctb iso15_uni.tbl
 $ define/user sys$output 'CHRwhere'utf8_uni.h	!UNICODE UTF-8
 $ makeuctb utf8_uni.tbl
 $ define/user sys$output 'CHRwhere'rfc_suni.h	!RFC 1345 w/o Intro
diff --git a/src/chrtrans/caselower.h b/src/chrtrans/caselower.h
index df42c073..f55994dc 100644
--- a/src/chrtrans/caselower.h
+++ b/src/chrtrans/caselower.h
@@ -734,4 +734,4 @@ static CONST unipair unicode_to_lower_case[] =
   {0xFF38, 0xFF58},  /* FULLWIDTH LATIN CAPITAL LETTER X */
   {0xFF39, 0xFF59},  /* FULLWIDTH LATIN CAPITAL LETTER Y */
   {0xFF3A, 0xFF5A}   /* FULLWIDTH LATIN CAPITAL LETTER Z */
-};
\ No newline at end of file
+};
diff --git a/src/chrtrans/dmcs_uni.tbl b/src/chrtrans/dmcs_uni.tbl
index 676b728d..51072fad 100644
--- a/src/chrtrans/dmcs_uni.tbl
+++ b/src/chrtrans/dmcs_uni.tbl
@@ -9,6 +9,9 @@ ODEC Multinational
 #   Date:             29 October 1997
 #   Author:           Fote
 #
+#   1999-01-01	various corrections, verified against actual DEC VT220
+#		Christian "naddy" Weisgerber <naddy@mips.rhein-neckar.de>
+#
 ##################
 
 #0x20    U+0020  # SPACE
@@ -107,18 +110,18 @@ ODEC Multinational
 #0x7D    U+007D  # RIGHT CURLY BRACKET
 #0x7E    U+007E  # TILDE
 #
-0x20-0x7f       idem
-#
+0x20-0x7E       idem	# ASCII
+
 0xA1    U+00A1  # inverted exclamation mark (&#161;) - iexcl
 0xA2    U+00A2  # cent sign (&#162;) - cent
-0xA3    U+00A3  # pound sign (&#163;) - pound 
-# currency sign (&#164;) - curren
-U+00A4:CUR
-0xA5    U+00A5  # yen sign (&#165;) - yen 
+0xA3    U+00A3  # pound sign (&#163;) - pound
+0xA5    U+00A5  # yen sign (&#165;) - yen
 # broken vertical bar (&#166;) - brvbar, brkbar
 U+00A6:|
 0xA7    U+00A7  # section sign (&#167;) - sect
-0xA8    U+00A8  # spacing diaresis (&#168;) - uml, die
+0xA8    U+00A4  # currency sign (&#164;) - curren
+# spacing diaresis (&#168;) - uml, die
+U+00A8:"
 0xA9    U+00A9  # copyright sign (&#169;) - copy
 0xAA    U+00AA  # feminine ordinal indicator (&#170;) - ordf
 0xAB    U+00AB  # angle quotation mark, left (&#171;) - laquo
@@ -165,7 +168,7 @@ U+00BE: 3/4
 0xCD    U+00CD  # capital I, acute accent (&#205;) - Iacute
 0xCE    U+00CE  # capital I, circumflex accent (&#206;) - Icirc
 0xCF    U+00CF  # capital I, dieresis or umlaut mark (&#207;) - Iuml
-# capital Eth, Icelandic (&#208;) - ETH */ 
+# capital Eth, Icelandic (&#208;) - ETH */
 U+00D0:DH
 #      Dj  # capital D with stroke - Dstrok
 0xD1    U+00D1  # capital N, tilde (&#209;) - Ntilde
@@ -174,6 +177,7 @@ U+00D0:DH
 0xD4    U+00D4  # capital O, circumflex accent (&#212;) - Ocirc
 0xD5    U+00D5  # capital O, tilde (&#213;) - Otilde
 0xD6    U+00D6  # capital O, dieresis or umlaut mark (&#214;) - Ouml
+0xD7    U+0152  # captial OE ligature (&#338;) - OElig
 # multiplication sign (&#215;) - times
 U+00D7:*
 0xD8    U+00D8  # capital O, slash (&#216;) - Oslash
@@ -181,9 +185,11 @@ U+00D7:*
 0xDA    U+00DA  # capital U, acute accent (&#218;) - Uacute
 0xDB    U+00DB  # capital U, circumflex accent (&#219;) - Ucirc
 0xDC    U+00DC  # capital U, dieresis or umlaut mark (&#220;) - Uuml
-0xDD    U+00DD  # capital Y, acute accent (&#221;) - Yacute
-# capital THORN, Icelandic (&#222;) - THORN */ 
-U+00DE:P
+0xDD    U+0178  # capital Y, dieresis or umlaut mark (&#376;) - Yuml
+# capital Y, acute accent (&#221;) - Yacute
+U+00DD:Y'
+# capital THORN, Icelandic (&#222;) - THORN */
+U+00DE:TH
 0xDF    U+00DF  # small sharp s, German (sz ligature) (&#223;) - szlig
 0xE0    U+00E0  # small a, grave accent (&#224;) - agrave
 0xE1    U+00E1  # small a, acute accent (&#225;) - aacute
@@ -209,6 +215,7 @@ U+00F0:dh
 0xF4    U+00F4  # small o, circumflex accent (&#244;) - ocirc
 0xF5    U+00F5  # small o, tilde (&#245;) - otilde
 0xF6    U+00F6  # small o, dieresis or umlaut mark (&#246;) - ouml
+0xF7    U+0153  # small oe ligature (&#339;) - oelig
 # division sign (&#247;) - divide
 U+00F7:/
 0xF8    U+00F8  # small o, slash (&#248;) - oslash
@@ -220,7 +227,7 @@ U+00F7:/
 # small y, acute accent (&#253;) - yacute
 U+00FD:y'
 # small thorn, Icelandic (&#254;) - thorn
-U+00FE:p
+U+00FE:th
 #
 # TRADE MARK SIGN
 U+2122:(TM)
diff --git a/src/chrtrans/iso15_uni.tbl b/src/chrtrans/iso15_uni.tbl
new file mode 100644
index 00000000..efb5bf23
--- /dev/null
+++ b/src/chrtrans/iso15_uni.tbl
@@ -0,0 +1,216 @@
+# The MIME name of this charset.
+Miso-8859-15
+
+# Name as a Display Charset (used on Options screen)
+OWestern (ISO-8859-15)
+
+# This is not the default font!
+D0
+
+#Codepage number
+#?
+
+#
+# Name:		ISO 8859-15 Latin 9 (1998) to Unicode
+# Date:		1999-01-01
+# Authors:	Christian "naddy" Weisgerber <naddy@mips.rhein-neckar.de>
+#
+# Remarks:	Latin 9 is identical to Latin 1	except for
+#		code positions A4, A6, A8, B4, B8, BC, BD, BE
+
+0x20-0x7E idem	#	ASCII
+
+#0x20	U+0020	#	SPACE
+#0x21	U+0021	#	EXCLAMATION MARK
+#0x22	U+0022	#	QUOTATION MARK
+#0x23	U+0023	#	NUMBER SIGN
+#0x24	U+0024	#	DOLLAR SIGN
+#0x25	U+0025	#	PERCENT SIGN
+#0x26	U+0026	#	AMPERSAND
+#0x27	U+0027	#	APOSTROPHE
+#0x28	U+0028	#	LEFT PARENTHESIS
+#0x29	U+0029	#	RIGHT PARENTHESIS
+#0x2A	U+002A	#	ASTERISK
+#0x2B	U+002B	#	PLUS SIGN
+#0x2C	U+002C	#	COMMA
+#0x2D	U+002D	#	HYPHEN-MINUS
+#0x2E	U+002E	#	FULL STOP
+#0x2F	U+002F	#	SOLIDUS
+#0x30	U+0030	#	DIGIT ZERO
+#0x31	U+0031	#	DIGIT ONE
+#0x32	U+0032	#	DIGIT TWO
+#0x33	U+0033	#	DIGIT THREE
+#0x34	U+0034	#	DIGIT FOUR
+#0x35	U+0035	#	DIGIT FIVE
+#0x36	U+0036	#	DIGIT SIX
+#0x37	U+0037	#	DIGIT SEVEN
+#0x38	U+0038	#	DIGIT EIGHT
+#0x39	U+0039	#	DIGIT NINE
+#0x3A	U+003A	#	COLON
+#0x3B	U+003B	#	SEMICOLON
+#0x3C	U+003C	#	LESS-THAN SIGN
+#0x3D	U+003D	#	EQUALS SIGN
+#0x3E	U+003E	#	GREATER-THAN SIGN
+#0x3F	U+003F	#	QUESTION MARK
+#0x40	U+0040	#	COMMERCIAL AT
+#0x41	U+0041	#	LATIN CAPITAL LETTER A
+#0x42	U+0042	#	LATIN CAPITAL LETTER B
+#0x43	U+0043	#	LATIN CAPITAL LETTER C
+#0x44	U+0044	#	LATIN CAPITAL LETTER D
+#0x45	U+0045	#	LATIN CAPITAL LETTER E
+#0x46	U+0046	#	LATIN CAPITAL LETTER F
+#0x47	U+0047	#	LATIN CAPITAL LETTER G
+#0x48	U+0048	#	LATIN CAPITAL LETTER H
+#0x49	U+0049	#	LATIN CAPITAL LETTER I
+#0x4A	U+004A	#	LATIN CAPITAL LETTER J
+#0x4B	U+004B	#	LATIN CAPITAL LETTER K
+#0x4C	U+004C	#	LATIN CAPITAL LETTER L
+#0x4D	U+004D	#	LATIN CAPITAL LETTER M
+#0x4E	U+004E	#	LATIN CAPITAL LETTER N
+#0x4F	U+004F	#	LATIN CAPITAL LETTER O
+#0x50	U+0050	#	LATIN CAPITAL LETTER P
+#0x51	U+0051	#	LATIN CAPITAL LETTER Q
+#0x52	U+0052	#	LATIN CAPITAL LETTER R
+#0x53	U+0053	#	LATIN CAPITAL LETTER S
+#0x54	U+0054	#	LATIN CAPITAL LETTER T
+#0x55	U+0055	#	LATIN CAPITAL LETTER U
+#0x56	U+0056	#	LATIN CAPITAL LETTER V
+#0x57	U+0057	#	LATIN CAPITAL LETTER W
+#0x58	U+0058	#	LATIN CAPITAL LETTER X
+#0x59	U+0059	#	LATIN CAPITAL LETTER Y
+#0x5A	U+005A	#	LATIN CAPITAL LETTER Z
+#0x5B	U+005B	#	LEFT SQUARE BRACKET
+#0x5C	U+005C	#	REVERSE SOLIDUS
+#0x5D	U+005D	#	RIGHT SQUARE BRACKET
+#0x5E	U+005E	#	CIRCUMFLEX ACCENT
+#0x5F	U+005F	#	LOW LINE
+#0x60	U+0060	#	GRAVE ACCENT
+#0x61	U+0061	#	LATIN SMALL LETTER A
+#0x62	U+0062	#	LATIN SMALL LETTER B
+#0x63	U+0063	#	LATIN SMALL LETTER C
+#0x64	U+0064	#	LATIN SMALL LETTER D
+#0x65	U+0065	#	LATIN SMALL LETTER E
+#0x66	U+0066	#	LATIN SMALL LETTER F
+#0x67	U+0067	#	LATIN SMALL LETTER G
+#0x68	U+0068	#	LATIN SMALL LETTER H
+#0x69	U+0069	#	LATIN SMALL LETTER I
+#0x6A	U+006A	#	LATIN SMALL LETTER J
+#0x6B	U+006B	#	LATIN SMALL LETTER K
+#0x6C	U+006C	#	LATIN SMALL LETTER L
+#0x6D	U+006D	#	LATIN SMALL LETTER M
+#0x6E	U+006E	#	LATIN SMALL LETTER N
+#0x6F	U+006F	#	LATIN SMALL LETTER O
+#0x70	U+0070	#	LATIN SMALL LETTER P
+#0x71	U+0071	#	LATIN SMALL LETTER Q
+#0x72	U+0072	#	LATIN SMALL LETTER R
+#0x73	U+0073	#	LATIN SMALL LETTER S
+#0x74	U+0074	#	LATIN SMALL LETTER T
+#0x75	U+0075	#	LATIN SMALL LETTER U
+#0x76	U+0076	#	LATIN SMALL LETTER V
+#0x77	U+0077	#	LATIN SMALL LETTER W
+#0x78	U+0078	#	LATIN SMALL LETTER X
+#0x79	U+0079	#	LATIN SMALL LETTER Y
+#0x7A	U+007A	#	LATIN SMALL LETTER Z
+#0x7B	U+007B	#	LEFT CURLY BRACKET
+#0x7C	U+007C	#	VERTICAL LINE
+#0x7D	U+007D	#	RIGHT CURLY BRACKET
+#0x7E	U+007E	#	TILDE
+
+0xA0	U+00A0	#	NO-BREAK SPACE
+0xA1	U+00A1	#	INVERTED EXCLAMATION MARK
+0xA2	U+00A2	#	CENT SIGN
+0xA3	U+00A3	#	POUND SIGN
+0xA4	U+20AC	#	EURO SIGN
+0xA5	U+00A5	#	YEN SIGN
+0xA6	U+0160	#	LATIN CAPITAL LETTER S WITH CARON
+0xA7	U+00A7	#	SECTION SIGN
+0xA8	U+0161	#	LATIN SMALL LETTER S WITH CARON
+0xA9	U+00A9	#	COPYRIGHT SIGN
+0xAA	U+00AA	#	FEMININE ORDINAL INDICATOR
+0xAB	U+00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	U+00AC	#	NOT SIGN
+0xAD	U+00AD	#	SOFT HYPHEN
+0xAE	U+00AE	#	REGISTERED SIGN
+0xAF	U+00AF	#	MACRON
+0xB0	U+00B0	#	DEGREE SIGN
+0xB1	U+00B1	#	PLUS-MINUS SIGN
+0xB2	U+00B2	#	SUPERSCRIPT TWO
+0xB3	U+00B3	#	SUPERSCRIPT THREE
+0xB4	U+017D	#	LATIN CAPITAL LETTER Z WITH CARON
+0xB5	U+00B5	#	MICRO SIGN
+0xB6	U+00B6	#	PILCROW SIGN
+0xB7	U+00B7	#	MIDDLE DOT
+0xB8	U+017D	#	LATIN SMALL LETTER Z WITH CARON
+0xB9	U+00B9	#	SUPERSCRIPT ONE
+0xBA	U+00BA	#	MASCULINE ORDINAL INDICATOR
+0xBB	U+00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	U+0152	#	LATIN CAPITAL LIGATURE OE
+0xBD	U+0153	#	LATIN SMALL LIGATURE OE
+0xBE	U+0178	#	LATIN CAPITAL LETTER Y WITH DIAERESIS
+0xBF	U+00BF	#	INVERTED QUESTION MARK
+0xC0	U+00C0	#	LATIN CAPITAL LETTER A WITH GRAVE
+0xC1	U+00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	U+00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	U+00C3	#	LATIN CAPITAL LETTER A WITH TILDE
+0xC4	U+00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	U+00C5	#	LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	U+00C6	#	LATIN CAPITAL LETTER AE
+0xC7	U+00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	U+00C8	#	LATIN CAPITAL LETTER E WITH GRAVE
+0xC9	U+00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	U+00CA	#	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB	U+00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	U+00CC	#	LATIN CAPITAL LETTER I WITH GRAVE
+0xCD	U+00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	U+00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	U+00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0	U+00D0	#	LATIN CAPITAL LETTER ETH
+0xD1	U+00D1	#	LATIN CAPITAL LETTER N WITH TILDE
+0xD2	U+00D2	#	LATIN CAPITAL LETTER O WITH GRAVE
+0xD3	U+00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	U+00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	U+00D5	#	LATIN CAPITAL LETTER O WITH TILDE
+0xD6	U+00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	U+00D7	#	MULTIPLICATION SIGN
+0xD8	U+00D8	#	LATIN CAPITAL LETTER O WITH STROKE
+0xD9	U+00D9	#	LATIN CAPITAL LETTER U WITH GRAVE
+0xDA	U+00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	U+00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	U+00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	U+00DD	#	LATIN CAPITAL LETTER Y WITH ACUTE
+0xDE	U+00DE	#	LATIN CAPITAL LETTER THORN
+0xDF	U+00DF	#	LATIN SMALL LETTER SHARP S
+0xE0	U+00E0	#	LATIN SMALL LETTER A WITH GRAVE
+0xE1	U+00E1	#	LATIN SMALL LETTER A WITH ACUTE
+0xE2	U+00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	U+00E3	#	LATIN SMALL LETTER A WITH TILDE
+0xE4	U+00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	U+00E5	#	LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	U+00E6	#	LATIN SMALL LETTER AE
+0xE7	U+00E7	#	LATIN SMALL LETTER C WITH CEDILLA
+0xE8	U+00E8	#	LATIN SMALL LETTER E WITH GRAVE
+0xE9	U+00E9	#	LATIN SMALL LETTER E WITH ACUTE
+0xEA	U+00EA	#	LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB	U+00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	U+00EC	#	LATIN SMALL LETTER I WITH GRAVE
+0xED	U+00ED	#	LATIN SMALL LETTER I WITH ACUTE
+0xEE	U+00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	U+00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
+0xF0	U+00F0	#	LATIN SMALL LETTER ETH
+0xF1	U+00F1	#	LATIN SMALL LETTER N WITH TILDE
+0xF2	U+00F2	#	LATIN SMALL LETTER O WITH GRAVE
+0xF3	U+00F3	#	LATIN SMALL LETTER O WITH ACUTE
+0xF4	U+00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	U+00F5	#	LATIN SMALL LETTER O WITH TILDE
+0xF6	U+00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	U+00F7	#	DIVISION SIGN
+0xF8	U+00F8	#	LATIN SMALL LETTER O WITH STROKE
+0xF9	U+00F9	#	LATIN SMALL LETTER U WITH GRAVE
+0xFA	U+00FA	#	LATIN SMALL LETTER U WITH ACUTE
+0xFB	U+00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	U+00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	U+00FD	#	LATIN SMALL LETTER Y WITH ACUTE
+0xFE	U+00FE	#	LATIN SMALL LETTER THORN
+0xFF	U+00FF	#	LATIN SMALL LETTER Y WITH DIAERESIS
+
+## EOF ##
diff --git a/src/chrtrans/makefile.dos b/src/chrtrans/makefile.dos
index dba0d787..3abe6b58 100644
--- a/src/chrtrans/makefile.dos
+++ b/src/chrtrans/makefile.dos
@@ -55,6 +55,7 @@ TABLES= \
  iso08_uni.h \
  iso09_uni.h \
  iso10_uni.h \
+ iso15_uni.h \
  koi8r_uni.h \
  mac_uni.h \
  mnem_suni.h \
@@ -103,6 +104,7 @@ iso07_uni.h:		iso07_uni.tbl		makeuctb.exe
 iso08_uni.h:		iso08_uni.tbl		makeuctb.exe
 iso09_uni.h:		iso09_uni.tbl		makeuctb.exe
 iso10_uni.h:		iso10_uni.tbl		makeuctb.exe
+iso15_uni.h:		iso15_uni.tbl		makeuctb.exe
 koi8r_uni.h:		koi8r_uni.tbl		makeuctb.exe
 mac_uni.h:		mac_uni.tbl		makeuctb.exe
 mnem_suni.h:		mnem_suni.tbl		makeuctb.exe
diff --git a/src/chrtrans/makefile.in b/src/chrtrans/makefile.in
index 285e0566..37bd948d 100644
--- a/src/chrtrans/makefile.in
+++ b/src/chrtrans/makefile.in
@@ -74,6 +74,7 @@ TABLES= \
  iso08_uni.h \
  iso09_uni.h \
  iso10_uni.h \
+ iso15_uni.h \
  koi8r_uni.h \
  mac_uni.h \
  mnem_suni.h \
@@ -135,6 +136,7 @@ iso07_uni.h:		$(srcdir)/iso07_uni.tbl		makeuctb$x
 iso08_uni.h:		$(srcdir)/iso08_uni.tbl		makeuctb$x
 iso09_uni.h:		$(srcdir)/iso09_uni.tbl		makeuctb$x
 iso10_uni.h:		$(srcdir)/iso10_uni.tbl		makeuctb$x
+iso15_uni.h:		$(srcdir)/iso15_uni.tbl		makeuctb$x
 koi8r_uni.h:		$(srcdir)/koi8r_uni.tbl		makeuctb$x
 mac_uni.h:		$(srcdir)/mac_uni.tbl		makeuctb$x
 mnem_suni.h:		$(srcdir)/mnem_suni.tbl		makeuctb$x
diff --git a/src/makefile.dos b/src/makefile.dos
index 24622277..a7b30b41 100644
--- a/src/makefile.dos
+++ b/src/makefile.dos
@@ -12,7 +12,7 @@ LYStyle.o LYHash.o
 CFLAGS= $(MCFLAGS) -I. -I.. $(SLANGINC)

 

 CC = gcc

-MCFLAGS = -O3 -DHAVE_GETBKGD -DDISP_PARTIAL -DUSE_ZLIB \

+MCFLAGS = -O2 -DHAVE_GETBKGD -DDISP_PARTIAL -DUSE_ZLIB \

  -DUSE_EXTERNALS -DCOLOR_CURSES -DNCURSES -DFANCY_CURSES \

  -DACCESS_AUTH -DNO_CUSERID -DNOUSERS -DDOSPATH -DNO_TTYTYPE -DNO_UTMP \

  -Ichrtrans -I../WWW/library/implementation \

diff --git a/src/makefile.dsl b/src/makefile.dsl
index e77a2289..f5cfe76b 100644
--- a/src/makefile.dsl
+++ b/src/makefile.dsl
@@ -12,7 +12,7 @@ LYStyle.o LYHash.o
 CFLAGS= $(MCFLAGS) -I. -I.. $(SLANGINC)

 

 CC = gcc

-MCFLAGS = -O3 -DDISP_PARTIAL -DUSE_ZLIB -DUSE_EXTERNALS \

+MCFLAGS = -O2 -DDISP_PARTIAL -DUSE_ZLIB -DUSE_EXTERNALS \

 -DUSE_SLANG -DDJGPP_KEYHANDLER -DACCESS_AUTH -DNO_CUSERID \

 -DNOUSERS -DDOSPATH -DNO_TTYTYPE -DNO_UTMP -I../WWW/library/implement -I../djgpp/tcplib/include \

 -I./chrtrans -I../djgpp/tcplib/include/tcp

diff --git a/src/makefile.in b/src/makefile.in
index 0136a49f..21addeff 100644
--- a/src/makefile.in
+++ b/src/makefile.in
@@ -113,7 +113,7 @@ LYCharSets.o:	$(top_srcdir)/userdefs.h
 LYGetFile.o:	$(top_srcdir)/userdefs.h
 LYKeymap.o:	$(top_srcdir)/userdefs.h
 LYMail.o:	$(top_srcdir)/userdefs.h
-LYMain.o:	$(top_srcdir)/userdefs.h
+LYMain.o:	$(top_srcdir)/userdefs.h $(top_builddir)/lynx_cfg.h
 LYMainLoop.o:	$(top_srcdir)/userdefs.h
 LYOptions.o:	$(top_srcdir)/userdefs.h
 LYReadCFG.o:	$(top_srcdir)/userdefs.h
@@ -153,6 +153,7 @@ TABLES= \
  $(CHRTR)iso08_uni.h \
  $(CHRTR)iso09_uni.h \
  $(CHRTR)iso10_uni.h \
+ $(CHRTR)iso15_uni.h \
  $(CHRTR)koi8r_uni.h \
  $(CHRTR)mac_uni.h \
  $(CHRTR)mnem_suni.h \
diff --git a/src/makefile.wsl b/src/makefile.wsl
index 82964341..1b238170 100644
--- a/src/makefile.wsl
+++ b/src/makefile.wsl
@@ -12,7 +12,7 @@ LYStyle.o LYHash.o
 CFLAGS= $(MCFLAGS) -I. -I.. $(SLANGINC)

 

 CC = gcc

-MCFLAGS = -O3 -DDISP_PARTIAL -DUSE_ZLIB -DUSE_EXTERNALS \

+MCFLAGS = -O2 -DDISP_PARTIAL -DUSE_ZLIB -DUSE_EXTERNALS \

 -DUSE_SLANG -DACCESS_AUTH -DNO_CUSERID \

 -DNOUSERS -DDOSPATH -DNO_TTYTYPE -DNO_UTMP -I../WWW/library/implement -I../djgpp/tcplib/include \

 -I./chrtrans -I../djgpp/tcplib/include/tcp

diff --git a/userdefs.h b/userdefs.h
index 63e019a8..533daa28 100644
--- a/userdefs.h
+++ b/userdefs.h
@@ -1217,12 +1217,12 @@
  * the version definition with the Project Version on checkout.  Just
  * ignore it. - kw */
 /* $Format: "#define LYNX_VERSION \"$ProjectVersion$\""$ */
-#define LYNX_VERSION "2.8.2dev.12"
+#define LYNX_VERSION "2.8.2dev.13"
 #define LYNX_WWW_HOME "http://lynx.browser.org/"
 #define LYNX_WWW_DIST "http://www.slcc.edu/lynx/current/"
 #define LYNX_RELEASE FALSE
 /* $Format: "#define LYNX_DATE \"$ProjectDate$\""$ */
-#define LYNX_DATE "Sat, 26 Dec 1998 13:50:01 -0700"
+#define LYNX_DATE "Sat, 09 Jan 1999 05:56:33 -0700"
 #define LYNX_DATE_OFF 5		/* truncate the automatically-generated date */
 #define LYNX_DATE_LEN 11	/* truncate the automatically-generated date */
 #define LYNX_RELEASE_DATE "1998"