about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2000-08-25 01:41:14 -0400
committerThomas E. Dickey <dickey@invisible-island.net>2000-08-25 01:41:14 -0400
commit1a6a3318d96d97c4cc8d9fc827e930b3cfb22085 (patch)
treeef3eb0b7ce0306f73717f6cc3da54835a904d9ad /src
parent0726d2fa354eae3a7913d3ea28f19115ca904e02 (diff)
downloadlynx-snapshots-1a6a3318d96d97c4cc8d9fc827e930b3cfb22085.tar.gz
snapshot of project "lynx", label v2-8-4dev_8
Diffstat (limited to 'src')
-rw-r--r--src/GridText.c43
-rw-r--r--src/HTFWriter.c105
-rw-r--r--src/HTInit.c14
-rw-r--r--src/LYBookmark.c59
-rw-r--r--src/LYCgi.c5
-rw-r--r--src/LYCookie.c4
-rw-r--r--src/LYCurses.c70
-rw-r--r--src/LYDownload.c8
-rw-r--r--src/LYEdit.c10
-rw-r--r--src/LYJump.c5
-rw-r--r--src/LYLocal.c25
-rw-r--r--src/LYMail.c12
-rw-r--r--src/LYMain.c6
-rw-r--r--src/LYMainLoop.c4
-rw-r--r--src/LYNews.c14
-rw-r--r--src/LYPrint.c8
-rw-r--r--src/LYReadCFG.c10
-rw-r--r--src/LYStrings.c62
-rw-r--r--src/LYStyle.c7
-rw-r--r--src/LYTraversal.c14
-rw-r--r--src/LYUpload.c8
-rw-r--r--src/LYUtils.c181
-rw-r--r--src/LYUtils.h4
-rw-r--r--src/LYrcFile.c4
24 files changed, 413 insertions, 269 deletions
diff --git a/src/GridText.c b/src/GridText.c
index 5786b5cb..dc68cf1b 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -8507,7 +8507,7 @@ PUBLIC BOOLEAN HTreparse_document NOARGS
 #endif /* 0 */
 	HTAnchor_setProtocol(HTMainAnchor, &HTFile);
 	ret = HTParseFile(format, HTOutputFormat, HTMainAnchor, fp, NULL);
-	fclose(fp);
+	LYCloseInput(fp);
 	if (ret == HT_PARTIAL_CONTENT) {
 	    HTInfoMsg(gettext("Loading incomplete."));
 	    CTRACE((tfp, "SourceCache: `%s' has been accessed, partial content.\n",
@@ -8586,14 +8586,7 @@ PUBLIC BOOLEAN HTcan_reparse_document NOARGS
 	return FALSE;
 
     if (LYCacheSource == SOURCE_CACHE_FILE && HTMainAnchor->source_cache_file) {
-	FILE * fp;
-
-	fp = fopen(HTMainAnchor->source_cache_file, "r");
-	if (!fp) {
-	    return FALSE;
-	}
-	fclose(fp);
-	return TRUE;
+	return LYCanReadFile(HTMainAnchor->source_cache_file);
     }
 
     if (LYCacheSource == SOURCE_CACHE_MEMORY &&
@@ -9606,6 +9599,27 @@ PUBLIC char * HText_setLastOptionValue ARGS7(
 }
 
 /*
+ * Count the number of anchors on the current line so we can allow for the
+ * length of numbered fields.
+ */
+PRIVATE int AnchorsOnThisLine ARGS2(
+	HText *,	txt,
+	TextAnchor *,	ank)
+{
+    TextAnchor *chk = txt->first_anchor;
+    int count = 1;
+
+    while (chk != 0
+    	&& chk != txt->last_anchor
+	&& chk != ank) {
+	if (chk->line_num == ank->line_num)
+	    count++;
+	chk = chk->next;
+    }
+    return count;
+}
+
+/*
  *  Assign a form input anchor.
  *  Returns the number of characters to leave
  *  blank so that the input field can fit.
@@ -9615,7 +9629,6 @@ PUBLIC int HText_beginInput ARGS3(
 	BOOL,			underline,
 	InputFieldData *,	I)
 {
-
     TextAnchor * a = typecalloc(TextAnchor);
     FormInfo * f = typecalloc(FormInfo);
     CONST char *cp_option = NULL;
@@ -10030,7 +10043,7 @@ PUBLIC int HText_beginInput ARGS3(
 	     *  account as well. - FM
 	     */
 	    if (keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED)
-		MaximumSize -= ((a->number/10) + 3);
+		MaximumSize -= AnchorsOnThisLine(text, a) / 10 + 3;
 	    if (f->size > MaximumSize)
 		f->size = MaximumSize;
 
@@ -10850,10 +10863,10 @@ PUBLIC int HText_SubmitForm ARGS4(
 		    if (ferror(fd)) {
 			/* We got an error reading the file, what do we do? */
 			HTAlert("Short read from file, problem?");
-			fclose(fd);
+			LYCloseInput(fd);
 			goto exit_disgracefully;
 		    }
-		    fclose(fd);
+		    LYCloseInput(fd);
 		    /* we need to modify the mime-type here - rp */
 		    /* Note: could use LYGetFileInfo for that and for
 		       other headers that should be transmitted - kw */
@@ -12581,7 +12594,7 @@ PUBLIC int HText_ExtEditForm ARGS1(
 
 	fp = fopen (ed_temp, "r");
 	size = fread (ebuf, 1, size, fp);
-	fclose (fp);
+	LYCloseInput (fp);
 	ebuf[size] = '\0';	/* Terminate! - kw */
     }
 
@@ -12977,7 +12990,7 @@ PUBLIC int HText_InsertFile ARGS1(
 	    return 0;
 	}
 	size = fread (fbuf, 1, size, fp);
-	fclose (fp);
+	LYCloseInput (fp);
 	FREE(fn);
 	fbuf[size] = '\0';	/* Terminate! - kw */
     }
diff --git a/src/HTFWriter.c b/src/HTFWriter.c
index b765e520..54b0aa90 100644
--- a/src/HTFWriter.c
+++ b/src/HTFWriter.c
@@ -93,8 +93,9 @@ struct _HTStream {
 */
 PRIVATE void HTFWriter_put_character ARGS2(HTStream *, me, char, c)
 {
-    if (me->fp)
+    if (me->fp) {
 	putc(c, me->fp);
+    }
 }
 
 /*	String handling
@@ -104,8 +105,9 @@ PRIVATE void HTFWriter_put_character ARGS2(HTStream *, me, char, c)
 */
 PRIVATE void HTFWriter_put_string ARGS2(HTStream *, me, CONST char*, s)
 {
-    if (me->fp)
+    if (me->fp) {
 	fputs(s, me->fp);
+    }
 }
 
 /*	Buffer write.  Buffers can (and should!) be big.
@@ -113,8 +115,9 @@ PRIVATE void HTFWriter_put_string ARGS2(HTStream *, me, CONST char*, s)
 */
 PRIVATE void HTFWriter_write ARGS3(HTStream *, me, CONST char*, s, int, l)
 {
-    if (me->fp)
+    if (me->fp) {
 	fwrite(s, 1, l, me->fp);
+    }
 }
 
 
@@ -129,12 +132,12 @@ PRIVATE void HTFWriter_write ARGS3(HTStream *, me, CONST char*, s, int, l)
 */
 PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
 {
-    FILE *fp = NULL;
     int len;
     char *path = NULL;
     char *addr = NULL;
     int status;
     BOOL use_gzread = NO;
+    BOOLEAN found = FALSE;
 #ifdef WIN_EX
     HANDLE cur_handle;
 
@@ -208,15 +211,13 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
 		     */
 		    if (me->end_command && me->end_command[0])
 			LYSystem(me->end_command);
-		    fp = fopen(me->anchor->FileCache, "r");
+		    found = LYCanReadFile(me->anchor->FileCache);
 		}
-		if (fp != NULL) {
+		if (found) {
 		    /*
 		     *	It's still there with the "gz" or "Z" suffix,
 		     *	so the uncompression failed. - FM
 		     */
-		    fclose(fp);
-		    fp = NULL;
 		    if (!dump_output_immediately) {
 			lynx_force_repaint();
 			refresh();
@@ -500,11 +501,89 @@ PUBLIC HTStream* HTFWriter_new ARGS1(FILE *, fp)
     return me;
 }
 
+PRIVATE void chrcat ARGS2(
+	char *,		result,
+	int,		ch)
+{
+    result += strlen(result);
+    *result++ = ch;
+    *result = 0;
+}
+
 /*	Make system command from template
 **	---------------------------------
 **
 **	See mailcap spec for description of template.
 */
+PRIVATE char *mailcap_substitute ARGS3(
+	HTParentAnchor *,	anchor,
+	HTPresentation *,	pres,
+	char *,			fnam)
+{
+    int pass;
+    int skip;
+    size_t need = 0;
+    char *result = 0;
+    char *s;
+    char *repl;
+
+    for (pass = 0; pass < 2; pass++) {
+	for (s = pres->command; *s; s++) {
+	    if (*s == '%') {
+		repl = 0;
+		skip = 0;
+		if (s[1] == 't') {
+		    repl = pres->rep->name;
+		    skip = 1;
+		} else if (!strncasecomp(s+1, "{charset}", 9)) {
+		    repl = anchor->charset;
+		    skip = 9;
+		} else if (!strncasecomp(s+1, "{encoding}", 10)) {
+		    repl = anchor->content_encoding;
+		    skip = 10;
+		}
+		if (skip != 0) {
+		    if (repl == 0)
+			repl = "";
+		    if (pass) {
+			strcat(result, repl);
+		    } else {
+			need += strlen(repl);
+		    }
+		    s += skip;
+		} else {
+		    if (pass) {
+			chrcat(result, *s);
+		    } else {
+			need++;
+		    }
+		}
+	    } else {
+		if (pass) {
+		    chrcat(result, *s);
+		} else {
+		    need++;
+		}
+	    }
+	}
+	if (pass == 0) {
+	    if ((result = malloc(need)) == 0)
+		outofmem(__FILE__, "mailcap_substitute");
+	    *result = 0;
+	}
+    }
+#if defined(UNIX)
+    /* if we don't have a "%s" token, expect to provide the file via stdin */
+    if (strstr(pres->command, "%s") == 0) {
+	char *prepend = 0;
+	HTAddParam(&prepend, "cat %s", 1, fnam); /* ...to quote if needed */
+	HTSprintf(&prepend, "|%s", pres->command); /* ...avoid quoting */
+	FREE(result);
+	result = prepend;
+    }
+#endif
+    return result;
+}
 
 #ifndef VMS
 #define REMOVE_COMMAND "/bin/rm -f %s"
@@ -624,11 +703,7 @@ PUBLIC HTStream* HTSaveAndExecute ARGS3(
 
 	    StrAllocCopy(me->viewer_command, pres->command);
 
-	    me->end_command = typecallocn(char,
-			strlen (pres->command) + 10 + strlen(view_fname));
-	    if (me->end_command == NULL)
-		outofmem(__FILE__, "HTSaveAndExecute");
-	    sprintf(me->end_command, pres->command, view_fname);
+	    me->end_command = mailcap_substitute(anchor, pres, view_fnam);
 	    me->remove_command = NULL;
 
 	    return me;
@@ -664,9 +739,7 @@ PUBLIC HTStream* HTSaveAndExecute ARGS3(
     /*
      *	Make command to process file.
      */
-    me->end_command = 0;
-    HTAddParam(&(me->end_command), pres->command, 1, fnam);
-    HTEndParam(&(me->end_command), pres->command, 1);
+    me->end_command = mailcap_substitute(anchor, pres, fnam);
 
     /*
      *	Make command to delete file.
diff --git a/src/HTInit.c b/src/HTInit.c
index c524045b..b86ade2d 100644
--- a/src/HTInit.c
+++ b/src/HTInit.c
@@ -33,8 +33,6 @@ PRIVATE int HTLoadExtensionsConfigFile PARAMS((char *fn));
 
 PUBLIC void HTFormatInit NOARGS
 {
- FILE *fp = NULL;
-
 #ifdef NeXT
   HTSetPresentation("application/postscript",   "open %s", 1.0, 2.0, 0.0, 0);
   HTSetPresentation("image/x-tiff",             "open %s", 2.0, 2.0, 0.0, 0);
@@ -159,8 +157,7 @@ PUBLIC void HTFormatInit NOARGS
  /*
   *  Load the local maps.
   */
- if ((fp = fopen(personal_type_map, TXT_R)) != NULL) {
-     fclose(fp);
+ if (LYCanReadFile(personal_type_map)) {
      /* These should override everything else. */
      HTLoadTypesConfigFile(personal_type_map);
  } else {
@@ -637,7 +634,7 @@ PRIVATE int ProcessMailcapFile ARGS1(
     while (fp && !feof(fp)) {
 	ProcessMailcapEntry(fp, &mc);
     }
-    fclose(fp);
+    LYCloseInput(fp);
     RememberTestResult(RTR_forget, NULL, 0);
     return(0 == 0);
 }
@@ -725,8 +722,6 @@ PRIVATE int HTLoadTypesConfigFile ARGS1(
  */
 PUBLIC void HTFileInit NOARGS
 {
-    FILE *fp;
-
 #ifdef BUILTIN_SUFFIX_MAPS
     if (LYUseBuiltinSuffixes)
     {
@@ -1049,8 +1044,7 @@ PUBLIC void HTFileInit NOARGS
     /* These should override the default extensions as necessary. */
     HTLoadExtensionsConfigFile(global_extension_map);
 
-    if ((fp = fopen(personal_extension_map, TXT_R)) != NULL) {
-	fclose(fp);
+    if (LYCanReadFile(personal_extension_map)) {
 	/* These should override everything else. */
 	HTLoadExtensionsConfigFile(personal_extension_map);
     } else {
@@ -1175,7 +1169,7 @@ PRIVATE int HTLoadExtensionsConfigFile ARGS1(
 	}
 	FREE(ct);
     }
-    fclose(f);
+    LYCloseInput(f);
 
     return count;
 }
diff --git a/src/LYBookmark.c b/src/LYBookmark.c
index eb26456b..6e75e9aa 100644
--- a/src/LYBookmark.c
+++ b/src/LYBookmark.c
@@ -95,36 +95,29 @@ PUBLIC char * get_bookmark_filename ARGS1(
     CTRACE((tfp, "\nget_bookmark_filename: SEEKING %s\n   AS %s\n\n",
 		BookmarkPage, filename_buffer));
     if ((fp = fopen(filename_buffer, TXT_R)) != NULL) {
-	goto success;
-    }
-
-    /*
-     *	Failure.
-     */
-    return(NULL);
-
-success:
-    /*
-     *	We now have the file open.
-     *	Check if it is a mosaic hotlist.
-     */
-    if (LYSafeGets(&string_buffer, fp) != 0
-     && !strncmp(string_buffer, "ncsa-xmosaic-hotlist-format-1", 29)) {
-	char *newname;
 	/*
-	 *  It is a mosaic hotlist file.
+	 * We now have the file open.
+	 * Check if it is a mosaic hotlist.
 	 */
-	is_mosaic_hotlist = TRUE;
-	newname = convert_mosaic_bookmark_file(filename_buffer);
-	LYLocalFileToURL(URL, newname);
-    } else {
-	is_mosaic_hotlist = FALSE;
-	LYLocalFileToURL(URL, filename_buffer);
-    }
-    FREE(string_buffer);
-    fclose(fp);
+	if (LYSafeGets(&string_buffer, fp) != 0
+	 && !strncmp(string_buffer, "ncsa-xmosaic-hotlist-format-1", 29)) {
+	    char *newname;
+	    /*
+	     *  It is a mosaic hotlist file.
+	     */
+	    is_mosaic_hotlist = TRUE;
+	    newname = convert_mosaic_bookmark_file(filename_buffer);
+	    LYLocalFileToURL(URL, newname);
+	} else {
+	    is_mosaic_hotlist = FALSE;
+	    LYLocalFileToURL(URL, filename_buffer);
+	}
+	FREE(string_buffer);
+	LYCloseInput(fp);
 
-    return(filename_buffer);  /* bookmark file exists */
+	return(filename_buffer);  /* bookmark file exists */
+    }
+    return(NULL);
 
 } /* big end */
 
@@ -181,7 +174,7 @@ PRIVATE char * convert_mosaic_bookmark_file ARGS1(
 	line++;
     }
     LYCloseTempFP(nfp);
-    fclose(fp);
+    LYCloseInput(fp);
     return(newfile);
 }
 
@@ -399,7 +392,7 @@ Note: if you edit this file manually\n\
     } else {
 	fprintf(fp,"<LI><a href=\"%s\">%s</a>\n", Address, Title);
     }
-    fclose(fp);
+    LYCloseOutput(fp);
 
     SetDefaultMode(O_BINARY);
     /*
@@ -484,7 +477,7 @@ PUBLIC void remove_bookmark_link ARGS2(
 
     LYAddPathToHome(homepath, sizeof(homepath), "");
     if ((nfp = LYOpenScratch(newfile, homepath)) == 0) {
-	fclose(fp);
+	LYCloseInput(fp);
 	HTAlert(BOOKSCRA_OPEN_FAILED_FOR_DEL);
 	return;
     }
@@ -498,7 +491,7 @@ PUBLIC void remove_bookmark_link ARGS2(
 	mode = ((stat_buf.st_mode & 0777) | 0600); /* make it writable */
 	(void) chmod(newfile, mode);
 	if ((nfp = LYReopenTemp(newfile)) == NULL) {
-	    (void) fclose(fp);
+	    (void) LYCloseInput(fp);
 	    HTAlert(BOOKTEMP_REOPEN_FAIL_FOR_DEL);
 	    return;
 	}
@@ -554,7 +547,7 @@ PUBLIC void remove_bookmark_link ARGS2(
     CTRACE((tfp, "remove_bookmark_link: files: %s %s\n",
 			newfile, filename_buffer));
 
-    fclose(fp);
+    LYCloseInput(fp);
     fp = NULL;
     if (fflush(nfp) == EOF) {
 	CTRACE((tfp, "fflush(nfp): %s", LYStrerror(errno)));
@@ -667,7 +660,7 @@ failure:
     if (nfp)
 	LYCloseTempFP(nfp);
     if (fp != NULL)
-	fclose(fp);
+	LYCloseInput(fp);
     if (keep_tempfile) {
 	HTUserMsg2(gettext("File may be recoverable from %s during this session"),
 		   newfile);
diff --git a/src/LYCgi.c b/src/LYCgi.c
index 97e4a93e..d8b70d88 100644
--- a/src/LYCgi.c
+++ b/src/LYCgi.c
@@ -45,10 +45,7 @@
 #include <LYLocal.h>
 
 #include <LYLeaks.h>
-
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
+#include <www_wait.h>
 
 struct _HTStream
 {
diff --git a/src/LYCookie.c b/src/LYCookie.c
index edd492ed..972cf2c3 100644
--- a/src/LYCookie.c
+++ b/src/LYCookie.c
@@ -2166,7 +2166,7 @@ PUBLIC void LYLoadCookies ARGS1 (
 	 */
 	store_cookie(moo, domain, path);
     }
-    fclose (cookie_handle);
+    LYCloseInput (cookie_handle);
 }
 
 /* rjp - experimental persistent cookie support */
@@ -2264,7 +2264,7 @@ PUBLIC void LYStoreCookies ARGS1 (
 	    CTRACE((tfp, "STORED\n"));
 	}
     }
-    fclose(cookie_handle);
+    LYCloseOutput(cookie_handle);
 
     HTSYS_purge(cookie_file);
 }
diff --git a/src/LYCurses.c b/src/LYCurses.c
index 040df6a5..c6cf922e 100644
--- a/src/LYCurses.c
+++ b/src/LYCurses.c
@@ -657,6 +657,27 @@ PUBLIC void LYnoVideo ARGS1(
 #endif
 }
 
+#if       !defined(VMS) && !defined(USE_SLANG)
+/*
+ * If newterm is not defined, assume a curses subset which
+ * supports only initscr.  --gil
+ */
+#ifdef    HAVE_NEWTERM
+static SCREEN *LYscreen = NULL;
+#define LYDELSCR(scr) { \
+    delscreen(scr);     \
+    scr = NULL; }
+/*
+ * Surrogates for newterm annd delscreen
+ */
+#else  /* HAVE_NEWTERM   */
+static WINDOW *LYscreen = NULL;
+#undef  newterm
+#define newterm(type, out, in) (initscr())
+#define LYDELSCR(scr)  /* nothing */
+#endif /* HAVE_NEWTERM   */
+#endif /* !defined(VMS) && !defined(USE_SLANG) */
+
 PUBLIC void start_curses NOARGS
 {
 #ifdef USE_SLANG
@@ -773,7 +794,7 @@ PUBLIC void start_curses NOARGS
 
    lynx_enable_mouse (1);
 
-#else /* Using curses: */
+#else /* USE_SLANG; Now using curses: */
 
 
 #ifdef VMS
@@ -784,14 +805,26 @@ PUBLIC void start_curses NOARGS
     initscr();	/* start curses */
 #else  /* Unix: */
 
-    static BOOLEAN first_time = TRUE;
-
-    if (first_time) {
+    if (!LYscreen) {
 	/*
 	 *  If we're not VMS then only do initscr() one time,
 	 *  and one time only!
 	 */
-	if (initscr() == NULL) {  /* start curses */
+	{
+	    static char lines_putenv[] = "LINES=abcde",
+			cols_putenv[]  = "COLUMNS=abcde";
+	    BOOLEAN savesize;
+
+	    savesize = recent_sizechange;
+	    size_change(0);
+	    recent_sizechange = savesize;    /* avoid extra redraw */
+	    sprintf(lines_putenv + 6, "%d", LYlines & 0xfff);
+	    sprintf(cols_putenv  + 8, "%d", LYcols  & 0xfff);
+	    putenv(lines_putenv);
+	    putenv(cols_putenv);
+	    CTRACE((tfp, "start_curses putenv %s, %s\n", lines_putenv, cols_putenv));
+	}
+	if (!(LYscreen=newterm(NULL,stdout,stdin))) {  /* start curses */
 	    fprintf(tfp, "%s\n",
 		gettext("Terminal initialisation failed - unknown terminal type?"));
 	    exit_immediately (-1);
@@ -864,7 +897,6 @@ PUBLIC void start_curses NOARGS
 #ifdef USE_COLOR_STYLE
 	parse_userstyles();
 #endif
-	first_time = FALSE;
 #if USE_COLOR_TABLE
 	lynx_init_colors();
 #endif /* USE_COLOR_TABLE */
@@ -1018,9 +1050,14 @@ PUBLIC void stop_curses NOARGS
      *	05-28-94 Lynx 2-3-1 Garrett Arch Blythe
      */
     if(LYCursesON == TRUE)	{
-	 lynx_enable_mouse (0);
-#if (!defined(WIN_EX) || defined(__CYGWIN__))	/* @@@ */
-	 endwin();	/* stop curses */
+	lynx_enable_mouse (0);
+#if !defined(NCURSES) && !defined(VMS) && !defined(USE_SLANG) && (!defined(WIN_EX) || defined(__CYGWIN__))	/* @@@ */
+	if(LYscreen) {
+	    endwin();	/* stop curses */
+	    if (recent_sizechange) {
+		LYDELSCR(LYscreen);
+	    }
+	 }
 #endif
     }
 #ifdef SH_EX
@@ -1403,21 +1440,20 @@ PUBLIC void LYtouchline ARGS1(
 #if defined(HAVE_WREDRAWLN)
     wredrawln(stdscr, row, 1);
 #else
-#if defined(VMS) && !defined(_BSD44_CURSES) && !defined(USE_SLANG)
-    /* touchline() is not available on VMS before version 7.0, and then
-     * only on Alpha, since prior ports of curses were broken.
+#if defined(HAVE_TOUCHLINE)
+    /* touchline() is not available on VMS before version 7.0, and then only on
+     * Alpha, since prior ports of curses were broken.  BSD touchline() has a
+     * 4th parameter since it is used internally by touchwin().
      */
-    touchwin(stdscr);
+    touchline(stdscr, row, 1, 0);
 #else
-#if defined(FANCY_CURSES)
-    touchline(stdscr, row, 1);
+#if !defined(USE_SLANG)
+    touchwin(stdscr);
 #else
-#if defined(USE_SLANG)
     SLsmg_touch_lines(row, 1);
 #endif
 #endif
 #endif
-#endif
 }
 
 /*
diff --git a/src/LYDownload.c b/src/LYDownload.c
index be1a8134..839af32b 100644
--- a/src/LYDownload.c
+++ b/src/LYDownload.c
@@ -35,7 +35,6 @@ PUBLIC void LYDownload ARGS1(
     char command[LY_MAXPATH];
     char *cp;
     lynx_html_item_type *download_command = 0;
-    FILE *fp;
     int ch, recall;
     int FnameTotal;
     int FnameNum;
@@ -249,12 +248,7 @@ check_recall:
 	 */
 	CTRACE((tfp, "LYDownload: filename is %s\n", buffer));
 
-	if ((fp = fopen(buffer, "w")) != NULL) {
-	    fclose(fp);
-	    remove(buffer);
-	} else {
-	    HTAlert(CANNOT_WRITE_TO_FILE);
-	    _statusline(NEW_FILENAME_PROMPT);
+	if (! LYCanWriteFile(buffer)) {
 	    FirstRecall = TRUE;
 	    FnameNum = FnameTotal;
 	    goto retry;
diff --git a/src/LYEdit.c b/src/LYEdit.c
index 966f8d68..37b182db 100644
--- a/src/LYEdit.c
+++ b/src/LYEdit.c
@@ -62,7 +62,9 @@ PUBLIC int edit_current_file ARGS3(
 #endif
     char *number_sign;
     char position[80];
+#if defined(VMS) || defined(CANT_EDIT_UNWRITABLE_FILES)
     FILE *fp;
+#endif
 #if defined(__CYGWIN__) && defined(DOSPATH)
     unsigned char temp_buff[LY_MAXPATH];
 #endif
@@ -92,8 +94,7 @@ PUBLIC int edit_current_file ARGS3(
     filename = HTParse(newfile, "", PARSE_PATH+PARSE_PUNCTUATION);
     HTUnEscape(filename);
     StrAllocCopy(filename, HTSYS_name(filename));
-    if ((fp = fopen(filename, "r")) == NULL)
-    {
+    if (!LYCanReadFile(filename)) {
 #ifdef SH_EX
 	HTUserMsg2(COULD_NOT_EDIT_FILE, filename);
 #else
@@ -113,17 +114,16 @@ PUBLIC int edit_current_file ARGS3(
 #endif
     StrAllocCopy(filename, (colon + 1));
     HTUnEscape(filename);
-    if ((fp = fopen(filename, "r")) == NULL) {
+    if (!LYCanReadFile(filename)) {
 	FREE(filename);
 	filename = HTParse(newfile, "", PARSE_PATH+PARSE_PUNCTUATION);
 	HTUnEscape(filename);
-	if ((fp = fopen(HTSYS_name(filename), "r")) == NULL) {
+	if (!LYCanReadFile(HTSYS_name(filename))) {
 	    HTAlert(COULD_NOT_ACCESS_FILE);
 	    goto done;
 	}
     }
 #endif /* !(VMS || !DOSPATH || !__EMX__) */
-    fclose(fp);
 
 #if defined(VMS) || defined(CANT_EDIT_UNWRITABLE_FILES)
     /*
diff --git a/src/LYJump.c b/src/LYJump.c
index 8f2758c4..b198f3df 100644
--- a/src/LYJump.c
+++ b/src/LYJump.c
@@ -422,8 +422,9 @@ PRIVATE unsigned LYRead_Jumpfile ARGS1(struct JumpTable *,jtp)
 	FREE(mp);
 	return 0;
     } else
-	while(fgets(mp+strlen(mp), 1024, fp) != NULL) ;
-    fclose(fp);
+	while(fgets(mp+strlen(mp), 1024, fp) != NULL)
+	    ;
+	LYCloseInput(fp);
     }
 #endif /* VMS */
 
diff --git a/src/LYLocal.c b/src/LYLocal.c
index deb7f0be..defb7044 100644
--- a/src/LYLocal.c
+++ b/src/LYLocal.c
@@ -43,30 +43,7 @@
 #include <LYUpload.h>
 #include <LYLocal.h>
 #include <LYClean.h>
-
-#ifndef VMS
-#ifndef _WINDOWS
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-#endif /*_WINDOWS */
-#endif /* VMS */
-
-#ifndef WEXITSTATUS
-# ifdef HAVE_TYPE_UNIONWAIT
-#  define	WEXITSTATUS(status)	(status.w_retcode)
-# else
-#  define	WEXITSTATUS(status)	(((status) & 0xff00) >> 8)
-# endif
-#endif
-
-#ifndef WTERMSIG
-# ifdef HAVE_TYPE_UNIONWAIT
-#  define	WTERMSIG(status)	(status.w_termsig)
-# else
-#  define	WTERMSIG(status)	((status) & 0x7f)
-# endif
-#endif
+#include <www_wait.h>
 
 #ifdef SUPPORT_CHDIR
 #include <LYMainLoop.h>
diff --git a/src/LYMail.c b/src/LYMail.c
index 4a8d7d63..d586cf8a 100644
--- a/src/LYMail.c
+++ b/src/LYMail.c
@@ -93,7 +93,7 @@ PRIVATE char *blat_cmd(
     if (ccaddr && strlen(ccaddr) > 0) {
 	fprintf(fp, "-c\n%s\n", ccaddr);
     }
-    fclose(fp);
+    LYCloseOutput(fp);
 
 #ifdef __CYGWIN__
     cygwin_conv_to_full_win32_path(bl_cmd_file, dosname);
@@ -876,7 +876,7 @@ PUBLIC void mailmsg ARGS4(
 	fputs("-- \n", fd);
 	while (LYSafeGets(&cmd, fp) != NULL)
 	    fputs(cmd, fd);
-	fclose(fp);
+	LYCloseInput(fp);
     }
 #if defined(UNIX) && !defined(__CYGWIN__)
     pclose(fd);
@@ -977,7 +977,7 @@ PUBLIC void mailmsg ARGS4(
 
 	fprintf(ofp, "%s\t%s \tin %s\n",
 		     links[cur].lname, links[cur].target, filename);
-	fclose(ofp);
+	LYCloseOutput(ofp);
     }
 
     FREE(address);
@@ -1818,10 +1818,10 @@ PUBLIC void reply_by_mail ARGS4(
 		while (LYSafeGets(&buffer, fp) != NULL) {
 		    fputs(buffer, fd);
 		}
-		fclose(fd);
+		LYCloseOutput(fd);
 	    }
 	}
-	fclose(fp);
+	LYCloseInput(fp);
     }
     clear();  /* Clear the screen. */
 
@@ -1998,7 +1998,7 @@ PUBLIC void reply_by_mail ARGS4(
 	    start_curses();
 	    LYRemoveTemp(tmpfile2);	/* Delete the tmpfile. */
 #endif /* CAN_PIPE_TO_MAILER */
-	    fclose(fd); /* Close the tmpfile. */
+	    LYCloseInput(fd); /* Close the tmpfile. */
 	}
     }
 #endif /* VMS */
diff --git a/src/LYMain.c b/src/LYMain.c
index 0f082263..5be08daa 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -1278,12 +1278,11 @@ PUBLIC int main ARGS2(
      *	If the configuration file is not available,
      *	inform the user and exit.
      */
-    if ((fp = fopen(lynx_cfg_file, "r")) == NULL) {
+    if (!LYCanReadFile(lynx_cfg_file)) {
 	fprintf(stderr, gettext("\nConfiguration file %s is not available.\n\n"),
 			lynx_cfg_file);
 	exit(-1);
     }
-    fclose(fp);
 
     /*
      * Make sure we have the character sets declared.
@@ -1342,13 +1341,12 @@ PUBLIC int main ARGS2(
      *	If the lynx-style file is not available,
      *	inform the user and exit.
      */
-    if ((fp = fopen(lynx_lss_file, "r")) == NULL) {
+    if (!LYCanReadFile(lynx_lss_file)) {
 	fprintf(stderr, gettext("\nLynx file %s is not available.\n\n"),
 			lynx_lss_file);
     }
     else
     {
-	fclose(fp);
 	style_readFromFile(lynx_lss_file);
     }
 #endif /* USE_HASH */
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index 916d649a..9f8733f4 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -5591,7 +5591,7 @@ try_again:
 					newdoc.address : links[curdoc.link].lname,
 					links[curdoc.link].target);
 			    }
-			    fclose(ofp);
+			    LYCloseOutput(ofp);
 			}
 		    }
 
@@ -6463,7 +6463,7 @@ try_again:
 		ccount = ccount + 1;
 		if ((cfp = LYNewTxtFile(cfile))  != NULL) {
 		    print_crawl_to_fd(cfp,curdoc.address,curdoc.title);
-		    fclose(cfp);
+		    LYCloseOutput(cfp);
 		} else {
 		    if (!dump_output_immediately)
 			cleanup();
diff --git a/src/LYNews.c b/src/LYNews.c
index 7211ffe0..119b4bf8 100644
--- a/src/LYNews.c
+++ b/src/LYNews.c
@@ -69,7 +69,7 @@ PRIVATE BOOLEAN message_has_content ARGS2(
 	}
 	if (firstnonblank && firstnonblank != '>') {
 	    if (!in_headers) {
-		fclose(fp);
+		LYCloseInput(fp);
 		FREE(buffer);
 		return TRUE;
 	    }
@@ -79,7 +79,7 @@ PRIVATE BOOLEAN message_has_content ARGS2(
 	}
     }
     FREE(buffer);
-    fclose(fp);
+    LYCloseInput(fp);
     return FALSE;
 }
 
@@ -291,7 +291,7 @@ PUBLIC char *LYNewsPost ARGS2(
 	    }
 	}
 	FREE(buffer);
-	fclose(fp);
+	LYCloseInput(fp);
     }
 #else
 #ifdef _WINDOWS	/* 1998/05/14 (Thu) 17:47:01 */
@@ -311,7 +311,7 @@ PUBLIC char *LYNewsPost ARGS2(
 			StrAllocCat(cp, user_input);
 		    }
 		}
-		fclose(fp);
+		LYCloseInput(fp);
 	    }
 	}
     }
@@ -457,10 +457,10 @@ PUBLIC char *LYNewsPost ARGS2(
 		while (LYSafeGets(&buffer, fp) != NULL) {
 		    fputs(buffer, fd);
 		}
-		fclose(fd);
+		LYCloseOutput(fd);
 	    }
 	}
-	fclose(fp);
+	LYCloseInput(fp);
 	FREE(msg);
 	LYStatusLine = -1;
     }
@@ -483,7 +483,7 @@ PUBLIC char *LYNewsPost ARGS2(
 	    }
 	    LYCloseTempFP(fc);
 	    StrAllocCopy(postfile, CJKfile);
-	    fclose(fd);
+	    LYCloseInput(fd);
 	    LYRemoveTemp(my_tempfile);
 	    strcpy(my_tempfile, CJKfile);
 	    CJKfile[0] = '\0';
diff --git a/src/LYPrint.c b/src/LYPrint.c
index a7024688..393abbaa 100644
--- a/src/LYPrint.c
+++ b/src/LYPrint.c
@@ -452,7 +452,7 @@ check_recall:
 	pclose(outfile_fp);
     else
 #endif
-    fclose(outfile_fp);
+    LYCloseOutput(outfile_fp);
 #ifdef VMS
     if (0 == strncasecomp(buffer, "sys$disk:", 9)) {
 	if (0 == strncmp((buffer+9), "[]", 2)) {
@@ -1383,8 +1383,6 @@ PUBLIC char * GetFileName NOARGS
 {
     struct stat stat_info;
 
-    FILE *fp;
-
     char  fbuf[LY_MAXPATH];
     char  tbuf[LY_MAXPATH];
     char *fn;
@@ -1459,14 +1457,12 @@ check_recall:
 	goto retry;
     }
 
-    if ((fp = fopen (tbuf, "r")) == NULL) {
+    if (!LYCanReadFile(tbuf)) {
 	HTInfoMsg (FILE_NOT_READABLE);
 	_statusline(FILE_NOT_READABLE_RE);
 	FirstRecall = TRUE;
 	FnameNum    = FnameTotal;
 	goto retry;
-    } else {
-	fclose (fp);
     }
 
     /*
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index 5600b2aa..3a51949a 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -2013,7 +2013,7 @@ PRIVATE void do_read_cfg ARGS5(
 	}
     }
 
-    fclose (fp);
+    LYCloseInput (fp);
 
     /*
      *	If any DOWNLOADER: commands have always_enabled set (:TRUE),
@@ -2195,9 +2195,7 @@ PUBLIC int lynx_cfg_infopage ARGS1(
     if (LYforce_no_cache && reloading) {
 	FREE(lynxcfginfo_url); /* flag to code below to regenerate - kw */
     } else if (lynxcfginfo_url != NULL) {
-	if ((fp0 = fopen(tempfile, "r")) != NULL) { /* check existence */
-	    fclose(fp0);		/* OK */
-	} else {
+	if (!LYCanReadFile(tempfile)) { /* check existence */
 	    FREE(lynxcfginfo_url); /* flag to code below to try again - kw */
 	}
     }
@@ -2341,9 +2339,7 @@ PUBLIC int lynx_compile_opts ARGS1(
     if (LYforce_no_cache && reloading) {
 	FREE(configinfo_url); /* flag to code below to regenerate - kw */
     } else if (configinfo_url != NULL) {
-	if ((fp0 = fopen(tempfile, "r")) != NULL) { /* check existence */
-	    fclose(fp0);		/* OK */
-	} else {
+	if (!LYCanReadFile(tempfile)) { /* check existence */
 	    FREE(configinfo_url); /* flag to code below to try again - kw */
 	}
     }
diff --git a/src/LYStrings.c b/src/LYStrings.c
index dfaecfc4..3457e501 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -1218,8 +1218,7 @@ PRIVATE int read_keymap_file NOARGS
 
     linenum = 0;
     ret = 0;
-    while (LYSafeGets(&line, fp) != 0 && (ret == 0))
-    {
+    while (LYSafeGets(&line, fp) != 0 && (ret == 0)) {
 	char *s = LYSkipBlanks(line);
 
 	linenum++;
@@ -1240,7 +1239,7 @@ PRIVATE int read_keymap_file NOARGS
     }
     FREE(line);
 
-    fclose (fp);
+    LYCloseInput (fp);
 
     if (ret == -1)
 	fprintf (stderr, FAILED_READING_KEYMAP, linenum, file);
@@ -1966,33 +1965,44 @@ re_read:
 #ifdef KEY_RESIZE
 	case KEY_RESIZE:	   /* size change detected by ncurses */
 #if HAVE_SIZECHANGE || defined(USE_SLANG)
-	   /* Make call to detect new size, if that may be implemented.
-	    * The call may set recent_sizechange (except for USE_SLANG),
-	    * which will tell mainloop() to refresh. - kw */
-	   CTRACE((tfp, "Got KEY_RESIZE, recent_sizechange so far is %d\n",
+	    /* Make call to detect new size, if that may be implemented.
+	     * The call may set recent_sizechange (except for USE_SLANG),
+	     * which will tell mainloop() to refresh. - kw
+	     */
+	    CTRACE((tfp, "Got KEY_RESIZE, recent_sizechange so far is %d\n",
 		  recent_sizechange));
-	   size_change(0);
-	   CTRACE((tfp, "Now recent_sizechange is %d\n", recent_sizechange));
+	    size_change(0);
+	    CTRACE((tfp, "Now recent_sizechange is %d\n", recent_sizechange));
 #else /* HAVE_SIZECHANGE || USE_SLANG */
-	   CTRACE((tfp, "Got KEY_RESIZE, recent_sizechange is %d\n",
+	    CTRACE((tfp, "Got KEY_RESIZE, recent_sizechange is %d\n",
 		  recent_sizechange));
 #endif /* HAVE_SIZECHANGE || USE_SLANG */
-	   if (!recent_sizechange) {
+	    if (!recent_sizechange) {
 #if 0			/* assumption seems flawed? */
-	       /*  Not detected by us or already processed by us.  It can
-		*  happens that ncurses lags behind us in detecting the
-		*  change, since its own SIGTSTP handler is not installed
-		*  so detecting happened *at the end* of the last refresh.
-		*  Tell it to refresh again... - kw */
-	       refresh();
+	        /*  Not detected by us or already processed by us.  It can
+		 *  happens that ncurses lags behind us in detecting the
+		 *  change, since its own SIGTSTP handler is not installed
+		 *  so detecting happened *at the end* of the last refresh.
+		 *  Tell it to refresh again... - kw
+		 */
+	        refresh();
 #endif
-	       /*
-		*  May be just the delayed effect of mainloop()'s call
-		*  to resizeterm().  Pretend we haven't read anything
-		*  yet, don't return. - kw
-		*/
-	       goto re_read;
-	   }
+#if defined(NCURSES)
+		/*
+		 * Work-around for scenario (Linux libc5) where we got a
+		 * recent sizechange before reading KEY_RESIZE.  If we do
+		 * not reset the flag, we'll next get an EOF read, which
+		 * causes Lynx to exit.
+		 */
+		recent_sizechange = TRUE;
+#endif
+	        /*
+		 *  May be just the delayed effect of mainloop()'s call
+		 *  to resizeterm().  Pretend we haven't read anything
+		 *  yet, don't return. - kw
+		 */
+	        goto re_read;
+	    }
 	   /*
 	    *  Yep, we agree there was a change.  Return now so that
 	    *  the caller can react to it. - kw
@@ -5533,11 +5543,11 @@ PUBLIC void LYWriteCmdKey ARGS1(
 PUBLIC void LYCloseCmdLogfile NOARGS
 {
     if (cmd_logfile != 0) {
-	fclose(cmd_logfile);
+	LYCloseOutput(cmd_logfile);
 	cmd_logfile = 0;
     }
     if (cmd_script != 0) {
-	fclose(cmd_script);
+	LYCloseInput(cmd_script);
 	cmd_script = 0;
     }
     FREE(lynx_cmd_logfile);
diff --git a/src/LYStyle.c b/src/LYStyle.c
index 42c98a67..01869a18 100644
--- a/src/LYStyle.c
+++ b/src/LYStyle.c
@@ -1,6 +1,6 @@
 /* character level styles for Lynx
  * (c) 1996 Rob Partington -- donated to the Lyncei (if they want it :-)
- * @Id: LYStyle.c 1.37 Sun, 16 Jul 2000 20:16:13 -0700 dickey @
+ * @Id: LYStyle.c 1.38 Thu, 24 Aug 2000 18:30:11 -0700 dickey @
  */
 #include <HTUtils.h>
 #include <HTML.h>
@@ -454,8 +454,7 @@ PRIVATE int style_readFromFileREC ARGS2(char*, file, int, toplevel)
 	style_deleteStyleList();
     }
 
-    while (LYSafeGets(&buffer, fh) != NULL)
-    {
+    while (LYSafeGets(&buffer, fh) != NULL) {
 	LYTrimTrailing(buffer);
 	LYTrimTail(buffer);
 	LYTrimHead(buffer);
@@ -465,7 +464,7 @@ PRIVATE int style_readFromFileREC ARGS2(char*, file, int, toplevel)
 	    HStyle_addStyle(buffer);
     }
 
-    fclose (fh);
+    LYCloseInput (fh);
     if (toplevel && LYCursesON)
 	parse_userstyles();
     return 0;
diff --git a/src/LYTraversal.c b/src/LYTraversal.c
index 35e5327a..14253b01 100644
--- a/src/LYTraversal.c
+++ b/src/LYTraversal.c
@@ -41,7 +41,7 @@ PUBLIC BOOLEAN lookup ARGS1(char *,target)
 	if ((ifp = LYNewTxtFile(TRAVERSE_FILE)) == NULL) {
 	    exit_with_perror(CANNOT_OPEN_TRAV_FILE);
 	} else {
-	    fclose(ifp);
+	    LYCloseOutput(ifp);
 	    return(FALSE);
 	}
     }
@@ -57,7 +57,7 @@ PUBLIC BOOLEAN lookup ARGS1(char *,target)
     FREE(line);
     FREE(buffer);
 
-    fclose(ifp);
+    LYCloseInput(ifp);
     return (BOOL) (result);
 }
 
@@ -72,7 +72,7 @@ PUBLIC void add_to_table ARGS1(char *,target)
 
     fprintf(ifp,"%s\n",target);
 
-    fclose(ifp);
+    LYCloseOutput(ifp);
 }
 
 PUBLIC void add_to_traverse_list ARGS2(char *,fname, char *,prev_link_name)
@@ -86,7 +86,7 @@ PUBLIC void add_to_traverse_list ARGS2(char *,fname, char *,prev_link_name)
 
     fprintf(ifp,"%s\t%s\n",fname, prev_link_name);
 
-    fclose(ifp);
+    LYCloseOutput(ifp);
 }
 
 PUBLIC void dump_traversal_history NOARGS
@@ -110,7 +110,7 @@ PUBLIC void dump_traversal_history NOARGS
 	fprintf(ifp,"%s\t%s\n", history[x].title, history[x].address);
     }
 
-    fclose(ifp);
+    LYCloseOutput(ifp);
 }
 
 PUBLIC void add_to_reject_list ARGS1(char *,target)
@@ -124,7 +124,7 @@ PUBLIC void add_to_reject_list ARGS1(char *,target)
 
     fprintf(ifp,"%s\n",target);
 
-    fclose(ifp);
+    LYCloseOutput(ifp);
 }
 
 /* there need not be a reject file, so if it doesn't open, just return
@@ -168,6 +168,6 @@ PUBLIC BOOLEAN lookup_reject ARGS1(char *,target)
     FREE(buffer);
     FREE(line);
 
-    fclose(ifp);
+    LYCloseInput(ifp);
     return (BOOL) (result);
 }
diff --git a/src/LYUpload.c b/src/LYUpload.c
index 104d2087..63ab40d4 100644
--- a/src/LYUpload.c
+++ b/src/LYUpload.c
@@ -48,7 +48,6 @@ PUBLIC int LYUpload ARGS1(
     char tmpbuf[LY_MAXPATH];
     char *filename = NULL;
     lynx_html_item_type *upload_command = 0;
-    FILE *fp;
     char *the_command = 0;
 
     /*
@@ -130,12 +129,7 @@ retry:
 	 */
 	CTRACE((tfp, "LYUpload: filename is %s", filename));
 
-	if ((fp = fopen(filename, "w")) != NULL) {
-	    fclose(fp);
-	    remove(filename);
-	} else {
-	    HTAlert(CANNOT_WRITE_TO_FILE);
-	    _statusline(NEW_FILENAME_PROMPT);
+	if (! LYCanWriteFile(filename)) {
 	    goto retry;
 	}
 
diff --git a/src/LYUtils.c b/src/LYUtils.c
index 6334f935..5abe0bac 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -143,6 +143,7 @@ PUBLIC	HTList * sug_filenames = NULL;		/* Suggested filenames	 */
 typedef struct _LYTemp {
     struct _LYTemp *next;
     char *name;
+    BOOLEAN outs;
     FILE *file;
 } LY_TEMP;
 
@@ -2065,16 +2066,25 @@ PUBLIC void statusline ARGS1(
     clrtoeol();
 
     if (text != NULL && text[0] != '\0') {
-#ifdef HAVE_UTF8_STATUSLINES
-	if ((LYCharSet_UC[current_char_set].enc == UCT_ENC_UTF8) || 
-	    (HTCJK != NOCJK)) {
-	    refresh();
-	}
-#else
+	BOOLEAN has_CJK = FALSE;
+
 	if (HTCJK != NOCJK) {
+	    for (i = 0; buffer[i] != '\0'; i++) {
+		if (buffer[i] & 0x80) {
+		    has_CJK = TRUE;
+		    break;
+		}
+	    }
+	}
+
+	if (has_CJK
+#ifdef HAVE_UTF8_STATUSLINES
+	    || (LYCharSet_UC[current_char_set].enc == UCT_ENC_UTF8)
+#endif
+	    ) {
 	    refresh();
 	}
-#endif /* HAVE_UTF8_STATUSLINES */
+
 #ifndef USE_COLOR_STYLE
 	lynx_start_status_color ();
 	addstr (buffer);
@@ -3144,6 +3154,68 @@ PUBLIC BOOLEAN LYCanDoHEAD ARGS1(
 }
 
 /*
+ * Close an input file.
+ */
+PUBLIC BOOLEAN LYCloseInput ARGS1(
+	FILE *,		fp)
+{
+    if (fp != 0) {
+	int err = ferror(fp);
+	fclose(fp);
+	if (!err) {
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/*
+ * Close an output file, reporting any problems with writing to it.
+ */
+PUBLIC BOOLEAN LYCloseOutput ARGS1(
+	FILE *,		fp)
+{
+    if (fp != 0) {
+	int err = ferror(fp);
+	fclose(fp);
+	if (!err) {
+	    return TRUE;
+	}
+    }
+    HTAlert(CANNOT_WRITE_TO_FILE);
+    return FALSE;
+}
+
+/*
+ * Test if we'll be able to write a file.  If not, warn the user.
+ */
+PUBLIC BOOLEAN LYCanWriteFile ARGS1(
+	CONST char*,	filename)
+{
+    if (LYCloseOutput(fopen(filename, "w"))) {
+	remove(filename);
+	return TRUE;
+    } else {
+	_statusline(NEW_FILENAME_PROMPT);
+	return FALSE;
+    }
+}
+
+/*
+ * Test if we'll be able to read a file.
+ */
+PUBLIC BOOLEAN LYCanReadFile ARGS1(
+	CONST char*,	filename)
+{
+    FILE *fp;
+
+    if ((fp = fopen(filename, "r")) != 0) {
+	return LYCloseInput(fp);
+    }
+    return FALSE;
+}
+
+/*
  *  Remove backslashes from any string.
  */
 PUBLIC void remove_backslashes ARGS1(
@@ -3187,7 +3259,7 @@ PUBLIC BOOLEAN inlocaldomain NOARGS
 	do {
 	    n = fread((char *) &me, sizeof(struct utmp), 1, fp);
 	} while (n > 0 && !STREQ(me.ut_line, mytty));
-	(void) fclose(fp);
+	(void) LYCloseInput(fp);
 
 	if (n > 0 &&
 	    strlen(me.ut_host) > strlen(LYLocalDomain) &&
@@ -3822,7 +3894,7 @@ PRIVATE int fmt_tempname ARGS3(
 	    break;
 	}
     }
-    if (counter >= MAX_TEMPNAME)
+    if (names_used >= MAX_TEMPNAME)
 	HTAlert("Too many tempfiles");
 #else
     counter++;
@@ -4372,7 +4444,6 @@ PUBLIC void LYConvertToURL ARGS2(
     char *cp = NULL;
 #ifndef VMS
     struct stat st;
-    FILE *fptemp = NULL;
 #endif /* !VMS */
 
     if (!old_string || *old_string == '\0')
@@ -4634,7 +4705,7 @@ have_VMS_URL:
 	    LYTrimRelFromAbsPath(temp);
 	    CTRACE((tfp, "Converted '%s' to '%s'\n", old_string, temp));
 	    if ((stat(temp, &st) > -1) ||
-		(fptemp = fopen(temp, "r")) != NULL) {
+		LYCanReadFile(temp)) {
 		/*
 		 *  It is a subdirectory or file on the local system.
 		 */
@@ -4672,7 +4743,7 @@ have_VMS_URL:
 
 		if (strcmp(temp2, temp) != 0 &&
 		    ((stat(temp2, &st) > -1) ||
-		     (fptemp = fopen(temp2, "r")) != NULL)) {
+		     LYCanReadFile(temp2))) {
 		    /*
 		     *	It is a subdirectory or file on the local system
 		     *	with escaped characters and/or a fragment to be
@@ -4779,10 +4850,6 @@ have_VMS_URL:
 	    }
 	    FREE(temp);
 	    FREE(temp2);
-	    if (fptemp) {
-		fclose(fptemp);
-		fptemp = NULL;
-	    }
 	}
 #endif /* VMS */
     } else {
@@ -4800,7 +4867,7 @@ have_VMS_URL:
 #else
 	    StrAllocCat(*AllocatedString, "/");
 	} else if ((stat(old_string, &st) > -1) ||
-		   (fptemp = fopen(old_string, "r")) != NULL) {
+		   LYCanReadFile(old_string)) {
 	    /*
 	     *	It is an absolute directory or file
 	     *	on the local system. - KW
@@ -4812,10 +4879,6 @@ have_VMS_URL:
 	    StrAllocCat(*AllocatedString, cp);
 	    FREE(cp);
 	    FREE(temp);
-	    if (fptemp) {
-		fclose(fptemp);
-		fptemp = NULL;
-	    }
 	    CTRACE((tfp, "Converted '%s' to '%s'\n",
 			old_string, *AllocatedString));
 #endif /* VMS */
@@ -6425,13 +6488,10 @@ PUBLIC BOOLEAN LYCachedTemp ARGS2(
 	char *,		result,
 	char **,	cached)
 {
-    FILE *fp;
-
     if (*cached) {
 	LYstrncpy(result, *cached, LY_MAXPATH);
 	FREE(*cached);
-	if ((fp = fopen(result, "r")) != NULL) {
-	    fclose(fp);
+	if (LYCanReadFile(result)) {
 	    remove(result);
 	}
 	return TRUE;
@@ -6466,7 +6526,7 @@ PUBLIC FILE *LYOpenTemp ARGS3(
 	case 'b':	txt = FALSE;	break;
 	default:
 		CTRACE((tfp, "%s @%d: BUG\n", __FILE__, __LINE__));
-		return fp;
+		return 0;
 	}
     }
 
@@ -6543,6 +6603,7 @@ PUBLIC FILE *LYOpenTemp ARGS3(
 	p->next = ly_temp;
 	StrAllocCopy((p->name), result);
 	p->file = fp;
+	p->outs = (wrt != 'r');
 	ly_temp = p;
     } else {
 	outofmem(__FILE__, "LYOpenTemp");
@@ -6759,6 +6820,19 @@ PUBLIC FILE *LYOpenScratch ARGS2(
     return fp;
 }
 
+PRIVATE void LY_close_temp ARGS1(
+	LY_TEMP *,	p)
+{
+    if (p->file != 0) {
+	if (p->outs) {
+	    LYCloseOutput(p->file);
+	} else {
+	    LYCloseInput(p->file);
+	}
+	p->file = 0;
+    }
+}
+
 /*
  * Close a temp-file, given its name
  */
@@ -6771,10 +6845,7 @@ PUBLIC void LYCloseTemp ARGS1(
     if ((p = FindTempfileByName(name)) != 0) {
 	CTRACE((tfp, "...LYCloseTemp(%s)%s\n", name,
 	    (p->file != 0) ? ", closed" : ""));
-	if (p->file != 0) {
-	    fclose(p->file);
-	    p->file = 0;
-	}
+	LY_close_temp(p);
     }
 }
 
@@ -6788,8 +6859,7 @@ PUBLIC void LYCloseTempFP ARGS1(
 
     CTRACE((tfp, "LYCloseTempFP\n"));
     if ((p = FindTempfileByFP(fp)) != 0) {
-	fclose(p->file);
-	p->file = 0;
+	LY_close_temp(p);
 	CTRACE((tfp, "...LYCloseTempFP(%s)\n", p->name));
     }
 }
@@ -6812,8 +6882,7 @@ PUBLIC int LYRemoveTemp ARGS1(
 		} else {
 		    ly_temp = p->next;
 		}
-		if (p->file != 0)
-		    fclose(p->file);
+		LY_close_temp(p);
 		code = HTSYS_remove(name);
 		CTRACE((tfp, "...LYRemoveTemp done(%d)%s\n", code,
 		       (p->file != 0) ? ", closed" : ""));
@@ -7145,7 +7214,6 @@ PUBLIC BOOLEAN LYValidateFilename ARGS2(
 PUBLIC int LYValidateOutput ARGS1(
 	char *,		filename)
 {
-    FILE *fp;
     int c;
 
     /*
@@ -7166,8 +7234,7 @@ PUBLIC int LYValidateOutput ARGS1(
     /*
      *  See if it already exists.
      */
-    if ((fp = fopen(filename, "r")) != NULL) {
-	fclose(fp);
+    if (LYCanReadFile(filename)) {
 #ifdef VMS
 	c = HTConfirm(FILE_EXISTS_HPROMPT);
 #else
@@ -7395,6 +7462,8 @@ PUBLIC int LYCopyFile ARGS2(
 	char *,		src,
 	char *,		dst)
 {
+    int code;
+
 #if defined(DOSPATH) || defined(__CYGWIN__) /* thanks to Hiroyuki Senshu */
 
 #define BUF_SIZE	1024
@@ -7403,26 +7472,22 @@ PUBLIC int LYCopyFile ARGS2(
     unsigned char buff[BUF_SIZE];
     int len;
 
-    fin = fopen(src, "rb");
-    if (fin == NULL)
-	return EOF;
-
-    fout = fopen(dst, "wb");
-    if (fout == NULL) {
-	fclose(fin);		/* it was opened, yes? */
-	return EOF;
-    }
-
-    while ((len = fread(buff, 1, BUF_SIZE, fin)) > 0) {
-	fwrite(buff, 1, len, fout);
+    code = EOF;
+    if ((fin = fopen(src, "rb")) != 0) {
+	if ((fout = fopen(dst, "wb")) != 0) {
+	    code = 0;
+	    while ((len = fread(buff, 1, BUF_SIZE, fin)) > 0) {
+		fwrite(buff, 1, len, fout);
+		if (ferror(fout)) {
+		    code = EOF;
+		    break;
+		}
+	    }
+	    LYCloseOutput(fout);
+	}
+	LYCloseInput(fin);
     }
-    fclose(fin);
-    fclose(fout);
-
-    return 0;
-
 #else
-    int code;
     char *the_command = 0;
 
     HTAddParam(&the_command, COPY_COMMAND, 1, COPY_PATH);
@@ -7436,8 +7501,12 @@ PUBLIC int LYCopyFile ARGS2(
     start_curses();
 
     FREE(the_command);
-    return code;
 #endif
+
+    if (code) {
+	HTAlert(CANNOT_WRITE_TO_FILE);
+    }
+    return code;
 }
 
 /*
diff --git a/src/LYUtils.h b/src/LYUtils.h
index 038942b8..4573192e 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -55,6 +55,10 @@ extern BOOL strn_dash_equ PARAMS((CONST char* p1,CONST char* p2,int len));
 extern BOOLEAN LYAddSchemeForURL PARAMS((char **AllocatedString, char *default_scheme));
 extern BOOLEAN LYCachedTemp PARAMS((char *result, char **cached));
 extern BOOLEAN LYCanDoHEAD PARAMS((CONST char *address));
+extern BOOLEAN LYCanReadFile PARAMS((CONST char* name));
+extern BOOLEAN LYCanWriteFile PARAMS((CONST char* name));
+extern BOOLEAN LYCloseInput PARAMS((FILE * fp));
+extern BOOLEAN LYCloseOutput PARAMS((FILE * fp));
 extern BOOLEAN LYExpandHostForURL PARAMS((char **AllocatedString, char *prefix_list, char *suffix_list));
 extern BOOLEAN LYFixCursesOnForAccess PARAMS((CONST char* addr, CONST char* physical));
 extern BOOLEAN LYPathOffHomeOK PARAMS((char *fbuffer, size_t fbuffer_size));
diff --git a/src/LYrcFile.c b/src/LYrcFile.c
index de97c538..3671ca5f 100644
--- a/src/LYrcFile.c
+++ b/src/LYrcFile.c
@@ -550,7 +550,7 @@ PUBLIC void read_rc ARGS1(FILE *, fp)
 
     } /* end of while */
 
-    fclose(fp);
+    LYCloseInput(fp);
 } /* big end */
 
 /*
@@ -1080,7 +1080,7 @@ in the Visited Links Page.\n\
     if (is_tempfile) {
 	LYCloseTempFP(fp);
     } else {
-	fclose(fp);
+	LYCloseOutput(fp);
 	HTSYS_purge(rcfile);
     }