about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GridText.c264
-rw-r--r--src/HTAlert.c39
-rw-r--r--src/HTML.c40
-rw-r--r--src/LYCurses.h3
-rw-r--r--src/LYForms.c10
-rw-r--r--src/LYGlobalDefs.h2
-rw-r--r--src/LYLeaks.c2
-rw-r--r--src/LYLocal.c157
-rw-r--r--src/LYMain.c9
-rw-r--r--src/LYMainLoop.c14
-rw-r--r--src/LYOptions.c38
-rw-r--r--src/LYShowInfo.c10
-rw-r--r--src/LYStrings.c95
-rw-r--r--src/LYStrings.h4
-rw-r--r--src/LYUtils.c63
-rw-r--r--src/LYUtils.h7
-rw-r--r--src/LYrcFile.c4
-rw-r--r--src/makefile.dsl4
18 files changed, 532 insertions, 233 deletions
diff --git a/src/GridText.c b/src/GridText.c
index 957a8a3d..174b29cd 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -120,8 +120,6 @@ PUBLIC BOOLEAN underline_on = OFF;
 PUBLIC BOOLEAN bold_on      = OFF;
 
 #ifdef SOURCE_CACHE
-PUBLIC char * source_cache_filename = NULL;
-PUBLIC HTChunk * source_cache_chunk = NULL;
 PUBLIC int LYCacheSource = SOURCE_CACHE_NONE;
 PUBLIC BOOLEAN from_source_cache = FALSE;  /* mutable */
 #endif
@@ -187,13 +185,12 @@ struct _HText {
 	HTParentAnchor *	node_anchor;
 #ifdef SOURCE_CACHE
 #undef	lines			/* FIXME */
-	char *			source_cache_file;
-	HTChunk *		source_cache_chunk;
 	/*
 	 * Parse settings when this HText was generated.
 	 */
 	BOOLEAN			clickable_images;
 	BOOLEAN			pseudo_inline_alts;
+	BOOLEAN			verbose_img;
 	BOOLEAN			raw_mode;
 	BOOLEAN			historical_comments;
 	BOOLEAN			minimal_comments;
@@ -516,24 +513,11 @@ PUBLIC HText *	HText_new ARGS1(
     self->tabs = NULL;
 #ifdef SOURCE_CACHE
     /*
-     * Yes, this is a Gross And Disgusting Hack(TM), I know...
-     */
-    self->source_cache_file = NULL;
-    if (LYCacheSource == SOURCE_CACHE_FILE && source_cache_filename) {
-      StrAllocCopy(self->source_cache_file, source_cache_filename);
-      FREE(source_cache_filename);
-    }
-    self->source_cache_chunk = NULL;
-    if (LYCacheSource == SOURCE_CACHE_MEMORY && source_cache_chunk) {
-	self->source_cache_chunk = source_cache_chunk;
-	source_cache_chunk = NULL;
-    }
-
-    /*
      * Remember the parse settings.
      */
     self->clickable_images = clickable_images;
     self->pseudo_inline_alts = pseudo_inline_alts;
+    self->verbose_img = verbose_img;
     self->raw_mode = LYUseDefaultRawMode;
     self->historical_comments = historical_comments;
     self->minimal_comments = minimal_comments;
@@ -792,23 +776,6 @@ PUBLIC void HText_free ARGS1(
 	    HTMainAnchor = NULL;
     }
 
-#ifdef SOURCE_CACHE
-    /*
-     * Clean up the source cache, if any.
-     */
-    if (self->source_cache_file) {
-	CTRACE(tfp, "Removing source cache file %s\n",
-	       self->source_cache_file);
-	LYRemoveTemp(self->source_cache_file);
-	FREE(self->source_cache_file);
-    }
-    if (self->source_cache_chunk) {
-	CTRACE(tfp, "Removing memory source cache %p\n",
-	       (void *)self->source_cache_chunk);
-	HTChunkFree(self->source_cache_chunk);
-    }
-#endif
-
     FREE(self);
 }
 
@@ -2122,9 +2089,9 @@ PRIVATE void split_line ARGS2(
 		    (previous->styles[spare - 1].direction == ABS_ON &&
 		     previous->styles[spare - 2].direction == ABS_OFF)
 		       )) {
-	       /*
-		*  Skip pairs of adjacent ON/OFF or OFF/ON changes.
-		*/
+	        /*
+		 *  Skip pairs of adjacent ON/OFF or OFF/ON changes.
+		 */
 	    spare -= 2;
 	} else if (spare && !previous->styles[spare - 1].direction) {
 	    /*
@@ -3765,8 +3732,8 @@ PUBLIC void HText_trimHightext ARGS2(
     if (!text)
 	return;
 
-    CTRACE(tfp,"Gridtext: Entering HText_trimHightext %s\n",
-	       final ? "(final)" : "(partial)");
+    CTRACE(tfp, "Gridtext: Entering HText_trimHightext %s\n",
+	        final ? "(final)" : "(partial)");
 
     /*
      *  Get the first line.
@@ -6171,7 +6138,7 @@ PUBLIC void HTuncache_current_document NOARGS
 		FREE(htmain_anchor->UCStages);
 	    }
 	}
-	CTRACE(tfp, "\rHTuncache.. freeing document for '%s'%s\n",
+	CTRACE(tfp, "\nHTuncache.. freeing document for '%s'%s\n",
 			    ((htmain_anchor &&
 			      htmain_anchor->address) ?
 			       htmain_anchor->address : "unknown anchor"),
@@ -6191,30 +6158,30 @@ PUBLIC BOOLEAN HTreparse_document NOARGS
 {
     BOOLEAN ok = FALSE;
 
-    if (!HTMainText || LYCacheSource == SOURCE_CACHE_NONE ||
+    if (!HTMainAnchor || LYCacheSource == SOURCE_CACHE_NONE ||
 	(LYCacheSource == SOURCE_CACHE_FILE &&
-	 !HTMainText->source_cache_file) ||
+	!HTMainAnchor->source_cache_file) ||
 	(LYCacheSource == SOURCE_CACHE_MEMORY &&
-	 !HTMainText->source_cache_chunk))
+	!HTMainAnchor->source_cache_chunk))
 	return FALSE;
 
-    if (LYCacheSource == SOURCE_CACHE_FILE && HTMainText->source_cache_file) {
+    if (LYCacheSource == SOURCE_CACHE_FILE && HTMainAnchor->source_cache_file) {
 	FILE * fp;
 	HTFormat format;
 	int ret;
 
 	CTRACE(tfp, "Reparsing source cache file %s\n",
-	       HTMainText->source_cache_file);
+	      HTMainAnchor->source_cache_file);
 
 	/*
 	 * This is more or less copied out of HTLoadFile(), except we don't
 	 * get a content encoding.  This may be overkill.  -dsb
 	 */
-	if (HTMainText->node_anchor->content_type) {
-	    format = HTAtom_for(HTMainText->node_anchor->content_type);
+	if (HTMainAnchor->content_type) {
+	   format = HTAtom_for(HTMainAnchor->content_type);
 	} else {
-	    format = HTFileFormat(HTMainText->source_cache_file, NULL, NULL);
-	    format = HTCharsetFormat(format, HTMainText->node_anchor,
+	   format = HTFileFormat(HTMainAnchor->source_cache_file, NULL, NULL);
+	   format = HTCharsetFormat(format, HTMainAnchor,
 					     UCLYhndl_for_unspec);
 	    /* not UCLYhndl_HTFile_for_unspec - we are talking about remote
 	     * documents...
@@ -6222,17 +6189,10 @@ PUBLIC BOOLEAN HTreparse_document NOARGS
 	}
 	CTRACE(tfp, "  Content type is \"%s\"\n", format->name);
 
-	/*
-	 * Pass the source cache filename on to the next HText.  Mark it
-	 * NULL here so that it won't get deleted by HText_free().
-	 */
-	source_cache_filename = HTMainText->source_cache_file;
-	HTMainText->source_cache_file = NULL;
-
-	fp = fopen(source_cache_filename, "r");
+	fp = fopen(HTMainAnchor->source_cache_file, "r");
 	if (!fp) {
-	    CTRACE(tfp, "  Cannot read file %s\n", source_cache_filename);
-	    FREE(source_cache_filename);
+	   CTRACE(tfp, "  Cannot read file %s\n", HTMainAnchor->source_cache_file);
+	   FREE(HTMainAnchor->source_cache_file);
 	    return FALSE;
 	}
 #ifdef DISP_PARTIAL
@@ -6245,22 +6205,19 @@ PUBLIC BOOLEAN HTreparse_document NOARGS
 	     */
 	    HTAlert(RELOADING_FORM);
 	}
-	ret = HTParseFile(format, HTOutputFormat, HTMainText->node_anchor,
+	ret = HTParseFile(format, HTOutputFormat, HTMainAnchor,
 			  fp, NULL);
 	fclose(fp);
 	ok = (ret == HT_LOADED);
-	if (!ok) {
-	    FREE(source_cache_filename);
-	}
     }
 
     if (LYCacheSource == SOURCE_CACHE_MEMORY &&
-	HTMainText->source_cache_chunk) {
+	HTMainAnchor->source_cache_chunk) {
 	HTFormat format = WWW_HTML;
 	int ret;
 
 	CTRACE(tfp, "Reparsing from source memory cache %p\n",
-	       (void *)HTMainText->source_cache_chunk);
+		    (void *)HTMainAnchor->source_cache_chunk);
 
 	/*
 	 * This is only done to make things aligned with SOURCE_CACHE_NONE and
@@ -6270,17 +6227,10 @@ PUBLIC BOOLEAN HTreparse_document NOARGS
 	 * user-visible benefits, seems just '=' Info Page will show source's
 	 * effective charset as "(assumed)".
 	 */
-	format = HTCharsetFormat(format, HTMainText->node_anchor,
+	format = HTCharsetFormat(format, HTMainAnchor,
 					 UCLYhndl_for_unspec);
 	/* not UCLYhndl_HTFile_for_unspec - we are talking about remote documents... */
 
-	/*
-	 * Pass the source cache HTChunk on to the next HText.  Clear it
-	 * here so that it won't get deleted by HText_free().
-	 */
-	source_cache_chunk = HTMainText->source_cache_chunk;
-	HTMainText->source_cache_chunk = NULL;
-
 #ifdef DISP_PARTIAL
 	display_partial = display_partial_flag;  /* restore */
 	Newline_partial = Newline;  /* initialize */
@@ -6291,13 +6241,9 @@ PUBLIC BOOLEAN HTreparse_document NOARGS
 	     */
 	    HTAlert(RELOADING_FORM);
 	}
-	ret = HTParseMem(format, HTOutputFormat, HTMainText->node_anchor,
-			 source_cache_chunk, NULL);
+	ret = HTParseMem(format, HTOutputFormat, HTMainAnchor,
+			HTMainAnchor->source_cache_chunk, NULL);
 	ok = (ret == HT_LOADED);
-	if (!ok) {
-	    HTChunkFree(source_cache_chunk);
-	    source_cache_chunk = NULL;
-	}
     }
 
     CTRACE(tfp, "Reparse %s\n", (ok ? "succeeded" : "failed"));
@@ -6311,17 +6257,17 @@ PUBLIC BOOLEAN HTreparse_document NOARGS
 
 PUBLIC BOOLEAN HTcan_reparse_document NOARGS
 {
-    if (!HTMainText || LYCacheSource == SOURCE_CACHE_NONE ||
+    if (!HTMainAnchor || LYCacheSource == SOURCE_CACHE_NONE ||
 	(LYCacheSource == SOURCE_CACHE_FILE &&
-	 !HTMainText->source_cache_file) ||
+	!HTMainAnchor->source_cache_file) ||
 	(LYCacheSource == SOURCE_CACHE_MEMORY &&
-	 !HTMainText->source_cache_chunk))
+	!HTMainAnchor->source_cache_chunk))
 	return FALSE;
 
-    if (LYCacheSource == SOURCE_CACHE_FILE && HTMainText->source_cache_file) {
+    if (LYCacheSource == SOURCE_CACHE_FILE && HTMainAnchor->source_cache_file) {
 	FILE * fp;
 
-	fp = fopen(HTMainText->source_cache_file, "r");
+	fp = fopen(HTMainAnchor->source_cache_file, "r");
 	if (!fp) {
 	    return FALSE;
 	}
@@ -6330,7 +6276,7 @@ PUBLIC BOOLEAN HTcan_reparse_document NOARGS
     }
 
     if (LYCacheSource == SOURCE_CACHE_MEMORY &&
-	HTMainText->source_cache_chunk) {
+	HTMainAnchor->source_cache_chunk) {
 	return TRUE;
     }
 
@@ -6353,11 +6299,11 @@ PUBLIC BOOLEAN HTdocument_settings_changed NOARGS
      * Annoying Hack(TM):  If we don't have a source cache, we can't
      * reparse anyway, so pretend the settings haven't changed.
      */
-    if (!HTMainText || LYCacheSource == SOURCE_CACHE_NONE ||
+    if (!HTMainAnchor || !HTMainText || LYCacheSource == SOURCE_CACHE_NONE ||
 	(LYCacheSource == SOURCE_CACHE_FILE &&
-	 !HTMainText->source_cache_file) ||
+	!HTMainAnchor->source_cache_file) ||
 	(LYCacheSource == SOURCE_CACHE_MEMORY &&
-	 !HTMainText->source_cache_chunk))
+	!HTMainAnchor->source_cache_chunk))
 	return FALSE;
 
     if (TRACE) {
@@ -6369,6 +6315,9 @@ PUBLIC BOOLEAN HTdocument_settings_changed NOARGS
 	trace_setting_change("PSEUDO_INLINE_ALTS",
 			     HTMainText->pseudo_inline_alts,
 			     pseudo_inline_alts);
+	trace_setting_change("VERBOSE_IMG",
+			    HTMainText->verbose_img,
+			    verbose_img);
 	trace_setting_change("RAW_MODE", HTMainText->raw_mode,
 			     LYUseDefaultRawMode);
 	trace_setting_change("HISTORICAL_COMMENTS",
@@ -6387,6 +6336,7 @@ PUBLIC BOOLEAN HTdocument_settings_changed NOARGS
 
     return (HTMainText->clickable_images != clickable_images ||
 	    HTMainText->pseudo_inline_alts != pseudo_inline_alts ||
+	   HTMainText->verbose_img != verbose_img ||
 	    HTMainText->raw_mode != LYUseDefaultRawMode ||
 	    HTMainText->historical_comments != historical_comments ||
 	    HTMainText->minimal_comments != minimal_comments ||
@@ -7535,6 +7485,7 @@ PUBLIC int HText_beginInput ARGS3(
 	    f->type = F_RANGE_TYPE;
 	} else if (!strcasecomp(I->type,"file")) {
 	    f->type = F_FILE_TYPE;
+	    CTRACE(tfp, "ok, got a file uploader\n");
 	} else if (!strcasecomp(I->type,"keygen")) {
 	    f->type = F_KEYGEN_TYPE;
 	} else {
@@ -7683,7 +7634,9 @@ PUBLIC int HText_beginInput ARGS3(
 	 *  for types that are not yet implemented.
 	 */
 	case F_HIDDEN_TYPE:
+#ifndef EXP_FILE_UPLOAD
 	case F_FILE_TYPE:
+#endif
 	case F_RANGE_TYPE:
 	case F_KEYGEN_TYPE:
 	    a->number = 0;
@@ -8295,6 +8248,15 @@ PUBLIC int HText_SubmitForm ARGS4(
 			}
 			break;
 		    }
+
+#ifdef EXP_FILE_UPLOAD
+		case F_FILE_TYPE:
+		    CTRACE(tfp, "I'd submit %s (from %s), but you've not finished it\n", form_ptr->value, form_ptr->name);
+		    name_used = (form_ptr->name ? form_ptr->name : "");
+		    val_used = (form_ptr->value ? form_ptr->value : "");
+ 		    break;
+#endif
+ 
 		    /*  fall through  */
 		case F_RADIO_TYPE:
 		case F_CHECKBOX_TYPE:
@@ -8495,6 +8457,86 @@ PUBLIC int HText_SubmitForm ARGS4(
 		case F_RESET_TYPE:
 		    break;
 
+#ifdef EXP_FILE_UPLOAD
+		case F_FILE_TYPE:
+		{
+		    int cdisp_name_startpos = 0;
+		    FILE *fd;
+		    int bytes;
+		    char buffer[257];
+
+		    CTRACE(tfp, "Ok, about to convert %s to mime/thingy\n", form_ptr->value);
+		    if (first_one) {
+			if (Boundary) {
+			    HTSprintf(&query, "--%s\r\n", Boundary);
+			}
+			first_one = FALSE;
+		    } else {
+			if (PlainText) {
+			    HTSprintf(&query, "\n");
+			} else if (SemiColon) {
+			    HTSprintf(&query, ";");
+			} else if (Boundary) {
+			    HTSprintf(&query, "\r\n--%s\r\n", Boundary);
+			} else {
+			    HTSprintf(&query, "&");
+			}
+		    }
+
+		    if (PlainText) {
+			StrAllocCopy(escaped1, name_used);
+		    } else if (Boundary) {
+			StrAllocCopy(escaped1,
+				"Content-Disposition: form-data; name=");
+			cdisp_name_startpos = strlen(escaped1);
+			StrAllocCat(escaped1, name_used);
+			StrAllocCat(escaped1, "; filename=\"");
+			StrAllocCat(escaped1, val_used); 
+			StrAllocCat(escaped1, "\"");
+			if (MultipartContentType) {
+			    StrAllocCat(escaped1, MultipartContentType);
+			    StrAllocCat(escaped1, "\r\nContent-Transfer-Encoding: base64");
+			}
+			StrAllocCat(escaped1, "\r\n\r\n");
+		    } else {
+			escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
+		    }
+
+		    if ((fd = fopen(val_used, "rb")) == 0) {
+			/* We can't open the file, what do we do? */
+			HTAlert("Can't open file for uploading");
+			return 0;
+		    }
+		    StrAllocCopy(escaped2, "");
+		    while ((bytes = fread(buffer, sizeof(char), 45, fd)) != 0) {
+			char base64buf[128];
+			base64_encode(base64buf, buffer, bytes);
+			StrAllocCat(escaped2, base64buf);
+		    }
+		    if (ferror(fd)) {
+			/* We got an error reading the file, what do we do? */
+			HTAlert("Short read from file, problem?");
+			fclose(fd);
+			return 0;
+		    }
+		    fclose(fd);
+		    /* we need to modify the mime-type here */
+
+		    /* Argh.  We need counted-length strings here */
+		    HTSprintf(&query,
+				   "%s%s%s%s%s",
+				   escaped1,
+				   (Boundary ? "" : "="),
+				   (PlainText ? "\n" : ""),
+					escaped2,
+				   ((PlainText && *escaped2) ?
+							 "\n" : ""));
+		    FREE(escaped1);
+		    FREE(escaped2);
+		}
+		break;
+#endif /* EXP_FILE_UPLOAD */
+
 		case F_SUBMIT_TYPE:
 		case F_TEXT_SUBMIT_TYPE:
 		case F_IMAGE_SUBMIT_TYPE:
@@ -8830,6 +8872,8 @@ PUBLIC int HText_SubmitForm ARGS4(
 	StrAllocCopy(query, "");
     }
     FREE(previous_blanks);
+	
+    CTRACE(tfp, "QUERY (%d) >> \n%s\n", strlen(query), query);
 
     if (submit_item->submit_method == URL_MAIL_METHOD) {
 	HTUserMsg2(gettext("Submitting %s"), submit_item->submit_action);
@@ -8959,7 +9003,7 @@ PUBLIC BOOLEAN HText_HaveUserChangedForms NOARGS
     TextAnchor * anchor_ptr;
 
     if (HTMainText == 0)
-       return FALSE;
+	return FALSE;
 
     /*
      *  Go through list of anchors to check if any value was changed.
@@ -9904,23 +9948,23 @@ PRIVATE void update_subsequent_anchors ARGS4(
 		if ((anchor->number - n) == start_tag)
 		    break;
 
-	        /*** A HANG (infinite loop) *has* occurred here, with */
-	        /*** the values of anchor and anchor->next being the  */
-	        /*** the same, OR with anchor->number "magically" and */
-	        /*** suddenly taking on an anchor-pointer-like value. */
-	        /***                                                  */
-	        /*** The same code and same doc have both passed and  */
-	        /*** failed at different times, which indicates some  */
-	        /*** sort of content/html dependency, or some kind of */
-	        /*** a "race" condition, but I'll be damned if I can  */
-	        /*** find it after tons of CTRACE's, printf()'s, gdb  */
-	        /*** breakpoints and watchpoints, etc.                */
-	        /***                                                  */
-	        /*** I have added a hang detector (with error msg and */
-	        /*** beep) here, to break the loop and warn the user, */
-	        /*** until it can be isolated and fixed.              */
-	        /***                                                  */
-	        /*** [One UGLY intermittent .. gak ..!  02/22/99 KED] */
+		/*** A HANG (infinite loop) *has* occurred here, with */
+		/*** the values of anchor and anchor->next being the  */
+		/*** the same, OR with anchor->number "magically" and */
+		/*** suddenly taking on an anchor-pointer-like value. */
+		/***                                                  */
+		/*** The same code and same doc have both passed and  */
+		/*** failed at different times, which indicates some  */
+		/*** sort of content/html dependency, or some kind of */
+		/*** a "race" condition, but I'll be damned if I can  */
+		/*** find it after tons of CTRACE's, printf()'s, gdb  */
+		/*** breakpoints and watchpoints, etc.                */
+		/***                                                  */
+		/*** I have added a hang detector (with error msg and */
+		/*** beep) here, to break the loop and warn the user, */
+		/*** until it can be isolated and fixed.              */
+		/***                                                  */
+		/*** [One UGLY intermittent .. gak ..!  02/22/99 KED] */
 
 		hang++;
 		if ((anchor == anchor->next) || (hang >= hang_detect))
@@ -10284,7 +10328,7 @@ PUBLIC void HText_ExpandTextarea ARGS2(
 	    !strcmp (anchor_ptr->input_field->name, areaname))   {
 
 	    if (firstanchor)
-	        firstanchor = FALSE;
+		firstanchor = FALSE;
 
 	    end_anchor = anchor_ptr;
 
@@ -10312,7 +10356,7 @@ PUBLIC void HText_ExpandTextarea ARGS2(
     }
 
     CTRACE(tfp, "GridText: %d blank line(s) added to TEXTAREA name=|%s|\n",
-	        newlines, areaname);
+		newlines, areaname);
 
     /*
      *	We need to adjust various things in all anchor bearing lines
@@ -10849,7 +10893,7 @@ PUBLIC void redraw_lines_of_link ARGS1(
 PUBLIC void HTMark_asSource NOARGS
 {
     if (HTMainText)
-        HTMainText->source = TRUE;
+	HTMainText->source = TRUE;
 }
 #endif
 
diff --git a/src/HTAlert.c b/src/HTAlert.c
index eae16bd7..4889f719 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -473,7 +473,7 @@ PUBLIC BOOL HTConfirmCookie ARGS4(
 	CONST char *,	value)
 {
     domain_entry *de;
-    int ch, namelen, valuelen, space_free;
+    int ch;
 
     if ((de = (domain_entry *)dp) == NULL)
 	return FALSE;
@@ -511,26 +511,27 @@ PUBLIC BOOL HTConfirmCookie ARGS4(
 	if (de->bv == REJECT_ALWAYS)
 	    return FALSE;
     }
-    space_free = (((LYcols - 1)
-	       - strlen(ADVANCED_COOKIE_CONFIRMATION))
-	       - strlen(server));
-    if (space_free < 0)
-	space_free = 0;
-    namelen = strlen(name);
-    valuelen = strlen(value);
-    if ((namelen + valuelen) > space_free) {
-	/*
-	**  Argh... there isn't enough space on our single line for
-	**  the whole cookie.  Reduce them both by a percentage.
-	**  This should be smarter.
-	*/
-        int percentage;  /* no float */
-        percentage = (100 * space_free) / (namelen + valuelen);
-        namelen = (percentage * namelen) / 100;
-        valuelen = (percentage * valuelen) / 100;
-    }
     if(!LYAcceptAllCookies) {
+	int namelen, valuelen, space_free, percentage;
 	char *message = 0;
+
+	space_free = (((LYcols - 1)
+		   - strlen(ADVANCED_COOKIE_CONFIRMATION))
+		   - strlen(server));
+	if (space_free < 0)
+	    space_free = 0;
+	namelen = strlen(name);
+	valuelen = strlen(value);
+	if ((namelen + valuelen) > space_free) {
+	    /*
+	    **  Argh... there isn't enough space on our single line for
+	    **  the whole cookie.  Reduce them both by a percentage.
+	    **  This should be smarter.
+	    */
+	    percentage = (100 * space_free) / (namelen + valuelen);
+	    namelen = (percentage * namelen) / 100;
+	    valuelen = (percentage * valuelen) / 100;
+	}
 	HTSprintf(&message, ADVANCED_COOKIE_CONFIRMATION,
 		 server, namelen, name, valuelen, value);
 	_statusline(message);
diff --git a/src/HTML.c b/src/HTML.c
index 2f036c9d..36143414 100644
--- a/src/HTML.c
+++ b/src/HTML.c
@@ -4615,6 +4615,7 @@ PRIVATE void HTML_start_element ARGS6(
 		} else if (!strcasecomp(I.type, "file")) {
 		    if (present[HTML_INPUT_ACCEPT])
 			I.accept = value[HTML_INPUT_ACCEPT];
+#ifdef EXP_FILE_UPLOAD
 		    /*
 		     *	Not yet implemented.
 		     */
@@ -4627,12 +4628,14 @@ PRIVATE void HTML_start_element ARGS6(
 			HText_appendCharacter(me->text,
 					      LY_UNDERLINE_END_CHAR);
 		    }
+#else 
+		    CTRACE(tfp, "Attempting to fake as: %s\n", I.type);
+#endif /* EXP_FILE_UPLOAD */
 #ifdef NOTDEFINED
 		    if (me->inFORM)
 			HText_DisableCurrentForm();
 #endif /* NOTDEFINED */
 		    CTRACE(tfp, "HTML: Ignoring TYPE=\"file\"\n");
-		    break;
 
 		} else if (!strcasecomp(I.type, "button")) {
 		    /*
@@ -4662,6 +4665,8 @@ PRIVATE void HTML_start_element ARGS6(
 		 */
 	    }
 
+	    CTRACE(tfp, "Ok, we're trying [%s]\n", I.type);
+
 	    /*
 	     *	Check for an unclosed TEXTAREA.
 	     */
@@ -4774,6 +4779,8 @@ PRIVATE void HTML_start_element ARGS6(
 		}
 		FREE(href);
 	    }
+	    CTRACE(tfp, "2.Ok, we're trying [%s] (present=%p)\n", I.type, present);
+	    /* text+file don't go in here */
 	    if ((UseALTasVALUE == TRUE) ||
 		(present && present[HTML_INPUT_VALUE] &&
 		 value[HTML_INPUT_VALUE] && *value[HTML_INPUT_VALUE])) {
@@ -4793,13 +4800,20 @@ PRIVATE void HTML_start_element ARGS6(
 		    HTMLSetCharacterHandling(current_char_set);
 		}
 
+		CTRACE(tfp, "3.Ok, we're trying [%s]\n", I.type);
 		if (!I.type)
 		    me->UsePlainSpace = TRUE;
 		else if (!strcasecomp(I.type, "text") ||
+#ifdef EXP_FILE_UPLOAD
+			 !strcasecomp(I.type, "file") ||
+#endif
 			 !strcasecomp(I.type, "submit") ||
 			 !strcasecomp(I.type, "image") ||
-			 !strcasecomp(I.type, "reset"))
+			 !strcasecomp(I.type, "reset")) {
+		    CTRACE(tfp, "normal field type: %s\n", I.type);
 		    me->UsePlainSpace = TRUE;
+		}
+
 		StrAllocCopy(I_value,
 			     ((UseALTasVALUE == TRUE) ?
 				value[HTML_INPUT_ALT] :
@@ -4807,6 +4821,7 @@ PRIVATE void HTML_start_element ARGS6(
 		if (me->UsePlainSpace && !me->HiddenValue) {
 		    I.value_cs = current_char_set;
 		}
+	    CTRACE(tfp, "4.Ok, we're trying [%s]\n", I.type);
 		TRANSLATE_AND_UNESCAPE_ENTITIES6(
 		    &I_value,
 		    ATTR_CS_IN,
@@ -4895,6 +4910,9 @@ PRIVATE void HTML_start_element ARGS6(
 		I.md = value[HTML_INPUT_MD];
 
 	    chars = HText_beginInput(me->text, me->inUnderline, &I);
+#ifndef EXP_FILE_UPLOAD
+	    CTRACE(tfp, "I.%s have %d chars, or something\n", I.type, chars);
+#endif
 	    /*
 	     *	Submit and reset buttons have values which don't change,
 	     *	so HText_beginInput() sets I.value to the string which
@@ -4967,6 +4985,9 @@ PRIVATE void HTML_start_element ARGS6(
 		}
 		HText_setIgnoreExcess(me->text, TRUE);
 	    }
+#ifndef EXP_FILE_UPLOAD
+	    CTRACE(tfp, "I.%s, %d\n", I.type, IsSubmitOrReset);
+#endif
 	    if (IsSubmitOrReset == FALSE) {
 		/*
 		 *  This is not a submit or reset button,
@@ -7764,9 +7785,9 @@ PRIVATE HTStream* CacheThru_new ARGS2(
     stream->actions = target->isa;
 
     if (LYCacheSource == SOURCE_CACHE_FILE) {
-	if (source_cache_filename) {
+	if (anchor->source_cache_file) {
 	    CTRACE(tfp, "Reusing source cache file %s\n",
-		   source_cache_filename);
+		   anchor->source_cache_file);
 	    FREE(stream);
 	    return target;
 	}
@@ -7784,25 +7805,22 @@ PRIVATE HTStream* CacheThru_new ARGS2(
 	    return target;
 	}
 
-	/*
-	 * Yes, this is a Gross And Disgusting Hack(TM), I know...
-	 */
-	StrAllocCopy(source_cache_filename, filename);
+	StrAllocCopy(anchor->source_cache_file, filename);
 
 	CTRACE(tfp, "Caching source for URL %s in file %s\n",
 	       HTAnchor_address((HTAnchor *)anchor), filename);
     }
 
     if (LYCacheSource == SOURCE_CACHE_MEMORY) {
-	if (source_cache_chunk) {
+	if (anchor->source_cache_chunk) {
 	    CTRACE(tfp, "Reusing source memory cache %p\n",
-		   (void *)source_cache_chunk);
+		   (void *)anchor->source_cache_chunk);
 	    FREE(stream);
 	    return target;
 	}
 
 	/* I think this is right... */
-	source_cache_chunk = stream->chunk = HTChunkCreate(128);
+	anchor->source_cache_chunk = stream->chunk = HTChunkCreate(128);
 	CTRACE(tfp, "Caching source for URL %s in memory cache %p\n",
 	       HTAnchor_address((HTAnchor *)anchor), (void *)stream->chunk);
 
diff --git a/src/LYCurses.h b/src/LYCurses.h
index bf0dc014..5505e9ca 100644
--- a/src/LYCurses.h
+++ b/src/LYCurses.h
@@ -25,9 +25,6 @@
 #endif /* FALSE */
 
 #ifdef USE_SLANG
-#if defined(UNIX) && !defined(unix)
-#define unix
-#endif /* UNIX && !unix */
 #include <slang.h>
 
 #else /* Using curses: */
diff --git a/src/LYForms.c b/src/LYForms.c
index 36f06b7f..2f12576f 100644
--- a/src/LYForms.c
+++ b/src/LYForms.c
@@ -175,6 +175,7 @@ PUBLIC int change_form_link ARGS7(
 	    }
 	    break;
 
+	case F_FILE_TYPE:
 	case F_TEXT_TYPE:
 	case F_TEXTAREA_TYPE:
 	case F_PASSWORD_TYPE:
@@ -373,6 +374,9 @@ PRIVATE int form_getstr ARGS2(
 			statusline(FORM_LINK_TEXT_SUBMIT_MESSAGE);
 		    }
 		    break;
+		case F_FILE_TYPE:
+		    statusline(FORM_LINK_FILE_MESSAGE);
+		    break;
 		case F_TEXT_TYPE:
 		    statusline(FORM_LINK_TEXT_MESSAGE);
 		    break;
@@ -1779,6 +1783,12 @@ PUBLIC void show_formlink_statusline ARGS1(
 	else
 	    statusline(FORM_LINK_RESET_MESSAGE);
 	break;
+    case F_FILE_TYPE:
+	if (form->disabled == YES)
+	    statusline(FORM_LINK_FILE_UNM_MSG);
+	else
+	    statusline(FORM_LINK_FILE_MESSAGE);
+	break;
     case F_TEXT_TYPE:
 	if (form->disabled == YES)
 	    statusline(FORM_LINK_TEXT_UNM_MSG);
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index e1d9e92f..91923705 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -266,8 +266,6 @@ extern BOOLEAN historical_comments;
 extern BOOLEAN minimal_comments;
 extern BOOLEAN soft_dquotes;
 #ifdef SOURCE_CACHE
-extern char * source_cache_filename;
-extern HTChunk * source_cache_chunk;
 extern BOOLEAN from_source_cache; /* mutable */
 extern int LYCacheSource;
 #define SOURCE_CACHE_NONE	0
diff --git a/src/LYLeaks.c b/src/LYLeaks.c
index 504954a3..70c8d8a1 100644
--- a/src/LYLeaks.c
+++ b/src/LYLeaks.c
@@ -116,7 +116,7 @@ PUBLIC void LYLeaks NOARGS
 	    fprintf(Fp_leakagesink, "%s\t%p\n",
 		    gettext("Pointer:"),
 		    ALp_head->vp_Alloced);
-	    fprintf(Fp_leakagesink, "%s:\t",
+	    fprintf(Fp_leakagesink, "%s\t",
 		    gettext("Contains:"));
 	    for (i_counter = 0;
 		 i_counter < ALp_head->st_Bytes &&
diff --git a/src/LYLocal.c b/src/LYLocal.c
index 04a85fa2..df254292 100644
--- a/src/LYLocal.c
+++ b/src/LYLocal.c
@@ -70,6 +70,18 @@
 
 #include <LYLeaks.h>
 
+#undef USE_COMPRESS
+
+#ifdef __DJGPP__
+#define EXT_TAR_GZ ".tgz"
+#define EXT_TAR_Z  ".taz"
+#define EXT_Z      ".z"
+#else
+#define EXT_TAR_GZ ".tar.gz"
+#define EXT_TAR_Z  ".tar.Z"
+#define EXT_Z      ".Z"
+#endif
+
 PRIVATE int LYExecv PARAMS((
 	char *		path,
 	char ** 	argv,
@@ -133,8 +145,10 @@ struct dired_menu {
 "(of current selection)", "LYNXDIRED://MODIFY_NAME%p",		NULL },
 { DE_DIR,	      "", "Modify Directory Name",
 "(of current selection)", "LYNXDIRED://MODIFY_NAME%p",		NULL },
+#ifdef S_IFLNK
 { DE_SYMLINK,	      "", "Modify Name",
 "(of selected symbolic link)", "LYNXDIRED://MODIFY_NAME%p",	NULL },
+#endif  /* S_IFLNK */
 
 #ifdef OK_PERMIT
 { DE_FILE,	      "", "Modify File Permissions",
@@ -147,15 +161,19 @@ struct dired_menu {
 "(of selected file)"	, "LYNXDIRED://MODIFY_LOCATION%p",	NULL },
 { DE_DIR,	      "", "Change Location",
 "(of selected directory)", "LYNXDIRED://MODIFY_LOCATION%p",	NULL },
+#ifdef S_IFLNK
 { DE_SYMLINK,	      "", "Change Location",
 "(of selected symbolic link)", "LYNXDIRED://MODIFY_LOCATION%p", NULL },
+#endif /* S_IFLNK */
 
 { DE_FILE,	      "", "Remove File",
    "(current selection)", "LYNXDIRED://REMOVE_SINGLE%p",	NULL },
 { DE_DIR,	      "", "Remove Directory",
    "(current selection)", "LYNXDIRED://REMOVE_SINGLE%p",	NULL },
+#ifdef S_IFLNK
 { DE_SYMLINK,	      "", "Remove Symbolic Link",
    "(current selection)", "LYNXDIRED://REMOVE_SINGLE%p",	NULL },
+#endif /* S_IFLNK */
 
 #if defined(OK_UUDECODE) && !defined(ARCHIVE_ONLY)
 { DE_FILE,	      "", "UUDecode",
@@ -163,7 +181,7 @@ struct dired_menu {
 #endif /* OK_UUDECODE && !ARCHIVE_ONLY */
 
 #if defined(OK_TAR) && !defined(ARCHIVE_ONLY)
-{ DE_FILE,	".tar.Z", "Expand",
+{ DE_FILE,	EXT_TAR_Z, "Expand",
    "(current selection)", "LYNXDIRED://UNTAR_Z%p",		NULL },
 #endif /* OK_TAR && !ARCHIVE_ONLY */
 
@@ -176,7 +194,7 @@ struct dired_menu {
 #endif /* OK_TAR && OK_GZIP && !ARCHIVE_ONLY */
 
 #ifndef ARCHIVE_ONLY
-{ DE_FILE,	    ".Z", "Uncompress",
+{ DE_FILE,	   EXT_Z, "Uncompress",
    "(current selection)", "LYNXDIRED://DECOMPRESS%p",		NULL },
 #endif /* ARCHIVE_ONLY */
 
@@ -205,6 +223,11 @@ struct dired_menu {
       "(using GNU gzip)", "LYNXDIRED://TAR_GZ%p",		NULL },
 #endif /* OK_TAR && OK_GZIP */
 
+#if defined(OK_TAR) && defined(USE_COMPRESS)
+{ DE_DIR,	      "", "Tar and compress",
+      "(using compress)", "LYNXDIRED://TAR_Z%p",		NULL },
+#endif /* OK_TAR && USE_COMPRESS */
+
 #ifdef OK_ZIP
 { DE_DIR,	      "", "Package and compress",
 	   "(using zip)", "LYNXDIRED://ZIP%p",			NULL },
@@ -360,7 +383,7 @@ PRIVATE BOOLEAN remove_tagged NOARGS
     if (HTList_isEmpty(tagged))  /* should never happen */
 	return 0;
 
-    ans = HTConfirm(gettext("Remove all tagged files and directories "));
+    ans = HTConfirm(gettext("Remove all tagged files and directories?"));
 
     count = 0;
     tag = tagged;
@@ -588,10 +611,10 @@ PRIVATE BOOLEAN modify_name ARGS1(
 	/*
 	 *  Do not allow the user to also change the location at this time.
 	 */
-	if (strchr(tmpbuf, '/') != NULL) {
-	    HTAlert(gettext("Illegal character \"/\" found! Request ignored."));
+	if (LYLastPathSep(tmpbuf) != 0) {
+	    HTAlert(gettext("Illegal character (path-separator) found! Request ignored."));
 	} else if (strlen(tmpbuf) &&
-		   (cp = strrchr(testpath, '/')) != NULL) {
+		   (cp = LYLastPathSep(testpath)) != NULL) {
 	    strcpy(savepath,testpath);
 	    *(++cp) = '\0';
 	    strcpy(newpath,testpath);
@@ -657,16 +680,16 @@ PRIVATE BOOLEAN modify_location ARGS1(
 	    strcat(newpath, (tmpbuf + 1));
 	    strcpy(tmpbuf, newpath);
 	}
-	if (!LYIsPathSep(tmpbuf[0])) {
-	    if ((cp = strrchr(newpath,'/')) != NULL) {
+	if (LYisAbsPath(tmpbuf)) {
+	    strcpy(newpath,tmpbuf);
+	} else {
+	    if ((cp = LYLastPathSep(newpath)) != NULL) {
 		*++cp = '\0';
 		strcat(newpath,tmpbuf);
 	    } else {
-		HTAlert(gettext("Unexpected failure - unable to find trailing \"/\""));
+		HTAlert(gettext("Unexpected failure - unable to find trailing path separator"));
 		return 0;
 	    }
-	} else {
-	    strcpy(newpath,tmpbuf);
 	}
 
 	/*
@@ -903,7 +926,7 @@ PRIVATE BOOLEAN remove_single ARGS1(
     /*
      *	Locate the filename portion of the path.
      */
-    if ((cp = strrchr(testpath, '/')) != NULL) {
+    if ((cp = LYLastPathSep(testpath)) != NULL) {
 	++cp;
     } else {
 	cp = testpath;
@@ -913,23 +936,23 @@ PRIVATE BOOLEAN remove_single ARGS1(
 	/*** Course, it's probably broken for screen sizes other 80, too     ***/
 	if (strlen(cp) < 37) {
 	    HTSprintf0(&tmpbuf,
-		       gettext("Remove '%s' and all of its contents: "), cp);
+		       gettext("Remove '%s' and all of its contents?"), cp);
 	} else {
 	    HTSprintf0(&tmpbuf,
-		       gettext("Remove directory and all of its contents: "));
+		       gettext("Remove directory and all of its contents?"));
 	}
     } else if (S_ISREG(dir_info.st_mode)) {
 	if (strlen(cp) < 60) {
-	    HTSprintf0(&tmpbuf, gettext("Remove file '%s': "), cp);
+	    HTSprintf0(&tmpbuf, gettext("Remove file '%s'?"), cp);
 	} else {
-	    HTSprintf0(&tmpbuf, gettext("Remove file: "));
+	    HTSprintf0(&tmpbuf, gettext("Remove file?"));
 	}
 #ifdef S_IFLNK
     } else if (S_ISLNK(dir_info.st_mode)) {
 	if (strlen(cp) < 50) {
-	    HTSprintf0(&tmpbuf, gettext("Remove symbolic link '%s': "), cp);
+	    HTSprintf0(&tmpbuf, gettext("Remove symbolic link '%s'?"), cp);
 	} else {
-	    HTSprintf0(&tmpbuf, gettext("Remove symbolic link: "));
+	    HTSprintf0(&tmpbuf, gettext("Remove symbolic link?"));
 	}
 #endif
     } else {
@@ -1319,17 +1342,46 @@ PRIVATE char * DirectoryOf ARGS1(
 	char *,		pathname)
 {
     char *result = 0;
+    char *result1 = 0;
     char *leaf;
 
     StrAllocCopy(result, pathname);
     leaf = LYPathLeaf(result);
     if (leaf != result) {
 	*leaf = '\0';
-	LYTrimPathSep(result);
+	if (!LYisRootPath(result))
+	    LYTrimPathSep(result);
+	result1 = wwwName(result);
+	StrAllocCopy (result, result1);
     }
     return result;
 }
 
+#ifdef __DJGPP__
+/*  Convert filenames to acceptable 8+3 names when necessary
+*/
+PRIVATE char * LYonedot ARGS1(
+	char *,		line)
+{
+    char *dot;
+    if (pathconf (line, _PC_NAME_MAX) <= 12) {
+	for (;;) {
+	    if ((dot = strrchr(line, '.')) == 0
+	     || LYLastPathSep(dot) != 0) {
+		break;
+	    } else if (strlen(dot) == 1) {
+		*dot = 0;
+	    } else {
+		*dot = '_';
+	    }
+	}
+    }
+    return(line);
+}
+#else
+#define LYonedot(path) path
+#endif /*  __DJGPP__ */
+
 /*
  *  Perform file management operations for LYNXDIRED URL's.
  *  Attempt to be consistent.  These are (pseudo) URLs - i.e., they should
@@ -1360,6 +1412,16 @@ PUBLIC int local_dired ARGS1(
     HTUnEscape(line);	/* _file_ (not URL) syntax, for those functions
 			   that need it.  Don't forget to FREE it. */
 
+#ifdef __DJGPP__
+    if (!strncmp(line, "LYNXDIRED://", 12)) {
+	char *s;
+	int i;
+	s = strchr(&line[12], '/');
+	if (s != NULL)
+	    for(i = 0; s[i] != 0; i++)
+		s[i] = s[i+1];
+    }
+#endif /* __DJGPP__ */
     if (!strncmp(line, "LYNXDIRED://NEW_FILE", 20)) {
 	if (create_file(&line[20]) > 0)
 	    LYforce_no_cache = TRUE;
@@ -1417,7 +1479,7 @@ PUBLIC int local_dired ARGS1(
 	    LYforce_no_cache = TRUE;
     } else {
 	LYTrimPathSep(line);
-	if (strrchr(line, '/') == NULL) {
+	if (LYLastPathSep(line) == NULL) {
 	    FREE(line);
 	    return 0;
 	}
@@ -1445,21 +1507,21 @@ PUBLIC int local_dired ARGS1(
 # ifndef ARCHIVE_ONLY
 #  ifdef OK_GZIP
 	} else if (!strncmp(line, "LYNXDIRED://UNTAR_GZ", 20)) {
-#define FMT_UNTAR_GZ "%s -qdc %s | (cd %s; %s -xf -)"
+#define FMT_UNTAR_GZ "cd %s; %s -qdc %s |  %s -xf -"
 	    dirname = DirectoryOf(line+20);
-	    HTAddParam(&buffer, FMT_UNTAR_GZ, 1, GZIP_PATH);
-	    HTAddParam(&buffer, FMT_UNTAR_GZ, 2, line+20);
-	    HTAddParam(&buffer, FMT_UNTAR_GZ, 3, dirname);
+	    HTAddParam(&buffer, FMT_UNTAR_GZ, 1, dirname);
+	    HTAddParam(&buffer, FMT_UNTAR_GZ, 2, GZIP_PATH);
+	    HTAddParam(&buffer, FMT_UNTAR_GZ, 3, line+20);
 	    HTAddParam(&buffer, FMT_UNTAR_GZ, 4, TAR_PATH);
 	    HTEndParam(&buffer, FMT_UNTAR_GZ, 4);
 #  endif /* OK_GZIP */
 
 	} else if (!strncmp(line, "LYNXDIRED://UNTAR_Z", 19)) {
-#define FMT_UNTAR_Z "%s %s | (cd %s; %s -xf -)"
+#define FMT_UNTAR_Z "cd %s; %s %s |  %s -xf -"
 	    dirname = DirectoryOf(line+19);
-	    HTAddParam(&buffer, FMT_UNTAR_Z, 1, ZCAT_PATH);
-	    HTAddParam(&buffer, FMT_UNTAR_Z, 2, line+19);
-	    HTAddParam(&buffer, FMT_UNTAR_Z, 3, dirname);
+	    HTAddParam(&buffer, FMT_UNTAR_Z, 1, dirname);
+	    HTAddParam(&buffer, FMT_UNTAR_Z, 2, ZCAT_PATH);
+	    HTAddParam(&buffer, FMT_UNTAR_Z, 3, line+19);
 	    HTAddParam(&buffer, FMT_UNTAR_Z, 4, TAR_PATH);
 	    HTEndParam(&buffer, FMT_UNTAR_Z, 4);
 
@@ -1474,34 +1536,34 @@ PUBLIC int local_dired ARGS1(
 
 # ifdef OK_GZIP
 	} else if (!strncmp(line, "LYNXDIRED://TAR_GZ", 18)) {
-#define FMT_TAR_GZ "(cd %s; %s -cf - %s) | %s -qc >%s/%s.tar.gz"
+#define FMT_TAR_GZ "cd %s; %s -cf - %s | %s -qc >%s%s"
 	    dirname = DirectoryOf(line+18);
 	    HTAddParam(&buffer, FMT_TAR_GZ, 1, dirname);
 	    HTAddParam(&buffer, FMT_TAR_GZ, 2, TAR_PATH);
 	    HTAddParam(&buffer, FMT_TAR_GZ, 3, LYPathLeaf(line+18));
 	    HTAddParam(&buffer, FMT_TAR_GZ, 4, GZIP_PATH);
-	    HTAddParam(&buffer, FMT_TAR_GZ, 5, dirname);
-	    HTAddParam(&buffer, FMT_TAR_GZ, 6, LYPathLeaf(line+18));
+	    HTAddParam(&buffer, FMT_TAR_GZ, 5, LYonedot(LYPathLeaf(line+18)));
+	    HTAddParam(&buffer, FMT_TAR_GZ, 6, EXT_TAR_GZ);
 	    HTEndParam(&buffer, FMT_TAR_GZ, 6);
 # endif /* OK_GZIP */
 
 	} else if (!strncmp(line, "LYNXDIRED://TAR_Z", 17)) {
-#define FMT_TAR_Z "(cd %s; %s -cf - %s) | %s >%s/%s.tar.Z"
+#define FMT_TAR_Z "cd %s; %s -cf - %s | %s >%s%s"
 	    dirname = DirectoryOf(line+17);
 	    HTAddParam(&buffer, FMT_TAR_Z, 1, dirname);
 	    HTAddParam(&buffer, FMT_TAR_Z, 2, TAR_PATH);
 	    HTAddParam(&buffer, FMT_TAR_Z, 3, LYPathLeaf(line+17));
 	    HTAddParam(&buffer, FMT_TAR_Z, 4, COMPRESS_PATH);
-	    HTAddParam(&buffer, FMT_TAR_Z, 5, dirname);
-	    HTAddParam(&buffer, FMT_TAR_Z, 6, LYPathLeaf(line+17));
+	    HTAddParam(&buffer, FMT_TAR_Z, 5, LYonedot(LYPathLeaf(line+17)));
+	    HTAddParam(&buffer, FMT_TAR_Z, 6, EXT_TAR_Z);
 	    HTEndParam(&buffer, FMT_TAR_Z, 6);
 
 	} else if (!strncmp(line, "LYNXDIRED://TAR", 15)) {
-#define FMT_TAR "(cd %s; %s -cf %s.tar %s)"
+#define FMT_TAR "cd %s; %s -cf %s.tar %s"
 	    dirname = DirectoryOf(line+15);
 	    HTAddParam(&buffer, FMT_TAR, 1, dirname);
 	    HTAddParam(&buffer, FMT_TAR, 2, TAR_PATH);
-	    HTAddParam(&buffer, FMT_TAR, 3, LYPathLeaf(line+15));
+	    HTAddParam(&buffer, FMT_TAR, 3, LYonedot(LYPathLeaf(line+15)));
 	    HTAddParam(&buffer, FMT_TAR, 4, LYPathLeaf(line+15));
 	    HTEndParam(&buffer, FMT_TAR, 4);
 #endif /* OK_TAR */
@@ -1527,7 +1589,7 @@ PUBLIC int local_dired ARGS1(
 	    dirname = DirectoryOf(line+15);
 	    HTAddParam(&buffer, FMT_ZIP, 1, dirname);
 	    HTAddParam(&buffer, FMT_ZIP, 2, ZIP_PATH);
-	    HTAddParam(&buffer, FMT_ZIP, 3, line+15);
+	    HTAddParam(&buffer, FMT_ZIP, 3, LYonedot(LYPathLeaf(line+15)));
 	    HTAddParam(&buffer, FMT_ZIP, 4, LYPathLeaf(line+15));
 	    HTEndParam(&buffer, FMT_ZIP, 4);
 #ifndef ARCHIVE_ONLY
@@ -1756,7 +1818,7 @@ PRIVATE char *get_filename ARGS3(
     }
 
     if (no_dotfiles || !show_dotfiles) {
-	cp = strrchr(buf, '/'); /* find last slash */
+	cp = LYLastPathSep(buf); /* find last slash */
 	if (cp)
 	    cp += 1;
 	else
@@ -1889,8 +1951,10 @@ PUBLIC void add_menu_item ARGS1(
 	new->cond = DE_DIR;
     } else if (strcasecomp(str, "file") == 0) {
 	new->cond = DE_FILE;
+#ifdef S_IFLNK
     } else if (strcasecomp(str, "link") == 0) {
 	new->cond = DE_SYMLINK;
+#endif /* S_IFLNK */
     }
 
     /*
@@ -1962,7 +2026,7 @@ PRIVATE char * render_item ARGS6(
 			*BP_INC = *cp++;
 		    break;
 		case 'f':
-		    cp = strrchr(path, '/');
+		    cp = LYLastPathSep(path);
 		    if (cp)
 			cp++;
 		    else
@@ -2020,7 +2084,7 @@ PRIVATE char * render_item ARGS6(
 #endif /* DIRED_SUPPORT */
 
 /*
- *  Execute DIRED command.
+ *  Execute DIRED command, return -1 or 0 on failure, 1 success.
  */
 PRIVATE int LYExecv ARGS3(
 	char *, 	path,
@@ -2032,7 +2096,16 @@ PRIVATE int LYExecv ARGS3(
     return(0);
 #else
     int rc;
+    int n;
     char *tmpbuf = 0;
+#ifdef __DJGPP__
+    stop_curses();
+    HTSprintf(&tmpbuf, "%s", path);
+    for (n = 1; argv[n] != 0; n++)
+	HTSprintf(&tmpbuf, " %s", argv[n]);
+    HTSprintf(&tmpbuf, "\n");
+    rc = LYSystem(tmpbuf) ? 0 : 1;
+#else
     pid_t pid;
 #ifdef HAVE_TYPE_UNIONWAIT
     union wait wstatus;
@@ -2041,7 +2114,6 @@ PRIVATE int LYExecv ARGS3(
 #endif
 
     if (TRACE) {
-	int n;
 	CTRACE(tfp, "LYExecv path='%s'\n", path);
 	for (n = 0; argv[n] != 0; n++)
 	    CTRACE(tfp, "argv[%d] = '%s'\n", n, argv[n]);
@@ -2049,7 +2121,7 @@ PRIVATE int LYExecv ARGS3(
 
     rc = 1;		/* It will work */
     stop_curses();
-    pid = fork();	/* fork and execute rm */
+    pid = fork();	/* fork and execute command */
     switch (pid) {
 	case -1:
 	    HTSprintf(&tmpbuf, gettext("Unable to %s due to system error!"), msg);
@@ -2086,6 +2158,7 @@ PRIVATE int LYExecv ARGS3(
 		rc = 0;
 	    }
     }
+#endif /* __DJGPP__ */
 
     if (rc == 0) {
 	/*
diff --git a/src/LYMain.c b/src/LYMain.c
index cc85ece3..e422853b 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -718,6 +718,7 @@ PUBLIC int main ARGS2(
     atexit(reset_break);
     dbug_init();
     sock_init();
+    __system_flags = 0x501D;
 #endif
 
     /*
@@ -1841,7 +1842,7 @@ PUBLIC int main ARGS2(
 	if (persistent_cookies)
 	    LYStoreCookies(LYCookieFile);
 #endif /* EXP_PERSISTENT_COOKIES */
-	cleanup_files();
+	cleanup_files();	/* if someone starts with LYNXfoo: page */
 	exit_immediately(status);
     } else {
 	/*
@@ -1911,7 +1912,7 @@ PUBLIC void reload_read_cfg NOARGS
      *  that gets automatically set for -anonymous and -validate
      *  (and whether it applies for -anonymous can be made installer-
      *  configurable in the usual way at the bottom of userdefs.h). - kw
-     *  
+     *
      */
     if (no_option_save) {
 	/* current logic requires(?) that saving user preferences is
@@ -1930,7 +1931,7 @@ PUBLIC void reload_read_cfg NOARGS
 
     {
 	/* set few safe flags: */
-#ifdef PERSISTENT_COOKIES
+#ifdef EXP_PERSISTENT_COOKIES
 	BOOLEAN persistent_cookies_flag = persistent_cookies;
 	char * LYCookieFile_flag = LYCookieFile;
 #endif
@@ -1968,7 +1969,7 @@ PUBLIC void reload_read_cfg NOARGS
 		 * a major problem: file paths
 		 * like lynx_save_space, LYCookieFile etc.
 		 */
-#ifdef PERSISTENT_COOKIES
+#ifdef EXP_PERSISTENT_COOKIES
 	/* restore old settings */
 	 if (persistent_cookies != persistent_cookies_flag) {
 	     persistent_cookies = persistent_cookies_flag;
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index f3e5835e..51cfb467 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -3500,7 +3500,7 @@ new_cmd:  /*
 		    psrc_view = FALSE;	/* we get here if link is not internal */
 #endif
 
-#ifdef DIRED_SUPPORT
+#if defined(DIRED_SUPPORT) && !defined(__DJGPP__)
 		    if (lynx_edit_mode) {
 			  HTuncache_current_document();
 			  /*
@@ -3511,7 +3511,7 @@ new_cmd:  /*
 			  HTUnEscapeSome(newdoc.address,"/");
 			  strip_trailing_slash(newdoc.address);
 		    }
-#endif /* DIRED_SUPPORT */
+#endif /* DIRED_SUPPORT  && !__DJGPP__ */
 		    if (!strncmp(curdoc.address, "LYNXCOOKIE:", 11)) {
 			HTuncache_current_document();
 		    }
@@ -5172,6 +5172,9 @@ if (!LYUseFormsOptions) {
 	    /*
 	     *	Don't do if not allowed or already viewing the menu.
 	     */
+#ifdef __DJGPP__
+	    lynx_edit_mode = TRUE;
+#endif /* __DJGPP__ */
 	    if (lynx_edit_mode && !no_dired_support &&
 		strcmp(curdoc.address, LYDiredFileURL) &&
 		strcmp((curdoc.title ? curdoc.title : ""),
@@ -6435,19 +6438,20 @@ PRIVATE void exit_immediately_with_error_message ARGS2(
     if (state == NOT_FOUND)
     {
 	HTSprintf0(&buf, "%s\n%s %s\n",
-		   buf2,
+		   buf2 ? buf2 : "",
 		   gettext("lynx: Can't access startfile"),
 		   /*
 		    * hack: if we fail in HTAccess.c
 		    * avoid duplicating URL, oh.
 		    */
-		   strstr(buf2, gettext("Can't Access")) ? "" : startfile);
+		   (buf2 && strstr(buf2, gettext("Can't Access"))) ?
+							       "" : startfile);
     }
 
     if (state == NULLFILE)
     {
 	HTSprintf0(&buf, "%s\n%s\n%s\n",
-		   buf2,
+		   buf2 ? buf2 : "",
 		   gettext("lynx: Start file could not be found or is not text/html or text/plain"),
 		   gettext("      Exiting..."));
     }
diff --git a/src/LYOptions.c b/src/LYOptions.c
index 06c7663f..560b29e8 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -158,9 +158,9 @@ PRIVATE void addlbl ARGS1(CONST char *, text)
 
 PUBLIC void LYoptions NOARGS
 {
-#ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
+#ifdef ENABLE_OPTS_CHANGE_EXEC
     int itmp;
-#endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
     int response, ch;
     /*
      *	If the user changes the display we need memory to put it in.
@@ -176,7 +176,7 @@ PUBLIC void LYoptions NOARGS
     BOOL use_assume_charset, old_use_assume_charset;
 
 #ifdef DIRED_SUPPORT
-#ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
+#ifdef ENABLE_OPTS_CHANGE_EXEC
     if (LYlines < 24) {
 	HTAlert(OPTION_SCREEN_NEEDS_24);
 	return;
@@ -186,9 +186,9 @@ PUBLIC void LYoptions NOARGS
 	HTAlert(OPTION_SCREEN_NEEDS_23);
 	return;
     }
-#endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
 #else
-#ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
+#ifdef ENABLE_OPTS_CHANGE_EXEC
     if (LYlines < 23) {
 	HTAlert(OPTION_SCREEN_NEEDS_23);
 	return;
@@ -198,7 +198,7 @@ PUBLIC void LYoptions NOARGS
 	HTAlert(OPTION_SCREEN_NEEDS_22);
 	return;
     }
-#endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
 #endif /* DIRED_SUPPORT */
 
     term_options = FALSE;
@@ -422,7 +422,7 @@ draw_options:
     addlbl("user (A)gent                 : ");
     addstr((LYUserAgent && *LYUserAgent) ? LYUserAgent : "NONE");
 
-#ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
+#ifdef ENABLE_OPTS_CHANGE_EXEC
     move(L_Exec, 5);
     addlbl("local e(X)ecution links      : ");
 #ifndef NEVER_ALLOW_REMOTE_EXEC
@@ -433,7 +433,7 @@ draw_options:
     addstr(local_exec_on_local_files ? "FOR LOCAL FILES ONLY" :
 				       "ALWAYS OFF          ");
 #endif /* !NEVER_ALLOW_REMOTE_EXEC */
-#endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
 
     move(LYlines-3, 2);
     addstr(SELECT_SEGMENT);
@@ -1594,7 +1594,7 @@ draw_options:
 		response = ' ';
 		break;
 
-#ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
+#ifdef ENABLE_OPTS_CHANGE_EXEC
 	    case 'x':	/* Change local exec restriction. */
 	    case 'X':
 		if (exec_frozen && !LYSelectPopups) {
@@ -1634,7 +1634,8 @@ draw_options:
 		    itmp = popup_choice(itmp,
 					L_Exec, -1,
 					choices,
-					0, (exec_frozen ? TRUE : FALSE));
+					0, (exec_frozen ? TRUE : FALSE),
+					FALSE);
 #if defined(VMS) || defined(USE_SLANG)
 		    move(L_Exec, COL_OPTION_VALUES);
 		    clrtoeol();
@@ -1678,7 +1679,7 @@ draw_options:
 #endif /* !VMS || USE_SLANG */
 		}
 		break;
-#endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
 
 	    case '>':	/* Save current options to RC file. */
 		if (!no_option_save) {
@@ -3177,8 +3178,7 @@ restore_popup_statusline:
     }
     FREE(popup_status_msg);
 #ifndef USE_SLANG
-    /* added touchline() - kw 19990513 */
-    touchline(stdscr, top, bottom - top);
+    touchwin(stdscr);
     delwin(form_window);
 #ifdef NCURSES
     LYsubwindow(0);
@@ -3246,7 +3246,7 @@ static char * x_display_string		= "display";
 static char * editor_string		= "editor";
 static char * emacs_keys_string		= "emacs_keys";
 
-#ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
+#ifdef ENABLE_OPTS_CHANGE_EXEC
 #define EXEC_ALWAYS 2
 #define EXEC_LOCAL  1
 #define EXEC_NEVER  0
@@ -3258,7 +3258,7 @@ static OptValues exec_links_values[]	= {
 	{ EXEC_ALWAYS,	"ALWAYS ON",		"ALWAYS ON" },
 #endif
 	{ 0, 0, 0 }};
-#endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
 
 #ifdef EXP_KEYBOARD_LAYOUT
 static char * kblayout_string		= "kblayout";
@@ -3634,7 +3634,7 @@ PUBLIC int postoptions ARGS1(
 	}
 
 	/* Execution links: SELECT */
-#ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
+#ifdef ENABLE_OPTS_CHANGE_EXEC
 	if (!strcmp(data[i].tag, exec_links_string)
 	 && GetOptValues(exec_links_values, data[i].value, &code)) {
 #ifndef NEVER_ALLOW_REMOTE_EXEC
@@ -3642,7 +3642,7 @@ PUBLIC int postoptions ARGS1(
 #endif /* !NEVER_ALLOW_REMOTE_EXEC */
 	    local_exec_on_local_files = (code == EXEC_LOCAL);
 	}
-#endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
 
 	/* Keypad Mode: SELECT */
 	if (!strcmp(data[i].tag, keypad_mode_string)) {
@@ -4432,7 +4432,7 @@ PRIVATE int gen_options ARGS1(
     }
 
     /* Execution links: SELECT */
-#ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
+#ifdef ENABLE_OPTS_CHANGE_EXEC
     PutLabel(fp0, gettext("Execution links"));
     BeginSelect(fp0, exec_links_string);
 #ifndef NEVER_ALLOW_REMOTE_EXEC
@@ -4449,7 +4449,7 @@ PRIVATE int gen_options ARGS1(
 	       exec_links_values);
 #endif /* !NEVER_ALLOW_REMOTE_EXEC */
     EndSelect(fp0);
-#endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
 
     /*
      * Headers transferred to remote server
diff --git a/src/LYShowInfo.c b/src/LYShowInfo.c
index e324623f..56340c16 100644
--- a/src/LYShowInfo.c
+++ b/src/LYShowInfo.c
@@ -150,7 +150,7 @@ PUBLIC int showinfo ARGS4(
 #endif
 	    name = HTAA_UidToName(dir_info.st_uid);
 	    if (*name)
-		fprintf(fp0, "   <em>%s</em>  %s\n", gettext("Name of owner"), name);
+		fprintf(fp0, "   <em>%s</em>  %s\n", gettext("Name of owner:"), name);
 	    name = HTAA_GidToName (dir_info.st_gid);
 	    if (*name)
 		fprintf(fp0, "      <em>%s</em>  %s\n", gettext("Group name:"), name);
@@ -162,13 +162,13 @@ PUBLIC int showinfo ARGS4(
 	     *	Include date and time information.
 	     */
 	    cp = ctime(&dir_info.st_ctime);
-	    fprintf(fp0, "   <em>%s</em>  %s", cp, gettext("Creation date:"));
+	    fprintf(fp0, "   <em>%s</em>  %s", gettext("Creation date:"), cp);
 
 	    cp = ctime(&dir_info.st_mtime);
-	    fprintf(fp0, "   <em>%s</em>  %s", cp, gettext("Last modified:"));
+	    fprintf(fp0, "   <em>%s</em>  %s", gettext("Last modified:"), cp);
 
 	    cp = ctime(&dir_info.st_atime);
-	    fprintf(fp0, "   <em>%s</em>  %s\n", cp, gettext("Last accessed:"));
+	    fprintf(fp0, "   <em>%s</em>  %s\n", gettext("Last accessed:"), cp);
 
 	    fprintf(fp0, "   %s\n", gettext("Access Permissions"));
 	    fprintf(fp0, "      <em>%s</em>  ", gettext("Owner:"));
@@ -323,7 +323,7 @@ PUBLIC int showinfo ARGS4(
 		  HTisDocumentSource() ?
 				  gettext("source") : gettext("normal")),
 		 (doc->safe ? gettext(", safe") : ""),
-		 (doc->internal_link ? gettext(", internal link") : "")
+		 (doc->internal_link ? gettext(", via internal link") : "")
 	    );
 #ifdef ADVANCED_INFO
     if (LYInfoAdvanced) {
diff --git a/src/LYStrings.c b/src/LYStrings.c
index 4e736f4f..5fa74a85 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -3448,3 +3448,98 @@ PUBLIC char *LYSafeGets ARGS2(
 	*src = result;
     return result;
 }
+
+#ifdef EXP_FILE_UPLOAD
+static char basis_64[] =
+   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+#define B64_LINE       76
+
+#if 0
+#define XX 255	/* illegal base64 char */
+#define EQ 254	/* padding */
+static unsigned char index_64[256] = {
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,62, XX,XX,XX,63,
+    52,53,54,55, 56,57,58,59, 60,61,XX,XX, XX,EQ,XX,XX,
+    XX, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
+    15,16,17,18, 19,20,21,22, 23,24,25,XX, XX,XX,XX,XX,
+    XX,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
+    41,42,43,44, 45,46,47,48, 49,50,51,XX, XX,XX,XX,XX,
+
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+};
+
+#define GETC(str,len)  (len > 0 ? len--,*str++ : EOF)
+#define INVALID_B64(c) (index_64[(unsigned char)c] == XX)
+#endif
+
+PUBLIC void base64_encode ARGS3(
+    char *,	dest,
+    char *,	src,
+    int,	len)
+{
+    int rlen;   /* length of result string */
+    unsigned char c1, c2, c3;
+    char *eol, *r, *str;
+    int eollen;
+    int chunk;
+
+    str = src;
+    eol = "\n";
+    eollen = 1;
+
+    /* calculate the length of the result */
+    rlen = (len+2) / 3 * 4;	/* encoded bytes */
+    if (rlen) {
+	/* add space for EOL */
+	rlen += ((rlen-1) / B64_LINE + 1) * eollen;
+    }
+
+    /* allocate a result buffer */
+    r = dest;
+
+    /* encode */
+    for (chunk=0; len > 0; len -= 3, chunk++) {
+	if (chunk == (B64_LINE/4)) {
+	    char *c = eol;
+	    char *e = eol + eollen;
+	    while (c < e)
+		*r++ = *c++;
+	    chunk = 0;
+	}
+	c1 = *str++;
+	c2 = *str++;
+	*r++ = basis_64[c1>>2];
+	*r++ = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
+	if (len > 2) {
+	    c3 = *str++;
+	    *r++ = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
+	    *r++ = basis_64[c3 & 0x3F];
+	} else if (len == 2) {
+	    *r++ = basis_64[(c2 & 0xF) << 2];
+	    *r++ = '=';
+	} else { /* len == 1 */
+	    *r++ = '=';
+	    *r++ = '=';
+	}
+    }
+    if (rlen) {
+	/* append eol to the result string */
+	char *c = eol;
+	char *e = eol + eollen;
+	while (c < e)
+	    *r++ = *c++;
+    }
+    *r = '\0';  /* every SV in perl should be NUL-terminated */
+}
+
+#endif /* EXP_FILE_UPLOAD */
diff --git a/src/LYStrings.h b/src/LYStrings.h
index 4333b760..33e38a67 100644
--- a/src/LYStrings.h
+++ b/src/LYStrings.h
@@ -77,6 +77,10 @@ extern char * SNACat PARAMS((
 
 extern char *LYSafeGets PARAMS((char ** src, FILE * fp));
 
+#ifdef EXP_FILE_UPLOAD
+extern void base64_encode PARAMS((char * dest, char * src, int len));
+#endif
+
 /* values for LYgetch */
 /* The following are lynxkeycodes, not to be confused with
    lynxactioncodes (LYK_*) to which they are often mapped.
diff --git a/src/LYUtils.c b/src/LYUtils.c
index f2ecb7fc..157cef47 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -2326,6 +2326,41 @@ PUBLIC int HTCheckForInterrupt NOARGS
 }
 
 /*
+ * Check if the given filename looks like it's an absolute pathname, i.e.,
+ * references a directory.
+ */
+PUBLIC BOOLEAN LYisAbsPath ARGS1(
+	char *,		path)
+{
+    BOOLEAN result;
+#ifdef DOSPATH
+    result = (LYIsPathSep(path[0])
+     || (isalpha(path[0])
+      && (path[1] == ':')
+       && LYIsPathSep(path[2])));
+#else
+    result = (LYIsPathSep(path[0]));
+#endif /* __DJGPP__ */
+    return result;
+}
+
+/*
+ * Check if the given filename is the root path, e.g., "/" on Unix.
+ */
+PUBLIC BOOLEAN LYisRootPath ARGS1(
+	char *,		path)
+{
+#ifdef DOSPATH
+    if (strlen(path) == 3
+     && isalpha(path[0])
+     && path[1] == ':'
+     && LYIsPathSep(path[2]))
+    	return TRUE;
+#endif
+    return ((strlen(path) == 1) && LYIsPathSep(path[0]));
+}
+
+/*
  *  A file URL for a remote host is an obsolete ftp URL.
  *  Return YES only if we're certain it's a local file. - FM
  */
@@ -4210,7 +4245,7 @@ have_VMS_URL:
 	    /*
 	     *	On Unix, convert '~' to Home_Dir().
 	     */
-	    StrAllocCat(*AllocatedString, Home_Dir());
+	    StrAllocCat(*AllocatedString, wwwName(Home_Dir()));
 	    if ((cp = strchr(old_string, '/')) != NULL) {
 		/*
 		 *  Append rest of path, if present, skipping "user" if
@@ -4415,11 +4450,7 @@ have_VMS_URL:
 	     *	Has a Home_Dir() reference.  Handle it
 	     *	as if there weren't a lead slash. - FM
 	     */
-#ifdef VMS
-	    StrAllocCat(*AllocatedString, HTVMS_wwwName((char *)Home_Dir()));
-#else
-	    StrAllocCat(*AllocatedString, Home_Dir());
-#endif /* VMS */
+	    StrAllocCat(*AllocatedString, wwwName(Home_Dir()));
 	    if ((cp = strchr((old_string + 1), '/')) != NULL) {
 		/*
 		 *  Append rest of path, if present, skipping "user" if
@@ -6490,7 +6521,7 @@ PUBLIC void LYAddPathSep ARGS1(
  * to it.  This only applies to local filesystems.
  */
 PUBLIC void LYAddPathSep0 ARGS1(
-	char *,	path)
+	char *,		path)
 {
     size_t len;
 
@@ -6502,6 +6533,22 @@ PUBLIC void LYAddPathSep0 ARGS1(
 }
 
 /*
+ * Check if a given string contains a path separator
+ */
+PUBLIC char * LYLastPathSep ARGS1(
+	char *,		path)
+{
+    char *result;
+#ifdef DOSPATH
+    if ((result = strrchr(path, '\\')) == 0)
+	result = strrchr(path, '/');
+#else
+    result = strrchr(path, '/');
+#endif
+    return result;
+}
+
+/*
  * Trim a trailing path-separator to avoid confusing other programs when we concatenate
  * to it.  This only applies to HTML paths.
  */
@@ -6576,7 +6623,7 @@ PUBLIC int LYCopyFile ARGS2(
 }
 
 /*
- * Invoke a shell command
+ * Invoke a shell command, return nonzero on error.
  */
 PUBLIC int LYSystem ARGS1(
 	char *,	command)
diff --git a/src/LYUtils.h b/src/LYUtils.h
index 482adc97..8a8608f3 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -56,11 +56,14 @@ extern BOOLEAN LYAddSchemeForURL PARAMS((char **AllocatedString, char *default_s
 extern BOOLEAN LYCachedTemp PARAMS((char *result, char **cached));
 extern BOOLEAN LYCanDoHEAD PARAMS((CONST char *address));
 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));
 extern BOOLEAN LYValidateFilename PARAMS((char * result, char * given));
+extern BOOLEAN LYisAbsPath PARAMS((char *path));
 extern BOOLEAN LYisLocalAlias PARAMS((char *filename));
 extern BOOLEAN LYisLocalFile PARAMS((char *filename));
 extern BOOLEAN LYisLocalHost PARAMS((char *filename));
+extern BOOLEAN LYisRootPath PARAMS((char *path));
 extern BOOLEAN inlocaldomain NOPARAMS;
 extern CONST char *Home_Dir NOPARAMS;
 extern FILE *LYAppendToTxtFile PARAMS((char * name));
@@ -70,6 +73,7 @@ extern FILE *LYOpenScratch PARAMS((char *result, CONST char *prefix));
 extern FILE *LYOpenTemp PARAMS((char *result, CONST char *suffix, CONST char *mode));
 extern FILE *LYReopenTemp PARAMS((char *name));
 extern char *Current_Dir PARAMS((char * pathname));
+extern char *LYLastPathSep PARAMS((char *path));
 extern char *LYPathLeaf PARAMS((char * pathname));
 extern char *LYSysShell NOPARAMS;
 extern char *LYgetXDisplay NOPARAMS;
@@ -83,8 +87,6 @@ extern int LYOpenInternalPage PARAMS((FILE **fp0, char **newfile));
 extern int LYSystem PARAMS((char *command));
 extern int LYValidateOutput PARAMS((char * filename));
 extern int is_url PARAMS((char *filename));
-extern void LYFixCursesOn PARAMS((CONST char* reason));
-extern BOOLEAN LYFixCursesOnForAccess PARAMS((CONST char* addr, CONST char* physical));
 extern int number2arrows PARAMS((int number));
 extern time_t LYmktime PARAMS((char *string, BOOL absolute));
 extern void BeginInternalPage PARAMS((FILE *fp0, char *Title, char *HelpURL));
@@ -105,6 +107,7 @@ extern void LYConvertToURL PARAMS((char **AllocatedString, int fixit));
 extern void LYDoCSI PARAMS((char *url, CONST char *comment, char **csi));
 extern void LYEnsureAbsoluteURL PARAMS((char **href, CONST char *name, int fixit));
 extern void LYFakeZap PARAMS((BOOL set));
+extern void LYFixCursesOn PARAMS((CONST char* reason));
 extern void LYLocalFileToURL PARAMS((char **target, CONST char *source));
 extern void LYLocalhostAliases_free NOPARAMS;
 extern void LYRemoveTemp PARAMS((char *name));
diff --git a/src/LYrcFile.c b/src/LYrcFile.c
index 2a81edd6..efe6b22e 100644
--- a/src/LYrcFile.c
+++ b/src/LYrcFile.c
@@ -480,7 +480,7 @@ PUBLIC void read_rc NOPARAMS
 #endif /* DISP_PARTIAL */
 #endif /* NOTUSED */
 
-#ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
+#ifdef ENABLE_OPTS_CHANGE_EXEC
 	/*
 	 *  Local execution mode - all links.
 	 */
@@ -501,7 +501,7 @@ PUBLIC void read_rc NOPARAMS
 		local_exec_on_local_files = TRUE;
 	    else
 		local_exec_on_local_files=FALSE;
-#endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
 
 	} else if (FIND_KEYWORD(cp, "verbose_images")) {
 	   cp = SkipEquals(cp);
diff --git a/src/makefile.dsl b/src/makefile.dsl
index 0be75cd2..326fa90c 100644
--- a/src/makefile.dsl
+++ b/src/makefile.dsl
@@ -11,8 +11,12 @@ LYStyle.o LYHash.o LYPrettySrc.o
 

 CFLAGS= $(MCFLAGS) $(INTLFLAGS) -I. -I.. $(SLANGINC)

 

+# comment this line to suppress DIRED support

+DIRED_DEFS = -DDIRED_SUPPORT -DOK_UUDECODE -DOK_TAR -DOK_GZIP -DOK_ZIP

+

 CC = gcc

 MCFLAGS = -O2 -DDISP_PARTIAL -DUSE_ZLIB -DUSE_EXTERNALS \

+$(DIRED_DEFS) \

 -DSOURCE_CACHE -DUSE_PSRC \

 -DUSE_SLANG -DDJGPP_KEYHANDLER -DACCESS_AUTH -DNO_CUSERID \

 -DNOUSERS -DDOSPATH -DNO_TTYTYPE -DNO_UTMP -I../WWW/Library/Implementation \