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.c114
-rw-r--r--src/GridText.h8
-rw-r--r--src/HTAlert.c42
-rw-r--r--src/HTAlert.h1
-rw-r--r--src/HTFWriter.c6
-rw-r--r--src/HTForms.h4
-rw-r--r--src/HTML.c30
-rw-r--r--src/LYBookmark.c16
-rw-r--r--src/LYCgi.c7
-rw-r--r--src/LYCharSets.c2
-rw-r--r--src/LYCharUtils.c49
-rw-r--r--src/LYClean.c11
-rw-r--r--src/LYCookie.c68
-rw-r--r--src/LYCurses.c92
-rw-r--r--src/LYCurses.h26
-rw-r--r--src/LYDownload.c32
-rw-r--r--src/LYEdit.c31
-rw-r--r--src/LYExtern.c10
-rw-r--r--src/LYForms.c6
-rw-r--r--src/LYGetFile.c58
-rw-r--r--src/LYGetFile.h4
-rw-r--r--src/LYGlobalDefs.h5
-rw-r--r--src/LYHistory.c240
-rw-r--r--src/LYHistory.h18
-rw-r--r--src/LYJump.c122
-rw-r--r--src/LYKeymap.c15
-rw-r--r--src/LYList.c10
-rw-r--r--src/LYList.h2
-rw-r--r--src/LYLocal.c52
-rw-r--r--src/LYLocal.h10
-rw-r--r--src/LYMail.c14
-rw-r--r--src/LYMain.c198
-rw-r--r--src/LYMainLoop.c819
-rw-r--r--src/LYMap.c4
-rw-r--r--src/LYNews.c7
-rw-r--r--src/LYOptions.c37
-rw-r--r--src/LYOptions.h2
-rw-r--r--src/LYPrint.c47
-rw-r--r--src/LYPrint.h2
-rw-r--r--src/LYReadCFG.c179
-rw-r--r--src/LYReadCFG.h5
-rw-r--r--src/LYSearch.c2
-rw-r--r--src/LYSearch.h2
-rw-r--r--src/LYShowInfo.c4
-rw-r--r--src/LYShowInfo.h2
-rw-r--r--src/LYStrings.c102
-rw-r--r--src/LYStrings.h6
-rw-r--r--src/LYStructs.h38
-rw-r--r--src/LYStyle.c51
-rw-r--r--src/LYTraversal.c2
-rw-r--r--src/LYUpload.c4
-rw-r--r--src/LYUtils.c504
-rw-r--r--src/LYUtils.h182
-rw-r--r--src/LYrcFile.c13
-rw-r--r--src/LYrcFile.h1
-rw-r--r--src/UCAux.c5
-rw-r--r--src/Xsystem.c20
-rw-r--r--src/chrtrans/makefile.bcb8
-rw-r--r--src/chrtrans/makefile.msc2
-rw-r--r--src/makefile.in2
60 files changed, 1795 insertions, 1560 deletions
diff --git a/src/GridText.c b/src/GridText.c
index 4787541a..a76c7faa 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -1318,14 +1318,14 @@ PRIVATE int display_line ARGS4(
 		} else {
 		    inunderline = YES;
 		    if (!intarget) {
-#if (defined(DOSPATH) || defined(WIN_EX)) && !defined(USE_SLANG)
+#if defined(PDCURSES)
 			if (LYShowColor == SHOW_COLOR_NEVER)
 			    start_bold();
 			else
 			    start_underline();
 #else
 			start_underline();
-#endif	/* DOSPATH ... */
+#endif	/* PDCURSES */
 		    }
 		}
 		break;
@@ -1337,14 +1337,14 @@ PRIVATE int display_line ARGS4(
 		} else {
 		    inunderline = NO;
 		    if (!intarget) {
-#if (defined(DOSPATH) || defined(WIN_EX)) && !defined(USE_SLANG)
+#if defined(PDCURSES)
 		    if (LYShowColor == SHOW_COLOR_NEVER)
 			stop_bold();
 		    else
 			stop_underline();
 #else
 		    stop_underline();
-#endif	/* DOSPATH ... */
+#endif	/* PDCURSES */
 		    }
 		}
 		break;
@@ -1366,6 +1366,9 @@ PRIVATE int display_line ARGS4(
 		if (!dump_output_immediately) {
 		    LYaddch('+');
 		    i++;
+#if defined(SHOW_WHEREIS_TARGETS) && !defined(USE_COLOR_STYLE)
+		    i_after_tgt++;
+#endif
 		}
 		break;
 
@@ -1621,11 +1624,9 @@ PRIVATE void display_title ARGS1(
 	LYmove(0, i);
     } else {
 	/*
-	 *  Note that this truncation is not taking into
-	 *  account the possibility that multibyte
-	 *  characters might be present. -FM
+	 *  Truncation takes into account the possibility that
+	 *  multibyte characters might be present. -HS (H. Senshu)
 	 */
-#ifdef SH_EX	/* 1999/06/15 (Tue) 10:17:28 */
 	int last;
 	last = (int)strlen(percent) + CHAR_WIDTH;
 	if (limit - 3 >= last) {
@@ -1635,10 +1636,6 @@ PRIVATE void display_title ARGS1(
 	} else {
 	    title[(limit - 1) - last] = '\0';
 	}
-#else
-	if ((i = ((limit - 2) - strlen(percent)) - CHAR_WIDTH) >= 0)
-	    title[i] = '\0';
-#endif
 	LYmove(0, CHAR_WIDTH);
     }
     LYaddstr(title);
@@ -3118,7 +3115,7 @@ PRIVATE void split_line ARGS2(
 		    CTRACE_SPLITLINE((tfp, "anchor %d: no relocation", n));
 		    if (end > s_post) {
 			CTRACE_SPLITLINE((tfp, " of the start.\n"));
-			a->extent += -(TailTrim + HeadTrim) - SpecialAttrChars;
+			a->extent += -(TailTrim + HeadTrim) + SpecialAttrChars;
 		    } else {
 			CTRACE_SPLITLINE((tfp, ", cut the end.\n"));
 			a->extent = s_pre - start;
@@ -6975,7 +6972,7 @@ PUBLIC BOOL HText_select ARGS1(
  *  (memory cached) text. -FM
  */
 PUBLIC BOOL HText_POSTReplyLoaded ARGS1(
-	document *,	doc)
+	DocInfo *,	doc)
 {
     HText *text = NULL;
     HTList *cur = loaded_texts;
@@ -7019,21 +7016,21 @@ PUBLIC BOOL HTFindPoundSelector ARGS1(
 {
     TextAnchor * a;
 
-    for (a=HTMainText->first_anchor; a; a=a->next) {
+    for (a = HTMainText->first_anchor; a != 0; a = a->next) {
 
-	if (a->anchor && a->anchor->tag)
+	if (a->anchor && a->anchor->tag) {
 	    if (!strcmp(a->anchor->tag, selector)) {
 
 		www_search_result = a->line_num+1;
 
-		CTRACE((tfp,
-		       "HText: Selecting anchor [%d] at line %d\n",
-				     a->number, www_search_result));
+		CTRACE((tfp, "FindPound: Selecting anchor [%d] at line %d\n",
+			     a->number, www_search_result));
 		if (!strcmp(selector, LYToolbarName)) {
 		    --www_search_result;
 		}
 		return(YES);
 	    }
+	}
     }
 
     return(NO);
@@ -7068,9 +7065,8 @@ PUBLIC BOOL HText_selectAnchor ARGS2(
 
     {
 	 int l = a->line_num;
-	 CTRACE((tfp,
-	    "HText: Selecting anchor [%d] at line %d\n",
-	    a->number, l));
+	 CTRACE((tfp, "HText: Selecting anchor [%d] at line %d\n",
+		      a->number, l));
 
 	if ( !text->stale &&
 	     (l >= text->top_of_screen) &&
@@ -7247,7 +7243,7 @@ PUBLIC void HTAddSearchQuery ARGS1(
 }
 
 PUBLIC int do_www_search ARGS1(
-	document *,	doc)
+	DocInfo *,	doc)
 {
     char searchstring[256], temp[256], *cp, *tmpaddress = NULL;
     int ch, recall;
@@ -7641,7 +7637,7 @@ PUBLIC void print_crawl_to_fd ARGS3(
 }
 
 PRIVATE void adjust_search_result ARGS3(
-    document *,	doc,
+    DocInfo *,	doc,
     int,	tentative_result,
     int,	start_line)
 {
@@ -7853,7 +7849,7 @@ PRIVATE TextAnchor *get_prev_anchor ARGS1(
 
 PRIVATE int www_search_forward ARGS5(
 	int,		start_line,
-	document *,	doc,
+	DocInfo *,	doc,
 	char *,		target,
 	HTLine *,	line,
 	int,		count)
@@ -7896,7 +7892,7 @@ PRIVATE int www_search_forward ARGS5(
 
 PRIVATE int www_search_backward ARGS5(
 	int,		start_line,
-	document *,	doc,
+	DocInfo *,	doc,
 	char *,		target,
 	HTLine *,	line,
 	int,		count)
@@ -7939,7 +7935,7 @@ PRIVATE int www_search_backward ARGS5(
 
 PUBLIC void www_user_search ARGS4(
 	int,		start_line,
-	document *,	doc,
+	DocInfo *,	doc,
 	char *,		target,
 	int,		direction)
 {
@@ -7984,7 +7980,7 @@ PUBLIC void user_message ARGS2(
 	return;
     }
 
-    HTSprintf0(&temp, message, (argument == 0) ? "" : argument);
+    HTSprintf0(&temp, message, NonNull(argument));
 
     statusline(temp);
 
@@ -8717,7 +8713,7 @@ PUBLIC void HText_beginForm ARGS5(
      *  Check the ACTION. -FM
      */
     if (action != NULL) {
-	if (!strncmp(action, "mailto:", 7)) {
+	if (isMAILTO_URL(action)) {
 	    HTFormMethod = URL_MAIL_METHOD;
 	}
 	StrAllocCopy(HTFormAction, action);
@@ -8782,11 +8778,11 @@ PUBLIC void HText_beginForm ARGS5(
     CTRACE((tfp, "BeginForm: action:%s Method:%d%s%s%s%s%s%s\n",
 		HTFormAction, HTFormMethod,
 		(HTFormTitle ? " Title:" : ""),
-		(HTFormTitle ? HTFormTitle : ""),
+		NonNull(HTFormTitle),
 		(HTFormEnctype ? " Enctype:" : ""),
-		(HTFormEnctype ? HTFormEnctype : ""),
+		NonNull(HTFormEnctype),
 		(HTFormAcceptCharset ? " Accept-charset:" : ""),
-		(HTFormAcceptCharset ? HTFormAcceptCharset : "")));
+		NonNull(HTFormAcceptCharset)));
 }
 
 PUBLIC void HText_endForm ARGS1(
@@ -9177,7 +9173,7 @@ PUBLIC char * HText_setLastOptionValue ARGS7(
 	    last_input->value_cs          = new_ptr->value_cs;
 	} else {
 	    int newlen = strlen(new_ptr->name);
-	    int curlen = strlen(HTCurSelectedOptionValue);
+	    int curlen = HTCurSelectedOptionValue ? strlen(HTCurSelectedOptionValue) : 0;
 		/*
 		 *  Make the selected Option Value as long as
 		 *  the longest option.
@@ -9707,7 +9703,7 @@ PUBLIC int HText_beginInput ARGS3(
 
     CTRACE((tfp, "Input link: name=%s\nvalue=%s\nsize=%d\n",
 			f->name,
-			((f->value != NULL) ? f->value : ""),
+			NonNull(f->value),
 			f->size));
     CTRACE((tfp, "Input link: name_cs=%d \"%s\" (from %d \"%s\")\n",
 			f->name_cs,
@@ -9971,7 +9967,7 @@ PRIVATE unsigned check_form_specialchars ARGS1(
  */
 PUBLIC int HText_SubmitForm ARGS4(
 	FormInfo *,	submit_item,
-	document *,	doc,
+	DocInfo *,	doc,
 	char *,		link_name,
 	char *,		link_value)
 {
@@ -9981,7 +9977,6 @@ PUBLIC int HText_SubmitForm ARGS4(
     BOOLEAN PlainText = FALSE;
     BOOLEAN SemiColon = FALSE;
     BOOLEAN first_one = TRUE;
-    BOOLEAN use_mime;
     CONST char *out_csname;
     CONST char *target_csname = NULL;
     PerFormInfo *thisform;
@@ -10004,6 +9999,9 @@ PUBLIC int HText_SubmitForm ARGS4(
     int target_cs = -1;
     int textarea_lineno = 0;
     unsigned form_is_special = 0;
+#ifdef EXP_FILE_UPLOAD
+    BOOLEAN use_mime;
+#endif
 
     CTRACE((tfp, "SubmitForm\n  link_name=%s\n  link_value=%s\n", link_name, link_value));
     if (!HTMainText)
@@ -10025,7 +10023,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 	 *  If we're mailing, make sure it's a mailto ACTION. -FM
 	 */
 	if ((submit_item->submit_method == URL_MAIL_METHOD) &&
-	    strncmp(submit_item->submit_action, "mailto:", 7)) {
+	    !isMAILTO_URL(submit_item->submit_action)) {
 	    HTAlert(BAD_FORM_MAILTO);
 	    return 0;
 	}
@@ -10285,8 +10283,8 @@ PUBLIC int HText_SubmitForm ARGS4(
 		break;
 #ifdef EXP_FILE_UPLOAD
 	    case F_FILE_TYPE:
-		name_used = (form_ptr->name ? form_ptr->name : "");
-		val_used = (form_ptr->value ? form_ptr->value : "");
+		name_used = NonNull(form_ptr->name);
+		val_used = NonNull(form_ptr->value);
 		CTRACE((tfp, "SubmitForm[%d/%d]: I'd submit %s (from %s), but you've not finished it\n",
 			     anchor_count, anchor_limit,
 			     val_used, name_used));
@@ -10346,7 +10344,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 							target_cs, PlainText);
 		    CTRACE((tfp, "SubmitForm[%d/%d]: field \"%s\" %d %s -> %d %s %s\n",
 				 anchor_count, anchor_limit,
-				 form_ptr->name ? form_ptr->name : "",
+				 NonNull(form_ptr->name),
 				 form_ptr->value_cs,
 				 form_ptr->value_cs >= 0
 				     ? LYCharSet_UC[form_ptr->value_cs].MIMEname
@@ -10360,7 +10358,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 		} else {  /* We can use the value directly. */
 		    CTRACE((tfp, "SubmitForm[%d/%d]: field \"%s\" %d %s OK\n",
 				 anchor_count, anchor_limit,
-				 form_ptr->name ? form_ptr->name : "",
+				 NonNull(form_ptr->name),
 				 target_cs,
 				 target_csname ? target_csname : "???"));
 		    success = YES;
@@ -10413,7 +10411,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 							target_cs, PlainText);
 		    CTRACE((tfp, "SubmitForm[%d/%d]: name \"%s\" %d %s -> %d %s %s\n",
 				 anchor_count, anchor_limit,
-				 form_ptr->name ? form_ptr->name : "",
+				 NonNull(form_ptr->name),
 				 form_ptr->name_cs,
 				 form_ptr->name_cs >= 0
 				     ? LYCharSet_UC[form_ptr->name_cs].MIMEname
@@ -10436,7 +10434,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 		} else {  /* We can use the name directly. */
 		    CTRACE((tfp, "SubmitForm[%d/%d]: name \"%s\" %d %s OK\n",
 				anchor_count, anchor_limit,
-				form_ptr->name ? form_ptr->name : "",
+				NonNull(form_ptr->name),
 				target_cs,
 				target_csname ? target_csname : "???"));
 		    success = YES;
@@ -10804,17 +10802,15 @@ PUBLIC int HText_SubmitForm ARGS4(
     }
 
     if (submit_item->submit_method == URL_POST_METHOD || Boundary) {
-	StrAllocCopy(doc->post_data, query);
-	FREE(doc->post_content_type);
+	LYFreePostData(doc);
+	doc->post_data = query;
 	doc->post_content_type = content_type_out; /* don't free c_t_out */
 	CTRACE((tfp,"GridText - post_data: %s\n",doc->post_data));
 	StrAllocCopy(doc->address, submit_item->submit_action);
-	FREE(query);
 	return 1;
     } else { /* GET_METHOD */
 	StrAllocCopy(doc->address, query);
-	FREE(doc->post_data);
-	FREE(doc->post_content_type);
+	LYFreePostData(doc);
 	FREE(content_type_out);
 	FREE(query);
 	return 1;
@@ -11217,7 +11213,6 @@ PUBLIC BOOL HText_AreDifferent ARGS2(
     HTParentAnchor *MTanc;
     char *MTaddress;
     char *MTpound;
-    char *TargetPound;
 
     /*
      *  Do we have a loaded document and both
@@ -11236,7 +11231,7 @@ PUBLIC BOOL HText_AreDifferent ARGS2(
     /*
      *  Do we have a fragment associated with the target?
      */
-    if ((TargetPound = strchr(full_address, '#')) == NULL)
+    if (findPoundSelector(full_address) == NULL)
 	return (TRUE);
 
     /*
@@ -11244,7 +11239,7 @@ PUBLIC BOOL HText_AreDifferent ARGS2(
      *  as potentially stale, so we'll create a
      *  fresh menu from the LynxMaps HTList.
      */
-    if (!strncasecomp(anchor->address, "LYNXIMGMAP:", 11))
+    if (isLYNXIMGMAP(anchor->address))
 	return (TRUE);
 
     /*
@@ -11258,20 +11253,15 @@ PUBLIC BOOL HText_AreDifferent ARGS2(
      *  out a "LYNXIMGMAP:" leader in the MainText URL
      *  and its fragment, if present?
      */
-    MTaddress = (strncasecomp(MTanc->address,
-			      "LYNXIMGMAP:", 11) ?
-				  MTanc->address : (MTanc->address + 11));
-    if ((MTpound = strchr(MTaddress, '#')) != NULL)
-	*MTpound = '\0';
+    MTaddress = (isLYNXIMGMAP(MTanc->address)
+		? MTanc->address + LEN_LYNXIMGMAP
+		: MTanc->address);
+    MTpound = trimPoundSelector(MTaddress);
     if (strcmp(MTaddress, anchor->address)) {
-	if (MTpound != NULL) {
-	    *MTpound = '#';
-	}
+	restorePoundSelector(MTpound);
 	return(TRUE);
     }
-    if (MTpound != NULL) {
-	*MTpound = '#';
-    }
+    restorePoundSelector(MTpound);
 
     /*
      *  If the MainText is not an image map menu,
diff --git a/src/GridText.h b/src/GridText.h
index e2887925..760d88ae 100644
--- a/src/GridText.h
+++ b/src/GridText.h
@@ -110,7 +110,7 @@ extern CONST char * HText_getStyle NOPARAMS;
 extern void HText_setMainTextOwner PARAMS((CONST char * owner));
 extern void print_wwwfile_to_fd PARAMS((FILE * fp, BOOLEAN is_reply));
 extern BOOL HText_select PARAMS((HText *text));
-extern BOOL HText_POSTReplyLoaded PARAMS((document *doc));
+extern BOOL HText_POSTReplyLoaded PARAMS((DocInfo *doc));
 extern BOOL HTFindPoundSelector PARAMS((char *selector));
 extern int HTGetRelLinkNum PARAMS((int num, int rel, int cur));
 extern int HTGetLinkInfo PARAMS((
@@ -147,7 +147,7 @@ extern BOOLEAN HTdocument_settings_changed NOPARAMS;
 extern int HText_getTopOfScreen NOPARAMS;
 extern int HText_getLines PARAMS((HText * text));
 extern int HText_getNumOfLines NOPARAMS;
-extern int do_www_search PARAMS((document *doc));
+extern int do_www_search PARAMS((DocInfo *doc));
 extern char * HTLoadedDocumentURL NOPARAMS;
 extern char * HTLoadedDocumentPost_data NOPARAMS;
 extern char * HTLoadedDocumentTitle NOPARAMS;
@@ -211,7 +211,7 @@ extern void HText_endInput PARAMS((
 	HText *		text));
 extern int HText_SubmitForm PARAMS((
 	FormInfo *	submit_item,
-	document *	doc,
+	DocInfo *	doc,
 	char *		link_name,
 	char *		link_value));
 extern void HText_DisableCurrentForm NOPARAMS;
@@ -231,7 +231,7 @@ extern void user_message PARAMS((
 
 extern void www_user_search PARAMS((
 	int		start_line,
-	document *	doc,
+	DocInfo *	doc,
 	char *		target,
 	int		direction));
 
diff --git a/src/HTAlert.c b/src/HTAlert.c
index d70423aa..90d65ed0 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -69,9 +69,7 @@ PUBLIC void HTAlwaysAlert ARGS2(
 	    LYstore_message2(ALERT_FORMAT, Msg);
 	    LYSleepAlert();
 	} else {
-	    fprintf(((TRACE) ? stdout : stderr),
-		    ALERT_FORMAT,
-		    (Msg == 0) ? "" : Msg);
+	    fprintf(((TRACE) ? stdout : stderr), ALERT_FORMAT, NonNull(Msg));
 	    fflush(stdout);
 	    LYstore_message2(ALERT_FORMAT, Msg);
 	    LYSleepAlert();
@@ -179,6 +177,22 @@ PRIVATE char *sprint_bytes ARGS3(
     return u;
 }
 
+#ifdef EXP_READPROGRESS
+#define TIME_HMS_LENGTH (16)
+PRIVATE char *sprint_tbuf ARGS2(
+       char *,         s,
+       long,           t)
+{
+    if (t > 3600)
+       sprintf (s, "%ldh%ldm%lds", t / 3600, (t / 60) % 60, t % 60);
+    else if (t > 60)
+       sprintf (s, "%ldm%lds", t / 60, t % 60);
+    else
+       sprintf (s, "%ld sec", t);
+    return s;
+}
+#endif /* EXP_READPROGRESS */
+
 /*	Issue a read-progress message.			HTReadProgress()
 **	------------------------------
 */
@@ -198,6 +212,7 @@ PUBLIC void HTReadProgress ARGS2(
     int dummy = gettimeofday(&tv, (struct timezone *)0);
     double now = tv.tv_sec + tv.tv_usec/1000000. ;
     static double first, last, last_active;
+    (void)dummy;		/* quiet unused-assignment warning */
 #else
 #if defined(HAVE_FTIME) && defined(HAVE_SYS_TIMEB_H)
     static double now, first, last, last_active;
@@ -271,10 +286,15 @@ PUBLIC void HTReadProgress ARGS2(
 #ifdef EXP_READPROGRESS
 	    if (LYTransferRate == rateEtaBYTES
 	     || LYTransferRate == rateEtaKB) {
+                char tbuf[TIME_HMS_LENGTH];
 		if (now - last_active >= 5)
-		    HTSprintf (&line, gettext(" (stalled for %ld sec)"), (long)(now - last_active));
+                    HTSprintf (&line,
+			       gettext(" (stalled for %s)"),
+			       sprint_tbuf (tbuf, (long)(now - last_active)));
 		if (total > 0 && transfer_rate)
-		    HTSprintf (&line, gettext(", ETA %ld sec"), (long)((total - bytes)/transfer_rate));
+                    HTSprintf (&line,
+			       gettext(", ETA %s"),
+			       sprint_tbuf (tbuf, (long)((total - bytes)/transfer_rate)));
 	    }
 #endif
 
@@ -440,14 +460,14 @@ PUBLIC BOOL confirm_post_resub ARGS4(
     size_t maxlen = LYcols - 6;
     if (!address) {
 	return(NO);
-    } else if (!strncmp(address, "LYNXIMGMAP:", 11)) {
+    } else if (isLYNXIMGMAP(address)) {
 	if (if_imgmap <= 0)
 	    return(NO);
 	else if (if_imgmap == 1)
 	    return(YES);
 	else
 	    msg = CONFIRM_POST_LIST_RELOAD;
-    } else if (!strncmp(address, "file:", 5)) {
+    } else if (isFILE_URL(address)) {
 	if (if_file <= 0)
 	    return(NO);
 	else if (if_file == 1)
@@ -1038,6 +1058,14 @@ PUBLIC void LYSleepMsg NOARGS
 	LYSleep(MessageSecs);
 }
 
+#ifdef EXP_CMD_LOGGING
+PUBLIC void LYSleepReplay NOARGS
+{
+    if (okToSleep())
+	LYSleep(ReplaySecs);
+}
+#endif /* EXP_CMD_LOGGING */
+
 /*
  *  LYstrerror emulates the ANSI strerror() function.
  */
diff --git a/src/HTAlert.h b/src/HTAlert.h
index 87ac615e..2bc828c8 100644
--- a/src/HTAlert.h
+++ b/src/HTAlert.h
@@ -152,6 +152,7 @@ extern int HTConfirmPostRedirect PARAMS((
 extern void LYSleepAlert NOPARAMS;
 extern void LYSleepInfo NOPARAMS;
 extern void LYSleepMsg NOPARAMS;
+extern void LYSleepReplay NOPARAMS;
 
 #ifdef HAVE_STRERROR
 #define LYStrerror strerror
diff --git a/src/HTFWriter.c b/src/HTFWriter.c
index 052a34c6..819c25b9 100644
--- a/src/HTFWriter.c
+++ b/src/HTFWriter.c
@@ -17,7 +17,7 @@
 #include <HTParse.h>
 #endif
 
-#if _WIN_CC
+#ifdef _WIN_CC
 extern int exec_command(char * cmd, int wait_flag); /* xsystem.c */
 #endif
 
@@ -322,7 +322,7 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
 			    stop_curses();
 #endif
 			}
-#if _WIN_CC
+#ifdef _WIN_CC
 			exec_command(me->end_command, FALSE);
 #else
 			LYSystem(me->end_command);
@@ -378,7 +378,7 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
 		stop_curses();
 #endif
 	    }
-#if _WIN_CC
+#ifdef _WIN_CC
 	    exec_command(me->end_command, FALSE);
 #else
 	    LYSystem(me->end_command);
diff --git a/src/HTForms.h b/src/HTForms.h
index c9c82dcc..0541a519 100644
--- a/src/HTForms.h
+++ b/src/HTForms.h
@@ -10,13 +10,13 @@
 /* change_form_link calls change_form_link_ex with all its args and FALSE as
   last arg */
 extern int change_form_link PARAMS((int cur,
-				    document *newdoc,
+				    DocInfo *newdoc,
 				    BOOLEAN *refresh_screen,
 				    BOOLEAN use_last_tfpos,
 				    BOOLEAN immediate_submit));
 
 extern int change_form_link_ex PARAMS((int cur,
-				    document *newdoc,
+				    DocInfo *newdoc,
 				    BOOLEAN *refresh_screen,
 				    BOOLEAN use_last_tfpos,
 				    BOOLEAN immediate_submit,
diff --git a/src/HTML.c b/src/HTML.c
index 366c18d9..7bae9995 100644
--- a/src/HTML.c
+++ b/src/HTML.c
@@ -733,7 +733,7 @@ PRIVATE void HTMLSRC_apply_markup ARGS4(
 #  define START TRUE
 #  define STOP FALSE
 
-#if defined(__STDC__) || _WIN_CC
+#if defined(__STDC__) || defined(_WIN_CC)
 #  define PSRCSTART(x)	HTMLSRC_apply_markup(me,HTL_##x,START,tag_charset)
 #  define PSRCSTOP(x)  HTMLSRC_apply_markup(me,HTL_##x,STOP,tag_charset)
 #else
@@ -1230,7 +1230,7 @@ PRIVATE int HTML_start_element ARGS6(
 	    StrAllocCopy(base, value[HTML_BASE_HREF]);
 	    if (!(url_type = LYLegitimizeHREF(me, &base, TRUE, TRUE))) {
 		CTRACE((tfp, "HTML: BASE '%s' is not an absolute URL.\n",
-			    (base ? base : "")));
+			    NonNull(base)));
 		if (me->inBadBASE == FALSE)
 		    HTAlert(BASE_NOT_ABSOLUTE);
 		me->inBadBASE = TRUE;
@@ -1285,9 +1285,9 @@ PRIVATE int HTML_start_element ARGS6(
 		    StrAllocCat(me->base_href, "localhost");
 		}
 	    } else {
-		if (!strcmp(me->base_href, "file:")) {
+		if (isFILE_URL(me->base_href)) {
 		    StrAllocCat(me->base_href, "//localhost");
-		} else if (strcmp(me->base_href, "news:")) {
+		} else if (strcmp(me->base_href, STR_NEWS_URL)) {
 		    FREE(temp);
 		    StrAllocCat(me->base_href, (temp = HTParse(related, "",
 					    PARSE_HOST+PARSE_PUNCTUATION)));
@@ -1303,11 +1303,11 @@ PRIVATE int HTML_start_element ARGS6(
 				PARSE_PATH+PARSE_PUNCTUATION)) &&
 		*temp != '\0') {
 		StrAllocCat(me->base_href, temp);
-	    } else if (!strcmp(me->base_href, "news:")) {
+	    } else if (!strcmp(me->base_href, STR_NEWS_URL)) {
 		StrAllocCat(me->base_href, "*");
-	    } else if (!strncmp(me->base_href, "news:", 5) ||
-		       !strncmp(me->base_href, "nntp:", 5) ||
-		       !strncmp(me->base_href, "snews:", 6)) {
+	    } else if (isNEWS_URL(me->base_href) ||
+		       isNNTP_URL(me->base_href) ||
+		       isSNEWS_URL(me->base_href)) {
 		StrAllocCat(me->base_href, "/*");
 	    } else {
 		StrAllocCat(me->base_href, "/");
@@ -2390,9 +2390,7 @@ PRIVATE int HTML_start_element ARGS6(
 	break; /* ignore */
 
     case HTML_SUP:
-	if (isxdigit(UCH(HText_getLastChar(me->text)))) {
-	    HText_appendCharacter(me->text, '^');
-	}
+	HText_appendCharacter(me->text, '^');
 	CHECK_ID(HTML_GEN_ID);
 	break;
 
@@ -3058,8 +3056,8 @@ PRIVATE int HTML_start_element ARGS6(
 	     *	Deal with our ftp gateway kludge. - FM
 	     */
 	    if (!url_type && !strncmp(href, "/foo/..", 7) &&
-		(!strncmp(me->node_anchor->address, "ftp:", 4) ||
-		 !strncmp(me->node_anchor->address, "file:", 5))) {
+		(isFTP_URL(me->node_anchor->address) ||
+		 isFILE_URL(me->node_anchor->address))) {
 		for (i = 0; (href[i] = href[i+7]) != 0; i++)
 		    ;
 	    }
@@ -3100,7 +3098,7 @@ PRIVATE int HTML_start_element ARGS6(
 		!strcasecomp(value[HTML_A_TYPE], HTAtom_name(LINK_INTERNAL)) &&
 		!LYIsUIPage3(me->node_anchor->address, UIP_LIST_PAGE, 0) &&
 		!LYIsUIPage3(me->node_anchor->address, UIP_ADDRLIST_PAGE, 0) &&
-		0 != strncmp(me->node_anchor->address, "LYNXIMGMAP:", 11)) {
+		!isLYNXIMGMAP(me->node_anchor->address)) {
 		/* Some kind of spoof?
 		** Found TYPE="internal link" but not in a valid context
 		** where we have written it. - kw
@@ -3242,7 +3240,7 @@ PRIVATE int HTML_start_element ARGS6(
 	     *	If map_href ended up zero-length or otherwise doesn't
 	     *	have a hash, it can't be valid, so ignore it. - FM
 	     */
-	    if (strchr(map_href, '#') == NULL) {
+	    if (findPoundSelector(map_href) == NULL) {
 		FREE(map_href);
 	    }
 	}
@@ -3303,7 +3301,7 @@ PRIVATE int HTML_start_element ARGS6(
 	    /*
 	     *	Prepend our client-side MAP access field. - FM
 	     */
-	    StrAllocCopy(temp, "LYNXIMGMAP:");
+	    StrAllocCopy(temp, STR_LYNXIMGMAP);
 	    StrAllocCat(temp, map_href);
 	    StrAllocCopy(map_href, temp);
 	    FREE(temp);
diff --git a/src/LYBookmark.c b/src/LYBookmark.c
index e6e49851..bdab256b 100644
--- a/src/LYBookmark.c
+++ b/src/LYBookmark.c
@@ -413,12 +413,12 @@ Note: if you edit this file manually\n\
      */
     if (!first_time && nhist > 0 && bookmark_URL) {
 	for (i = 0; i < nhist; i++) {
-	    if (history[i].bookmark &&
-		!strcmp(history[i].address, bookmark_URL)) {
-		WWWDoc.address = history[i].address;
+	    if (HDOC(i).bookmark &&
+		!strcmp(HDOC(i).address, bookmark_URL)) {
+		WWWDoc.address = HDOC(i).address;
 		WWWDoc.post_data = NULL;
 		WWWDoc.post_content_type = NULL;
-		WWWDoc.bookmark = history[i].bookmark;
+		WWWDoc.bookmark = HDOC(i).bookmark;
 		WWWDoc.isHEAD = FALSE;
 		WWWDoc.safe = FALSE;
 		if (((tmpanchor = HTAnchor_parent(
@@ -605,10 +605,10 @@ PUBLIC void remove_bookmark_link ARGS2(
 #endif  /* UNIX */
 
     if (rename(newfile, filename_buffer) != -1) {
-#ifdef UNIX
+#ifdef MULTI_USER_UNIX
 	if (regular)
 	    chmod(filename_buffer, stat_buf.st_mode & 07777);
-#endif /* UNIX */
+#endif
 	HTSYS_purge(filename_buffer);
 	return;
     } else {
@@ -639,10 +639,10 @@ PUBLIC void remove_bookmark_link ARGS2(
 	    HTAddParam(&buffer, MV_FMT, 3, filename_buffer);
 	    HTEndParam(&buffer, MV_FMT, 3);
 	    if (LYSystem(buffer) == 0) {
-#ifdef UNIX
+#ifdef MULTI_USER_UNIX
 		if (regular)
 		    chmod(filename_buffer, stat_buf.st_mode & 07777);
-#endif /* UNIX */
+#endif
 		FREE(buffer);
 		return;
 	    } else {
diff --git a/src/LYCgi.c b/src/LYCgi.c
index cbd8ed05..8f80eec0 100644
--- a/src/LYCgi.c
+++ b/src/LYCgi.c
@@ -130,7 +130,7 @@ PUBLIC void add_lynxcgi_environment ARGS1(
 {
     char *env_value;
 
-    env_value = getenv(variable_name);
+    env_value = LYGetEnv(variable_name);
     if (env_value != NULL) {
 	char *add_value = NULL;
 
@@ -178,7 +178,7 @@ PRIVATE int LYLoadCGI ARGS4(
     }
 
     StrAllocCopy(orig_pgm, pgm);
-    if ((cp=strchr(pgm, '#')) != NULL) {
+    if ((cp = trimPoundSelector(pgm)) != NULL) {
 	/*
 	 *  Strip a #fragment from path.  In this case any pgm_args
 	 *  found above will also be bogus, since the '?' came after
@@ -186,7 +186,6 @@ PRIVATE int LYLoadCGI ARGS4(
 	 *  handle the case where a '#' appears after a '?' properly
 	 *  according to URL rules. - kw
 	 */
-	*cp = '\0';
 	pgm_args = NULL;
     }
     HTUnEscape(pgm);
@@ -319,7 +318,7 @@ PRIVATE int LYLoadCGI ARGS4(
 	HTStream *target  = NULL;		/* Unconverted data */
 	int fd1[2], fd2[2];
 	char buf[1024];
-	pid_t pid;
+	int pid;
 #ifdef HAVE_TYPE_UNIONWAIT
 	union wait wstatus;
 #else
diff --git a/src/LYCharSets.c b/src/LYCharSets.c
index 4e96b576..e13b156b 100644
--- a/src/LYCharSets.c
+++ b/src/LYCharSets.c
@@ -692,6 +692,8 @@ PRIVATE CONST names_pairs OLD_charset_names[] = {
     {"ISO 8859-6 Arabic",   "iso-8859-6"},
     {"ISO 8859-7 Greek",    "iso-8859-7"},
     {"ISO 8859-8 Hebrew",   "iso-8859-8"},
+    {"ISO-8859-8-I",        "iso-8859-8"},
+    {"ISO-8859-8-E",        "iso-8859-8"},
     {"ISO 8859-9 (Latin 5)","iso-8859-9"},
     {"ISO 8859-10",         "iso-8859-10"},
     {"UNICODE UTF 8",       "utf-8"},
diff --git a/src/LYCharUtils.c b/src/LYCharUtils.c
index 0ff084f9..9f0a66a0 100644
--- a/src/LYCharUtils.c
+++ b/src/LYCharUtils.c
@@ -399,13 +399,13 @@ PUBLIC void LYFillLocalFileURL ARGS2(
 	return;
 
     if (!strcmp(*href, "//") || !strncmp(*href, "///", 3)) {
-	if (base != NULL && !strncmp(base, "file:", 5)) {
-	    StrAllocCopy(temp, "file:");
+	if (base != NULL && isFILE_URL(base)) {
+	    StrAllocCopy(temp, STR_FILE_URL);
 	    StrAllocCat(temp, *href);
 	    StrAllocCopy(*href, temp);
 	}
     }
-    if (!strncmp(*href, "file:", 5)) {
+    if (isFILE_URL(*href)) {
 	if (*(*href+5) == '\0') {
 	    StrAllocCat(*href, "//localhost");
 	} else if (!strcmp(*href, "file://")) {
@@ -419,8 +419,8 @@ PUBLIC void LYFillLocalFileURL ARGS2(
 	}
     }
 
-#if defined(DOSPATH) || defined(__EMX__)
-    if (isalpha(*(*href)) && (*(*href+1) == ':'))  {
+#if defined(USE_DOS_DRIVES)
+    if (LYIsDosDrive(*href))  {
 	/*
 	 * If it's a local DOS path beginning with drive letter,
 	 * add file://localhost/ prefix and go ahead.
@@ -432,13 +432,12 @@ PUBLIC void LYFillLocalFileURL ARGS2(
     /* use below: strlen("file://localhost/") = 17 */
     if (!strncmp(*href, "file://localhost/", 17)
 	  && (strlen(*href) == 19)
-	  && isalpha(*(*href+17))
-	  && (*(*href+18) == ':')) {
+	  && LYIsDosDrive(*href+17)) {
 	/*
 	 * Terminate DOS drive letter with a slash to surf root successfully.
 	 * Here seems a proper place to do so.
 	 */
-	StrAllocCat(*href, "/");
+	LYAddPathSep(href);
     }
 #endif /* DOSPATH */
 
@@ -447,9 +446,9 @@ PUBLIC void LYFillLocalFileURL ARGS2(
      * directory listing for the current default. - FM
      */
     if (!strcmp(*href, "file://localhost")) {
-	char *temp2;
+	CONST char *temp2;
 #ifdef VMS
-	temp2 = HTVMS_wwwName(getenv("PATH"));
+	temp2 = HTVMS_wwwName(LYGetEnv("PATH"));
 #else
 	char curdir[LY_MAXPATH];
 	temp2 = wwwName(Current_Dir(curdir));
@@ -2117,8 +2116,8 @@ PUBLIC void LYHandleMETA ARGS4(
      * Check for a no-cache Pragma
      * or Cache-Control directive. - FM
      */
-    if (!strcasecomp((http_equiv ? http_equiv : ""), "Pragma") ||
-	!strcasecomp((http_equiv ? http_equiv : ""), "Cache-Control")) {
+    if (!strcasecomp(NonNull(http_equiv), "Pragma") ||
+	!strcasecomp(NonNull(http_equiv), "Cache-Control")) {
 	LYUCTranslateHTMLString(&content, me->tag_charset, me->tag_charset,
 				 NO, NO, YES, st_other);
 	LYTrimHead(content);
@@ -2136,7 +2135,7 @@ PUBLIC void LYHandleMETA ARGS4(
 	 *  should. - FM
 	 */
 	if ((!me->node_anchor->cache_control) &&
-	    !strcasecomp((http_equiv ? http_equiv : ""), "Cache-Control")) {
+	    !strcasecomp(NonNull(http_equiv), "Cache-Control")) {
 	    LYLowerCase(content);
 	    StrAllocCopy(me->node_anchor->cache_control, content);
 	    if (me->node_anchor->no_cache == FALSE) {
@@ -2182,7 +2181,7 @@ PUBLIC void LYHandleMETA ARGS4(
     /*
      * Check for an Expires directive. - FM
      */
-    } else if (!strcasecomp((http_equiv ? http_equiv : ""), "Expires")) {
+    } else if (!strcasecomp(NonNull(http_equiv), "Expires")) {
 	/*
 	 *  If we didn't get an Expires MIME header,
 	 *  store it in the anchor element, and if we
@@ -2233,7 +2232,7 @@ PUBLIC void LYHandleMETA ARGS4(
      *	the charset via a server's header. - AAC & FM
      */
     } else if (!(me->node_anchor->charset && *me->node_anchor->charset) &&
-	       !strcasecomp((http_equiv ? http_equiv : ""), "Content-Type")) {
+	       !strcasecomp(NonNull(http_equiv), "Content-Type")) {
 	LYUCcharset * p_in = NULL;
 	LYUCcharset * p_out = NULL;
 	LYUCTranslateHTMLString(&content, me->tag_charset, me->tag_charset,
@@ -2417,7 +2416,7 @@ PUBLIC void LYHandleMETA ARGS4(
     /*
      *	Check for a Refresh directive. - FM
      */
-    } else if (!strcasecomp((http_equiv ? http_equiv : ""), "Refresh")) {
+    } else if (!strcasecomp(NonNull(http_equiv), "Refresh")) {
 	char *Seconds = NULL;
 
 	/*
@@ -2600,7 +2599,7 @@ PUBLIC void LYHandleMETA ARGS4(
     /*
      *	Check for a Set-Cookie directive. - AK
      */
-    } else if (!strcasecomp((http_equiv ? http_equiv : ""), "Set-Cookie")) {
+    } else if (!strcasecomp(NonNull(http_equiv), "Set-Cookie")) {
 	/*
 	 *  This will need to be updated when Set-Cookie/Set-Cookie2
 	 *  handling is finalized.  For now, we'll still assume
@@ -2979,7 +2978,7 @@ PUBLIC int LYLegitimizeHREF ARGS4(
 	 *  with atrocities inflicted on the Web by
 	 *  authoring tools such as Frontpage. - FM
 	 */
-	if ((pound = strchr(*href, '#')) != NULL) {
+	if ((pound = findPoundSelector(*href)) != NULL) {
 	    StrAllocCopy(fragment, pound);
 	    *pound = '\0';
 	    convert_to_spaces(fragment, FALSE);
@@ -2988,8 +2987,10 @@ PUBLIC int LYLegitimizeHREF ARGS4(
 	 * No blanks really belong in the HREF, but if it refers to an actual
 	 * file, it may actually have blanks in the name.  Try to accommodate.
 	 */
-	LYRemoveNewlines(*href);
-	convert_to_spaces(*href, FALSE);
+	if (LYRemoveNewlines(*href) || strchr(*href, '\t') != 0)
+	    LYRemoveBlanks(*href);
+	else
+	    convert_to_spaces(*href, FALSE);
 	LYTrimLeading(*href);
 	LYTrimTrailing(*href);
 	if (fragment != NULL) {
@@ -3004,9 +3005,9 @@ PUBLIC int LYLegitimizeHREF ARGS4(
     url_type = is_url(*href);
     if (!url_type && force_slash &&
 	(!strcmp(*href, ".") || !strcmp(*href, "..")) &&
-	 strncmp((me->inBASE ?
-	       me->base_href : me->node_anchor->address),
-		 "file:", 5)) {
+	 !isFILE_URL((me->inBASE
+		     ? me->base_href
+		     : me->node_anchor->address))) {
 	/*
 	 *  The Fielding RFC/ID for resolving partial HREFs says
 	 *  that a slash should be on the end of the preceding
@@ -3340,7 +3341,7 @@ PUBLIC BOOLEAN LYCheckForCSI ARGS2(
     if (!(anchor && anchor->address))
 	return FALSE;
 
-    if (strncasecomp(anchor->address, "file:", 5))
+    if (!isFILE_URL(anchor->address))
 	return FALSE;
 
     if (!LYisLocalHost(anchor->address))
diff --git a/src/LYClean.c b/src/LYClean.c
index a006084a..cbdb820f 100644
--- a/src/LYClean.c
+++ b/src/LYClean.c
@@ -6,6 +6,7 @@
 #include <LYMainLoop.h>
 #include <LYGlobalDefs.h>
 #include <LYTraversal.h>
+#include <LYHistory.h>
 #include <LYCookie.h>
 #include <UCAuto.h>
 #include <HTAlert.h>
@@ -69,9 +70,9 @@ PUBLIC void cleanup_sig ARGS1(
 	 *  Ask if exit is intended.
 	 */
 	if (LYQuitDefaultYes == TRUE) {
-	    c = HTConfirmDefault(REALLY_EXIT_Y, YES);
+	    c = HTConfirmDefault(REALLY_EXIT, YES);
 	} else {
-	    c = HTConfirmDefault(REALLY_EXIT_N, NO);
+	    c = HTConfirmDefault(REALLY_EXIT, NO);
 	}
 	HadVMSInterrupt = TRUE;
 	if (LYQuitDefaultYes == TRUE) {
@@ -205,11 +206,7 @@ PUBLIC void cleanup NOARGS
 
     cleanup_files();
     for (i = 0; i < nhist; i++) {
-	FREE(history[i].title);
-	FREE(history[i].address);
-	FREE(history[i].post_data);
-	FREE(history[i].post_content_type);
-	FREE(history[i].bookmark);
+	LYFreeDocInfo(&HDOC(i));
     }
     nhist = 0;
 #ifdef VMS
diff --git a/src/LYCookie.c b/src/LYCookie.c
index fdf37227..34d6b967 100644
--- a/src/LYCookie.c
+++ b/src/LYCookie.c
@@ -175,8 +175,10 @@ PRIVATE void LYCookieJar_free NOARGS
     HTList *cl = NULL, *next = NULL;
     cookie *co = NULL;
 
+    CTRACE((tfp, "LYCookieJar_free\n"));
     while (dl) {
 	if ((de = dl->object) != NULL) {
+	    CTRACE((tfp, "...LYCookieJar_free domain %s\n", de->domain));
 	    cl = de->cookie_list;
 	    while (cl) {
 		next = cl->next;
@@ -308,14 +310,23 @@ PRIVATE domain_entry * find_domain_entry ARGS1(
      && *name != '\0') {
 	for (hl = domain_list; hl != NULL; hl = hl->next) {
 	    de = (domain_entry *)hl->object;
-	    if (de != NULL
-	     && de->domain != NULL
-	     && !strcasecomp(name, de->domain)) {
-		break;
+	    if (de != NULL && de->domain != NULL) {
+		CTRACE2(TRACE_CFG,
+			(tfp, "...test_domain_entry(%s) bv:%d, invcheck_bv:%d\n",
+			      de->domain,
+			      de->bv,
+			      de->invcheck_bv));
+		if (!strcasecomp(name, de->domain)) {
+		    break;
+		}
 	    }
 	    de = NULL;
 	}
     }
+    CTRACE((tfp, "find_domain_entry(%s) bv:%d, invcheck_bv:%d\n",
+		 name,
+		 de ? de->bv : -1,
+		 de ? de->invcheck_bv : -1));
     return de;
 }
 
@@ -848,6 +859,8 @@ PRIVATE char *alloc_attr_value ARGS2(
 #define FLAGS_KNOWN_ATTR   2
 #define FLAGS_MAXAGE_ATTR  4
 
+#define is_attr(s, len) attr_len == len && !strncasecomp(attr_start, s, len)
+
 PRIVATE unsigned parse_attribute ARGS9(
 	unsigned,	flags,
 	cookie *,	cur_cookie,
@@ -863,7 +876,7 @@ PRIVATE unsigned parse_attribute ARGS9(
     int url_type;
 
     flags &= ~FLAGS_KNOWN_ATTR;
-    if (attr_len == 6 && !strncasecomp(attr_start, "secure", 6)) {
+    if (is_attr("secure", 6)) {
 	if (value == NULL) {
 	    known_attr = YES;
 	    if (cur_cookie != NULL) {
@@ -876,7 +889,7 @@ PRIVATE unsigned parse_attribute ARGS9(
 	     */
 	    known_attr = NO;
 	}
-    } else if (attr_len == 7 && !strncasecomp(attr_start, "discard", 7)) {
+    } else if (is_attr("discard", 7)) {
 	if (value == NULL) {
 	    known_attr = YES;
 	    if (cur_cookie != NULL) {
@@ -889,7 +902,7 @@ PRIVATE unsigned parse_attribute ARGS9(
 	     */
 	    known_attr = NO;
 	}
-    } else if (attr_len == 7 && !strncasecomp(attr_start, "comment", 7)) {
+    } else if (is_attr("comment", 7)) {
 	known_attr = YES;
 	if (cur_cookie != NULL && value &&
 	    /*
@@ -899,8 +912,7 @@ PRIVATE unsigned parse_attribute ARGS9(
 	    StrAllocCopy(cur_cookie->comment, value);
 	    *cookie_len += strlen(cur_cookie->comment);
 	}
-    } else if (attr_len == 10 && !strncasecomp(attr_start,
-					  "commentURL", 10)) {
+    } else if (is_attr("commentURL", 10)) {
 	known_attr = YES;
 	if (cur_cookie != NULL && value &&
 	    /*
@@ -928,7 +940,7 @@ PRIVATE unsigned parse_attribute ARGS9(
 		FREE(cur_cookie->commentURL);
 	    }
 	}
-    } else if (attr_len == 6 && !strncasecomp(attr_start, "domain", 6)) {
+    } else if (is_attr("domain", 6)) {
 	known_attr = YES;
 	if (cur_cookie != NULL && value &&
 	    /*
@@ -970,7 +982,7 @@ PRIVATE unsigned parse_attribute ARGS9(
 	    *cookie_len += strlen(cur_cookie->domain);
 	    cur_cookie->flags |= COOKIE_FLAG_DOMAIN_SET;
 	}
-    } else if (attr_len == 4 && !strncasecomp(attr_start, "path", 4)) {
+    } else if (is_attr("path", 4)) {
 	known_attr = YES;
 	if (cur_cookie != NULL && value &&
 	    /*
@@ -982,7 +994,7 @@ PRIVATE unsigned parse_attribute ARGS9(
 	    *cookie_len += (cur_cookie->pathlen = strlen(cur_cookie->path));
 	    cur_cookie->flags |= COOKIE_FLAG_PATH_SET;
 	}
-    } else if (attr_len == 4 && !strncasecomp(attr_start, "port", 4)) {
+    } else if (is_attr("port", 4)) {
 	if (cur_cookie != NULL && value &&
 	    /*
 	     *	Don't process a repeat port. - FM
@@ -1015,7 +1027,7 @@ PRIVATE unsigned parse_attribute ARGS9(
 	    }
 	    known_attr = YES;
 	}
-    } else if (attr_len == 7 && !strncasecomp(attr_start, "version", 7)) {
+    } else if (is_attr("version", 7)) {
 	known_attr = YES;
 	if (cur_cookie != NULL && value &&
 	    /*
@@ -1027,7 +1039,7 @@ PRIVATE unsigned parse_attribute ARGS9(
 		cur_cookie->version = temp;
 	    }
 	}
-    } else if (attr_len == 7 && !strncasecomp(attr_start, "max-age", 7)) {
+    } else if (is_attr("max-age", 7)) {
 	known_attr = YES;
 	if (cur_cookie != NULL && value &&
 	    /*
@@ -1046,7 +1058,7 @@ PRIVATE unsigned parse_attribute ARGS9(
 	    }
 	    flags |= FLAGS_MAXAGE_ATTR;
 	}
-    } else if (attr_len == 7 && !strncasecomp(attr_start, "expires", 7)) {
+    } else if (is_attr("expires", 7)) {
 	/*
 	 *  Convert an 'expires' attribute value if we haven't
 	 *  received a 'max-age'.  Note that 'expires' should not
@@ -1118,7 +1130,7 @@ PRIVATE void LYProcessSetCookies ARGS6(
      *	Process the Set-Cookie2 header, if present and not zero-length,
      *	adding each cookie to the CombinedCookies list. - FM
      */
-    p = (SetCookie2 ? SetCookie2 : "");
+    p = NonNull(SetCookie2);
     if (SetCookie && *p) {
 	CTRACE((tfp, "LYProcessSetCookies: Using Set-Cookie2 header.\n"));
     }
@@ -1704,7 +1716,7 @@ PRIVATE void LYProcessSetCookies ARGS6(
 			    (long)co->expires,
 			    ctime(&co->expires)));
 	}
-	if (!strncasecomp(address, "https:", 6) &&
+	if (isHTTPS_URL(address) &&
 	    LYForceSSLCookiesSecure == TRUE &&
 	    !(co->flags & COOKIE_FLAG_SECURE)) {
 	    co->flags |= COOKIE_FLAG_SECURE;
@@ -1745,7 +1757,7 @@ PUBLIC void LYSetCookie ARGS3(
 	*ptr = '\0';
 	ptr++;
 	port = atoi(ptr);
-    } else if (!strncasecomp(address, "https:", 6)) {
+    } else if (isHTTPS_URL(address)) {
 	port = 443;
     }
     if (((path = HTParse(address, "",
@@ -1767,15 +1779,13 @@ PUBLIC void LYSetCookie ARGS3(
 	BadHeaders = TRUE;
     }
     CTRACE((tfp, "LYSetCookie called with host '%s', path '%s',\n",
-		(hostname ? hostname : ""),
-		(path ? path : "")));
+		NonNull(hostname),
+		NonNull(path)));
     if (SetCookie) {
-	CTRACE((tfp, "    and Set-Cookie: '%s'\n",
-			 (SetCookie ? SetCookie : "")));
+	CTRACE((tfp, "    and Set-Cookie: '%s'\n", SetCookie));
     }
     if (SetCookie2) {
-	CTRACE((tfp, "    and Set-Cookie2: '%s'\n",
-			 (SetCookie2 ? SetCookie2 : "")));
+	CTRACE((tfp, "    and Set-Cookie2: '%s'\n", SetCookie2));
     }
     if (LYSetCookies == FALSE || BadHeaders == TRUE) {
 	CTRACE((tfp, "    Ignoring this Set-Cookie/Set-Cookie2 request.\n"));
@@ -2076,7 +2086,7 @@ PUBLIC void LYStoreCookies ARGS1 (
 		co->flags & COOKIE_FLAG_SECURE ? "TRUE" : "FALSE",
 		(long) co->expires, co->name,
 		    (co->quoted ? "\"" : ""),
-		    co->value,
+		    NonNull(co->value),
 		    (co->quoted ? "\"" : ""));
 
 	    CTRACE((tfp, "STORED\n"));
@@ -2398,8 +2408,8 @@ Delete_all_cookies_in_domain:
 	/*
 	 *  Show the domain link and 'allow' setting. - FM
 	 */
-	HTSprintf0(&buf, "<dt>%s<dd><a href=\"LYNXCOOKIE://%s/\">Domain=%s</a>\n",
-		      de->domain, de->domain, de->domain);
+	HTSprintf0(&buf, "<dt>%s<dd><a href=\"%s//%s/\">Domain=%s</a>\n",
+		      de->domain, STR_LYNXCOOKIE, de->domain, de->domain);
 	PUTS(buf);
 	switch (de->bv) {
 	case (ACCEPT_ALWAYS):
@@ -2441,8 +2451,8 @@ Delete_all_cookies_in_domain:
 	    } else {
 		StrAllocCopy(value, NO_VALUE);
 	    }
-	    HTSprintf0(&buf, "<dd><a href=\"LYNXCOOKIE://%s/%s\">%s=%s</a>\n",
-			 de->domain, co->lynxID, name, value);
+	    HTSprintf0(&buf, "<dd><a href=\"%s//%s/%s\">%s=%s</a>\n",
+			 STR_LYNXCOOKIE, de->domain, co->lynxID, name, value);
 	    FREE(name);
 	    FREE(value);
 	    PUTS(buf);
diff --git a/src/LYCurses.c b/src/LYCurses.c
index 57f4f3a8..d3a1cff7 100644
--- a/src/LYCurses.c
+++ b/src/LYCurses.c
@@ -46,17 +46,17 @@ int lynx_has_color = FALSE;
 char *XCursesProgramName = "Lynx";
 #endif
 
-#if defined(USE_COLOR_STYLE) && !USE_COLOR_TABLE
+#if defined(USE_COLOR_STYLE) && !defined(USE_COLOR_TABLE)
 #define COLOR_BKGD ((s_normal != NOSTYLE) ? hashStyles[s_normal].color : A_NORMAL)
 #else
-#define COLOR_BKGD ((COLOR_PAIRS >= 9) ? COLOR_PAIR(9) : A_NORMAL)
+#define COLOR_BKGD ((COLOR_PAIRS >= 9) ? get_color_pair(9) : A_NORMAL)
 #endif
 
 #ifdef USE_CURSES_PADS
 WINDOW *LYwin = 0;
 int LYshiftWin = 0;
 int LYwideLines = FALSE;
-int LYtableCols = 0;			/* in 1/12 of screen width */
+int LYtableCols = 0;		/* in 1/12 of screen width */
 BOOL LYuseCursesPads = TRUE;	/* use pads for left/right shifting */
 #endif
 
@@ -72,7 +72,7 @@ BOOLEAN LYCursesON = FALSE;
 PRIVATE void make_blink_boldbg NOARGS;
 #endif
 
-#if USE_COLOR_TABLE || defined(USE_SLANG)
+#if defined(USE_COLOR_TABLE) || defined(USE_SLANG)
 PUBLIC int Current_Attr, Masked_Attr;
 #endif
 
@@ -553,9 +553,7 @@ PUBLIC void curses_style ARGS2(
 }
 #endif /* USE_COLOR_STYLE */
 
-#ifndef USE_SLANG
 PRIVATE BOOL lynx_called_initscr = FALSE;
-#endif
 
 #if defined(HAVE_USE_DEFAULT_COLORS) && defined(USE_DEFAULT_COLORS)
 /*
@@ -577,7 +575,7 @@ PUBLIC int lynx_default_colors NOARGS
 }
 #endif /* HAVE_USE_DEFAULT_COLORS && USE_DEFAULT_COLORS */
 
-#if USE_COLOR_TABLE && defined(COLOR_CURSES)
+#if defined(USE_COLOR_TABLE) && defined(COLOR_CURSES)
 /*
  * This block of code is designed to produce the same color effects using SVr4
  * curses as the slang library's implementation in this module.  That maps the
@@ -610,6 +608,20 @@ PRIVATE struct {
 } lynx_color_pairs[25];
 
 /*
+ * If we find an exact match for the given default colors, force curses to use
+ * color pair 0, which corresponds to the terminal's default colors.  Normally
+ * curses assumes white-on-black, but we can override the assumption with this
+ * function.
+ */
+PRIVATE int get_color_pair ARGS1(int, n)
+{
+    if (lynx_color_pairs[n].fg == default_fg
+     && lynx_color_pairs[n].bg == default_bg)
+    	return 0;
+    return COLOR_PAIR(n);
+}
+
+/*
  * Map the SGR attributes (0-7) into ANSI colors, modified with the actual BOLD
  * attribute we'll get 16 colors.
  */
@@ -621,15 +633,15 @@ PRIVATE void LYsetWAttr ARGS1(WINDOW *, win)
 	int offs = 1;
 
 	if (Current_Attr & A_BOLD)
-		code |= 1;
+	    code |= 1;
 	if (Current_Attr & A_REVERSE)
-		code |= 2;
+	    code |= 2;
 	if (Current_Attr & A_UNDERLINE)
-		code |= 4;
+	    code |= 4;
 	attr = lynx_color_cfg[code].attr;
 
 	if (code+offs < COLOR_PAIRS) {
-		attr |= COLOR_PAIR(code+offs);
+	    attr |= get_color_pair(code+offs);
 	}
 
 	wattrset(win, attr & ~Masked_Attr);
@@ -689,7 +701,7 @@ PUBLIC void lynx_set_color ARGS1(int, a)
     if (lynx_has_color && LYShowColor >= SHOW_COLOR_ON) {
 	wattrset(LYwin, lynx_color_cfg[a].attr
 		| (((a+1) < COLOR_PAIRS)
-			? COLOR_PAIR(a+1)
+			? get_color_pair(a+1)
 			: A_NORMAL));
     }
 }
@@ -707,7 +719,8 @@ PRIVATE void lynx_init_colors NOARGS
     if (lynx_has_color) {
 	size_t n, m;
 
-	CTRACE((tfp, "lynx_init_colors\n"));
+	CTRACE((tfp, "lynx_init_colors (default %d/%d)\n",
+		     default_fg, default_bg));
 
 	lynx_color_cfg[0].fg = default_fg;
 	lynx_color_cfg[0].bg = default_bg;
@@ -747,7 +760,7 @@ PUBLIC void LYnoVideo ARGS1(
     if (a & 4) Masked_Attr |= SLTT_ULINE_MASK;
     lynx_setup_attrs();
 #else
-#if USE_COLOR_TABLE
+#ifdef USE_COLOR_TABLE
     if (a & 1) Masked_Attr |= A_BOLD;
     if (a & 2) Masked_Attr |= A_REVERSE;
     if (a & 4) Masked_Attr |= A_UNDERLINE;
@@ -909,6 +922,19 @@ PUBLIC void start_curses NOARGS
     initscr();	/* start curses */
 #else  /* Unix: */
 
+#ifdef __CYGWIN__
+    /*
+     * Workaround for buggy Cygwin, which breaks subprocesses of a
+     * full-screen application (tested with cygwin dll, dated
+     * 2002/6/23 -TD)
+     */
+    if (!lynx_called_initscr) {
+	FILE *fp = fopen("/dev/tty", "w");
+	if (fp != 0)
+	    stdout = fp;
+    }
+#endif
+
     if (!LYscreen) {
 	/*
 	 *  If we're not VMS then only do initscr() one time,
@@ -1007,7 +1033,7 @@ PUBLIC void start_curses NOARGS
 	    lynx_has_color = TRUE;
 	    start_color();
 #ifdef USE_DEFAULT_COLORS
-#ifdef EXP_ASSUMED_COLOR
+#if defined(EXP_ASSUMED_COLOR) && defined(USE_COLOR_TABLE)
 	    /*
 	     * Adjust the color mapping table to match the ASSUMED_COLOR
 	     * setting in lynx.cfg
@@ -1016,6 +1042,8 @@ PUBLIC void start_curses NOARGS
 		default_fg = COLOR_WHITE;
 		default_bg = COLOR_BLACK;
 	    }
+	    CTRACE((tfp, "initializing default colors %d/%d\n",
+			 default_fg, default_bg));
 	    if (default_fg >= 0 || default_bg >= 0) {
 		unsigned n;
 		for (n = 0; n < TABLESIZE(lynx_color_cfg); n++) {
@@ -1039,7 +1067,7 @@ PUBLIC void start_curses NOARGS
 #ifdef USE_COLOR_STYLE
 	parse_userstyles();
 #endif
-#if USE_COLOR_TABLE
+#ifdef USE_COLOR_TABLE
 	lynx_init_colors();
 #endif /* USE_COLOR_TABLE */
     }
@@ -1054,7 +1082,7 @@ PUBLIC void start_curses NOARGS
     crmode();
     raw();
 #else
-#if HAVE_CBREAK
+#ifdef HAVE_CBREAK
     cbreak();
 #else
     crmode();
@@ -1064,7 +1092,7 @@ PUBLIC void start_curses NOARGS
 
     noecho();
 
-#if HAVE_KEYPAD
+#ifdef HAVE_KEYPAD
     if (!keypad_on)
 	keypad(LYwin,TRUE);
 #endif /* HAVE_KEYPAD */
@@ -1097,8 +1125,7 @@ PUBLIC void lynx_enable_mouse ARGS1(int,state)
 
 #if defined(WIN_EX)
 /* modify lynx_enable_mouse() for pdcurses configuration so that mouse support
-   is disabled unless -use_mouse is specified.  This is ifdef'd with
-   __BORLANDC__ for the time being (WB).
+   is disabled unless -use_mouse is specified
 */
     HANDLE hConIn = INVALID_HANDLE_VALUE;
     hConIn = GetStdHandle(STD_INPUT_HANDLE);
@@ -1113,7 +1140,6 @@ PUBLIC void lynx_enable_mouse ARGS1(int,state)
     if (LYUseMouse == 0)
 	return;
 
-
 #if defined(USE_SLANG)
     SLtt_set_mouse_mode (state, 0);
     SLtt_flush_output ();
@@ -1240,7 +1266,7 @@ PUBLIC void stop_curses NOARGS
     _eth_release();
 #endif /* __DJGPP__ */
 
-#if defined(DOSPATH) && !(defined(USE_SLANG) || _WIN_CC)
+#if defined(DOSPATH) && !(defined(USE_SLANG) || defined(_WIN_CC))
 #ifdef __DJGPP__
     ScreenClear();
 #else
@@ -1248,15 +1274,11 @@ PUBLIC void stop_curses NOARGS
 #endif
 #else
 
-    /*
-     *	Fixed for better dumb terminal support.
-     *	05-28-94 Lynx 2-3-1 Garrett Arch Blythe
-     */
     if(LYCursesON == TRUE)	{
 	lynx_nl2crlf(TRUE);
 	lynx_enable_mouse (0);
 #if (!defined(WIN_EX) || defined(__CYGWIN__))	/* @@@ */
-	if(LYscreen) {
+	if(LYscreen || lynx_called_initscr) {
 	    endwin();	/* stop curses */
 	    LYDELSCR();
 	}
@@ -1272,7 +1294,7 @@ PUBLIC void stop_curses NOARGS
 #endif
 
     fflush(stdout);
-#endif /* defined(DOSPATH) && !(defined(USE_SLANG) || _WIN_CC) */
+#endif /* defined(DOSPATH) && !(defined(USE_SLANG) || defined(_WIN_CC)) */
     fflush(stderr);
 
     LYCursesON = FALSE;
@@ -1392,7 +1414,7 @@ PUBLIC BOOLEAN setup ARGS1(
     /*
      *	Query the terminal type.
      */
-    if (dumbterm(getenv("TERM"))) {
+    if (dumbterm(LYGetEnv("TERM"))) {
 	printf("\n\n  %s\n\n", gettext("Your Terminal type is unknown!"));
 	printf("  %s [vt100] ", gettext("Enter a terminal type:"));
 
@@ -1408,13 +1430,13 @@ PUBLIC BOOLEAN setup ARGS1(
 	FREE(buffer);
 
 	(void) putenv(term_putenv);
-	printf("\n%s %s\n", gettext("TERMINAL TYPE IS SET TO"), getenv("TERM"));
+	printf("\n%s %s\n", gettext("TERMINAL TYPE IS SET TO"), LYGetEnv("TERM"));
 	LYSleepMsg();
     }
 
     start_curses();
 
-#if HAVE_TTYTYPE
+#ifdef HAVE_TTYTYPE
     /*
      *  Account for lossage on the 'sun' terminal type (80x24) Sun text
      *  console driver. It only supports reverse video, but all SGR
@@ -1456,7 +1478,7 @@ PRIVATE int dumbterm ARGS1(
 
 #ifdef FANCY_CURSES
 #ifndef USE_COLOR_STYLE
-#if USE_COLOR_TABLE
+#ifdef USE_COLOR_TABLE
 PUBLIC void LYaddWAttr ARGS2(
 	WINDOW *,	win,
 	int,		a)
@@ -1681,7 +1703,7 @@ PUBLIC void LYwaddnstr ARGS3(
      * have problems with combining-characters in this version of ncurses
      * (successive calls are not merged), so I'm using them for testing -TD
      */
-#if defined(WIDEC_CURSES) && defined(HAVE_MBSTATE_T)
+#if 0	/* defined(WIDEC_CURSES) && defined(HAVE_MBSTATE_T) */
 #if 1	/* array of wchar_t's */
     {
 	static wchar_t *temp = 0;
@@ -2474,7 +2496,7 @@ PUBLIC void lynx_start_target_color NOARGS
 
 PUBLIC void lynx_start_status_color NOARGS
 {
-#if USE_COLOR_TABLE && defined(COLOR_CURSES)
+#if defined(USE_COLOR_TABLE) && defined(COLOR_CURSES)
     if (lynx_has_color && LYShowColor >= SHOW_COLOR_ON)
 	lynx_set_color (2);
     else
@@ -2484,7 +2506,7 @@ PUBLIC void lynx_start_status_color NOARGS
 
 PUBLIC void lynx_stop_status_color NOARGS
 {
-#if USE_COLOR_TABLE && defined(COLOR_CURSES)
+#if defined(USE_COLOR_TABLE) && defined(COLOR_CURSES)
     if (lynx_has_color && LYShowColor >= SHOW_COLOR_ON)
 	lynx_set_color (0);
     else
diff --git a/src/LYCurses.h b/src/LYCurses.h
index 3ec42649..e0e0c357 100644
--- a/src/LYCurses.h
+++ b/src/LYCurses.h
@@ -289,6 +289,12 @@ extern WINDOW *LYstartPopup PARAMS((int top_y, int left_x, int height, int width
 #define HAVE_NAPMS 1	/* can use millisecond-delays */
 #endif
 
+#ifdef HAVE_NAPMS
+#define SECS2Secs(n) (1000 * (n))
+#else
+#define SECS2Secs(n) (n)
+#endif
+
 /* Both slang and curses: */
 #ifndef TRUE
 #define TRUE  1
@@ -381,7 +387,7 @@ extern void curses_w_style PARAMS((WINDOW* win, int style, int	dir));
 #  define LynxWChangeStyle(win,style,dir)	(void)1
 #endif /* USE_COLOR_STYLE */
 
-#if USE_COLOR_TABLE
+#ifdef USE_COLOR_TABLE
 extern void LYaddAttr PARAMS((int a));
 extern void LYsubAttr PARAMS((int a));
 extern void lynx_setup_colors NOPARAMS;
@@ -402,12 +408,21 @@ extern unsigned int Lynx_Color_Flags;
 #define SL_LYNX_USE_COLOR	1
 #define SL_LYNX_OVERRIDE_COLOR	2
 
+#ifdef UNDERLINE_LINKS
+#define start_bold()      	LYaddAttr(4)
+#define start_reverse()   	LYaddAttr(2)
+#define start_underline() 	LYaddAttr(1)
+#define stop_bold()       	LYsubAttr(4)
+#define stop_reverse()    	LYsubAttr(2)
+#define stop_underline()  	LYsubAttr(1)
+#else
 #define start_bold()      	LYaddAttr(1)
 #define start_reverse()   	LYaddAttr(2)
 #define start_underline() 	LYaddAttr(4)
 #define stop_bold()       	LYsubAttr(1)
 #define stop_reverse()    	LYsubAttr(2)
 #define stop_underline()  	LYsubAttr(4)
+#endif
 
 #ifdef FANCY_CURSES
 #undef FANCY_CURSES
@@ -504,7 +519,7 @@ extern int string_to_attr PARAMS((char *name));
  *  our own functions to add or subtract the
  *  A_foo attributes. - FM
  */
-#if USE_COLOR_TABLE
+#ifdef USE_COLOR_TABLE
 extern void LYaddWAttr PARAMS((WINDOW *win, int a));
 extern void LYsubWAttr PARAMS((WINDOW *win, int a));
 extern void LYaddWAttr PARAMS((WINDOW *win, int a));
@@ -526,13 +541,8 @@ extern int  lynx_chg_color PARAMS((int, int, int));
 #ifdef UNDERLINE_LINKS
 #define start_bold()		LYaddAttr(A_UNDERLINE)
 #define stop_bold()		LYsubAttr(A_UNDERLINE)
-#ifdef __CYGWIN__	/* 1999/02/25 (Thu) 01:09:45 */
-#define start_underline()	/* LYaddAttr(A_BOLD) */
-#define stop_underline()	/* LYsubAttr(A_BOLD) */
-#else
 #define start_underline()	LYaddAttr(A_BOLD)
 #define stop_underline()	LYsubAttr(A_BOLD)
-#endif /* __CYGWIN__ */
 #else /* not UNDERLINE_LINKS: */
 #define start_bold()		LYaddAttr(A_BOLD)
 #define stop_bold()		LYsubAttr(A_BOLD)
@@ -621,7 +631,7 @@ FANCY_CURSES.  Check your config.log to see why the FANCY_CURSES test failed.
  * control it.
  */
 #ifdef USE_DEFAULT_COLORS
-#if USE_SLANG || (defined(HAVE_ASSUME_DEFAULT_COLORS) && !defined(USE_COLOR_STYLE))
+#if defined(USE_SLANG) || defined(HAVE_ASSUME_DEFAULT_COLORS)
 #define EXP_ASSUMED_COLOR 1
 #endif
 #endif
diff --git a/src/LYDownload.c b/src/LYDownload.c
index b2000e62..311bedbe 100644
--- a/src/LYDownload.c
+++ b/src/LYDownload.c
@@ -101,8 +101,8 @@ PUBLIC void LYDownload ARGS1(
 	file += 16;
 #endif /* __DJGPP__ */
     }
-    else if (!strncmp(file, "file:", 5))
-	file += 5;
+    else if (isFILE_URL(file))
+	file += LEN_FILE_URL;
     HTUnEscape(file);
 #else
 #if defined(_WINDOWS)	/* 1997/10/15 (Wed) 16:27:38 */
@@ -220,7 +220,7 @@ check_recall:
 	strcpy(command, buffer);
 	if (!LYValidateFilename(buffer, command))
 	    goto cancelled;
-#if HAVE_POPEN
+#ifdef HAVE_POPEN
 	else if (LYIsPipeCommand(buffer)) {
 	    /* I don't know how to download to a pipe */
 	    HTAlert(CANNOT_WRITE_TO_FILE);
@@ -283,10 +283,7 @@ check_recall:
 #else /* Unix: */
 
 	LYCopyFile(file, buffer);
-
-#if defined(UNIX)
 	LYRelaxFilePermissions(buffer);
-#endif /* defined(UNIX) */
 #endif /* VMS */
 
     } else {
@@ -402,19 +399,9 @@ check_recall:
 		}
 		/*
 		 *  Cancel if the user entered "/dev/null" on Unix,
-		 *  or an "nl:" path (case-insensitive) on VMS. - FM
+		 *  or an "nl:" path on VMS. - FM
 		 */
-#ifdef VMS
-		if (!strncasecomp(buffer, "nl:", 3) ||
-		    !strncasecomp(buffer, "/nl/", 4))
-#else
-#if defined(DOSPATH)	/* 1997/10/15 (Wed) 16:41:30 */
-		if (!strcmp(buffer, "nul"))
-#else
-		if (!strcmp(buffer, "/dev/null"))
-#endif /* DOSPATH */
-#endif /* VMS */
-		{
+		if (LYIsNullDevice(buffer)) {
 		    goto cancelled;
 		}
 		SecondS = TRUE;
@@ -542,9 +529,10 @@ PUBLIC int LYdownload_options ARGS2(
 	if (!lynx_edit_mode)
 #endif /* DIRED_SUPPORT */
 	fprintf(fp0,
-		"   <a href=\"LYNXDOWNLOAD://Method=-1/File=%s/SugFile=%s%s\">%s</a>\n",
+		"   <a href=\"%s//Method=-1/File=%s/SugFile=%s%s\">%s</a>\n",
+		STR_LYNXDOWNLOAD,
 		data_file,
-		(lynx_save_space ? lynx_save_space : ""),
+		NonNull(lynx_save_space),
 		sug_filename,
 		gettext("Save to disk"));
     } else {
@@ -558,8 +546,8 @@ PUBLIC int LYdownload_options ARGS2(
 	for (count = 0, cur_download = downloaders; cur_download != NULL;
 			cur_download = cur_download->next, count++) {
 	    if (!no_download || cur_download->always_enabled) {
-		fprintf(fp0, "   <a href=\"LYNXDOWNLOAD://Method=%d/File=%s/SugFile=%s\">",
-			count,data_file, sug_filename);
+		fprintf(fp0, "   <a href=\"%s//Method=%d/File=%s/SugFile=%s\">",
+			STR_LYNXDOWNLOAD, count,data_file, sug_filename);
 		fprintf(fp0, "%s", (cur_download->name ?
 			cur_download->name : gettext("No Name Given")));
 		fprintf(fp0,"</a>\n");
diff --git a/src/LYEdit.c b/src/LYEdit.c
index 3c7a725c..3f06242d 100644
--- a/src/LYEdit.c
+++ b/src/LYEdit.c
@@ -54,7 +54,7 @@ PUBLIC int edit_current_file ARGS3(
 {
     int result = FALSE;
     char *filename = NULL;
-#if !(defined(VMS) || defined(DOSPATH) || defined(__EMX__))
+#if !(defined(VMS) || defined(USE_DOS_DRIVES))
     char *colon;
 #endif
     char *number_sign;
@@ -62,9 +62,6 @@ PUBLIC int edit_current_file ARGS3(
 #if defined(VMS) || defined(CANT_EDIT_UNWRITABLE_FILES)
     FILE *fp;
 #endif
-#if defined(__CYGWIN__) && defined(DOSPATH)
-    unsigned char temp_buff[LY_MAXPATH];
-#endif
 
     CTRACE((tfp, "edit_current_file(newfile=%s, cur=%d, lineno=%d)\n",
 		 newfile, cur, lineno));
@@ -80,9 +77,7 @@ PUBLIC int edit_current_file ARGS3(
     /*
      *  If there's a fragment, trim it. - FM
      */
-    number_sign = strchr(newfile, '#');
-    if (number_sign)
-	*number_sign = '\0';
+    number_sign = trimPoundSelector(newfile);
 
     /*
      *  On Unix, first try to open it as a completely referenced file,
@@ -90,7 +85,7 @@ PUBLIC int edit_current_file ARGS3(
      *
      * On VMS, only try the path.
      */
-#if defined (VMS) || defined (DOSPATH) || defined (__EMX__)
+#if defined (VMS) || defined (USE_DOS_DRIVES)
     filename = HTParse(newfile, "", PARSE_PATH+PARSE_PUNCTUATION);
     HTUnEscape(filename);
     StrAllocCopy(filename, HTSYS_name(filename));
@@ -103,15 +98,11 @@ PUBLIC int edit_current_file ARGS3(
 	CTRACE((tfp, "filename: '%s'\n", filename));
 	goto done;
     }
-#else	/* !(VMS || !DOSPATH || !__EMX__) == UNIX */
-#ifdef SH_EX	/* Speed Up! */
+#else	/* something like UNIX */
     if (strncmp(newfile, "file://localhost/", 16) == 0)
 	colon = newfile + 16;
     else
 	colon = strchr(newfile, ':');
-#else
-    colon = strchr(newfile, ':');
-#endif
     StrAllocCopy(filename, (colon + 1));
     HTUnEscape(filename);
     if (!LYCanReadFile(filename)) {
@@ -123,7 +114,7 @@ PUBLIC int edit_current_file ARGS3(
 	    goto done;
 	}
     }
-#endif /* !(VMS || !DOSPATH || !__EMX__) */
+#endif
 
 #if defined(VMS) || defined(CANT_EDIT_UNWRITABLE_FILES)
     /*
@@ -162,8 +153,7 @@ done:
     /*
      *  Restore the fragment if there was one. - FM
      */
-    if (number_sign)
-	*number_sign = '#';
+    restorePoundSelector(number_sign);
 
     FREE(filename);
     CTRACE((tfp, "edit_current_file returns %d\n", result));
@@ -226,16 +216,7 @@ PUBLIC void edit_temporary_file ARGS3(
 	else
 	    HTAddXpand(&command, format, params++, editor);
 #else
-#if defined(__CYGWIN__) && defined(DOSPATH)
-	if (strchr(editor, ' ')) {
-	    cygwin_conv_to_full_posix_path(HTDOS_short_name(editor), temp_buff);
-	    HTAddXpand(&command, format, params++, temp_buff);
-	} else {
-	    HTAddXpand(&command, format, params++, editor);
-	}
-#else
 	HTAddXpand(&command, format, params++, editor);
-#endif /* __CYGWIN__ */
 #endif
 	HTAddParam(&command, format, params++, filename);
 	HTEndParam(&command, format, params);
diff --git a/src/LYExtern.c b/src/LYExtern.c
index 3bf057fb..ef48c399 100644
--- a/src/LYExtern.c
+++ b/src/LYExtern.c
@@ -98,7 +98,7 @@ PRIVATE void format ARGS3(
  * Format the given command into a buffer, returning the resulting string.
  *
  * It is too dangerous to leave any URL that may come along unquoted.  They
- * often contain '&', ';', and '?' chars, and who knows what else may occur. 
+ * often contain '&', ';', and '?' chars, and who knows what else may occur.
  * Prevent spoofing of the shell.  Dunno how this needs to be modified for VMS
  * or DOS.  - kw
  */
@@ -120,7 +120,7 @@ PRIVATE char *format_command ARGS2(
 	decode_string(pram_string);
 	param = pram_string;
 
-	if (strnicmp("mailto:", param, 7) == 0) {
+	if (isMAILTO_URL(param)) {
 	    format(&cmdbuf, command, param + 7);
 	} else if (strnicmp("telnet://", param, 9) == 0) {
 	    char host[sizeof(pram_string)];
@@ -143,10 +143,7 @@ PRIVATE char *format_command ARGS2(
 	    strncat(e_buff, p, sizeof(e_buff) - strlen(e_buff) - 1);
 	    p = strrchr(e_buff, '.');
 	    if (p) {
-		p = strchr(p, '#');
-		if (p) {
-		    *p = '\0';
-		}
+		trimPoundSelector(p);
 	    }
 
 	    /* Less ==> short filename with backslashes,
@@ -261,7 +258,6 @@ BOOL run_external ARGS2(
 {
 #ifdef WIN_EX
     int status;
-    extern int xsystem(char *cmd);
 #endif
     int redraw_flag = TRUE;
     char *cmdbuf = NULL;
diff --git a/src/LYForms.c b/src/LYForms.c
index f7b9e99b..43dd2f57 100644
--- a/src/LYForms.c
+++ b/src/LYForms.c
@@ -60,7 +60,7 @@ PRIVATE char ** options_list ARGS1(
 
 PUBLIC int change_form_link_ex ARGS6(
 	int,		cur,
-	document *,	newdoc,
+	DocInfo *,	newdoc,
 	BOOLEAN *,	refresh_screen,
 	BOOLEAN,	use_last_tfpos,
 	BOOLEAN,	immediate_submit,
@@ -276,7 +276,7 @@ PUBLIC int change_form_link_ex ARGS6(
 		    break;
 		} else if (!immediate_submit &&
 			   ((no_file_url &&
-			     !strncasecomp(form->submit_action, "file:", 5)) ||
+			     isFILE_URL(form->submit_action)) ||
 			    !strncasecomp(form->submit_action, "lynx", 4))) {
 		    c = LAC_TO_LKC0(LYK_SUBMIT);
 		    break;
@@ -344,7 +344,7 @@ PUBLIC int change_form_link_ex ARGS6(
 
 PUBLIC int change_form_link ARGS5(
 	int,		cur,
-	document *,	newdoc,
+	DocInfo *,	newdoc,
 	BOOLEAN *,	refresh_screen,
 	BOOLEAN,	use_last_tfpos,
 	BOOLEAN,	immediate_submit)
diff --git a/src/LYGetFile.c b/src/LYGetFile.c
index cb52fcb5..2cf6c794 100644
--- a/src/LYGetFile.c
+++ b/src/LYGetFile.c
@@ -33,7 +33,7 @@
 #include <LYexit.h>
 #include <LYLeaks.h>
 
-PRIVATE int fix_httplike_urls PARAMS((document *doc, UrlTypes type));
+PRIVATE int fix_httplike_urls PARAMS((DocInfo *doc, UrlTypes type));
 
 #ifdef VMS
 extern BOOLEAN LYDidRename;
@@ -71,7 +71,7 @@ PUBLIC int HTNoDataOK = 0;
  *  bogus error mail with MAIL_SYSTEM_ERROR_LOGGING:TRUE. - kw
  */
 PUBLIC int getfile ARGS1(
-	document *,	doc)
+	DocInfo *,	doc)
 {
 	int url_type = 0;
 	char *cp = NULL;
@@ -275,8 +275,7 @@ Try_Redirected_URL:
 		       LYIsUIPage(WWWDoc.address, UIP_ADDRLIST_PAGE)))) {
 		    CTRACE((tfp, "getfile: dropping post_data!\n"));
 		    HTAlert(IGNORED_POST);
-		    FREE(doc->post_data);
-		    FREE(doc->post_content_type);
+		    LYFreePostData(doc);
 		    WWWDoc.post_data = NULL;
 		    WWWDoc.post_content_type = NULL;
 		}
@@ -376,10 +375,9 @@ Try_Redirected_URL:
 		if (LYNoRefererHeader == FALSE &&
 		    LYNoRefererForThis == FALSE) {
 		    char *ref_url = HTLoadedDocumentURL();
-		    if (!strncmp(ref_url, "LYNXIMGMAP:", 11))
-			ref_url += 11;
-		    if (no_filereferer == TRUE &&
-			!strncmp(ref_url, "file:", 5)) {
+		    if (isLYNXIMGMAP(ref_url))
+			ref_url += LEN_LYNXIMGMAP;
+		    if (no_filereferer == TRUE && isFILE_URL(ref_url)) {
 			LYNoRefererForThis = TRUE;
 		    }
 		    if (LYNoRefererForThis == FALSE &&
@@ -555,7 +553,7 @@ Try_Redirected_URL:
 				title = "";
 			    }
 			}
-			cp = (char *)strchr(doc->address,':')+1;
+			cp = strchr(doc->address,':')+1;
 			reply_by_mail(cp,
 				      ((HTMainAnchor && !LYUserSpecifiedURL) ?
 				       (char *)HTMainAnchor->address :
@@ -601,15 +599,14 @@ Try_Redirected_URL:
 		     *  Detect weird case where interactive protocol would
 		     *  be proxied, and to a non-interactive protocol at that.
 		     */
-		    } else if ((proxy = (char *)getenv(
+		    } else if ((proxy = LYGetEnv(
 			(url_type==TN3270_URL_TYPE) ? "tn3270_proxy" :
 			(url_type==TELNET_GOPHER_URL_TYPE) ? "gopher_proxy" :
 			"telnet_proxy")) != NULL &&
-			       *proxy != '\0' &&
 			       !override_proxy(doc->address) &&
-			       (strncmp(proxy, "telnet:", 7) &&
-				strncmp(proxy, "tn3270:", 7) &&
-				strncmp(proxy, "rlogin:", 7))) {
+			       (!isTELNET_URL(proxy) &&
+				!isTN3270_URL(proxy) &&
+				!isRLOGIN_URL(proxy))) {
 			/* Do nothing, fall through to generic code - kw */
 		    } else {
 			stop_curses();
@@ -642,13 +639,12 @@ Try_Redirected_URL:
 		     *  Detect weird case where interactive protocol would
 		     *  be proxied, and to a non-interactive protocol at that.
 		     */
-		    } else if ((proxy = (char *)getenv(
+		    } else if ((proxy = LYGetEnv(
 			"rlogin_proxy")) != NULL &&
-			       *proxy != '\0' &&
 			       !override_proxy(doc->address) &&
-			       (strncmp(proxy, "telnet:", 7) &&
-				strncmp(proxy, "tn3270:", 7) &&
-				strncmp(proxy, "rlogin:", 7))) {
+			       (!isTELNET_URL(proxy) &&
+				!isTN3270_URL(proxy) &&
+				!isRLOGIN_URL(proxy))) {
 			/* Do nothing, fall through to generic code - kw */
 		    } else {
 			stop_curses();
@@ -947,8 +943,8 @@ Try_Redirected_URL:
 				FREE(use_this_url_instead);
 				return(NULLFILE);
 			    }
-			    if ((pound = strchr(doc->address, '#')) != NULL &&
-				strchr(use_this_url_instead, '#') == NULL) {
+			    if ((pound = findPoundSelector(doc->address)) != NULL
+			     && findPoundSelector(use_this_url_instead) == NULL) {
 				/*
 				 *  Our requested URL had a fragment
 				 *  associated with it, and the redirection
@@ -976,8 +972,7 @@ Try_Redirected_URL:
 				 *  Freeing the content also yields
 				 *  a GET request. - FM
 				 */
-				FREE(doc->post_data);
-				FREE(doc->post_content_type);
+				LYFreePostData(doc);
 			    }
 			    /*
 			     *	Go to top to check for URL's which get
@@ -1007,7 +1002,7 @@ Try_Redirected_URL:
 			/*
 			 *  Check for a #fragment selector.
 			 */
-			pound = (char *)strchr(doc->address, '#');
+			pound = findPoundSelector(doc->address);
 
 			/*
 			 *  Check to see if there is a temp
@@ -1049,9 +1044,8 @@ Try_Redirected_URL:
 			    FREE(fname);
 			    doc->internal_link = FALSE;
 			    WWWDoc.address = doc->address;
-			    FREE(doc->post_data);
+			    LYFreePostData(doc);
 			    WWWDoc.post_data = NULL;
-			    FREE(doc->post_content_type);
 			    WWWDoc.post_content_type = NULL;
 			    WWWDoc.bookmark = doc->bookmark = FALSE;
 			    WWWDoc.isHEAD = doc->isHEAD = FALSE;
@@ -1163,7 +1157,7 @@ PUBLIC void srcmode_for_next_retrieval ARGS1(
 PUBLIC int follow_link_number ARGS4(
 	int,		c,
 	int,		cur,
-	document *,	doc,
+	DocInfo *,	doc,
 	int *,		num)
 {
     char temp[120];
@@ -1515,7 +1509,7 @@ check_tp_for_entry:
 #endif /* EXEC_LINKS || LYNXCGI_LINKS */
 
 PRIVATE int fix_httplike_urls ARGS2(
-	document *,	doc,
+	DocInfo *,	doc,
 	UrlTypes,	type)
 {
     char *slash;
@@ -1524,7 +1518,7 @@ PRIVATE int fix_httplike_urls ARGS2(
      *  If there's a fragment present, our simplistic methods won't
      *  work.  - kw
      */
-    if (strchr(doc->address, '#'))
+    if (findPoundSelector(doc->address) != NULL)
 	return 0;
 
 #ifndef DISABLE_FTP
@@ -1550,8 +1544,8 @@ PRIVATE int fix_httplike_urls ARGS2(
 	/*
 	 *  If we're proxying ftp, don't trim anything. - KW
 	 */
-	if (((proxy = (char *)getenv("ftp_proxy")) != NULL) &&
-	    *proxy != '\0' && !override_proxy(doc->address))
+	if (((proxy = LYGetEnv("ftp_proxy")) != NULL) &&
+	    !override_proxy(doc->address))
 	    return 0;
 
 	/*
@@ -1569,7 +1563,7 @@ PRIVATE int fix_httplike_urls ARGS2(
 	CTRACE((tfp, "fix_httplike_urls: URL '%s'\n", doc->address));
 
 	*second++ = '\0';
-	HTSprintf0(&path, "ftp://%s%s", first, second);
+	HTSprintf0(&path, "%s//%s%s", STR_FTP_URL, first, second);
 	FREE(doc->address);
 	doc->address = path;
 
diff --git a/src/LYGetFile.h b/src/LYGetFile.h
index 4acd0c4a..7dbc7b5b 100644
--- a/src/LYGetFile.h
+++ b/src/LYGetFile.h
@@ -7,12 +7,12 @@
 #define NORMAL 1
 #define NULLFILE 3
 
-extern int getfile PARAMS((document *doc));
+extern int getfile PARAMS((DocInfo *doc));
 extern void srcmode_for_next_retrieval PARAMS((int));
 extern int follow_link_number PARAMS((
 	int		c,
 	int		cur,
-	document *	doc,
+	DocInfo *	doc,
 	int *		num));
 extern void add_trusted PARAMS((char *str, int type));
 extern BOOLEAN exec_ok PARAMS((CONST char *source, CONST char *linkpath, int type));
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index fc9468d4..3cd16f87 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -383,9 +383,12 @@ extern BOOLEAN more_links;
 extern int     ccount;
 extern BOOLEAN LYCancelledFetch;
 extern char * LYToolbarName;
+
+extern int AlertSecs;
 extern int InfoSecs;
 extern int MessageSecs;
-extern int AlertSecs;
+extern int ReplaySecs;
+
 extern char * LYUserAgent;		/* Lynx User-Agent header */
 extern char * LYUserAgentDefault;	/* Lynx default User-Agent header */
 extern BOOLEAN LYNoRefererHeader;	/* Never send Referer header? */
diff --git a/src/LYHistory.c b/src/LYHistory.c
index 554cc786..0a9a91c5 100644
--- a/src/LYHistory.c
+++ b/src/LYHistory.c
@@ -87,7 +87,7 @@ PRIVATE void trace_history ARGS1(
  *  links the most current in the list. - FM
  */
 PUBLIC void LYAddVisitedLink ARGS1(
-	document *,	doc)
+	DocInfo *,	doc)
 {
     VisitedLink *new;
     HTList *cur;
@@ -111,7 +111,7 @@ PUBLIC void LYAddVisitedLink ARGS1(
 	if (	LYIsUIPage(doc->address, UIP_HISTORY) ||
 		LYIsUIPage(doc->address, UIP_VLINKS) ||
 		LYIsUIPage(doc->address, UIP_SHOWINFO) ||
-		!strncmp(doc->address, "LYNXMESSAGES:", 13) ||
+		isLYNXMESSAGES(doc->address) ||
 			(related = 0)	||
 #ifdef DIRED_SUPPORT
 		LYIsUIPage(doc->address, UIP_DIRED_MENU) ||
@@ -121,14 +121,14 @@ PUBLIC void LYAddVisitedLink ARGS1(
 		LYIsUIPage(doc->address, UIP_PRINT_OPTIONS) ||
 		LYIsUIPage(doc->address, UIP_DOWNLOAD_OPTIONS) ||
 		LYIsUIPage(doc->address, UIP_OPTIONS_MENU) ||
-		!strncmp(doc->address, "LYNXKEYMAP:", 11) ||
+		isLYNXKEYMAP(doc->address) ||
 		LYIsUIPage(doc->address, UIP_LIST_PAGE) ||
 #ifdef EXP_ADDRLIST_PAGE
 		LYIsUIPage(doc->address, UIP_ADDRLIST_PAGE) ||
 #endif
 		LYIsUIPage(doc->address, UIP_CONFIG_DEF) ||
 		LYIsUIPage(doc->address, UIP_LYNXCFG) ||
-		!strncmp(doc->address, "LYNXCOOKIE:", 11) ||
+		isLYNXCOOKIE(doc->address) ||
 		LYIsUIPage(doc->address, UIP_TRACELOG)	) {
 	    if (!related)
 		PrevVisitedLink = NULL;
@@ -150,8 +150,8 @@ PUBLIC void LYAddVisitedLink ARGS1(
 
     cur = Visited_Links;
     while (NULL != (new = (VisitedLink *)HTList_nextObject(cur))) {
-	if (!strcmp((new->address ? new->address : ""),
-		    (doc->address ? doc->address : ""))) {
+	if (!strcmp(NonNull(new->address),
+		    NonNull(doc->address))) {
 	    PrevVisitedLink = PrevActiveVisitedLink = new;
 	    /* Already visited.  Update the last-visited info. */
 	    if (new->next_latest == &Latest_last)	/* optimization */
@@ -272,6 +272,28 @@ PUBLIC BOOLEAN LYwouldPush ARGS2(
 }
 
 /*
+ * Free post-data for 'DocInfo'
+ */
+PUBLIC void LYFreePostData ARGS1(
+    DocInfo *,		doc)
+{
+    FREE(doc->post_data);
+    FREE(doc->post_content_type);
+}
+
+/*
+ * Free strings associated with a 'DocInfo' struct.
+ */
+PUBLIC void LYFreeDocInfo ARGS1(
+    DocInfo *,		doc)
+{
+    FREE(doc->title);
+    FREE(doc->address);
+    FREE(doc->bookmark);
+    LYFreePostData(doc);
+}
+
+/*
  *  Free the information in the last history entry.
  */
 PRIVATE void clean_extra NOARGS
@@ -280,34 +302,30 @@ PRIVATE void clean_extra NOARGS
     nhist += nhist_extra;
     while (nhist_extra > 0) {
 	nhist--;
-	FREE(history[nhist].title);
-	FREE(history[nhist].address);
-	FREE(history[nhist].post_data);
-	FREE(history[nhist].post_content_type);
-	FREE(history[nhist].bookmark);
+	LYFreeDocInfo(&HDOC(nhist));
 	nhist_extra--;
     }
     trace_history("...clean_extra");
 }
 
-/* What is the relationship to are_different() from the mainloop?! */
+/* FIXME What is the relationship to are_different() from the mainloop?! */
 PRIVATE int are_identical ARGS2(
 	HistInfo *,	doc,
-	document *,	doc1)
+	DocInfo *,	doc1)
 {
-     return (	STREQ(doc1->address, doc->address)
-		&& !strcmp(doc1->post_data ? doc1->post_data : "",
-			   doc->post_data ?  doc->post_data : "")
-		&& !strcmp(doc1->bookmark ? doc1->bookmark : "",
-			   doc->bookmark ?  doc->bookmark : "")
-		&& doc1->isHEAD == doc->isHEAD );
+     return (	STREQ(doc1->address, doc->hdoc.address)
+		&& !strcmp(NonNull(doc1->post_data),
+			   NonNull(doc->hdoc.post_data))
+		&& !strcmp(NonNull(doc1->bookmark),
+			   NonNull(doc->hdoc.bookmark))
+		&& doc1->isHEAD == doc->hdoc.isHEAD );
 }
 
 /*
  *  Push the current filename, link and line number onto the history list.
  */
 PUBLIC int LYpush ARGS2(
-	document *,	doc,
+	DocInfo *,	doc,
 	BOOLEAN,	force_push)
 {
     /*
@@ -335,11 +353,11 @@ PUBLIC int LYpush ARGS2(
      *	If file is identical to one before it, don't push it.
      */
     if ( nhist > 1 && are_identical(&(history[nhist-1]), doc)) {
-	if (history[nhist-1].internal_link == doc->internal_link) {
+	if (HDOC(nhist-1).internal_link == doc->internal_link) {
 	    /* But it is nice to have the last position remembered!
 	       - kw */
-	    history[nhist-1].link = doc->link;
-	    history[nhist-1].line = doc->line;
+	    HDOC(nhist-1).link = doc->link;
+	    HDOC(nhist-1).line = doc->line;
 	    return 0;
 	}
     }
@@ -348,8 +366,8 @@ PUBLIC int LYpush ARGS2(
      *	If file is identical to the current document, just move the pointer.
      */
     if ( nhist_extra >= 1 && are_identical(&(history[nhist]), doc)) {
-	history[nhist].link = doc->link;
-	history[nhist].line = doc->line;
+	HDOC(nhist).link = doc->link;
+	HDOC(nhist).line = doc->line;
 	nhist_extra--;
 	nhist++;
 	trace_history("LYpush: just move the cursor");
@@ -362,28 +380,28 @@ PUBLIC int LYpush ARGS2(
      *	OK, push it if we have stack space.
      */
     if (nhist < MAXHIST)  {
-	history[nhist].link = doc->link;
-	history[nhist].line = doc->line;
+	HDOC(nhist).link = doc->link;
+	HDOC(nhist).line = doc->line;
 
-	history[nhist].title = NULL;
-	LYformTitle(&(history[nhist].title), doc->title);
+	HDOC(nhist).title = NULL;
+	LYformTitle(&(HDOC(nhist).title), doc->title);
 
-	history[nhist].address = NULL;
-	StrAllocCopy(history[nhist].address, doc->address);
+	HDOC(nhist).address = NULL;
+	StrAllocCopy(HDOC(nhist).address, doc->address);
 
-	history[nhist].post_data = NULL;
-	StrAllocCopy(history[nhist].post_data, doc->post_data);
+	HDOC(nhist).post_data = NULL;
+	StrAllocCopy(HDOC(nhist).post_data, doc->post_data);
 
-	history[nhist].post_content_type = NULL;
-	StrAllocCopy(history[nhist].post_content_type, doc->post_content_type);
+	HDOC(nhist).post_content_type = NULL;
+	StrAllocCopy(HDOC(nhist).post_content_type, doc->post_content_type);
 
-	history[nhist].bookmark = NULL;
-	StrAllocCopy(history[nhist].bookmark, doc->bookmark);
+	HDOC(nhist).bookmark = NULL;
+	StrAllocCopy(HDOC(nhist).bookmark, doc->bookmark);
 
-	history[nhist].isHEAD = doc->isHEAD;
-	history[nhist].safe = doc->safe;
+	HDOC(nhist).isHEAD = doc->isHEAD;
+	HDOC(nhist).safe = doc->safe;
 
-	history[nhist].internal_link = FALSE; /* by default */
+	HDOC(nhist).internal_link = FALSE; /* by default */
 	history[nhist].intern_seq_start = -1; /* by default */
 	if (doc->internal_link) {
 	    /* Now some tricky stuff: if the caller thinks that the doc
@@ -413,49 +431,49 @@ PUBLIC int LYpush ARGS2(
 		    /* If the last-pushed item is a LYNXIMGMAP but THIS one
 		    ** isn't, compare the physical URLs instead. - kw
 		    */
-		    if (0==strncmp(history[nhist-1].address,"LYNXIMGMAP:",11) &&
-			0!=strncmp(doc->address,"LYNXIMGMAP:",11)) {
-			WWWDoc.address = history[nhist-1].address + 11;
+		    if (isLYNXIMGMAP(HDOC(nhist-1).address) &&
+			!isLYNXIMGMAP(doc->address)) {
+			WWWDoc.address = HDOC(nhist-1).address + LEN_LYNXIMGMAP;
 		    /*
 		    ** If THIS item is a LYNXIMGMAP but the last-pushed one
 		    ** isn't, fake it by using THIS item's address for
 		    ** thatparent... - kw
 		    */
-		    } else if ((0==strncmp(doc->address,"LYNXIMGMAP:",11) &&
-		       0!=strncmp(history[nhist-1].address,"LYNXIMGMAP:",11))) {
+		    } else if (isLYNXIMGMAP(doc->address) &&
+		       !isLYNXIMGMAP(HDOC(nhist-1).address)) {
 			char *temp = NULL;
-			StrAllocCopy(temp, "LYNXIMGMAP:");
-			StrAllocCat(temp, doc->address+11);
+			StrAllocCopy(temp, STR_LYNXIMGMAP);
+			StrAllocCat(temp, doc->address + LEN_LYNXIMGMAP);
 			WWWDoc.address = temp;
-			WWWDoc.post_content_type = history[nhist-1].post_content_type;
-			WWWDoc.bookmark = history[nhist-1].bookmark;
-			WWWDoc.isHEAD = history[nhist-1].isHEAD;
-			WWWDoc.safe = history[nhist-1].safe;
+			WWWDoc.post_content_type = HDOC(nhist-1).post_content_type;
+			WWWDoc.bookmark = HDOC(nhist-1).bookmark;
+			WWWDoc.isHEAD = HDOC(nhist-1).isHEAD;
+			WWWDoc.safe = HDOC(nhist-1).safe;
 			thatparent =
 			    HTAnchor_parent(HTAnchor_findAddress(&WWWDoc));
 			FREE(temp);
 		    } else {
-			WWWDoc.address = history[nhist-1].address;
+			WWWDoc.address = HDOC(nhist-1).address;
 		    }
 		    if (!thatparent) { /* if not yet done */
-			WWWDoc.post_data = history[nhist-1].post_data;
-			WWWDoc.post_content_type = history[nhist-1].post_content_type;
-			WWWDoc.bookmark = history[nhist-1].bookmark;
-			WWWDoc.isHEAD = history[nhist-1].isHEAD;
-			WWWDoc.safe = history[nhist-1].safe;
+			WWWDoc.post_data = HDOC(nhist-1).post_data;
+			WWWDoc.post_content_type = HDOC(nhist-1).post_content_type;
+			WWWDoc.bookmark = HDOC(nhist-1).bookmark;
+			WWWDoc.isHEAD = HDOC(nhist-1).isHEAD;
+			WWWDoc.safe = HDOC(nhist-1).safe;
 			thatparent =
 			    HTAnchor_parent(HTAnchor_findAddress(&WWWDoc));
 		    }
-		/* In addition to equality of the ParentAnchors, require
-		** that IF we have a HTMainText (i.e., it wasn't just
-		** HTuncache'd by mainloop), THEN it has to be consistent
-		** with what we are trying to push.
-		**   This may be overkill... - kw
-		*/
+		    /* In addition to equality of the ParentAnchors, require
+		    ** that IF we have a HTMainText (i.e., it wasn't just
+		    ** HTuncache'd by mainloop), THEN it has to be consistent
+		    ** with what we are trying to push.
+		    **   This may be overkill... - kw
+		    */
 		    if (thatparent == thisparent &&
 			(!HTMainText || HTMainAnchor == thisparent)
 			) {
-			history[nhist].internal_link = TRUE;
+			HDOC(nhist).internal_link = TRUE;
 			history[nhist].intern_seq_start =
 			    history[nhist-1].intern_seq_start >= 0 ?
 			    history[nhist-1].intern_seq_start : nhist-1;
@@ -463,7 +481,7 @@ PUBLIC int LYpush ARGS2(
 		    }
 		}
 	    }
-	    if (!history[nhist].internal_link) {
+	    if (!HDOC(nhist).internal_link) {
 		CTRACE((tfp, "\nLYpush: push as internal link requested, %s\n",
 			    "but didn't check out!"));
 	    }
@@ -485,26 +503,16 @@ PUBLIC int LYpush ARGS2(
  *  Pop the previous filename, link and line number from the history list.
  */
 PUBLIC void LYpop ARGS1(
-	document *,	doc)
+	DocInfo *,	doc)
 {
     if (nhist > 0) {
 	clean_extra();
 	nhist--;
-	doc->link = history[nhist].link;
-	doc->line = history[nhist].line;
-	FREE(doc->title);
-	doc->title = history[nhist].title;	 /* will be freed later */
-	FREE(doc->address);
-	doc->address = history[nhist].address;	 /* will be freed later */
-	FREE(doc->post_data);
-	doc->post_data = history[nhist].post_data;
-	FREE(doc->post_content_type);
-	doc->post_content_type = history[nhist].post_content_type;
-	FREE(doc->bookmark);
-	doc->bookmark = history[nhist].bookmark; /* will be freed later */
-	doc->isHEAD = history[nhist].isHEAD;
-	doc->safe = history[nhist].safe;
-	doc->internal_link = history[nhist].internal_link;
+
+	LYFreeDocInfo(doc);
+
+	*doc = HDOC(nhist);
+
 #ifdef DISP_PARTIAL
 	/* assume we pop the 'doc' to show it soon... */
 	LYSetNewline(doc->line);	/* reinitialize */
@@ -518,7 +526,7 @@ PUBLIC void LYpop ARGS1(
  *  Move to the previous filename, link and line number from the history list.
  */
 PUBLIC void LYhist_prev ARGS1(
-	document *,	doc)
+	DocInfo *,	doc)
 {
     trace_history("LYhist_prev");
     if (nhist > 0 && (nhist_extra || nhist < MAXHIST)) {
@@ -533,14 +541,14 @@ PUBLIC void LYhist_prev ARGS1(
  *  Called before calling LYhist_prev().
  */
 PUBLIC void LYhist_prev_register ARGS1(
-	document *,	doc)
+	DocInfo *,	doc)
 {
     trace_history("LYhist_prev_register");
     if (nhist > 1) {
 	if (nhist_extra) {	/* Make something to return back */
 	    /* Store the new position */
-	    history[nhist].link = doc->link;
-	    history[nhist].line = doc->line;
+	    HDOC(nhist).link = doc->link;
+	    HDOC(nhist).line = doc->line;
 	} else if (nhist < MAXHIST) { /* push will fail */
 	    if (LYpush(doc, 0)) {
 		nhist--;
@@ -552,17 +560,17 @@ PUBLIC void LYhist_prev_register ARGS1(
 }
 
 /*
- *  Move to the next filename, link and line number from the history list.
+ *  Move to the next filename, link and line number from the history.
  */
 PUBLIC int LYhist_next ARGS2(
-	document *,	doc,
-	document *,	newdoc)
+	DocInfo *,	doc,
+	DocInfo *,	newdoc)
 {
     if (nhist_extra <= 1)	/* == 1 when we are the last one */
 	return 0;
     /* Store the new position */
-    history[nhist].link = doc->link;
-    history[nhist].line = doc->line;
+    HDOC(nhist).link = doc->link;
+    HDOC(nhist).line = doc->line;
     nhist++;
     nhist_extra--;
     LYpop_num(nhist, newdoc);
@@ -576,19 +584,19 @@ PUBLIC int LYhist_next ARGS2(
  */
 PUBLIC void LYpop_num ARGS2(
 	int,		number,
-	document *,	doc)
+	DocInfo *,	doc)
 {
     if (number >= 0 && nhist + nhist_extra > number) {
-	doc->link = history[number].link;
-	doc->line = history[number].line;
-	StrAllocCopy(doc->title, history[number].title);
-	StrAllocCopy(doc->address, history[number].address);
-	StrAllocCopy(doc->post_data, history[number].post_data);
-	StrAllocCopy(doc->post_content_type, history[number].post_content_type);
-	StrAllocCopy(doc->bookmark, history[number].bookmark);
-	doc->isHEAD = history[number].isHEAD;
-	doc->safe = history[number].safe;
-	doc->internal_link = history[number].internal_link; /* ?? */
+	doc->link = HDOC(number).link;
+	doc->line = HDOC(number).line;
+	StrAllocCopy(doc->title, HDOC(number).title);
+	StrAllocCopy(doc->address, HDOC(number).address);
+	StrAllocCopy(doc->post_data, HDOC(number).post_data);
+	StrAllocCopy(doc->post_content_type, HDOC(number).post_content_type);
+	StrAllocCopy(doc->bookmark, HDOC(number).bookmark);
+	doc->isHEAD = HDOC(number).isHEAD;
+	doc->safe = HDOC(number).safe;
+	doc->internal_link = HDOC(number).internal_link; /* ?? */
 #ifdef DISP_PARTIAL
 	/* assume we pop the 'doc' to show it soon... */
 	LYSetNewline(doc->line);	/* reinitialize */
@@ -625,8 +633,8 @@ PUBLIC int showhistory ARGS1(
 
     BeginInternalPage(fp0, HISTORY_PAGE_TITLE, HISTORY_PAGE_HELP);
 
-    fprintf(fp0, "<p align=right> <a href=\"LYNXMESSAGES:\">[%s]</a>\n",
-		 STATUSLINES_TITLE);
+    fprintf(fp0, "<p align=right> <a href=\"%s\">[%s]</a>\n",
+		 STR_LYNXMESSAGES, STATUSLINES_TITLE);
 
     fprintf(fp0, "<pre>\n");
 
@@ -636,8 +644,8 @@ PUBLIC int showhistory ARGS1(
 	 *  The number of the document in the hist stack,
 	 *  its title in a link, and its address. - FM
 	 */
-	if (history[x].title != NULL) {
-	    StrAllocCopy(Title, history[x].title);
+	if (HDOC(x).title != NULL) {
+	    StrAllocCopy(Title, HDOC(x).title);
 	    LYEntify(&Title, TRUE);
 	    LYTrimLeading(Title);
 	    LYTrimTrailing(Title);
@@ -647,16 +655,16 @@ PUBLIC int showhistory ARGS1(
 	    StrAllocCopy(Title, NO_TITLE);
 	}
 	fprintf(fp0,
-		"%s<em>%d</em>. <tab id=t%d><a href=\"LYNXHIST:%d\">%s</a>\n",
+		"%s<em>%d</em>. <tab id=t%d><a href=\"%s%d\">%s</a>\n",
 		(x > 99 ? "" : x < 10 ? "  " : " "),
-		x, x, x, Title);
-	if (history[x].address != NULL) {
-	    StrAllocCopy(Title, history[x].address);
+		x, x, STR_LYNXHIST, x, Title);
+	if (HDOC(x).address != NULL) {
+	    StrAllocCopy(Title, HDOC(x).address);
 	    LYEntify(&Title, TRUE);
 	} else {
 	    StrAllocCopy(Title, gettext("(no address)"));
 	}
-	if (history[x].internal_link) {
+	if (HDOC(x).internal_link) {
 	    if (history[x].intern_seq_start == history[nhist-1].intern_seq_start)
 		StrAllocCat(Title, gettext(" (internal)"));
 	    else
@@ -679,7 +687,7 @@ PUBLIC int showhistory ARGS1(
  *  The info looks like:  LYNXHIST:#
  */
 PUBLIC BOOLEAN historytarget ARGS1(
-	document *,	newdoc)
+	DocInfo *,	newdoc)
 {
     int number;
     DocAddress WWWDoc;
@@ -705,7 +713,7 @@ PUBLIC BOOLEAN historytarget ARGS1(
     if (HTMainText && nhist > 0 &&
 	!strcmp(HTLoadedDocumentTitle(), HISTORY_PAGE_TITLE) &&
 	LYIsUIPage3(HTLoadedDocumentURL(), UIP_HISTORY, 0) &&
-	strcmp(HTLoadedDocumentURL(), history[nhist-1].address)) {
+	strcmp(HTLoadedDocumentURL(), HDOC(nhist-1).address)) {
 	HTuncache_current_document();  /* don't waste the cache */
     }
 
@@ -713,7 +721,7 @@ PUBLIC BOOLEAN historytarget ARGS1(
     if (((newdoc->internal_link &&
 	  history[number].intern_seq_start == history[nhist-1].intern_seq_start) ||
 	 (number < nhist-1 &&
-	  history[nhist-1].internal_link &&
+	  HDOC(nhist-1).internal_link &&
 	  number == history[nhist-1].intern_seq_start))
 	&& !(LYforce_no_cache == TRUE && LYoverride_no_cache == FALSE)) {
 #ifndef DONT_TRACK_INTERNAL_LINKS
@@ -744,7 +752,7 @@ PUBLIC BOOLEAN historytarget ARGS1(
 		LYoverride_no_cache == FALSE)) &&
 	      !(treat_as_intern && !reloading)) ||
 	     text == NULL) &&
-	    (!strncmp(newdoc->address, "LYNXIMGMAP:", 11) ||
+	    (isLYNXIMGMAP(newdoc->address) ||
 	     HTConfirm(CONFIRM_POST_RESUBMISSION) == TRUE)) {
 	    LYforce_no_cache = TRUE;
 	    LYoverride_no_cache = FALSE;
@@ -802,7 +810,7 @@ PUBLIC int LYShowVisitedLinks ARGS1(
 
     BeginInternalPage(fp0, VISITED_LINKS_TITLE, VISITED_LINKS_HELP);
 
-    fprintf(fp0, "<form action=\"LYNXOPTIONS:\" method=\"post\">\n");
+    fprintf(fp0, "<form action=\"%s\" method=\"post\">\n", STR_LYNXOPTIONS);
     fprintf(fp0, "<select name=\"visited_pages_type\">\n");
     fprintf(fp0, " <option value=\"first_visited\" %s>Sort By First Visited\n",
 		 (Visited_Links_As == VISITED_LINKS_AS_FIRST_V ? "selected" : ""));
@@ -1017,7 +1025,7 @@ PUBLIC void LYstore_message2 ARGS2(
 
     if (message != NULL) {
 	char *temp = NULL;
-	HTSprintf0(&temp, message, (argument == 0) ? "" : argument);
+	HTSprintf0(&temp, message, NonNull(argument));
 	to_stack(temp);
     }
 }
diff --git a/src/LYHistory.h b/src/LYHistory.h
index 5d061a24..fe12c1a3 100644
--- a/src/LYHistory.h
+++ b/src/LYHistory.h
@@ -6,16 +6,18 @@
 #endif /* LYSTRUCTS_H */
 
 extern BOOLEAN LYwouldPush PARAMS((CONST char *title, CONST char *docurl));
-extern BOOLEAN historytarget PARAMS((document *newdoc));
+extern BOOLEAN historytarget PARAMS((DocInfo *newdoc));
 extern int LYShowVisitedLinks PARAMS((char **newfile));
-extern int LYhist_next PARAMS((document *doc, document *newdoc));
-extern int LYpush PARAMS((document *doc, BOOLEAN force_push));
+extern int LYhist_next PARAMS((DocInfo *doc, DocInfo *newdoc));
+extern int LYpush PARAMS((DocInfo *doc, BOOLEAN force_push));
 extern int showhistory PARAMS((char **newfile));
-extern void LYAddVisitedLink PARAMS((document *doc));
-extern void LYhist_prev PARAMS((document *doc));
-extern void LYhist_prev_register PARAMS((document *doc));
-extern void LYpop PARAMS((document *doc));
-extern void LYpop_num PARAMS((int number, document *doc));
+extern void LYAddVisitedLink PARAMS((DocInfo *doc));
+extern void LYFreePostData PARAMS((DocInfo * data));
+extern void LYFreeDocInfo PARAMS((DocInfo * data));
+extern void LYhist_prev PARAMS((DocInfo *doc));
+extern void LYhist_prev_register PARAMS((DocInfo *doc));
+extern void LYpop PARAMS((DocInfo *doc));
+extern void LYpop_num PARAMS((int number, DocInfo *doc));
 extern void LYstatusline_messages_on_exit PARAMS((char **buf));
 extern void LYstore_message PARAMS((CONST char *message));
 extern void LYstore_message2 PARAMS((CONST char *message, CONST char *argument));
diff --git a/src/LYJump.c b/src/LYJump.c
index 478ddfc9..97a0a072 100644
--- a/src/LYJump.c
+++ b/src/LYJump.c
@@ -10,7 +10,7 @@
 #include <LYLeaks.h>
 
 #ifdef _WINDOWS
-#include <stdlib.h>	/* bsearch() */
+#include <stdlib.h>		/* bsearch() */
 #endif
 
 #ifdef VMS
@@ -19,8 +19,8 @@
 
 struct JumpTable *JThead = NULL;
 
-PRIVATE int LYCompare PARAMS ((CONST void *e1, CONST void *e2));
-PRIVATE unsigned LYRead_Jumpfile PARAMS ((struct JumpTable *jtp));
+PRIVATE int LYCompare PARAMS((CONST void *e1, CONST void *e2));
+PRIVATE unsigned LYRead_Jumpfile PARAMS((struct JumpTable * jtp));
 
 PUBLIC void LYJumpTable_free NOARGS
 {
@@ -36,9 +36,10 @@ PUBLIC void LYJumpTable_free NOARGS
 	    char *shortcut;
 	    HTList *current = cur->history;
 
-	    while (NULL != (shortcut = (char *)HTList_nextObject(current))) {
+	    while (NULL != (shortcut = (char *) HTList_nextObject(current))) {
 		FREE(shortcut);
-	    }
+	    };
+
 	    HTList_delete(cur->history);
 	    cur->history = NULL;
 	}
@@ -55,18 +56,18 @@ PUBLIC void LYJumpTable_free NOARGS
  * Utility for listing shortcuts, making any repeated
  * shortcut the most current in the list. - FM
  */
-PUBLIC void LYAddJumpShortcut ARGS2(HTList *, historyp, char *,shortcut)
+PUBLIC void LYAddJumpShortcut ARGS2(HTList *, historyp, char *, shortcut)
 {
     char *new = NULL;
     char *old;
-    HTList *cur =  historyp;
+    HTList *cur = historyp;
 
     if (!historyp || !(shortcut && *shortcut))
 	return;
 
     StrAllocCopy(new, shortcut);
 
-    while (NULL != (old = (char *)HTList_nextObject(cur))) {
+    while (NULL != (old = (char *) HTList_nextObject(cur))) {
 	if (!strcmp(old, new)) {
 	    HTList_removeObject(historyp, old);
 	    FREE(old);
@@ -78,7 +79,7 @@ PUBLIC void LYAddJumpShortcut ARGS2(HTList *, historyp, char *,shortcut)
     return;
 }
 
-PUBLIC BOOL LYJumpInit ARGS1 (char *, config)
+PUBLIC BOOL LYJumpInit ARGS1(char *, config)
 {
     struct JumpTable *jtp;
     char *cp;
@@ -87,6 +88,7 @@ PUBLIC BOOL LYJumpInit ARGS1 (char *, config)
      * Create a JumpTable structure.
      */
     jtp = typecalloc(struct JumpTable);
+
     if (jtp == NULL) {
 	outofmem(__FILE__, "LYJumpInit");
     }
@@ -126,6 +128,7 @@ PUBLIC BOOL LYJumpInit ARGS1 (char *, config)
      */
     if (!cp && JThead) {
 	struct JumpTable *jtptmp = JThead;
+
 	jumpfile = jtp->file;
 	FREE(jtp);
 	while (jtptmp && jtptmp->key)
@@ -147,6 +150,7 @@ PUBLIC BOOL LYJumpInit ARGS1 (char *, config)
 	if (!jumpfile)
 	    StrAllocCopy(jumpfile, JThead->file);
 	jtp = typecalloc(struct JumpTable);
+
 	if (jtp == NULL) {
 	    outofmem(__FILE__, "LYJumpInit");
 	}
@@ -157,16 +161,16 @@ PUBLIC BOOL LYJumpInit ARGS1 (char *, config)
      * Complete the initialization of config.
      */
     if (cp) {
-	jtp->key = remap(cp, "JUMP", FALSE);  /* key is present, (re)map it */
-	cp = strtok(NULL, "\n");	    /* get prompt, if present */
+	jtp->key = remap(cp, "JUMP", FALSE);	/* key is present, (re)map it */
+	cp = strtok(NULL, "\n");	/* get prompt, if present */
 	if (cp && *cp)
-	    StrAllocCopy(jtp->msg, cp);     /* prompt is present, load it */
+	    StrAllocCopy(jtp->msg, cp);	/* prompt is present, load it */
 	else
 	    cp = NULL;
     }
-    if (!cp)				     /* no prompt, use default */
+    if (!cp)			/* no prompt, use default */
 	StrAllocCopy(jtp->msg, jumpprompt);
-    if (jtp->msg[strlen(jtp->msg)-1] != ' ') /* ensure a trailing space */
+    if (jtp->msg[strlen(jtp->msg) - 1] != ' ')	/* ensure a trailing space */
 	StrAllocCat(jtp->msg, " ");
     jtp->history = HTList_new();
     jtp->next = JThead;
@@ -193,6 +197,7 @@ PUBLIC char *LYJump ARGS1(int, key)
 	jtp = jtp->next;
     if (!jtp) {
 	char *msg = 0;
+
 	HTSprintf0(&msg, KEY_NOT_MAPPED_TO_JUMP_FILE, key);
 	HTAlert(msg);
 	FREE(msg);
@@ -223,7 +228,7 @@ PUBLIC char *LYJump ARGS1(int, key)
     }
 
     statusline(jtp->msg);
-    if ((ch=LYgetstr(buf, VISIBLE, (sizeof(buf) - 4), recall)) < 0) {
+    if ((ch = LYgetstr(buf, VISIBLE, (sizeof(buf) - 4), recall)) < 0) {
 	/*
 	 * User cancelled the Jump via ^G. - FM
 	 */
@@ -231,7 +236,7 @@ PUBLIC char *LYJump ARGS1(int, key)
 	return NULL;
     }
 
-check_recall:
+  check_recall:
     bp = buf;
     if (toupper(key) == 'G' && strncmp(buf, "o ", 2) == 0)
 	bp++;
@@ -248,7 +253,7 @@ check_recall:
     }
 #ifdef PERMIT_GOTO_FROM_JUMP
     if (strchr(bp, ':') || strchr(bp, '/')) {
-	char *temp=NULL;
+	char *temp = NULL;
 
 	LYJumpFileURL = FALSE;
 	if (no_goto) {
@@ -257,7 +262,7 @@ check_recall:
 	    HTUserMsg(RANDOM_URL_DISALLOWED);
 	    return NULL;
 	}
-	sprintf(buf, "Go %.*s", (int)sizeof(buf) - 4, bp);
+	sprintf(buf, "Go %.*s", (int) sizeof(buf) - 4, bp);
 	return (bp = buf);
     }
 #endif /* PERMIT_GOTO_FROM_JUMP */
@@ -280,9 +285,9 @@ check_recall:
 	     * Roll around to the last Shortcut in the list. - FM
 	     */
 	    ShortcutNum = 0;
-	if ((cp=(char *)HTList_objectAt(jtp->history,
-					ShortcutNum)) != NULL) {
-	    LYstrncpy(buf, cp, sizeof(buf)-1);
+	if ((cp = (char *) HTList_objectAt(jtp->history,
+					   ShortcutNum)) != NULL) {
+	    LYstrncpy(buf, cp, sizeof(buf) - 1);
 	    if (jump_buffer && jtp->shortcut &&
 		!strcmp(buf, jtp->shortcut)) {
 		_statusline(EDIT_CURRENT_SHORTCUT);
@@ -292,8 +297,8 @@ check_recall:
 	    } else {
 		_statusline(EDIT_A_PREV_SHORTCUT);
 	    }
-	    if ((ch=LYgetstr(buf, VISIBLE,
-			     sizeof(buf), recall)) < 0) {
+	    if ((ch = LYgetstr(buf, VISIBLE,
+			       sizeof(buf), recall)) < 0) {
 		/*
 		 * User cancelled the jump via ^G.
 		 */
@@ -320,9 +325,9 @@ check_recall:
 	     * Roll around to the first Shortcut in the list. - FM
 	     */
 	    ShortcutNum = ShortcutTotal - 1;
-	if ((cp=(char *)HTList_objectAt(jtp->history,
-					ShortcutNum)) != NULL) {
-	    LYstrncpy(buf, cp, sizeof(buf)-1);
+	if ((cp = (char *) HTList_objectAt(jtp->history,
+					   ShortcutNum)) != NULL) {
+	    LYstrncpy(buf, cp, sizeof(buf) - 1);
 	    if (jump_buffer && jtp->shortcut &&
 		!strcmp(buf, jtp->shortcut)) {
 		_statusline(EDIT_CURRENT_SHORTCUT);
@@ -332,8 +337,7 @@ check_recall:
 	    } else {
 		_statusline(EDIT_THE_PREV_SHORTCUT);
 	    }
-	    if ((ch=LYgetstr(buf, VISIBLE,
-			     sizeof(buf), recall)) < 0) {
+	    if ((ch = LYgetstr(buf, VISIBLE, sizeof(buf), recall)) < 0) {
 		/*
 		 * User cancelled the jump via ^G.
 		 */
@@ -345,8 +349,8 @@ check_recall:
     }
 
     seeking.key = bp;
-    found = (JumpDatum *)bsearch((char *)&seeking, (char *)jtp->table,
-				 jtp->nel, sizeof(JumpDatum), LYCompare);
+    found = (JumpDatum *) bsearch((char *) &seeking, (char *) jtp->table,
+				  jtp->nel, sizeof(JumpDatum), LYCompare);
     if (!found) {
 	user_message("Unknown target '%s'", buf);
 	LYSleepAlert();
@@ -357,12 +361,13 @@ check_recall:
     return found ? found->url : NULL;
 }
 
-PRIVATE unsigned LYRead_Jumpfile ARGS1(struct JumpTable *,jtp)
+PRIVATE unsigned LYRead_Jumpfile ARGS1(struct JumpTable *, jtp)
 {
     struct stat st;
     unsigned int nel;
     char *mp;
     int fd;
+
 #ifdef VMS
     FILE *fp;
     BOOL IsStream_LF = TRUE;
@@ -372,19 +377,20 @@ PRIVATE unsigned LYRead_Jumpfile ARGS1(struct JumpTable *,jtp)
 
     if (jtp->file == NULL || *(jtp->file) == '\0')
 	return 0;
+
+    CTRACE((tfp, "Read Jumpfile %s\n", jtp->file));
     if (stat(jtp->file, &st) < 0) {
 	HTAlert(CANNOT_LOCATE_JUMP_FILE);
 	return 0;
     }
 
     /* allocate storage to read entire file */
-    if ((mp= typecallocn(char, st.st_size + 1)) == NULL) {
+    if ((mp = typecallocn(char, st.st_size + 1)) == NULL) {
 	HTAlert(OUTOF_MEM_FOR_JUMP_FILE);
 	return 0;
     }
-
 #ifdef VMS
-    if (st.st_fab_rfm != (char)FAB$C_STMLF) {
+    if (st.st_fab_rfm != (char) FAB$C_STMLF) {
 	/** It's a record-oriented file. **/
 	IsStream_LF = FALSE;
 	if ((fp = fopen(jtp->file, "r", "mbc=32")) == NULL) {
@@ -392,38 +398,37 @@ PRIVATE unsigned LYRead_Jumpfile ARGS1(struct JumpTable *,jtp)
 	    FREE(mp);
 	    return 0;
 	}
-    } else
-    if ((fd=open(jtp->file, O_RDONLY, "mbc=32")) < 0)
+    } else if ((fd = open(jtp->file, O_RDONLY, "mbc=32")) < 0)
 #else
-    if ((fd=open(jtp->file, O_RDONLY)) < 0)
+    if ((fd = open(jtp->file, O_RDONLY)) < 0)
 #endif /* VMS */
     {
 	HTAlert(CANNOT_OPEN_JUMP_FILE);
 	FREE(mp);
 	return 0;
     }
-
 #ifdef VMS
     if (IsStream_LF) {
     /** Handle as a stream. **/
 #endif /* VMS */
-    if (read(fd, mp, st.st_size) < st.st_size) {
-	HTAlert(ERROR_READING_JUMP_FILE);
-	FREE(mp);
-	return 0;
-    }
-    mp[st.st_size] = '\0';
-    close(fd);
+	if (read(fd, mp, st.st_size) < st.st_size) {
+	    HTAlert(ERROR_READING_JUMP_FILE);
+	    FREE(mp);
+	    return 0;
+	}
+	mp[st.st_size] = '\0';
+	close(fd);
 #ifdef VMS
     } else {
-    /** Handle as a series of records. **/
-    if(fgets(mp, 1024, fp) == NULL) {
-	HTAlert(ERROR_READING_JUMP_FILE);
-	FREE(mp);
-	return 0;
-    } else
-	while(fgets(mp+strlen(mp), 1024, fp) != NULL)
-	    ;
+	/** Handle as a series of records. **/
+	if (fgets(mp, 1024, fp) == NULL) {
+	    HTAlert(ERROR_READING_JUMP_FILE);
+	    FREE(mp);
+	    return 0;
+	} else
+	    while (fgets(mp + strlen(mp), 1024, fp) != NULL) {
+		;
+	    }
 	LYCloseInput(fp);
     }
 #endif /* VMS */
@@ -431,12 +436,12 @@ PRIVATE unsigned LYRead_Jumpfile ARGS1(struct JumpTable *,jtp)
     /* quick scan for approximate number of entries */
     nel = 0;
     cp = mp;
-    while((cp = strchr(cp, '\n')) != NULL) {
+    while ((cp = strchr(cp, '\n')) != NULL) {
 	nel++;
 	cp++;
     }
 
-    jtp->table = (JumpDatum *)malloc(nel * sizeof(JumpDatum));
+    jtp->table = (JumpDatum *) malloc(nel * sizeof(JumpDatum));
     if (jtp->table == NULL) {
 	HTAlert(OUTOF_MEM_FOR_JUMP_TABLE);
 	FREE(mp);
@@ -476,6 +481,8 @@ PRIVATE unsigned LYRead_Jumpfile ARGS1(struct JumpTable *,jtp)
 	if (cp == NULL)
 	    break;
 	cp++;
+	CTRACE((tfp, "Read jumpfile[%d] key='%s', url='%s'\n",
+		i, jtp->table[i].key, jtp->table[i].url));
 	i++;
 	if (!cp)
 	    break;
@@ -484,7 +491,8 @@ PRIVATE unsigned LYRead_Jumpfile ARGS1(struct JumpTable *,jtp)
     return i;
 }
 
-PRIVATE int LYCompare ARGS2 (CONST void *, e1, CONST void *, e2)
+PRIVATE int LYCompare ARGS2(CONST void *, e1, CONST void *, e2)
 {
-    return strcasecomp(((CONST JumpDatum *)e1)->key, ((CONST JumpDatum *)e2)->key);
+    return strcasecomp(((CONST JumpDatum *) e1)->key,
+		       ((CONST JumpDatum *) e2)->key);
 }
diff --git a/src/LYKeymap.c b/src/LYKeymap.c
index 32af4a41..7a51bcfa 100644
--- a/src/LYKeymap.c
+++ b/src/LYKeymap.c
@@ -1172,9 +1172,9 @@ PUBLIC char *LYKeycodeToString ARGS2 (
 	else if (c < ' ')
 	    sprintf(buf, "^%c", c|0100);
 	else if (c >= 0400)
-	    sprintf(buf, "key-%#x", c);
+	    sprintf(buf, "key-0x%x", c);
 	else
-	    sprintf(buf, "%#x", c);
+	    sprintf(buf, "0x%x", c);
     }
     return buf;
 }
@@ -1186,11 +1186,16 @@ PUBLIC int LYStringToKeycode ARGS1 (
     int key = -1;
     int len = strlen(src);
 
-    if (len == 1)
+    if (len == 1) {
 	key = *src;
-    else if (len == 2 && *src == '^')
+    } else if (len == 2 && *src == '^') {
 	key = src[1] & 0x1f;
-    else if (len > 6 && !strncasecomp(src, "key-", 4)) {
+    } else if (len > 2 && !strncasecomp(src, "0x", 2)) {
+	char *dst = 0;
+	key = strtol(src, &dst, 0);
+	if (dst == 0 || *dst != 0)
+	    key = -1;
+    } else if (len > 6 && !strncasecomp(src, "key-", 4)) {
 	char *dst = 0;
 	key = strtol(src + 4, &dst, 0);
 	if (dst == 0 || *dst != 0)
diff --git a/src/LYList.c b/src/LYList.c
index 1606a3af..20c28d8d 100644
--- a/src/LYList.c
+++ b/src/LYList.c
@@ -14,6 +14,7 @@
 #include <LYGlobalDefs.h>
 #include <LYCharUtils.h>
 #include <LYCharSets.h>
+#include <LYHistory.h>
 
 #ifdef DIRED_SUPPORT
 #include <LYUpload.h>
@@ -35,7 +36,7 @@
 
 
 PUBLIC int showlist ARGS2(
-	document *,	newdoc,
+	DocInfo *,	newdoc,
 	BOOLEAN,	titles)
 {
     int cnt;
@@ -170,7 +171,7 @@ PUBLIC int showlist ARGS2(
 	    LYformTitle(&Title, title);
 	    LYEntify(&Title, TRUE);
 	    if (*Title) {
-		cp = strchr(Address, '#');
+		cp = findPoundSelector(Address);
 	    } else {
 		FREE(Title);
 	    }
@@ -178,7 +179,7 @@ PUBLIC int showlist ARGS2(
 
 	fprintf(fp0, "<li><a href=\"%s\"%s>%s%s%s%s%s</a>\n", Address,
 			dest_intl ? " TYPE=\"internal link\"" : "",
-			LinkTitle ? LinkTitle : "",
+			NonNull(LinkTitle),
 			((HTAnchor*)parent != dest) && Title ? "in " : "",
 			(char *)(Title ? Title : Address),
 			(Title && cp) ? " - " : "",
@@ -230,8 +231,7 @@ PUBLIC int showlist ARGS2(
     if (intern_w_post) {
 	newdoc->internal_link = TRUE;
     } else {
-	FREE(newdoc->post_data);
-	FREE(newdoc->post_content_type);
+	LYFreePostData(newdoc);
 	newdoc->internal_link = FALSE;
     }
     newdoc->isHEAD = FALSE;
diff --git a/src/LYList.h b/src/LYList.h
index 3c8e4c4e..dd0dee9f 100644
--- a/src/LYList.h
+++ b/src/LYList.h
@@ -3,7 +3,7 @@
 
 #include <LYStructs.h>
 
-extern int showlist PARAMS((document *newdoc, BOOLEAN titles));
+extern int showlist PARAMS((DocInfo *newdoc, BOOLEAN titles));
 extern void printlist PARAMS((FILE *fp, BOOLEAN titles));
 
 #endif /* LYLIST_H */
diff --git a/src/LYLocal.c b/src/LYLocal.c
index 1183b30e..c627315c 100644
--- a/src/LYLocal.c
+++ b/src/LYLocal.c
@@ -344,7 +344,7 @@ PRIVATE int LYExecv ARGS3(
     HTSprintf(&tmpbuf, "\n");
     rc = LYSystem(tmpbuf) ? 0 : 1;
 #else
-    pid_t pid;
+    int pid;
 #ifdef HAVE_TYPE_UNIONWAIT
     union wait wstatus;
 #else
@@ -393,8 +393,10 @@ PRIVATE int LYExecv ARGS3(
 		break;
 	    }
 #endif /* !HAVE_WAITPID */
-	    if (WEXITSTATUS(wstatus) != 0 ||
-		WTERMSIG(wstatus) > 0)	{ /* error return */
+	    if ((WIFEXITED(wstatus)
+	      && (WEXITSTATUS(wstatus) != 0))
+	     || (WIFSIGNALED(wstatus)
+	      && (WTERMSIG(wstatus) > 0)))	{ /* error return */
 		HTSprintf0(&tmpbuf, gettext("Probable failure to %s due to system error!"),
 				   msg);
 		rc = 0;
@@ -668,18 +670,18 @@ PRIVATE int modify_tagged ARGS1(
 	    if (cp) {
 		cp = strip_trailing_slash(cp);
 		cp = HTParse(".", cp, PARSE_PATH+PARSE_PUNCTUATION);
-		savepath = HTURLPath_toFile(cp, TRUE);
+		savepath = HTURLPath_toFile(cp, TRUE, FALSE);
 		FREE(cp);
 	    } else {	/* Last resort, should never happen. */
-		savepath = HTURLPath_toFile(".", TRUE);
+		savepath = HTURLPath_toFile(".", TRUE, FALSE);
 	    }
 	} else {
 	    if (!strncmp(cp, "file://localhost", 16)) {
 		cp += 16;
-	    } else if (!strncmp(cp, "file:", 5)) {
-		cp += 5;
+	    } else if (isFILE_URL(cp)) {
+		cp += LEN_FILE_URL;
 	    }
-	    savepath = HTURLPath_toFile(cp, TRUE);
+	    savepath = HTURLPath_toFile(cp, TRUE, FALSE);
 	}
 
 	if (!ok_stat(savepath, &dir_info)) {
@@ -925,7 +927,7 @@ PRIVATE int modify_location ARGS1(
  *  Modify name or location of a file or directory on localhost.
  */
 PUBLIC int local_modify ARGS2(
-	document *,	doc,
+	DocInfo *,	doc,
 	char **,	newpath)
 {
     int ans;
@@ -1079,7 +1081,7 @@ PRIVATE int create_directory ARGS1(
  *  Create a file or a directory at the current location.
  */
 PUBLIC int local_create ARGS1(
-	document *,	doc)
+	DocInfo *,	doc)
 {
     int ans;
     char *cp;
@@ -1169,7 +1171,7 @@ PRIVATE int remove_single ARGS1(
  *  Remove a file or a directory.
  */
 PUBLIC int local_remove ARGS1(
-	document *,	doc)
+	DocInfo *,	doc)
 {
     char *cp, *tp;
     char testpath[DIRED_MAXBUF];
@@ -1286,8 +1288,8 @@ PRIVATE int permit_location ARGS3(
 	     *	Prevent filenames which include '#' or '?' from messing it up.
 	     */
 	    char * srcpath_url = HTEscape(srcpath, URL_PATH);
-	    fprintf(fp0, "<Form Action=\"LYNXDIRED://PERMIT_LOCATION%s\">\n",
-		    srcpath_url);
+	    fprintf(fp0, "<Form Action=\"%s//PERMIT_LOCATION%s\">\n",
+		    STR_LYNXDIRED, srcpath_url);
 	    FREE(srcpath_url);
 	}
 
@@ -1380,7 +1382,7 @@ PRIVATE int permit_location ARGS3(
 			   start working on the masks. */
 
 	/* Will now operate only on filename part. */
-	if ((destpath = HTURLPath_toFile(destpath, TRUE)) == 0)
+	if ((destpath = HTURLPath_toFile(destpath, TRUE, FALSE)) == 0)
 		return(0);
 	if (strlen(destpath) >= LY_MAXPATH) {
 	    FREE(destpath);
@@ -1536,12 +1538,14 @@ PRIVATE char * DirectoryOf ARGS1(
 	char *,		pathname)
 {
     char *result = 0;
-    char *result1 = 0;
     char *leaf;
 
     StrAllocCopy(result, pathname);
     leaf = LYPathLeaf(result);
+
     if (leaf != result) {
+	CONST char *result1 = 0;
+
 	*leaf = '\0';
 	if (!LYisRootPath(result))
 	    LYTrimPathSep(result);
@@ -1591,7 +1595,7 @@ PRIVATE char * match_op ARGS2(
     if (!strncmp("LYNXDIRED://", data, 12)
      && !strncmp(prefix, data + 12, (unsigned)len)) {
 	len += 12;
-#if defined(DOSPATH) || defined(__EMX__)
+#if defined(USE_DOS_DRIVES)
 	if (data[len] == '/') {	/* this is normal */
 	    len++;
 	}
@@ -1779,7 +1783,7 @@ PRIVATE char *build_command ARGS3(
  *  doesn't look like a clean way.)
  */
 PUBLIC int local_dired ARGS1(
-	document *,	doc)
+	DocInfo *,	doc)
 {
     char *line_url;    /* will point to doc's address, which is a URL */
     char *line = NULL; /* same as line_url, but HTUnEscaped, will be alloced */
@@ -1907,7 +1911,7 @@ PUBLIC int local_dired ARGS1(
  *  Provide a menu of file management options.
  */
 PUBLIC int dired_options ARGS2(
-	document *,	doc,
+	DocInfo *,	doc,
 	char **,	newfile)
 {
     static char tempfile[LY_MAXPATH];
@@ -2107,6 +2111,7 @@ PRIVATE void clear_install_path NOARGS
     FREE(install_path);
 }
 #endif /* LY_FIND_LEAKS */
+
 /*
  *  Fill in args array for execv (or execvp etc.) call, after first
  *  allocating it if necessary.  No fancy parsing, cmd_args is just
@@ -2160,6 +2165,7 @@ PRIVATE int fill_argv_for_execv ARGS5(
     args[n] = (char *)0;
     return(n);
 }
+
 /*
  *  Install the specified file or directory.
  */
@@ -2277,10 +2283,7 @@ PUBLIC BOOLEAN local_install ARGS3(
 	    return(-1);		/* don't do it */
 	} else if (!strncmp(savepath, destpath, strlen(destpath)) &&
 		   LYIsPathSep(savepath[strlen(destpath)]) &&
-#ifdef DOSPATH
-		   !strchr(savepath + strlen(destpath) + 1, '\\') &&
-#endif
-		   !strchr(savepath + strlen(destpath) + 1, '/')) {
+		   LYLastPathSep(savepath + strlen(destpath) + 1) == 0) {
 	    HTUserMsg2(gettext("Already in target directory: %s"),
 		       savepath);
 	    FREE(tmpdest);
@@ -2309,10 +2312,7 @@ PUBLIC BOOLEAN local_install ARGS3(
 		continue;	/* skip this source file */
 	    } else if (!strncmp(args[src], destpath, strlen(destpath)) &&
 		       LYIsPathSep(args[src][strlen(destpath)]) &&
-#ifdef DOSPATH
-		       !strchr(args[src] + strlen(destpath) + 1, '\\') &&
-#endif
-		       !strchr(args[src] + strlen(destpath) + 1, '/')) {
+		       LYLastPathSep(args[src] + strlen(destpath) + 1) == 0) {
 		HTUserMsg2(gettext("Already in target directory: %s"),
 			   args[src]);
 		FREE(args[src]);
diff --git a/src/LYLocal.h b/src/LYLocal.h
index 4a9f5636..02044ee2 100644
--- a/src/LYLocal.h
+++ b/src/LYLocal.h
@@ -8,9 +8,9 @@
 /* Special return code for LYMainLoop.c */
 #define PERMIT_FORM_RESULT (-99)
 
-extern int local_create PARAMS((document *doc));
-extern int local_modify PARAMS((document *doc, char **newpath));
-extern int local_remove PARAMS((document *doc));
+extern int local_create PARAMS((DocInfo *doc));
+extern int local_modify PARAMS((DocInfo *doc, char **newpath));
+extern int local_remove PARAMS((DocInfo *doc));
 #ifdef OK_INSTALL
 extern BOOLEAN local_install PARAMS((char *destpath, char *srcpath, char **newpath));
 #endif
@@ -18,8 +18,8 @@ extern BOOLEAN local_install PARAMS((char *destpath, char *srcpath, char **newpa
 /* MainLoop needs to know about this one for atexit cleanup */
 extern void clear_tags NOPARAMS;
 
-extern int dired_options PARAMS ((document *doc, char ** newfile));
-extern int local_dired PARAMS((document *doc));
+extern int dired_options PARAMS ((DocInfo *doc, char ** newfile));
+extern int local_dired PARAMS((DocInfo *doc));
 extern void add_menu_item PARAMS((char *str));
 extern void reset_dired_menu NOPARAMS;
 extern void showtags PARAMS((HTList *tag));
diff --git a/src/LYMail.c b/src/LYMail.c
index 4fbf79a4..5a0f3eac 100644
--- a/src/LYMail.c
+++ b/src/LYMail.c
@@ -25,7 +25,7 @@ PRIVATE void terminate_letter ARGS1(int,sig GCC_UNUSED)
     term_letter = TRUE;
     /* Reassert the AST */
     signal(SIGINT, terminate_letter);
-#if USE_VMS_MAILER || defined(DOSPATH) || defined(WIN_EX)
+#if USE_VMS_MAILER || defined(PDCURSES)
     /*
      *	Refresh the screen to get rid of the "interrupt" message.
      */
@@ -350,7 +350,7 @@ PRIVATE char *blat_cmd(
 		subject,
 		system_mail_flags,
 		ccaddr? " -c \"" : "",
-		ccaddr? ccaddr : "",
+		NonNull(ccaddr),
 		ccaddr? "\"" : "");
 
 #else /* !USE_ALT_BLAT_MAILER */
@@ -496,7 +496,7 @@ PUBLIC int LYSendMailFile ARGS5(
     else
 #endif
 #ifdef __DJGPP__
-	if ((shell = getenv("SHELL")) != NULL) {
+	if ((shell = LYGetEnv("SHELL")) != NULL) {
 	    if (strstr(shell, "sh") != NULL) {
 		HTSprintf0(&cmd, "%s -c %s -t \"%s\" -F %s",
 			   shell,
@@ -709,7 +709,7 @@ PUBLIC void mailform ARGS4(
     if (!EMPTY(keywords))
 	fprintf(fd, "Keywords: %s\n", keywords);
     _statusline(SENDING_FORM_CONTENT);
-#else	/* e.g., VMS, DOSPATH */
+#else	/* e.g., VMS, DOS */
     if ((fd = LYOpenTemp(my_tmpfile, ".txt", "w")) == NULL) {
 	HTAlert(FORM_MAILTO_FAILED);
 	goto cleanup;
@@ -848,7 +848,7 @@ PUBLIC void mailform ARGS4(
     LYRemoveTemp(my_tmpfile);
     if (isPMDF)
 	LYRemoveTemp(hdrfile);
-#else /* DOSPATH */
+#else /* DOS */
     LYSendMailFile (
 	address,
 	my_tmpfile,
@@ -1064,7 +1064,7 @@ PUBLIC void mailmsg ARGS4(
     if (isPMDF) {
 	LYRemoveTemp(hdrfile);
     }
-#else /* DOSPATH */
+#else /* DOS */
     LYSendMailFile (
 	address,
 	my_tmpfile,
@@ -1253,7 +1253,7 @@ PUBLIC void reply_by_mail ARGS4(
 	 */
 	fprintf((isPMDF ? hfd : fd),
 		"X-URL: %s%s\n",
-		EMPTY(filename) ? "mailto:" : filename,
+		EMPTY(filename) ? STR_MAILTO_URL : filename,
 		EMPTY(filename) ? to_address : "");
 	fprintf((isPMDF ? hfd : fd),
 		"X-Mailer: %s, Version %s\n", LYNX_NAME, LYNX_VERSION);
diff --git a/src/LYMain.c b/src/LYMain.c
index e8905b90..5dfa4cb3 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -60,8 +60,10 @@
 
 #ifdef FNAMES_8_3
 #define COOKIE_FILE "cookies"
+#define TRACE_FILE "LY-TRACE.LOG"
 #else
 #define COOKIE_FILE ".lynx_cookies"
+#define TRACE_FILE "Lynx.trace"
 #endif /* FNAMES_8_3 */
 
 /* ahhhhhhhhhh!! Global variables :-< */
@@ -429,6 +431,7 @@ PUBLIC int LYStatusLine = -1;		/* Line for statusline() if > -1 */
 PUBLIC int LYcols = DFT_COLS;
 PUBLIC int LYlines = DFT_ROWS;
 PUBLIC int MessageSecs;			/* time-delay for important Messages   */
+PUBLIC int ReplaySecs;			/* time-delay for command-scripts */
 PUBLIC int ccount = 0;			/* Starting number for lnk#.dat files in crawls */
 PUBLIC int dump_output_width = 0;
 PUBLIC int lynx_temp_subspace = 0;	/* > 0 if we made temp-directory */
@@ -693,9 +696,6 @@ PRIVATE void free_lynx_globals NOARGS
     FREE(URLDomainPrefixes);
     FREE(URLDomainSuffixes);
     FREE(XLoadImageCommand);
-#ifndef VMS
-    FREE(lynx_version_putenv_command);
-#endif
     FREE(lynx_temp_space);
     FREE(LYTraceLogPath);
     FREE(lynx_cfg_file);
@@ -923,7 +923,7 @@ PUBLIC int main ARGS2(
 
 #endif /* _WINDOWS */
 
-#if defined(__CYGWIN__) && defined(DOSPATH)
+#if defined(__CYGWIN__)
     if (strcmp(ttyname(fileno(stdout)), "/dev/conout") != 0) {
 	printf("please \"$CYGWIN=notty\"\n");
 	exit(EXIT_SUCCESS);
@@ -964,7 +964,7 @@ PUBLIC int main ARGS2(
     SetOutputMode(O_BINARY);
 
 #ifdef DOSPATH
-    if (getenv("TERM")==NULL) putenv("TERM=vt100");
+    if (LYGetEnv("TERM")==NULL) putenv("TERM=vt100");
 #endif
 
     LYShowColor = (SHOW_COLOR ? SHOW_COLOR_ON : SHOW_COLOR_OFF);
@@ -973,12 +973,7 @@ PUBLIC int main ARGS2(
      */
     pgm = argv[0];
     cp = NULL;
-#ifdef DOSPATH
-    if ((cp = strrchr(pgm, '\\')) != NULL) {
-	pgm = cp + 1;
-    } else if (cp == NULL)
-#endif
-    if ((cp = strrchr(pgm, '/')) != NULL) {
+    if ((cp = LYLastPathSep(pgm)) != NULL) {
 	pgm = cp + 1;
     }
 
@@ -1016,9 +1011,11 @@ PUBLIC int main ARGS2(
     setlocale(LC_ALL, "");
 #endif /* LOCALE */
     /* Set the text message domain.  */
-#ifdef HAVE_LIBINTL_H
+#if defined(HAVE_LIBINTL_H) || defined(HAVE_LIBGETTEXT_H)
 #ifndef __DJGPP__
-    bindtextdomain ("lynx", LOCALEDIR);
+    if ((cp = LYGetEnv("LYNX_LOCALDIR")) == 0)
+	cp = LOCALEDIR;
+    bindtextdomain ("lynx", cp);
 #endif /* !__DJGPP__ */
     textdomain ("lynx");
 #endif /* HAVE_LIBINTL_H */
@@ -1030,7 +1027,7 @@ PUBLIC int main ARGS2(
     /*
      *	Need this for Ultrix.
      */
-    terminal = getenv("TERM");
+    terminal = LYGetEnv("TERM");
     if ((terminal == NULL) || !strncasecomp(terminal, "xterm", 5))
 	terminal = "vt100";
 #endif /* ULTRIX */
@@ -1048,18 +1045,13 @@ PUBLIC int main ARGS2(
     StrAllocCopy(list_format, LIST_FORMAT);
 #endif /* !VMS */
 
-#ifdef HAVE_NAPMS
-#define SECS2Secs(n) (1000 * (n))
-#else
-#define SECS2Secs(n) (n)
-#endif
     InfoSecs	= SECS2Secs(INFOSECS);
-    MessageSecs = SECS2Secs(MESSAGESECS);
+    MessageSecs	= SECS2Secs(MESSAGESECS);
     AlertSecs	= SECS2Secs(ALERTSECS);
 
     StrAllocCopy(helpfile, HELPFILE);
     StrAllocCopy(startfile, STARTFILE);
-    LYTrimStartfile(startfile);
+    LYEscapeStartfile(&startfile);
     StrAllocCopy(indexfile, DEFAULT_INDEX_FILE);
     StrAllocCopy(global_type_map, GLOBAL_MAILCAP);
     StrAllocCopy(personal_type_map, PERSONAL_MAILCAP);
@@ -1102,16 +1094,16 @@ PUBLIC int main ARGS2(
      */
 #endif /* VMS */
 
-    if ((cp = getenv("LYNX_TEMP_SPACE")) != NULL)
+    if ((cp = LYGetEnv("LYNX_TEMP_SPACE")) != NULL)
 	StrAllocCopy(lynx_temp_space, cp);
 #if defined (UNIX) || defined (__DJGPP__)
-    else if ((cp = getenv("TMPDIR")) != NULL)
+    else if ((cp = LYGetEnv("TMPDIR")) != NULL)
 	StrAllocCopy(lynx_temp_space, cp);
 #endif
 #if defined (DOSPATH) || defined (__EMX__)
-    else if ((cp = getenv("TEMP")) != NULL)
+    else if ((cp = LYGetEnv("TEMP")) != NULL)
 	StrAllocCopy(lynx_temp_space, cp);
-    else if ((cp = getenv("TMP")) != NULL)
+    else if ((cp = LYGetEnv("TMP")) != NULL)
 	StrAllocCopy(lynx_temp_space, cp);
 #endif
     else
@@ -1132,7 +1124,7 @@ PUBLIC int main ARGS2(
     if ((cp = strstr(lynx_temp_space, "$USER")) != NULL) {
 	char *cp1;
 
-	if ((cp1 = getenv("USER")) != NULL) {
+	if ((cp1 = LYGetEnv("USER")) != NULL) {
 	    *cp = '\0';
 	    StrAllocCopy(temp, lynx_temp_space);
 	    *cp = '$';
@@ -1166,7 +1158,7 @@ PUBLIC int main ARGS2(
 #endif /* VMS */
 
     if ((HTStat(lynx_temp_space, &dir_info) < 0
-#ifdef UNIX
+#if defined(MULTI_USER_UNIX)
 	&& mkdir(lynx_temp_space, 0700) < 0
 #endif
 	)
@@ -1224,7 +1216,7 @@ PUBLIC int main ARGS2(
      *	the help menu, output that and exit. - FM
      */
 #ifndef NO_LYNX_TRACE
-    if (getenv("LYNX_TRACE") != 0) {
+    if (LYGetEnv("LYNX_TRACE") != 0) {
 	WWW_TraceFlag = TRUE;
     }
 #endif
@@ -1308,7 +1300,7 @@ PUBLIC int main ARGS2(
     if (!LYValidate && !LYRestricted &&
 	strlen(ANONYMOUS_USER) > 0 &&
 #if defined (VMS) || defined (NOUSERS)
-	!strcasecomp((getenv("USER")==NULL ? " " : getenv("USER")),
+	!strcasecomp((LYGetEnv("USER")==NULL ? " " : LYGetEnv("USER")),
 		     ANONYMOUS_USER)
 #else
 #if HAVE_CUSERID
@@ -1326,13 +1318,9 @@ PUBLIC int main ARGS2(
     /*
      *	Set up the TRACE log path, and logging if appropriate. - FM
      */
-#ifdef FNAMES_8_3
-    LYAddPathToHome(LYTraceLogPath =
-		malloc(LY_MAXPATH), LY_MAXPATH, "LY-TRACE.LOG");
-#else
-    LYAddPathToHome(LYTraceLogPath =
-		malloc(LY_MAXPATH), LY_MAXPATH, "Lynx.trace");
-#endif
+    if ((cp = LYGetEnv("LYNX_TRACE_FILE")) == 0)
+	cp = TRACE_FILE;
+    LYAddPathToHome(LYTraceLogPath = malloc(LY_MAXPATH), LY_MAXPATH, cp);
 
     LYOpenTraceLog();
 
@@ -1374,8 +1362,8 @@ PUBLIC int main ARGS2(
      *	the command line, see if it's in the environment.
      */
     if (!lynx_cfg_file) {
-	if (((cp=getenv("LYNX_CFG")) != NULL) ||
-	    (cp=getenv("lynx_cfg")) != NULL)
+	if (((cp=LYGetEnv("LYNX_CFG")) != NULL) ||
+	    (cp=LYGetEnv("lynx_cfg")) != NULL)
 	    StrAllocCopy(lynx_cfg_file, cp);
     }
 
@@ -1444,8 +1432,8 @@ PUBLIC int main ARGS2(
      *	the command line, see if it's in the environment.
      */
     if (!lynx_lss_file) {
-	if (((cp=getenv("LYNX_LSS")) != NULL) ||
-	    (cp=getenv("lynx_lss")) != NULL)
+	if (((cp=LYGetEnv("LYNX_LSS")) != NULL) ||
+	    (cp=LYGetEnv("lynx_lss")) != NULL)
 	    StrAllocCopy(lynx_lss_file, cp);
     }
 
@@ -1483,7 +1471,7 @@ PUBLIC int main ARGS2(
      *  Set the original directory, used for default download
      */
     if (!strcmp(Current_Dir(filename), ".")) {
-	if ((cp = getenv("PWD")) != 0)
+	if ((cp = LYGetEnv("PWD")) != 0)
 	    StrAllocCopy(original_dir, cp);
     } else {
 	StrAllocCopy(original_dir, filename);
@@ -1520,9 +1508,9 @@ PUBLIC int main ARGS2(
     /*
      * Get WWW_HOME environment variable if it exists.
      */
-    if ((cp = getenv("WWW_HOME")) != NULL) {
+    if ((cp = LYGetEnv("WWW_HOME")) != NULL) {
 	StrAllocCopy(startfile, cp);
-	LYTrimStartfile(startfile);
+	LYEscapeStartfile(&startfile);
     }
 
     /*
@@ -1560,24 +1548,6 @@ PUBLIC int main ARGS2(
 	switch_display_charsets = 1;
 #endif
 
-#undef TTY_DEVICE
-#undef NUL_DEVICE
-
-#ifdef VMS
-#define TTY_DEVICE "tt:"
-#define NUL_DEVICE "nl:"
-#endif
-
-#ifdef _WINDOWS
-#define TTY_DEVICE "con"
-#define NUL_DEVICE "nul"
-#endif
-
-#ifndef TTY_DEVICE
-#define TTY_DEVICE "/dev/tty"
-#define NUL_DEVICE "/dev/null"
-#endif
-
 #if defined (TTY_DEVICE) || defined(HAVE_TTYNAME)
     /*
      *	If we are told to read the startfile from standard input, do it now,
@@ -1657,9 +1627,9 @@ PUBLIC int main ARGS2(
 
     if (LYCookieSaveFile == NULL) {
 	if (dump_output_immediately) {
-		StrAllocCopy(LYCookieSaveFile, "/dev/null");
+	    StrAllocCopy(LYCookieSaveFile, "/dev/null");
 	} else {
-		StrAllocCopy(LYCookieSaveFile, LYCookieFile);
+	    StrAllocCopy(LYCookieSaveFile, LYCookieFile);
 	}
     }
 #endif
@@ -1677,7 +1647,7 @@ PUBLIC int main ARGS2(
      *	If one was set in the configuration file, that
      *	one will be overridden. - FM
      */
-    if ((cp=getenv("LYNX_SAVE_SPACE")) != NULL)
+    if ((cp = LYGetEnv("LYNX_SAVE_SPACE")) != NULL)
 	StrAllocCopy(lynx_save_space, cp);
 
     /*
@@ -1735,7 +1705,7 @@ PUBLIC int main ARGS2(
 	!(Lynx_Color_Flags & SL_LYNX_USE_COLOR)) {
 	Lynx_Color_Flags |= SL_LYNX_USE_COLOR;
     } else if ((Lynx_Color_Flags & SL_LYNX_USE_COLOR) ||
-	       getenv("COLORTERM") != NULL) {
+	       LYGetEnv("COLORTERM") != NULL) {
 	if (LYShowColor != SHOW_COLOR_NEVER &&
 	    LYShowColor != SHOW_COLOR_ALWAYS) {
 	    LYShowColor = SHOW_COLOR_ON;
@@ -1853,8 +1823,9 @@ PUBLIC int main ARGS2(
 #ifdef WIN32
     SetConsoleCtrlHandler((PHANDLER_ROUTINE) cleanup_win32, TRUE);
 #endif
-    if (!dump_output_immediately)
+
 #ifndef NOSIGHUP
+    if (!dump_output_immediately)
 	(void) signal(SIGHUP, cleanup_sig);
 #endif /* NOSIGHUP */
 
@@ -2283,6 +2254,20 @@ PUBLIC void reload_read_cfg NOARGS
 }
 #endif /* !NO_CONFIG_INFO */
 
+PRIVATE void disable_pausing NOARGS
+{
+    InfoSecs = 0;
+    MessageSecs = 0;
+    AlertSecs = 0;
+    ReplaySecs = 0;
+}
+
+PRIVATE void force_dump_mode NOARGS
+{
+    dump_output_immediately = TRUE;
+    disable_pausing();
+    LYcols = DFT_COLS;
+}
 
 /* There are different ways of setting arguments on the command line, and
  * there are different types of arguments.  These include:
@@ -2552,8 +2537,7 @@ PRIVATE int display_charset_fun ARGS1(
 PRIVATE int dump_output_fun ARGS1(
 	char *,			next_arg GCC_UNUSED)
 {
-    dump_output_immediately = TRUE;
-    LYcols = DFT_COLS;
+    force_dump_mode();
     return 0;
 }
 
@@ -2612,8 +2596,7 @@ PRIVATE int get_data_fun ARGS1(
      *  potential conflicts, so don't force the dump here. - FM
      */
 #ifndef VMS
-    dump_output_immediately = TRUE;
-    LYcols = DFT_COLS;
+    force_dump_mode();
 #endif /* VMS */
 
     StrAllocCopy(form_get_data, "?");   /* Prime the pump */
@@ -2642,14 +2625,15 @@ PRIVATE int help_fun ARGS1(
 PRIVATE int hiddenlinks_fun ARGS1(
 	char *,			next_arg)
 {
+    static Config_Enum table[] = {
+	{ "merge",	HIDDENLINKS_MERGE },
+	{ "listonly",	HIDDENLINKS_SEPARATE },
+	{ "ignore",	HIDDENLINKS_IGNORE },
+	{ NULL,		-1 },
+    };
+
     if (next_arg != 0) {
-	if (strncasecomp(next_arg, "merge", 1) == 0)
-	    LYHiddenLinks = HIDDENLINKS_MERGE;
-	else if (strncasecomp(next_arg, "listonly", 1) == 0)
-	    LYHiddenLinks = HIDDENLINKS_SEPARATE;
-	else if (strncasecomp(next_arg, "ignore", 1) == 0)
-	    LYHiddenLinks = HIDDENLINKS_IGNORE;
-	else
+	if (!LYgetEnum(table, next_arg, &LYHiddenLinks))
 	    print_help_and_exit (-1);
     } else {
 	LYHiddenLinks = HIDDENLINKS_MERGE;
@@ -2664,7 +2648,7 @@ PRIVATE int homepage_fun ARGS1(
 {
     if (next_arg != 0) {
 	StrAllocCopy(homepage, next_arg);
-	LYTrimStartfile(homepage);
+	LYEscapeStartfile(&homepage);
     }
     return 0;
 }
@@ -2677,7 +2661,7 @@ PRIVATE int mime_header_fun ARGS1(
      *  Include mime headers and force source dump.
      */
     keep_mime_headers = TRUE;
-    dump_output_immediately = TRUE;
+    force_dump_mode();
     HTOutputFormat = (LYPrependBase ?
 		      HTAtom_for("www/download") : HTAtom_for("www/dump"));
     LYcols = MAX_COLS;
@@ -2750,9 +2734,7 @@ PRIVATE int nocolor_fun ARGS1(
 PRIVATE int nopause_fun ARGS1(
 	char *,			next_arg GCC_UNUSED)
 {
-    InfoSecs = 0;
-    MessageSecs = 0;
-    AlertSecs = 0;
+    disable_pausing();
     return 0;
 }
 
@@ -2813,8 +2795,7 @@ PRIVATE int post_data_fun ARGS1(
      * conflicts, so don't force a dump here.  - FM
      */
 #ifndef VMS
-    dump_output_immediately = TRUE;
-    LYcols = DFT_COLS;
+    force_dump_mode();
 #endif /* VMS */
 
     post_data = &form_post_data;
@@ -2829,6 +2810,25 @@ PRIVATE int post_data_fun ARGS1(
     return 0;
 }
 
+PRIVATE char *show_restriction ARGS1(
+	CONST char *,		name)
+{
+    char *value = 0;
+
+    switch (find_restriction(name, -1)) {
+    case TRUE:
+	value = "on";
+	break;
+    case FALSE:
+	value = "off";
+	break;
+    default:
+	value = "?";
+	break;
+    }
+    return value;
+}
+
 /* -restrictions */
 PRIVATE int restrictions_fun ARGS1(
 	char *,			next_arg)
@@ -2846,11 +2846,16 @@ disallow changing the eXecute permission on files\n\
 (but still allow it for directories) when local file\n\
 management is enabled." },
 #endif /* DIRED_SUPPORT && OK_PERMIT */
+#ifdef SUPPORT_CHDIR
+	{ "chdir", "\
+disallow changing the working directory of lynx, e.g.,\n\
+to affect the behavior of download command" },
+#endif
 #if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO)
 	{ "compileopts_info", "\
 disable info on options used to compile the binary" },
 #endif
-{ "default", "\
+	{ "default", "\
 same as commandline option -anonymous.  Sets the\n\
 default service restrictions for anonymous users.  Set to\n\
 all restricted, except for: inside_telnet, outside_telnet,\n\
@@ -2907,6 +2912,8 @@ disable viewing of lynx.cfg configuration file info" },
 	{ "lynxcfg_xinfo", "\
 disable extended lynx.cfg viewing and reloading" },
 #endif
+	{ "lynxcgi", "\
+disallow execution of Lynx CGI URLs" },
 	{ "mail", "disallow mail" },
 	{ "multibook", "disallow multiple bookmark files" },
 	{ "news_post", "disallow USENET News posting." },
@@ -2965,17 +2972,7 @@ G)oto's" },
 	     || !strcmp(table[j].name, "default")) {
 		value = NULL;
 	    } else {
-		switch (find_restriction(table[j].name, -1)) {
-		case TRUE:
-		    value = "on";
-		    break;
-		case FALSE:
-		    value = "off";
-		    break;
-		default:
-		    value = "?";
-		    break;
-		}
+		value = show_restriction(table[j].name);
 	    }
 	    print_help_strings (
 		table[j].name, table[j].help, value, FALSE);
@@ -2995,8 +2992,9 @@ G)oto's" },
 		if (first) {
 		    printf("Other restrictions (see the user's guide):\n");
 		}
-		printf("%s%s", column ? ", " : "  ", name);
-		column += 2 + strlen(name);
+		value = show_restriction(table[j].name);
+		printf("%s%s (%s)", column ? ", " : "  ", name, value);
+		column += 5 + strlen(name) + strlen(value);
 		if (column > 50) {
 		    column = 0;
 		    printf("\n");
@@ -3031,7 +3029,7 @@ PRIVATE int selective_fun ARGS1(
 PRIVATE int source_fun ARGS1(
 	char *,			next_arg GCC_UNUSED)
 {
-    dump_output_immediately = TRUE;
+    force_dump_mode();
     HTOutputFormat = (LYPrependBase ?
 		      HTAtom_for("www/download") : HTAtom_for("www/dump"));
     LYcols = MAX_COLS;
@@ -3964,7 +3962,7 @@ PRIVATE BOOL parse_arg ARGS3(
 	had_nonoption = TRUE;
 #endif
 	StrAllocCopy(startfile, arg_name);
-	LYTrimStartfile(startfile);
+	LYEscapeStartfile(&startfile);
 #ifdef _WINDOWS	/* 1998/01/14 (Wed) 20:11:17 */
 	HTUnEscape(startfile);
 	{
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index 545f0bb7..6e75a691 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -173,10 +173,10 @@ PRIVATE void exit_immediately_with_error_message PARAMS((int state, BOOLEAN firs
 PRIVATE void status_link PARAMS((char *curlink_name, BOOLEAN show_more, BOOLEAN show_indx));
 PRIVATE void show_main_statusline PARAMS((CONST LinkInfo curlink, int for_what));
 PRIVATE void form_noviceline PARAMS((int));
-PRIVATE int are_different PARAMS((document *doc1, document *doc2));
+PRIVATE int are_different PARAMS((DocInfo *doc1, DocInfo *doc2));
 
 #ifndef DONT_TRACK_INTERNAL_LINKS
-PRIVATE int are_phys_different PARAMS((document *doc1, document *doc2));
+PRIVATE int are_phys_different PARAMS((DocInfo *doc1, DocInfo *doc2));
 #endif
 
 #define FASTTAB
@@ -203,8 +203,8 @@ PUBLIC int NumOfLines_partial = 0;  /* number of lines displayed in partial mode
 #endif
 
 PRIVATE int Newline = 0;
-PRIVATE document newdoc;
-PRIVATE document curdoc;
+PRIVATE DocInfo newdoc;
+PRIVATE DocInfo curdoc;
 PRIVATE char *traversal_host = NULL;
 PRIVATE char *traversal_link_to_add = NULL;
 PRIVATE char *owner_address = NULL;  /* Holds the responsible owner's address     */
@@ -226,16 +226,9 @@ PUBLIC BOOL textinput_redrawn = FALSE;
  */
 PRIVATE void free_mainloop_variables NOARGS
 {
-    FREE(newdoc.title);
-    FREE(newdoc.address);
-    FREE(newdoc.post_data);
-    FREE(newdoc.post_content_type);
-    FREE(newdoc.bookmark);
-    FREE(curdoc.title);
-    FREE(curdoc.address);
-    FREE(curdoc.post_data);
-    FREE(curdoc.post_content_type);
-    FREE(curdoc.bookmark);
+    LYFreeDocInfo(&newdoc);
+    LYFreeDocInfo(&curdoc);
+
 #ifdef USE_COLOR_STYLE
     FREE(curdoc.style);
     FREE(newdoc.style);
@@ -445,6 +438,37 @@ PRIVATE BOOLEAN reparse_or_reload ARGS1(
 }
 
 /*
+ * Functions for setting the current address
+ */
+PRIVATE void set_address ARGS2(
+	DocInfo *,	doc,
+	CONST char *,	address)
+{
+    StrAllocCopy(doc->address, address);
+}
+
+PRIVATE void copy_address ARGS2(
+	DocInfo *,	dst,
+	DocInfo *,	src)
+{
+    StrAllocCopy(dst->address, src->address);
+}
+
+PRIVATE void free_address ARGS1(
+	DocInfo *,	doc)
+{
+    FREE(doc->address);
+}
+
+PRIVATE void move_address ARGS2(
+	DocInfo *,	dst,
+	DocInfo *,	src)
+{
+    copy_address(dst, src);
+    free_address(src);
+}
+
+/*
  * This is for traversal call from within partial mode in LYUtils.c
  * and HTFormat.c  It simply calls HText_pageDisplay() but utilizes
  * LYMainLoop.c PRIVATE variables.
@@ -471,7 +495,9 @@ PUBLIC void LYMainLoop_pageDisplay ARGS1(
      * but only if s/he did not mess screen up by scrolling before...  So fall
      * down to old behavior here ... until we rewrite HTFindPoundSelector()
      */
-    if (display_partial && newdoc.line == 1 && strchr(newdoc.address, '#')) {
+    if (display_partial
+     && newdoc.line == 1
+     && findPoundSelector(newdoc.address)) {
 	display_partial = FALSE; /* restrict for this document */
 	return;			/* no repaint */
     }
@@ -538,41 +564,41 @@ PRIVATE void do_check_goto_URL ARGS3(
 	CONST char *name;
 	BOOLEAN *flag;
     } table[] = {
-	{ "file:",		&no_file_url },
-	{ "file:",		&no_goto_file },
-	{ "lynxexec:",		&no_goto_lynxexec },
-	{ "lynxprog:",		&no_goto_lynxprog },
-	{ "lynxcgi:",		&no_goto_lynxcgi },
-	{ "cso:",		&no_goto_cso },
-	{ "finger:",		&no_goto_finger },
-	{ "ftp:",		&no_goto_ftp },
-	{ "gopher:",		&no_goto_gopher },
-	{ "http:",		&no_goto_http },
-	{ "https:",		&no_goto_https },
-	{ "mailto:",		&no_goto_mailto },
-	{ "rlogin:",		&no_goto_rlogin },
-	{ "telnet:",		&no_goto_telnet },
-	{ "tn3270:",		&no_goto_tn3270 },
-	{ "wais:",		&no_goto_wais },
+	{ STR_FILE_URL,		&no_file_url },
+	{ STR_FILE_URL,		&no_goto_file },
+	{ STR_LYNXEXEC,		&no_goto_lynxexec },
+	{ STR_LYNXPROG,		&no_goto_lynxprog },
+	{ STR_LYNXCGI,		&no_goto_lynxcgi },
+	{ STR_CSO_URL,		&no_goto_cso },
+	{ STR_FINGER_URL,	&no_goto_finger },
+	{ STR_FTP_URL,		&no_goto_ftp },
+	{ STR_GOPHER_URL,	&no_goto_gopher },
+	{ STR_HTTP_URL,		&no_goto_http },
+	{ STR_HTTPS_URL,	&no_goto_https },
+	{ STR_MAILTO_URL,	&no_goto_mailto },
+	{ STR_RLOGIN_URL,	&no_goto_rlogin },
+	{ STR_TELNET_URL,	&no_goto_telnet },
+	{ STR_TN3270_URL,	&no_goto_tn3270 },
+	{ STR_WAIS_URL,		&no_goto_wais },
 #ifndef DISABLE_BIBP
-	{ "bibp:",		&no_goto_bibp },
+	{ STR_BIBP_URL,		&no_goto_bibp },
 #endif
 #ifndef DISABLE_NEWS
-	{ "news:",		&no_goto_news },
-	{ "nntp:",		&no_goto_nntp },
-	{ "snews:",		&no_goto_snews },
+	{ STR_NEWS_URL,		&no_goto_news },
+	{ STR_NNTP_URL,		&no_goto_nntp },
+	{ STR_SNEWS_URL,	&no_goto_snews },
 #endif
 #ifdef EXEC_LINKS
-	{ "lynxexec:",		&local_exec_on_local_files },
-	{ "lynxprog:",		&local_exec_on_local_files },
+	{ STR_LYNXEXEC,		&local_exec_on_local_files },
+	{ STR_LYNXPROG,		&local_exec_on_local_files },
 #endif /* EXEC_LINKS */
-	{ "LYNXCFG:",		&no_goto_configinfo },
-	{ "LYNXCOMPILEOPTS:",	&no_goto_configinfo },
-	{ "LYNXCOOKIE:",	&always },
-	{ "LYNXDIRED:",		&always },
-	{ "LYNXDOWNLOAD:",	&always },
-	{ "LYNXOPTIONS:",	&always },
-	{ "LYNXPRINT:",		&always },
+	{ STR_LYNXCFG,		&no_goto_configinfo },
+	{ STR_LYNXCFLAGS,	&no_goto_configinfo },
+	{ STR_LYNXCOOKIE,	&always },
+	{ STR_LYNXDIRED,	&always },
+	{ STR_LYNXDOWNLOAD,	&always },
+	{ STR_LYNXOPTIONS,	&always },
+	{ STR_LYNXPRINT,	&always },
     };
     unsigned n;
     BOOLEAN found = FALSE;
@@ -584,6 +610,8 @@ PRIVATE void do_check_goto_URL ARGS3(
 	     /* HTFindPoundSelector will initialize www_search_result,
 		so we do nothing else. */
 	    HTAddGotoURL(user_input_buffer);
+	    trimPoundSelector(curdoc.address);
+	    StrAllocCat(curdoc.address, user_input_buffer);
 	}
     } else {
 	/*
@@ -607,12 +635,12 @@ PRIVATE void do_check_goto_URL ARGS3(
 	if (found) {
 	    ;
 	} else if (LYValidate &&
-		   strncmp(user_input_buffer, "http:", 5) &&
-		   strncmp(user_input_buffer, "https:", 6)) {
+		   !isHTTP_URL(user_input_buffer) &&
+		   !isHTTPS_URL(user_input_buffer)) {
 	    HTUserMsg(GOTO_NON_HTTP_DISALLOWED);
 
 	} else {
-	    StrAllocCopy(newdoc.address, user_input_buffer);
+	    set_address(&newdoc, user_input_buffer);
 	    newdoc.isHEAD = FALSE;
 	    /*
 	     *  Might be an anchor in the same doc from a POST
@@ -623,8 +651,7 @@ PRIVATE void do_check_goto_URL ARGS3(
 		 * Make a name for this new URL.
 		 */
 		StrAllocCopy(newdoc.title, gettext("A URL specified by the user"));
-		FREE(newdoc.post_data);
-		FREE(newdoc.post_content_type);
+		LYFreePostData(&newdoc);
 		FREE(newdoc.bookmark);
 		newdoc.safe = FALSE;
 		newdoc.internal_link = FALSE;
@@ -660,38 +687,27 @@ PRIVATE BOOL do_check_recall ARGS7(
     for (;;) {
 #ifdef WIN_EX	/* 1998/10/11 (Sun) 10:41:05 */
 	int len = strlen(user_input_buffer);
-	char last_2, last_1, last;
 
 	if (len >= 3) {
-
-	    last_2 = user_input_buffer[len - 3];
-	    last_1 = user_input_buffer[len - 2];
-	    last = user_input_buffer[len - 1];
-
 	    if (len < MAX_LINE - 1
-	     && last_2 == '/'
-	     && isalpha(last_1)
-	     && last == ':')
-		LYAddHtmlSep0(user_input_buffer);
-
-	} else if (len == 2 && user_input_buffer[1] == ':') {
-	    if (isalpha(UCH(user_input_buffer[0]))) {
-		LYAddHtmlSep0(user_input_buffer);
-	    } else {
-		HTUserMsg2(WWW_ILLEGAL_URL_MESSAGE, user_input_buffer);
-		LYstrncpy(user_input_buffer, *old_user_input, MAX_LINE - 1);
-		FREE(*old_user_input);
-		ret = FALSE;
-		break;
-	    }
+	     && LYIsHtmlSep(user_input_buffer[len - 3])
+	     && LYIsDosDrive(user_input_buffer + len - 2))
+		LYAddPathSep0(user_input_buffer);
+
+	} else if (len == 2 && LYIsDosDrive(user_input_buffer)) {
+	    LYAddPathSep0(user_input_buffer);
+	} else {
+	    HTUserMsg2(WWW_ILLEGAL_URL_MESSAGE, user_input_buffer);
+	    LYstrncpy(user_input_buffer, *old_user_input, MAX_LINE - 1);
+	    FREE(*old_user_input);
+	    ret = FALSE;
+	    break;
 	}
 #endif
 	/*
 	 * Get rid of leading spaces (and any other spaces).
 	 */
-	if (!LYTrimStartfile(user_input_buffer)) {
-	    LYRemoveBlanks(user_input_buffer);
-	}
+	LYTrimAllStartfile(user_input_buffer);
 	if (*user_input_buffer == '\0' &&
 	    !(recall && (ch == UPARROW || ch == DNARROW))) {
 	    LYstrncpy(user_input_buffer, *old_user_input, MAX_LINE - 1);
@@ -801,8 +817,7 @@ PRIVATE BOOL do_check_recall ARGS7(
 PRIVATE void do_cleanup_after_delete NOARGS
 {
     HTuncache_current_document();
-    StrAllocCopy(newdoc.address, curdoc.address);
-    FREE(curdoc.address);
+    move_address(&newdoc, &curdoc);
     newdoc.line = curdoc.line;
     if (curdoc.link == nlinks-1) {
 	/*
@@ -868,13 +883,13 @@ PRIVATE int DoTraversal ARGS2(
 	if (!rlink_rejected &&
 	     traversal_host &&
 	     links[curdoc.link].lname) {
-	    if (strncmp(links[curdoc.link].lname, "LYNXIMGMAP:", 11)) {
+	    if (!isLYNXIMGMAP(links[curdoc.link].lname)) {
 		rlink_allowed = (BOOL) !strncmp(traversal_host,
 					 links[curdoc.link].lname,
 					 strlen(traversal_host));
 	    } else {
 		rlink_allowed = (BOOL) !strncmp(traversal_host,
-					 links[curdoc.link].lname + 11,
+					 links[curdoc.link].lname + LEN_LYNXIMGMAP,
 					 strlen(traversal_host));
 	    }
 	} else {
@@ -902,7 +917,7 @@ PRIVATE int DoTraversal ARGS2(
 	} else {
 	    StrAllocCopy(traversal_link_to_add,
 			 links[curdoc.link].lname);
-	    if (strncmp(traversal_link_to_add, "LYNXIMGMAP:", 11))
+	    if (!isLYNXIMGMAP(traversal_link_to_add))
 		*crawl_ok = TRUE;
 	    c = RTARROW;
 	}
@@ -947,12 +962,12 @@ PRIVATE BOOLEAN check_history NOARGS
     if (nhist > 0
      && !LYresubmit_posts
      && curdoc.post_data
-     && history[nhist - 1].post_data
-     && !strcmp(curdoc.post_data, history[nhist - 1].post_data)
+     && HDOC(nhist - 1).post_data
+     && !strcmp(curdoc.post_data, HDOC(nhist - 1).post_data)
      && (base = HText_getContentBase()) != 0) {
-	 char *text = strncmp(history[nhist - 1].address, "LYNXIMGMAP:", 11)
-		     ? history[nhist - 1].address
-		     : history[nhist - 1].address + 11;
+	 char *text = !isLYNXIMGMAP(HDOC(nhist - 1).address)
+		     ? HDOC(nhist - 1).address
+		     : HDOC(nhist - 1).address + LEN_LYNXIMGMAP;
 	if (!strncmp(base, text, strlen(base))) {
 	    /*
 	     * Normal case - as best as we can check, the document at the top
@@ -1041,9 +1056,7 @@ PRIVATE int handle_LYK_ACTIVATE ARGS6(
 		 *  with restrictions on file URLs. - FM
 		 */
 		if (no_file_url &&
-		    !strncasecomp(
-			    links[curdoc.link].l_form->submit_action,
-				  "file:", 5)) {
+		    isFILE_URL(links[curdoc.link].l_form->submit_action)) {
 		    HTAlert(FILE_ACTIONS_DISALLOWED);
 		    HTOutputFormat = WWW_PRESENT;
 		    LYforce_no_cache = FALSE;
@@ -1054,46 +1067,27 @@ PRIVATE int handle_LYK_ACTIVATE ARGS6(
 		 *  Make sure this isn't a spoof attempt
 		 *  via an internal URL. - FM
 		 */
-		if (!strncasecomp(
-			    links[curdoc.link].l_form->submit_action,
-				  "LYNXCOOKIE:", 11) ||
+		if (isLYNXCOOKIE(links[curdoc.link].l_form->submit_action) ||
 #ifdef DIRED_SUPPORT
 #ifdef OK_PERMIT
-		    (!(strncasecomp(
-			    links[curdoc.link].l_form->submit_action,
-				   "LYNXDIRED:", 10)) &&
+		    (isLYNXDIRED(links[curdoc.link].l_form->submit_action) &&
 		     (no_dired_support ||
 		      strncasecomp(
 			(links[curdoc.link].l_form->submit_action + 10),
 				   "//PERMIT_LOCATION", 17) ||
 		      !LYIsUIPage(curdoc.address, UIP_PERMIT_OPTIONS))) ||
 #else
-		    !strncasecomp(
-			    links[curdoc.link].l_form->submit_action,
-				  "LYNXDIRED:", 10) ||
+		    isLYNXDIRED(links[curdoc.link].l_form->submit_action) ||
 #endif /* OK_PERMIT */
 #endif /* DIRED_SUPPORT */
-		    !strncasecomp(
-			    links[curdoc.link].l_form->submit_action,
-				  "LYNXDOWNLOAD:", 13) ||
-		    !strncasecomp(
-			    links[curdoc.link].l_form->submit_action,
-				  "LYNXHIST:", 9) ||
-		    !strncasecomp(
-			    links[curdoc.link].l_form->submit_action,
-				  "LYNXKEYMAP:", 11) ||
-		    !strncasecomp(
-			    links[curdoc.link].l_form->submit_action,
-				  "LYNXIMGMAP:", 11) ||
-		    !strncasecomp(
-			    links[curdoc.link].l_form->submit_action,
-				  "LYNXPRINT:", 10) ||
-		    !strncasecomp(
-			    links[curdoc.link].l_form->submit_action,
-				  "lynxexec:", 9) ||
-		    !strncasecomp(
-			    links[curdoc.link].l_form->submit_action,
-				  "lynxprog:", 9)) {
+		    isLYNXDOWNLOAD(links[curdoc.link].l_form->submit_action) ||
+		    isLYNXHIST(links[curdoc.link].l_form->submit_action) ||
+		    isLYNXKEYMAP(links[curdoc.link].l_form->submit_action) ||
+		    isLYNXIMGMAP(links[curdoc.link].l_form->submit_action) ||
+		    isLYNXPRINT(links[curdoc.link].l_form->submit_action) ||
+		    isLYNXEXEC(links[curdoc.link].l_form->submit_action) ||
+		    isLYNXPROG(links[curdoc.link].l_form->submit_action)) {
+
 		    HTAlert(SPECIAL_ACTION_DISALLOWED);
 		    CTRACE((tfp, "LYMainLoop: Rejected '%s'\n",
 				links[curdoc.link].l_form->submit_action));
@@ -1123,8 +1117,7 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 		if (check_realm) {
 		    LYPermitURL = TRUE;
 		}
-		if (no_filereferer == TRUE &&
-		    !strncmp(curdoc.address, "file:", 5)) {
+		if (no_filereferer == TRUE && isFILE_URL(curdoc.address)) {
 		    LYNoRefererForThis = TRUE;
 		}
 		if (links[curdoc.link].l_form->submit_method != URL_MAIL_METHOD) {
@@ -1189,7 +1182,7 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 			HTInfoMsg(CANCELLED);
 			HTOutputFormat = WWW_PRESENT;
 			LYforce_no_cache = FALSE;
-			StrAllocCopy(newdoc.address, curdoc.address);
+			copy_address(&newdoc, &curdoc);
 			StrAllocCopy(newdoc.title, curdoc.title);
 			StrAllocCopy(newdoc.post_data, curdoc.post_data);
 			StrAllocCopy(newdoc.post_content_type,
@@ -1245,11 +1238,10 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 	     *	Make sure this isn't a spoof in an account
 	     *	with restrictions on file URLs. - FM
 	     */
-	    if (no_file_url &&
-		!strncmp(links[curdoc.link].lname, "file:", 5)) {
-		if (strncmp(curdoc.address, "file:", 5) &&
-		    !((!strncmp(curdoc.address, "LYNXKEYMAP:", 11) ||
-		       !strncmp(curdoc.address, "LYNXCOOKIE:", 11)) &&
+	    if (no_file_url && isFILE_URL(links[curdoc.link].lname)) {
+		if (!isFILE_URL(curdoc.address) &&
+		    !((isLYNXKEYMAP(curdoc.address) ||
+		       isLYNXCOOKIE(curdoc.address)) &&
 		      !strncmp(links[curdoc.link].lname,
 			       helpfilepath,
 			       strlen(helpfilepath)))) {
@@ -1267,14 +1259,11 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 	     *	via an internal URL in a non-internal
 	     *	document. - FM
 	     */
-	    if ((!strncmp(links[curdoc.link].lname,
-			  "LYNXCOOKIE:", 11) &&
-		 (strcmp((curdoc.title ? curdoc.title : ""),
-			 COOKIE_JAR_TITLE) ||
-		  strncmp(curdoc.address, "LYNXCOOKIE:", 11))) ||
+	    if ((isLYNXCOOKIE(links[curdoc.link].lname) &&
+		 (strcmp(NonNull(curdoc.title), COOKIE_JAR_TITLE) ||
+		  !isLYNXCOOKIE(curdoc.address))) ||
 #ifdef DIRED_SUPPORT
-		(!strncmp(links[curdoc.link].lname,
-			  "LYNXDIRED:", 10) &&
+		(isLYNXDIRED(links[curdoc.link].lname) &&
 		 !LYIsUIPage(curdoc.address, UIP_DIRED_MENU) &&
 		 !LYIsUIPage(curdoc.address, UIP_PERMIT_OPTIONS) &&
 #ifdef OK_INSTALL
@@ -1282,16 +1271,13 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 #endif /* OK_INSTALL */
 		 !LYIsUIPage(curdoc.address, UIP_UPLOAD_OPTIONS)) ||
 #endif /* DIRED_SUPPORT */
-		(!strncmp(links[curdoc.link].lname,
-			 "LYNXDOWNLOAD:", 13) &&
+		(isLYNXDOWNLOAD(links[curdoc.link].lname) &&
 		 !LYIsUIPage(curdoc.address, UIP_DOWNLOAD_OPTIONS)) ||
-		(!strncmp(links[curdoc.link].lname,
-			  "LYNXHIST:", 9) &&
+		(isLYNXHIST(links[curdoc.link].lname) &&
 		 !LYIsUIPage(curdoc.address, UIP_HISTORY) &&
 		 !LYIsUIPage(curdoc.address, UIP_LIST_PAGE) &&
 		 !LYIsUIPage(curdoc.address, UIP_ADDRLIST_PAGE)) ||
-		(!strncmp(links[curdoc.link].lname,
-			  "LYNXPRINT:", 10) &&
+		(isLYNXPRINT(links[curdoc.link].lname) &&
 		 !LYIsUIPage(curdoc.address, UIP_PRINT_OPTIONS))) {
 		    HTAlert(SPECIAL_VIA_EXTERNAL_DISALLOWED);
 		    HTOutputFormat = WWW_PRESENT;
@@ -1311,7 +1297,7 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 	    /*
 	     *	Follow a normal link or anchor.
 	     */
-	    StrAllocCopy(newdoc.address, links[curdoc.link].lname);
+	    set_address(&newdoc, links[curdoc.link].lname);
 	    StrAllocCopy(newdoc.title, LYGetHiliteStr(curdoc.link, 0));
 #ifndef DONT_TRACK_INTERNAL_LINKS
 	/*
@@ -1335,7 +1321,7 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 		 *  for an internal link within the document the
 		 *  List Page is about. - kw
 		 */
-		if (LYIsListpageTitle(curdoc.title ? curdoc.title : "") &&
+		if (LYIsListpageTitle(NonNull(curdoc.title)) &&
 		    (LYIsUIPage(curdoc.address, UIP_LIST_PAGE) ||
 		     LYIsUIPage(curdoc.address, UIP_ADDRLIST_PAGE))) {
 		    if (check_history()) {
@@ -1354,7 +1340,7 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 				/* cancel the whole thing */
 				LYforce_no_cache = FALSE;
 				reloading = FALSE;
-				StrAllocCopy(newdoc.address, curdoc.address);
+				copy_address(&newdoc, &curdoc);
 				StrAllocCopy(newdoc.title, curdoc.title);
 				newdoc.internal_link = curdoc.internal_link;
 				HTInfoMsg(CANCELLED);
@@ -1372,8 +1358,7 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 				 * wasn't meant to be internal after
 				 * all, here we can recover from that
 				 * assumption. - kw */
-				FREE(newdoc.post_data);
-				FREE(newdoc.post_content_type);
+				LYFreePostData(&newdoc);
 				newdoc.internal_link = FALSE;
 				HTAlert(DISCARDING_POST_DATA);
 			    }
@@ -1383,7 +1368,7 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 		     *	Don't push the List Page if we follow an
 		     *	internal link given by it. - kw
 		     */
-		    FREE(curdoc.address);
+		    free_address(&curdoc);
 		} else if (cmd != LYK_NOCACHE) {
 		    *try_internal = TRUE;
 		}
@@ -1397,8 +1382,7 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 		/*
 		 *  Free POST content if not an internal link. - kw
 		 */
-		FREE(newdoc.post_data);
-		FREE(newdoc.post_content_type);
+		LYFreePostData(&newdoc);
 	    }
 #endif /* TRACK_INTERNAL_LINKS */
 	    /*
@@ -1406,10 +1390,9 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 	     *	form.  If so, don't free the content. -- FM
 	     */
 	    if (are_different(&curdoc, &newdoc)) {
-		FREE(newdoc.post_data);
-		FREE(newdoc.post_content_type);
+		LYFreePostData(&newdoc);
 		FREE(newdoc.bookmark);
-		if (!strncmp(newdoc.address, "LYNXMESSAGES:", 13))
+		if (isLYNXMESSAGES(newdoc.address))
 		    LYforce_no_cache = TRUE;
 	    }
 	    if (!no_jump && lynxjumpfile && curdoc.address &&
@@ -1423,8 +1406,7 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 		       (lynxjumpfile &&
 			!strcmp(lynxjumpfile, curdoc.address))) {
 		LYUserSpecifiedURL = TRUE;
-	    } else if (no_filereferer == TRUE &&
-		       !strncmp(curdoc.address, "file:", 5)) {
+	    } else if (no_filereferer == TRUE && isFILE_URL(curdoc.address)) {
 		LYNoRefererForThis = TRUE;
 	    }
 	    newdoc.link = 0;
@@ -1447,7 +1429,7 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 		      strip_trailing_slash(newdoc.address);
 	    }
 #endif /* DIRED_SUPPORT  && !__DJGPP__ */
-	    if (!strncmp(curdoc.address, "LYNXCOOKIE:", 11)) {
+	    if (isLYNXCOOKIE(curdoc.address)) {
 		HTuncache_current_document();
 	    }
 	}
@@ -1515,16 +1497,16 @@ PRIVATE void handle_LYK_ADD_BOOKMARK ARGS3(
 	!LYIsUIPage(curdoc.address, UIP_UPLOAD_OPTIONS) &&
 #endif /* DIRED_SUPPORT */
 	!LYIsUIPage(curdoc.address, UIP_DOWNLOAD_OPTIONS) &&
-	strncmp(curdoc.address, "LYNXCOOKIE:", 11) &&
+	!isLYNXCOOKIE(curdoc.address) &&
 	!LYIsUIPage(curdoc.address, UIP_OPTIONS_MENU) &&
 	((nlinks <= 0) ||
 	 (links[curdoc.link].lname != NULL &&
-	  strncmp(links[curdoc.link].lname, "LYNXHIST:", 9) &&
-	  strncmp(links[curdoc.link].lname, "LYNXPRINT:", 10) &&
-	  strncmp(links[curdoc.link].lname, "LYNXDIRED:", 10) &&
-	  strncmp(links[curdoc.link].lname, "LYNXDOWNLOAD:", 13) &&
-	  strncmp(links[curdoc.link].lname, "LYNXCOOKIE:", 11) &&
-	  strncmp(links[curdoc.link].lname, "LYNXOPTIONS:", 12)))) {
+	  !isLYNXHIST(links[curdoc.link].lname) &&
+	  !isLYNXPRINT(links[curdoc.link].lname) &&
+	  !isLYNXDIRED(links[curdoc.link].lname) &&
+	  !isLYNXDOWNLOAD(links[curdoc.link].lname) &&
+	  !isLYNXCOOKIE(links[curdoc.link].lname) &&
+	  !isLYNXPRINT(links[curdoc.link].lname)))) {
 	if (nlinks > 0) {
 	    if (curdoc.post_data == NULL &&
 		curdoc.bookmark == NULL &&
@@ -1548,8 +1530,8 @@ PRIVATE void handle_LYK_ADD_BOOKMARK ARGS3(
 		    curdoc.bookmark != NULL &&
 		    strstr(curdoc.address,
 			   (*bookmark_page == '.'
-					  ?
-			(bookmark_page+1) : bookmark_page)) != NULL) {
+					  ? (bookmark_page+1)
+					  : bookmark_page)) != NULL) {
 		    /*
 		     *	If multiple bookmarks are disabled, offer
 		     *	the L)ink or C)ancel, but with wording
@@ -1624,9 +1606,8 @@ check_add_bookmark_to_self:
 	if (curdoc.bookmark && BookmarkPage &&
 	    !strcmp(curdoc.bookmark, BookmarkPage)) {
 	    HTuncache_current_document();
-	    StrAllocCopy(newdoc.address, curdoc.address);
+	    move_address(&newdoc, &curdoc);
 	    StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
-	    FREE(curdoc.address);
 	    newdoc.line = curdoc.line;
 	    newdoc.link = curdoc.link;
 	    newdoc.internal_link = FALSE;
@@ -1726,7 +1707,7 @@ PRIVATE void handle_LYK_COMMENT ARGS4(
 			 */
 			if ((cp = strchr((temp+1), '/')) != NULL)
 			    *cp = '\0';
-			StrAllocCopy(address, "mailto:");
+			StrAllocCopy(address, STR_MAILTO_URL);
 			StrAllocCat(address, (temp+1));
 			StrAllocCat(address, "@");
 		    }
@@ -1754,7 +1735,7 @@ PRIVATE void handle_LYK_COMMENT ARGS4(
 		/*
 		 *  The address is a URL.  Just follow the link.
 		 */
-		StrAllocCopy(newdoc.address, *owner_address_p);
+		set_address(&newdoc, *owner_address_p);
 		newdoc.internal_link = FALSE;
 	    } else {
 		/*
@@ -1774,16 +1755,16 @@ PRIVATE void handle_LYK_COMMENT ARGS4(
 		    }
 		}
 
-		if (strchr(*owner_address_p,':')!=NULL)
+		if (strchr(*owner_address_p, ':') != NULL)
 		     /*
 		      *  Send a reply.	The address is after the colon.
 		      */
-		     reply_by_mail(strchr(*owner_address_p,':')+1,
+		     reply_by_mail(strchr(*owner_address_p, ':') + 1,
 				   curdoc.address,
-				   (kp ? kp : ""), id);
+				   NonNull(kp), id);
 		else
 		    reply_by_mail(*owner_address_p, curdoc.address,
-				  (kp ? kp : ""), id);
+				  NonNull(kp), id);
 
 		FREE(tmptitle);
 		*refresh_screen = TRUE;	/* to force a showpage */
@@ -1798,10 +1779,9 @@ PRIVATE BOOLEAN handle_LYK_COOKIE_JAR ARGS1(
     /*
      *	Don't do if already viewing the cookie jar.
      */
-    if (strncmp(curdoc.address, "LYNXCOOKIE:", 11)) {
-	StrAllocCopy(newdoc.address, "LYNXCOOKIE:/");
-	FREE(newdoc.post_data);
-	FREE(newdoc.post_content_type);
+    if (!isLYNXCOOKIE(curdoc.address)) {
+	set_address(&newdoc, "LYNXCOOKIE:/");
+	LYFreePostData(&newdoc);
 	FREE(newdoc.bookmark);
 	newdoc.isHEAD = FALSE;
 	newdoc.safe = FALSE;
@@ -1826,10 +1806,8 @@ PRIVATE void handle_LYK_CREATE NOARGS
     if (lynx_edit_mode && !no_dired_support) {
 	if (local_create(&curdoc) > 0) {
 	    DIRED_UNCACHE_1;
-	    StrAllocCopy(newdoc.address, curdoc.address);
-	    FREE(curdoc.address);
-	    FREE(newdoc.post_data);
-	    FREE(newdoc.post_content_type);
+	    move_address(&newdoc, &curdoc);
+	    LYFreePostData(&newdoc);
 	    FREE(newdoc.bookmark);
 	    newdoc.isHEAD = FALSE;
 	    newdoc.safe = FALSE;
@@ -1953,11 +1931,9 @@ PRIVATE void handle_LYK_DIRED_MENU ARGS3(
 	    /* could use DIRED_UNCACHE_1 but it's currently only defined
 	       for dired - kw */
 	    HTuncache_current_document();
-	    StrAllocCopy(newdoc.address, curdoc.address);
-	    StrAllocCopy(newdoc.title,
-			 curdoc.title ? curdoc.title : "");
+	    move_address(&newdoc, &curdoc);
+	    StrAllocCopy(newdoc.title, NonNull(curdoc.title));
 	    StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
-	    FREE(curdoc.address);
 	    newdoc.line = curdoc.line;
 	    newdoc.link = curdoc.link;
 	}
@@ -1981,8 +1957,7 @@ PRIVATE void handle_LYK_DIRED_MENU ARGS3(
      */
     if (lynx_edit_mode && !no_dired_support &&
 	!LYIsUIPage(curdoc.address, UIP_DIRED_MENU) &&
-	strcmp((curdoc.title ? curdoc.title : ""),
-	       DIRED_MENU_TITLE)) {
+	strcmp(NonNull(curdoc.title), DIRED_MENU_TITLE)) {
 	dired_options(&curdoc,&newdoc.address);
 	*refresh_screen = TRUE;	/* redisplay */
     }
@@ -2029,8 +2004,7 @@ PRIVATE int handle_LYK_DOWNLOAD ARGS3(
 		    }
 		    return 0;
 		}
-		if (!strncmp(links[curdoc.link].l_form->submit_action,
-			"LYNXOPTIONS:", 12)) {
+		if (isLYNXOPTIONS(links[curdoc.link].l_form->submit_action)) {
 		    if (*old_c != real_c) {
 			*old_c = real_c;
 			HTUserMsg(NO_DOWNLOAD_SPECIAL);
@@ -2047,7 +2021,7 @@ PRIVATE int handle_LYK_DOWNLOAD ARGS3(
 		HTUserMsg(NO_DOWNLOAD_INPUT);
 	    }
 
-	} else if (!strncmp(curdoc.address, "LYNXCOOKIE:", 11)) {
+	} else if (isLYNXCOOKIE(curdoc.address)) {
 	    if (*old_c != real_c)	{
 		*old_c = real_c;
 		HTUserMsg(NO_DOWNLOAD_COOKIES);
@@ -2077,26 +2051,26 @@ PRIVATE int handle_LYK_DOWNLOAD ARGS3(
 	    /*
 	     *	Don't bother making a /tmp copy of the local file.
 	     */
-	    char *temp = NULL;
-	    StrAllocCopy(temp, newdoc.address);
-	    StrAllocCopy(newdoc.address, links[curdoc.link].lname);
+	    static DocInfo temp;
+	    copy_address(&temp, &newdoc);
+	    set_address(&newdoc, links[curdoc.link].lname);
 	    if (LYdownload_options(&newdoc.address,
 				   links[curdoc.link].lname) < 0)
-		StrAllocCopy(newdoc.address, temp);
+		copy_address(&newdoc, &temp);
 	    else
 		newdoc.internal_link = FALSE;
-	    FREE(temp);
+	    LYFreeDocInfo(&temp);
 #endif /* DIRED_SUPPORT */
 
 	} else if (LYIsUIPage(curdoc.address, UIP_HISTORY) &&
-	    !strncmp(links[curdoc.link].lname, "LYNXHIST:", 9)) {
-	    int number = atoi(links[curdoc.link].lname+9);
+	    isLYNXHIST(links[curdoc.link].lname)) {
+	    int number = atoi(links[curdoc.link].lname + LEN_LYNXHIST);
 	    if (number >= nhist || number < 0) {
 		HTUserMsg(NO_DOWNLOAD_SPECIAL);
 		return 0;
 	    }
-	    if ((history[number].post_data != NULL &&
-		 history[number].safe != TRUE) &&
+	    if ((HDOC(number).post_data != NULL &&
+		 HDOC(number).safe != TRUE) &&
 		HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
 		HTInfoMsg(CANCELLED);
 		return 0;
@@ -2104,19 +2078,18 @@ PRIVATE int handle_LYK_DOWNLOAD ARGS3(
 	    /*
 	     *  OK, we download from history page, restore URL from stack.
 	     */
-	    StrAllocCopy(newdoc.address, history[number].address);
+	    copy_address(&newdoc, &HDOC(number));
 	    StrAllocCopy(newdoc.title, LYGetHiliteStr(curdoc.link, 0));
-	    StrAllocCopy(newdoc.bookmark, history[number].bookmark);
-	    FREE(newdoc.post_data);
-	    FREE(newdoc.post_content_type);
-	    if (history[number].post_data)
+	    StrAllocCopy(newdoc.bookmark, HDOC(number).bookmark);
+	    LYFreePostData(&newdoc);
+	    if (HDOC(number).post_data)
 		StrAllocCopy(newdoc.post_data,
-			     history[number].post_data);
-	    if (history[number].post_content_type)
+			     HDOC(number).post_data);
+	    if (HDOC(number).post_content_type)
 		StrAllocCopy(newdoc.post_content_type,
-			     history[number].post_content_type);
-	    newdoc.isHEAD = history[number].isHEAD;
-	    newdoc.safe = history[number].safe;
+			     HDOC(number).post_content_type);
+	    newdoc.isHEAD = HDOC(number).isHEAD;
+	    newdoc.safe = HDOC(number).safe;
 	    newdoc.internal_link = FALSE;
 	    newdoc.link = 0;
 	    HTOutputFormat = HTAtom_for("www/download");
@@ -2132,31 +2105,21 @@ PRIVATE int handle_LYK_DOWNLOAD ARGS3(
 		HTAlert(UNSUPPORTED_DATA_URL);
 	    }
 
-	} else if (!strncmp(links[curdoc.link].lname,
-			    "LYNXCOOKIE:", 11) ||
-		   !strncmp(links[curdoc.link].lname,
-			    "LYNXDIRED:", 10) ||
-		   !strncmp(links[curdoc.link].lname,
-			    "LYNXDOWNLOAD:", 13) ||
-		   !strncmp(links[curdoc.link].lname,
-			    "LYNXPRINT:", 10) ||
-		   !strncmp(links[curdoc.link].lname,
-			    "LYNXOPTIONS:", 12) ||
-		   !strncmp(links[curdoc.link].lname,
-			    "LYNXHIST:", 9) || /* handled above if valid - kw */
+	} else if (isLYNXCOOKIE(links[curdoc.link].lname) ||
+		   isLYNXDIRED(links[curdoc.link].lname) ||
+		   isLYNXDOWNLOAD(links[curdoc.link].lname) ||
+		   isLYNXPRINT(links[curdoc.link].lname) ||
+		   isLYNXOPTIONS(links[curdoc.link].lname) ||
+		   isLYNXHIST(links[curdoc.link].lname) ||
+		   /* handled above if valid - kw */
 /* @@@ should next two be downloadable? - kw */
-		   !strncmp(links[curdoc.link].lname,
-			    "LYNXCFG:", 8) ||
-		   !strncmp(links[curdoc.link].lname,
-			    "LYNXCOMPILEOPTS:", 16) ||
-		   !strncmp(links[curdoc.link].lname,
-			    "lynxexec:", 9) ||
-		   !strncmp(links[curdoc.link].lname,
-			    "lynxprog:", 9)) {
+		   isLYNXHIST(links[curdoc.link].lname) ||
+		   isLYNXCFLAGS(links[curdoc.link].lname) ||
+		   isLYNXEXEC(links[curdoc.link].lname) ||
+		   isLYNXPROG(links[curdoc.link].lname)) {
 	    HTUserMsg(NO_DOWNLOAD_SPECIAL);
 
-	} else if (!strncmp(links[curdoc.link].lname,
-			    "mailto:", 7)) {
+	} else if (isMAILTO_URL(links[curdoc.link].lname)) {
 	    HTUserMsg(NO_DOWNLOAD_MAILTO_LINK);
 
 	/*
@@ -2178,7 +2141,7 @@ PRIVATE int handle_LYK_DOWNLOAD ARGS3(
 	     *	if it's an anchor within the same document,
 	     *	entire document will be downloaded.
 	     */
-	    StrAllocCopy(newdoc.address, links[curdoc.link].lname);
+	    set_address(&newdoc, links[curdoc.link].lname);
 	    StrAllocCopy(newdoc.title, LYGetHiliteStr(curdoc.link, 0));
 #ifndef DONT_TRACK_INTERNAL_LINKS
 	    /*
@@ -2194,8 +2157,7 @@ PRIVATE int handle_LYK_DOWNLOAD ARGS3(
 	    if (are_different(&curdoc, &newdoc))
 #endif /* TRACK_INTERNAL_LINKS */
 	    {
-		FREE(newdoc.post_data);
-		FREE(newdoc.post_content_type);
+		LYFreePostData(&newdoc);
 		FREE(newdoc.bookmark);
 		newdoc.isHEAD = FALSE;
 		newdoc.safe = FALSE;
@@ -2393,9 +2355,7 @@ PRIVATE int handle_LYK_ECGOTO ARGS5(
 			MAX_LINE, RECALL_URL)) >= 0) &&
 	user_input_buffer[0] != '\0' &&
 	strcmp(user_input_buffer, curdoc.address)) {
-	if (!LYTrimStartfile(user_input_buffer)) {
-	    LYRemoveBlanks(user_input_buffer);
-	}
+	LYTrimAllStartfile(user_input_buffer);
 	if (user_input_buffer[0] != '\0') {
 	    return 2;
 	}
@@ -2449,9 +2409,7 @@ PRIVATE void handle_LYK_EDIT ARGS2(
 			HTUnEscapeSome(tp, "/");
 			if (edit_current_file(tp, curdoc.link, Newline)) {
 			    DIRED_UNCACHE_1;
-			    StrAllocCopy(newdoc.address,
-					 curdoc.address);
-			    FREE(curdoc.address);
+			    move_address(&newdoc, &curdoc);
 #ifdef NO_SEEK_OLD_POSITION
 			    /*
 			     *	Go to top of file.
@@ -2479,7 +2437,7 @@ PRIVATE void handle_LYK_EDIT ARGS2(
 	if (edit_current_file(newdoc.address, curdoc.link, Newline)) {
 	    HTuncache_current_document();
 	    LYforce_no_cache = TRUE;  /*force reload of document */
-	    FREE(curdoc.address); /* so it doesn't get pushed */
+	    free_address(&curdoc); /* so it doesn't get pushed */
 #ifdef NO_SEEK_OLD_POSITION
 	    /*
 	     *	Go to top of file.
@@ -2619,7 +2577,7 @@ PRIVATE int handle_LYK_ELGOTO ARGS5(
 	return 0;
     }
 #ifdef DIRED_SUPPORT
-    if (!strncmp(links[curdoc.link].lname, "LYNXDIRED:", 10) ||
+    if (isLYNXDIRED(links[curdoc.link].lname) ||
 	LYIsUIPage(curdoc.address, UIP_DIRED_MENU) ||
 	LYIsUIPage(curdoc.address, UIP_PERMIT_OPTIONS) ||
 	LYIsUIPage(curdoc.address, UIP_UPLOAD_OPTIONS)) {
@@ -2656,9 +2614,7 @@ PRIVATE int handle_LYK_ELGOTO ARGS5(
 	       ((links[curdoc.link].type == WWW_FORM_LINK_TYPE)
 			? links[curdoc.link].l_form->submit_action
 			: links[curdoc.link].lname))) {
-	if (!LYTrimStartfile(user_input_buffer)) {
-	    LYRemoveBlanks(user_input_buffer);
-	}
+	LYTrimAllStartfile(user_input_buffer);
 	if (user_input_buffer[0] != '\0') {
 	    return 2;
 	}
@@ -2972,8 +2928,9 @@ PRIVATE BOOLEAN handle_LYK_HEAD ARGS1(
 	_statusline(HEAD_D_L_OR_CANCEL);
 	c = LYgetch_single();
 	if (c == 'D') {
-	    char *scheme = strncmp(curdoc.address, "LYNXIMGMAP:", 11) ?
-		curdoc.address : curdoc.address + 11;
+	    char *scheme = !isLYNXIMGMAP(curdoc.address)
+			 ? curdoc.address
+			 : curdoc.address + LEN_LYNXIMGMAP;
 	    if (LYCanDoHEAD(scheme) != TRUE) {
 		HTUserMsg(DOC_NOT_HTTP_URL);
 	    } else {
@@ -2991,7 +2948,7 @@ PRIVATE BOOLEAN handle_LYK_HEAD ARGS1(
 		    StrAllocCopy(newdoc.title, curdoc.title);
 		    if (HTLoadedDocumentIsHEAD()) {
 			HTuncache_current_document();
-			FREE(curdoc.address);
+			free_address(&curdoc);
 		    } else {
 			StrAllocCat(newdoc.title, " - HEAD");
 		    }
@@ -3011,8 +2968,7 @@ PRIVATE BOOLEAN handle_LYK_HEAD ARGS1(
 		       links[curdoc.link].l_form->disabled) {
 		HTUserMsg(FORM_ACTION_DISABLED);
 	    } else if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
-		       strncmp(links[curdoc.link].l_form->submit_action,
-						      "lynxcgi:", 8) &&
+		       !isLYNXCGI(links[curdoc.link].l_form->submit_action) &&
 		       strncmp(links[curdoc.link].l_form->submit_action,
 							 "http", 4)) {
 		HTUserMsg(FORM_ACTION_NOT_HTTP_URL);
@@ -3055,8 +3011,9 @@ PRIVATE BOOLEAN handle_LYK_HEAD ARGS1(
 		c = 'D';
 	    }
 	    if (c == 'D') {
-		char *scheme = strncmp(curdoc.address, "LYNXIMGMAP:", 11) ?
-		    curdoc.address : curdoc.address + 11;
+		char *scheme = !isLYNXIMGMAP(curdoc.address)
+			     ? curdoc.address
+			     : curdoc.address + LEN_LYNXIMGMAP;
 		/*
 		 * The user didn't cancel, so check if a HEAD request is
 		 * appropriate for the current document.  - FM
@@ -3069,7 +3026,7 @@ PRIVATE BOOLEAN handle_LYK_HEAD ARGS1(
 		    StrAllocCopy(newdoc.title, curdoc.title);
 		    if (HTLoadedDocumentIsHEAD()) {
 			HTuncache_current_document();
-			FREE(curdoc.address);
+			free_address(&curdoc);
 		    } else {
 			StrAllocCat(newdoc.title, " - HEAD");
 		    }
@@ -3089,13 +3046,12 @@ PRIVATE void handle_LYK_HELP ARGS1(
 	/*
 	 *  Set the filename.
 	 */
-	StrAllocCopy(newdoc.address, *cshelpfile);
+	set_address(&newdoc, *cshelpfile);
 	/*
 	 *  Make a name for this help file.
 	 */
 	StrAllocCopy(newdoc.title, gettext("Help Screen"));
-	FREE(newdoc.post_data);
-	FREE(newdoc.post_content_type);
+	LYFreePostData(&newdoc);
 	FREE(newdoc.bookmark);
 	newdoc.isHEAD = FALSE;
 	newdoc.safe = FALSE;
@@ -3116,13 +3072,11 @@ PRIVATE void handle_LYK_HISTORICAL NOARGS
      */
     if ((curdoc.post_data != NULL &&
 	 curdoc.safe != TRUE) &&
-	confirm_post_resub(curdoc.address, NULL,
-			   0, 0) == FALSE) {
+	confirm_post_resub(curdoc.address, NULL, 0, 0) == FALSE) {
 	HTInfoMsg(WILL_NOT_RELOAD_DOC);
     } else {
 	HTuncache_current_document();
-	StrAllocCopy(newdoc.address, curdoc.address);
-	FREE(curdoc.address);
+	move_address(&newdoc, &curdoc);
 	newdoc.line = curdoc.line;
 	newdoc.link = curdoc.link;
     }
@@ -3175,14 +3129,13 @@ PRIVATE BOOLEAN handle_LYK_HISTORY ARGS1(
 	}
 	LYRegisterUIPage(newdoc.address, UIP_HISTORY);
 	StrAllocCopy(newdoc.title, HISTORY_PAGE_TITLE);
-	FREE(newdoc.post_data);
-	FREE(newdoc.post_content_type);
+	LYFreePostData(&newdoc);
 	FREE(newdoc.bookmark);
 	newdoc.isHEAD = FALSE;
 	newdoc.safe = FALSE;
 	newdoc.internal_link = FALSE;
 	newdoc.link = 1; /*@@@ bypass "recent statusline messages" link */
-	FREE(curdoc.address);  /* so it doesn't get pushed */
+	free_address(&curdoc);  /* so it doesn't get pushed */
 
 	if (LYValidate || check_realm) {
 	    LYPermitURL = TRUE;
@@ -3226,10 +3179,9 @@ PRIVATE void handle_LYK_INDEX ARGS2(
 		last_kcode = NOKANJI;	/* AUTO */
 	    }
 #endif
-	    StrAllocCopy(newdoc.address, indexfile);
+	    set_address(&newdoc, indexfile);
 	    StrAllocCopy(newdoc.title, gettext("System Index")); /* name it */
-	    FREE(newdoc.post_data);
-	    FREE(newdoc.post_content_type);
+	    LYFreePostData(&newdoc);
 	    FREE(newdoc.bookmark);
 	    newdoc.isHEAD = FALSE;
 	    newdoc.safe = FALSE;
@@ -3274,7 +3226,7 @@ PRIVATE void handle_LYK_INDEX_SEARCH ARGS4(
 	     *	getfile doesn't try to get the newdoc.address.
 	     *	Since we have already gotten it.
 	     */
-	    StrAllocCopy(curdoc.address, newdoc.address);
+	    copy_address(&curdoc, &newdoc);
 	    StrAllocCopy(newdoc.post_data, curdoc.post_data);
 	    StrAllocCopy(newdoc.post_content_type, curdoc.post_content_type);
 	    newdoc.internal_link = FALSE;
@@ -3290,9 +3242,8 @@ PRIVATE void handle_LYK_INDEX_SEARCH ARGS4(
 	     */
 	    StrAllocCopy(newdoc.title,
 			 "A URL specified by redirection");
-	    StrAllocCopy(newdoc.address, use_this_url_instead);
-	    FREE(newdoc.post_data);
-	    FREE(newdoc.post_content_type);
+	    set_address(&newdoc, use_this_url_instead);
+	    LYFreePostData(&newdoc);
 	    FREE(newdoc.bookmark);
 	    newdoc.isHEAD = FALSE;
 	    newdoc.safe = FALSE;
@@ -3303,7 +3254,7 @@ PRIVATE void handle_LYK_INDEX_SEARCH ARGS4(
 	    /*
 	     *	Yuk, the search failed.  Restore the old file.
 	     */
-	    StrAllocCopy(newdoc.address, curdoc.address);
+	    copy_address(&newdoc, &curdoc);
 	    StrAllocCopy(newdoc.post_data, curdoc.post_data);
 	    StrAllocCopy(newdoc.post_content_type,
 			 curdoc.post_content_type);
@@ -3330,8 +3281,7 @@ PRIVATE BOOLEAN handle_LYK_INFO ARGS1(
 		       &newdoc, owner_address) >= 0) {
 	    LYRegisterUIPage(newdoc.address, UIP_SHOWINFO);
 	    StrAllocCopy(newdoc.title, SHOWINFO_TITLE);
-	    FREE(newdoc.post_data);
-	    FREE(newdoc.post_content_type);
+	    LYFreePostData(&newdoc);
 	    FREE(newdoc.bookmark);
 	    newdoc.isHEAD = FALSE;
 	    newdoc.safe = FALSE;
@@ -3392,7 +3342,7 @@ PRIVATE void handle_LYK_INSERT_FILE ARGS3(
 	    if (*old_c != real_c) {
 		*old_c = real_c;
 		if (no_goto_file)
-		    HTUserMsg2(GOTO_XXXX_DISALLOWED, "file:");
+		    HTUserMsg2(GOTO_XXXX_DISALLOWED, STR_FILE_URL);
 		else
 		    HTUserMsg(NOAUTH_TO_ACCESS_FILES);
 		HTInfoMsg(FILE_INSERT_CANCELLED);
@@ -3483,10 +3433,9 @@ PRIVATE BOOLEAN handle_LYK_JUMP ARGS10(
 	    if (!LYTrimStartfile(ret)) {
 		LYRemoveBlanks(user_input_buffer);
 	    }
-	    StrAllocCopy(newdoc.address, ret);
+	    set_address(&newdoc, ret);
 	    StrAllocCopy(lynxjumpfile, ret);
-	    FREE(newdoc.post_data);
-	    FREE(newdoc.post_content_type);
+	    LYFreePostData(&newdoc);
 	    FREE(newdoc.bookmark);
 	    newdoc.isHEAD = FALSE;
 	    newdoc.safe = FALSE;
@@ -3508,10 +3457,9 @@ PRIVATE void handle_LYK_KEYMAP ARGS4(
 {
     if (*old_c != real_c) {
 	*old_c = real_c;
-	StrAllocCopy(newdoc.address, "LYNXKEYMAP:");
+	set_address(&newdoc, STR_LYNXKEYMAP);
 	StrAllocCopy(newdoc.title, CURRENT_KEYMAP_TITLE);
-	FREE(newdoc.post_data);
-	FREE(newdoc.post_content_type);
+	LYFreePostData(&newdoc);
 	FREE(newdoc.bookmark);
 	newdoc.isHEAD = FALSE;
 	newdoc.safe = FALSE;
@@ -3566,8 +3514,7 @@ PRIVATE BOOLEAN handle_LYK_LIST ARGS1(
     /*
      *	Don't do if already viewing list page.
      */
-    if (!strcmp((curdoc.title ? curdoc.title : ""),
-		LIST_PAGE_TITLE) &&
+    if (!strcmp(NonNull(curdoc.title), LIST_PAGE_TITLE) &&
 	LYIsUIPage(curdoc.address, UIP_LIST_PAGE)) {
 	/*
 	 *  Already viewing list page, so get out.
@@ -3606,10 +3553,9 @@ PRIVATE void handle_LYK_MAIN_MENU ARGS2(
     if (!STREQ(curdoc.address,homepage)) {
 
 	if (HTConfirmDefault(CONFIRM_MAIN_SCREEN, NO) == YES) {
-	    StrAllocCopy(newdoc.address, homepage);
+	    set_address(&newdoc, homepage);
 	    StrAllocCopy(newdoc.title, gettext("Entry into main screen"));
-	    FREE(newdoc.post_data);
-	    FREE(newdoc.post_content_type);
+	    LYFreePostData(&newdoc);
 	    FREE(newdoc.bookmark);
 	    newdoc.isHEAD = FALSE;
 	    newdoc.safe = FALSE;
@@ -3642,13 +3588,11 @@ PRIVATE void handle_LYK_MINIMAL NOARGS
 	 */
 	if ((curdoc.post_data != NULL &&
 	     curdoc.safe != TRUE) &&
-	    confirm_post_resub(curdoc.address, NULL,
-			       0, 0) == FALSE) {
+	    confirm_post_resub(curdoc.address, NULL, 0, 0) == FALSE) {
 	    HTInfoMsg(WILL_NOT_RELOAD_DOC);
 	} else {
 	    HTuncache_current_document();
-	    StrAllocCopy(newdoc.address, curdoc.address);
-	    FREE(curdoc.address);
+	    move_address(&newdoc, &curdoc);
 	    newdoc.line = curdoc.line;
 	    newdoc.link = curdoc.link;
 	}
@@ -3685,10 +3629,8 @@ PRIVATE void handle_LYK_MODIFY ARGS1(
 	    *refresh_screen = TRUE;
 	} else if (ret) {
 	    DIRED_UNCACHE_1;
-	    StrAllocCopy(newdoc.address, curdoc.address);
-	    FREE(curdoc.address);
-	    FREE(newdoc.post_data);
-	    FREE(newdoc.post_content_type);
+	    move_address(&newdoc, &curdoc);
+	    LYFreePostData(&newdoc);
 	    FREE(newdoc.bookmark);
 	    newdoc.isHEAD = FALSE;
 	    newdoc.safe = FALSE;
@@ -3744,8 +3686,8 @@ PRIVATE BOOLEAN handle_LYK_OPTIONS ARGS2(
 	      user_mode == NOVICE_MODE)) ||
 	    (((HTfileSortMethod_flag != HTfileSortMethod) ||
 	      (show_dotfiles_flag != show_dotfiles)) &&
-	     (!strncmp(curdoc.address, "file:", 5) ||
-	      !strncmp(curdoc.address, "ftp:", 4))) ||
+	     (isFILE_URL(curdoc.address) ||
+	      isFTP_URL(curdoc.address))) ||
 	    CurrentCharSet_flag != current_char_set ||
 	    CurrentAssumeCharSet_flag != UCLYhndl_for_unspec ||
 	    verbose_img_flag != verbose_img ||
@@ -3758,7 +3700,7 @@ PRIVATE BOOLEAN handle_LYK_OPTIONS ARGS2(
 	      strcmp(CurrentNegoCharset, (pref_charset ?
 					  pref_charset : ""))) &&
 	     (!strncmp(curdoc.address, "http", 4) ||
-	      !strncmp(curdoc.address, "lynxcgi:", 8)))) {
+	      isLYNXCGI(curdoc.address)))) {
 
 	    BOOLEAN canreparse_post = FALSE;
 
@@ -3776,15 +3718,13 @@ PRIVATE BOOLEAN handle_LYK_OPTIONS ARGS2(
 				   2, 1) == FALSE) {
 		HTInfoMsg(WILL_NOT_RELOAD_DOC);
 	    } else {
-		StrAllocCopy(newdoc.address, curdoc.address);
+		copy_address(&newdoc, &curdoc);
 		if (((strcmp(CurrentUserAgent, (LYUserAgent ?
 					LYUserAgent : "")) ||
-		      strcmp(CurrentNegoLanguage,
-			     (language ? language : "")) ||
-		      strcmp(CurrentNegoCharset,
-			     (pref_charset ? pref_charset : ""))) &&
+		      strcmp(CurrentNegoLanguage, NonNull(language)) ||
+		      strcmp(CurrentNegoCharset, NonNull(pref_charset))) &&
 		     (strncmp(curdoc.address, "http", 4) == 0 ||
-		      strncmp(curdoc.address, "lynxcgi:", 8) == 0))) {
+		      !isLYNXCGI(curdoc.address) == 0))) {
 		    /*
 		     *  An option has changed which may influence
 		     *  content negotiation, and the resource is from
@@ -3834,7 +3774,7 @@ PRIVATE BOOLEAN handle_LYK_OPTIONS ARGS2(
 		newdoc.link = curdoc.link;
 #endif /* NO_ASSUME_SAME_DOC */
 		LYforce_no_cache = TRUE;
-		FREE(curdoc.address); /* So it doesn't get pushed. */
+		free_address(&curdoc); /* So it doesn't get pushed. */
 	    }
 	}
 	FREE(CurrentUserAgent);
@@ -3862,9 +3802,8 @@ PRIVATE BOOLEAN handle_LYK_OPTIONS ARGS2(
      */
     if (!LYIsUIPage(curdoc.address, UIP_OPTIONS_MENU)) {
 
-	StrAllocCopy(newdoc.address, "LYNXOPTIONS:/");
-	FREE(newdoc.post_data);
-	FREE(newdoc.post_content_type);
+	set_address(&newdoc, "LYNXOPTIONS:/");
+	LYFreePostData(&newdoc);
 	FREE(newdoc.bookmark);
 	newdoc.isHEAD = FALSE;
 	newdoc.safe = FALSE;
@@ -3890,7 +3829,7 @@ PRIVATE BOOLEAN handle_LYK_OPTIONS ARGS2(
 PRIVATE void handle_NEXT_DOC NOARGS
 {
     if (LYhist_next(&curdoc, &newdoc)) {
-	FREE(curdoc.address);		/* avoid push */
+	free_address(&curdoc);	/* avoid push */
 	return;
     }
     HTUserMsg(gettext("No next document present"));
@@ -4041,40 +3980,39 @@ PRIVATE int handle_PREV_DOC ARGS3(
 	HTLastConfirmCancelled(); /* reset flag */
 	while (nhist > 0) {
 	    conf = FALSE;
-	    if (history[(nhist - 1)].post_data == NULL) {
+	    if (HDOC(nhist - 1).post_data == NULL) {
 		break;
 	    }
-	    WWWDoc.address = history[(nhist - 1)].address;
-	    WWWDoc.post_data = history[(nhist - 1)].post_data;
+	    WWWDoc.address = HDOC(nhist - 1).address;
+	    WWWDoc.post_data = HDOC(nhist - 1).post_data;
 	    WWWDoc.post_content_type =
-			       history[(nhist - 1)].post_content_type;
-	    WWWDoc.bookmark = history[(nhist - 1)].bookmark;
-	    WWWDoc.isHEAD = history[(nhist - 1)].isHEAD;
-	    WWWDoc.safe = history[(nhist - 1)].safe;
+			       HDOC(nhist - 1).post_content_type;
+	    WWWDoc.bookmark = HDOC(nhist - 1).bookmark;
+	    WWWDoc.isHEAD = HDOC(nhist - 1).isHEAD;
+	    WWWDoc.safe = HDOC(nhist - 1).safe;
 	    tmpanchor = HTAnchor_parent(HTAnchor_findAddress(&WWWDoc));
 	    if (HTAnchor_safe(tmpanchor)) {
 		break;
 	    }
-	    if (((text =
-		  (HText *)HTAnchor_document(tmpanchor)) == NULL &&
-		 (!strncmp(WWWDoc.address, "LYNXIMGMAP:", 11) ||
+	    if (((text = (HText *)HTAnchor_document(tmpanchor)) == NULL &&
+		 (isLYNXIMGMAP(WWWDoc.address) ||
 		 (conf = confirm_post_resub(WWWDoc.address,
-					    history[(nhist - 1)].title,
+					    HDOC(nhist - 1).title,
 					    0, 0))
 		  == FALSE)) ||
 		((LYresubmit_posts && !conf &&
 		  (NONINTERNAL_OR_PHYS_DIFFERENT(
-		      (document *)&history[(nhist - 1)],
+		      (DocInfo *)&history[(nhist - 1)],
 		      &curdoc) ||
 		   NONINTERNAL_OR_PHYS_DIFFERENT(
-		       (document *)&history[(nhist - 1)],
+		       (DocInfo *)&history[(nhist - 1)],
 		       &newdoc))) &&
 		 !confirm_post_resub(WWWDoc.address,
-				     history[(nhist - 1)].title,
+				     HDOC(nhist - 1).title,
 				     2, 2))) {
 		if (HTLastConfirmCancelled()) {
 		    if (!first && curdoc.internal_link)
-			FREE(curdoc.address);
+			free_address(&curdoc);
 		    *cmd = LYK_DO_NOTHING;
 		    return 2;
 		}
@@ -4088,7 +4026,7 @@ PRIVATE int handle_PREV_DOC ARGS3(
 		    do {	/* Should be LYhist_prev when _next supports */
 			LYpop(&curdoc);		/* skipping of forms */
 		    } while (nhist > 1 && !are_different(
-			(document *)&history[(nhist - 1)],
+			(DocInfo *)&history[(nhist - 1)],
 			&curdoc));
 		    first = FALSE; /* have popped at least one */
 		    continue;
@@ -4113,7 +4051,7 @@ PRIVATE int handle_PREV_DOC ARGS3(
 	 *  Set newdoc.address to empty to pop a file.
 	 */
 	LYhist_prev_register(&curdoc);	/* Why not call _prev instead of zeroing address?  */
-	FREE(newdoc.address);
+	free_address(&newdoc);
 #ifdef DIRED_SUPPORT
 	if (lynx_edit_mode) {
 	    DIRED_UNCACHE_2;
@@ -4164,8 +4102,7 @@ PRIVATE void handle_LYK_PRINT ARGS3(
 		      curdoc.address, HText_getNumOfLines()) >= 0) {
 	LYRegisterUIPage(newdoc.address, UIP_PRINT_OPTIONS);
 	StrAllocCopy(newdoc.title, PRINT_OPTIONS_TITLE);
-	FREE(newdoc.post_data);
-	FREE(newdoc.post_content_type);
+	LYFreePostData(&newdoc);
 	FREE(newdoc.bookmark);
 	newdoc.isHEAD = FALSE;
 	newdoc.safe = FALSE;
@@ -4180,9 +4117,9 @@ PRIVATE BOOLEAN handle_LYK_QUIT NOARGS
     int c;
 
     if (LYQuitDefaultYes == TRUE) {
-	c = HTConfirmDefault(REALLY_QUIT_Y, YES);
+	c = HTConfirmDefault(REALLY_QUIT, YES);
     } else {
-	c = HTConfirmDefault(REALLY_QUIT_N, NO);
+	c = HTConfirmDefault(REALLY_QUIT, NO);
     }
     if (LYQuitDefaultYes == TRUE) {
 	if (c != NO) {
@@ -4254,7 +4191,7 @@ PRIVATE void handle_LYK_RELOAD ARGS1(
     newdoc.line = curdoc.line;
     newdoc.link = curdoc.link;
 #endif /* NO_ASSUME_SAME_DOC */
-    FREE(curdoc.address); /* so it doesn't get pushed */
+    free_address(&curdoc); /* so it doesn't get pushed */
 #ifdef VMS
     lynx_force_repaint();
 #endif /* VMS */
@@ -4334,8 +4271,7 @@ PRIVATE void handle_LYK_SOFT_DQUOTES NOARGS
 	HTInfoMsg(WILL_NOT_RELOAD_DOC);
     } else {
 	HTuncache_current_document();
-	StrAllocCopy(newdoc.address, curdoc.address);
-	FREE(curdoc.address);
+	move_address(&newdoc, &curdoc);
 	newdoc.line = curdoc.line;
 	newdoc.link = curdoc.link;
     }
@@ -4370,8 +4306,7 @@ PRIVATE void handle_LYK_SOURCE ARGS1(
 	(!(canreparse_post = HTcan_reparse_document())) &&
 #endif
 	(curdoc.isHEAD ? HTConfirm(CONFIRM_POST_RESUBMISSION) :
-	 confirm_post_resub(curdoc.address, curdoc.title,
-			    1, 1)) == FALSE) {
+	 confirm_post_resub(curdoc.address, curdoc.title, 1, 1)) == FALSE) {
 	HTInfoMsg(CANCELLED);
 	return;
     }
@@ -4412,7 +4347,7 @@ PRIVATE void handle_LYK_SOURCE ARGS1(
 
     if (curdoc.title)
 	StrAllocCopy(newdoc.title, curdoc.title);
-    FREE(curdoc.address); /* so it doesn't get pushed */
+    free_address(&curdoc); /* so it doesn't get pushed */
     LYforce_no_cache = TRUE;
 }
 
@@ -4447,8 +4382,7 @@ PRIVATE void handle_LYK_SWITCH_DTD NOARGS
 		srcmode_for_next_retrieval(1);
 	    }
 	    HTuncache_current_document();
-	    StrAllocCopy(newdoc.address, curdoc.address);
-	    FREE(curdoc.address);
+	    move_address(&newdoc, &curdoc);
 #ifdef NO_ASSUME_SAME_DOC
 	    newdoc.line = 1;
 	    newdoc.link = 0;
@@ -4548,13 +4482,10 @@ PRIVATE void handle_LYK_TOOLBAR ARGS4(
 	}
     } else if (*old_c != real_c) {
 	*old_c = real_c;
-	if ((cp = strchr(curdoc.address, '#')) != NULL)
-	    *cp = '\0';
-
+	cp = trimPoundSelector(curdoc.address);
 	HTSprintf0(&toolbar, "%s#%s", curdoc.address, LYToolbarName);
-	if (cp)
-	    *cp = '#';
-	StrAllocCopy(newdoc.address, toolbar);
+	restorePoundSelector(cp);
+	set_address(&newdoc, toolbar);
 	FREE(toolbar);
 	*try_internal = TRUE;
 	*force_load = TRUE;  /* force MainLoop to reload */
@@ -4597,8 +4528,7 @@ PRIVATE void handle_LYK_TRACE_LOG ARGS1(
     LYLocalFileToURL (&(newdoc.address), LYTraceLogPath);
     LYRegisterUIPage(newdoc.address, UIP_TRACELOG);
     StrAllocCopy(newdoc.title, LYNX_TRACELOG_TITLE);
-    FREE(newdoc.post_data);
-    FREE(newdoc.post_content_type);
+    LYFreePostData(&newdoc);
     FREE(newdoc.bookmark);
     newdoc.isHEAD = FALSE;
     newdoc.safe = FALSE;
@@ -4622,11 +4552,9 @@ PRIVATE void handle_LYK_UPLOAD NOARGS
 	return;
 
     if (lynx_edit_mode && !no_dired_support) {
-	LYUpload_options((char **)&newdoc.address,
-			 (char *)curdoc.address);
+	LYUpload_options(&(newdoc.address), curdoc.address);
 	StrAllocCopy(newdoc.title, UPLOAD_OPTIONS_TITLE);
-	FREE(newdoc.post_data);
-	FREE(newdoc.post_content_type);
+	LYFreePostData(&newdoc);
 	FREE(newdoc.bookmark);
 	newdoc.isHEAD = FALSE;
 	newdoc.safe = FALSE;
@@ -4773,8 +4701,7 @@ PRIVATE void handle_LYK_VIEW_BOOKMARK ARGS3(
 	LYforce_no_cache = TRUE;  /*force the document to be reloaded*/
 	StrAllocCopy(newdoc.title, BOOKMARK_TITLE);
 	StrAllocCopy(newdoc.bookmark, BookmarkPage);
-	FREE(newdoc.post_data);
-	FREE(newdoc.post_content_type);
+	LYFreePostData(&newdoc);
 	newdoc.isHEAD = FALSE;
 	newdoc.safe = FALSE;
 	newdoc.internal_link = FALSE;
@@ -4813,8 +4740,7 @@ PRIVATE BOOLEAN handle_LYK_VLINKS ARGS2(
 	return FALSE;
     }
     StrAllocCopy(newdoc.title, VISITED_LINKS_TITLE);
-    FREE(newdoc.post_data);
-    FREE(newdoc.post_content_type);
+    LYFreePostData(&newdoc);
     FREE(newdoc.bookmark);
     newdoc.isHEAD = FALSE;
     newdoc.safe = FALSE;
@@ -4915,7 +4841,7 @@ PRIVATE void handle_LYK_digit ARGS6(
 	/*
 	 *  Follow a normal link.
 	 */
-	StrAllocCopy(newdoc.address, links[lindx].lname);
+	set_address(&newdoc, links[lindx].lname);
 	StrAllocCopy(newdoc.title, LYGetHiliteStr(lindx, 0));
 #ifndef DONT_TRACK_INTERNAL_LINKS
 	/*
@@ -4928,7 +4854,7 @@ PRIVATE void handle_LYK_digit ARGS6(
 	if (links[lindx].type == WWW_INTERN_LINK_TYPE) {
 	    LYinternal_flag = TRUE;
 	    newdoc.internal_link = TRUE;
-	    if (LYIsListpageTitle(curdoc.title ? curdoc.title : "") &&
+	    if (LYIsListpageTitle(NonNull(curdoc.title)) &&
 		(LYIsUIPage(curdoc.address, UIP_LIST_PAGE) ||
 		 LYIsUIPage(curdoc.address, UIP_ADDRLIST_PAGE))) {
 		if (check_history()) {
@@ -4946,7 +4872,7 @@ PRIVATE void handle_LYK_digit ARGS6(
 			    /* cancel the whole thing */
 			    LYforce_no_cache = FALSE;
 			    reloading = FALSE;
-			    StrAllocCopy(newdoc.address, curdoc.address);
+			    copy_address(&newdoc, &curdoc);
 			    StrAllocCopy(newdoc.title, curdoc.title);
 			    newdoc.internal_link = curdoc.internal_link;
 			    HTInfoMsg(CANCELLED);
@@ -4964,8 +4890,7 @@ PRIVATE void handle_LYK_digit ARGS6(
 			     * wasn't meant to be internal after
 			     * all, here we can recover from that
 			     * assumption. - kw */
-			    FREE(newdoc.post_data);
-			    FREE(newdoc.post_content_type);
+			    LYFreePostData(&newdoc);
 			    newdoc.internal_link = FALSE;
 			    HTAlert(DISCARDING_POST_DATA);
 			}
@@ -4975,7 +4900,7 @@ PRIVATE void handle_LYK_digit ARGS6(
 		 *  Don't push the List Page if we follow an
 		 *  internal link given by it. - kw
 		 */
-		FREE(curdoc.address);
+		free_address(&curdoc);
 	    } else
 		*try_internal = TRUE;
 	    if (!(LYresubmit_posts && newdoc.post_data))
@@ -4986,8 +4911,7 @@ PRIVATE void handle_LYK_digit ARGS6(
 	    /*
 	     *	Free POST content if not an internal link. - kw
 	     */
-	    FREE(newdoc.post_data);
-	    FREE(newdoc.post_content_type);
+	    LYFreePostData(&newdoc);
 	}
 #endif /* DONT_TRACK_INTERNAL_LINKS */
 	/*
@@ -4995,12 +4919,11 @@ PRIVATE void handle_LYK_digit ARGS6(
 	 *  form.  If so, don't free the content. -- FM
 	 */
 	if (are_different(&curdoc, &newdoc)) {
-	    FREE(newdoc.post_data);
-	    FREE(newdoc.post_content_type);
+	    LYFreePostData(&newdoc);
 	    FREE(newdoc.bookmark);
 	    newdoc.isHEAD = FALSE;
 	    newdoc.safe = FALSE;
-	    if (!strncmp(newdoc.address, "LYNXMESSAGES:", 13))
+	    if (isLYNXMESSAGES(newdoc.address))
 		LYforce_no_cache = TRUE;
 	}
 	newdoc.internal_link = FALSE;
@@ -5137,8 +5060,7 @@ PUBLIC void handle_LYK_CHDIR NOARGS
 	    newdoc.address = addr;
 	    newdoc.isHEAD = FALSE;
 	    StrAllocCopy(newdoc.title, gettext("A URL specified by the user"));
-	    FREE(newdoc.post_data);
-	    FREE(newdoc.post_content_type);
+	    LYFreePostData(&newdoc);
 	    FREE(newdoc.bookmark);
 	    newdoc.safe = FALSE;
 	    newdoc.internal_link = FALSE;
@@ -5161,7 +5083,7 @@ PUBLIC void handle_LYK_CHDIR NOARGS
  * would scroll 3-4 extra full screens.  When going back, the "accumulation"
  * logic would again start moving in full screens, so one would overshoot
  * again, etc.
- * 
+ *
  * Going back, one can fix it in 28 keypresses. The relevant text will appear
  * on the screen soon enough for the key-repeat to become not that important,
  * and we are still moving in smaller steps than when we overshot.  Since key
@@ -5345,7 +5267,7 @@ int mainloop NOARGS
     atexit(free_mainloop_variables);
 #endif
 initialize:
-    StrAllocCopy(newdoc.address, startfile);
+    set_address(&newdoc, startfile);
     StrAllocCopy(startrealm, startfile);
     StrAllocCopy(newdoc.title, gettext("Entry into main screen"));
     newdoc.isHEAD = FALSE;
@@ -5390,8 +5312,7 @@ initialize:
 		StrAllocCopy(newdoc.title, BOOKMARK_TITLE);
 		StrAllocCopy(newdoc.bookmark, BookmarkPage);
 		StrAllocCopy(startrealm, newdoc.address);
-		FREE(newdoc.post_data);
-		FREE(newdoc.post_content_type);
+		LYFreePostData(&newdoc);
 		newdoc.isHEAD = FALSE;
 		newdoc.safe = FALSE;
 		CTRACE((tfp, "Using bookmarks=%s\n", newdoc.address));
@@ -5444,7 +5365,7 @@ try_again:
 		     *	elements to the curdoc structure elements
 		     *	under case NORMAL.  - FM
 		     */
-		    if (strncmp(newdoc.address, "LYNXDOWNLOAD:", 13))
+		    if (!isLYNXDOWNLOAD(newdoc.address))
 		    {
 			LYpush(&curdoc, ForcePush);
 		    }
@@ -5504,10 +5425,10 @@ try_again:
 		    if (newdoc.address) {
 			if (LYCanDoHEAD(newdoc.address) == TRUE) {
 			    newdoc.isHEAD = TRUE;
-			} else if (!strncmp(newdoc.address, "LYNXIMGMAP:", 11)) {
-			    if (LYCanDoHEAD(newdoc.address + 11) == TRUE) {
-				StrAllocCopy(temp, newdoc.address + 11);
-				FREE(newdoc.address);
+			} else if (isLYNXIMGMAP(newdoc.address)) {
+			    if (LYCanDoHEAD(newdoc.address + LEN_LYNXIMGMAP) == TRUE) {
+				StrAllocCopy(temp, newdoc.address + LEN_LYNXIMGMAP);
+				free_address(&newdoc);
 				newdoc.address = temp;
 				newdoc.isHEAD = TRUE;
 				temp = NULL;
@@ -5585,15 +5506,15 @@ try_again:
 #ifndef DONT_TRACK_INTERNAL_LINKS
 		if (try_internal) {
 		    if (newdoc.address &&
-			0==strncmp(newdoc.address, "LYNXIMGMAP:", 11)) {
+			isLYNXIMGMAP(newdoc.address)) {
 			try_internal = FALSE;
 		    } else if (curdoc.address &&
-			0==strncmp(curdoc.address, "LYNXIMGMAP:", 11)) {
+			isLYNXIMGMAP(curdoc.address)) {
 			try_internal = FALSE;
 		    }
 		}
 		if (try_internal) {
-		    char *hashp = strchr(newdoc.address,'#');
+		    char *hashp = findPoundSelector(newdoc.address);
 		    if (hashp) {
 			HTFindPoundSelector(hashp+1);
 		    }
@@ -5602,11 +5523,11 @@ try_again:
 		    /* fix up newdoc.address which may have been fragment-only */
 		    if (getresult == NORMAL && (!hashp || hashp == newdoc.address)) {
 			if (!hashp) {
-			    StrAllocCopy(newdoc.address, HTLoadedDocumentURL());
+			    set_address(&newdoc, HTLoadedDocumentURL());
 			} else {
 			    StrAllocCopy(temp, HTLoadedDocumentURL());
 			    StrAllocCat(temp, hashp); /* append fragment */
-			    StrAllocCopy(newdoc.address, temp);
+			    set_address(&newdoc, temp);
 			    FREE(temp);
 			}
 		    }
@@ -5614,16 +5535,14 @@ try_again:
 		    if (newdoc.internal_link && newdoc.address &&
 			*newdoc.address == '#' && nhist > 0) {
 			char *cp0;
-			if (0==strncmp(history[nhist-1].address, "LYNXIMGMAP:", 11))
-			    cp0 = history[nhist-1].address + 11;
+			if (isLYNXIMGMAP(HDOC(nhist-1).address))
+			    cp0 = HDOC(nhist-1).address + LEN_LYNXIMGMAP;
 			else
-			    cp0 = history[nhist-1].address;
+			    cp0 = HDOC(nhist-1).address;
 			StrAllocCopy(temp, cp0);
-			cp0 = strchr(temp, '#');
-			if (cp0)
-			    *cp0 = '\0';
+			(void) trimPoundSelector(temp);
 			StrAllocCat(temp, newdoc.address);
-			FREE(newdoc.address);
+			free_address(&newdoc);
 			newdoc.address = temp;
 			temp = NULL;
 		    }
@@ -5661,14 +5580,11 @@ try_again:
 			    !LYUserSpecifiedURL &&
 			    HTMainText &&
 			    nlinks > 0 && curdoc.link < nlinks &&
-			    strncmp(newdoc.address ? newdoc.address : "",
-				    "LYNXHIST:", 9) &&
-			    strncmp(newdoc.address ? newdoc.address : "",
-				    "LYNXCOOKIE:", 11)) {
+			    !isLYNXHIST(NonNull(newdoc.address)) &&
+			    !isLYNXCOOKIE(NonNull(newdoc.address))) {
 			    char *mail_owner = NULL;
-			    if (owner_address &&
-				strncasecomp(owner_address, "mailto:", 7)) {
-				mail_owner = owner_address + 7;
+			    if (owner_address && isMAILTO_URL(owner_address)) {
+				mail_owner = owner_address + LEN_MAILTO_URL;
 			    }
 			    /*
 			     *  Email a bad link message to the owner of
@@ -5681,8 +5597,8 @@ try_again:
 #endif
 				mailmsg(curdoc.link,
 					mail_owner,
-					history[nhist-1].address,
-					history[nhist-1].title);
+					HDOC(nhist-1).address,
+					HDOC(nhist-1).title);
 			}
 			if (traversal) {
 			    FILE *ofp;
@@ -5699,7 +5615,7 @@ try_again:
 					popped_doc ?
 					newdoc.address : links[curdoc.link].lname,
 					links[curdoc.link].target,
-					history[nhist-1].address);
+					HDOC(nhist-1).address);
 			    } else {
 				fprintf(ofp,
 					"%s %s\t\n",
@@ -5733,7 +5649,7 @@ try_again:
 		    popped_doc = FALSE;		 /* Was TRUE if popped. - FM */
 		    LYinternal_flag = FALSE;	 /* Reset to default. - kw */
 		    turn_trace_back_on(&trace_mode_flag);
-		    FREE(newdoc.address); /* to pop last doc */
+		    free_address(&newdoc); /* to pop last doc */
 		    FREE(newdoc.bookmark);
 		    LYJumpFileURL = FALSE;
 		    reloading = FALSE;
@@ -5765,12 +5681,7 @@ try_again:
 			 *  If nhist = 0 then it must be the first file.
 			 */
 			if (first_file && homepage &&
-#ifdef VMS
-			   strcasecomp(homepage, startfile) != 0
-#else
-			   strcmp(homepage, startfile) != 0
-#endif /* VMS */
-			   ) {
+			   !LYSameFilename(homepage, startfile)) {
 			   /*
 			    *  Couldn't return to the first file but there is a
 			    *  homepage we can use instead. Useful for when the
@@ -5781,9 +5692,8 @@ try_again:
 			    *  so we don't enter an infinite getfile() loop on
 			    *  on failures to find the files. - FM
 			    */
-			   StrAllocCopy(newdoc.address, homepage);
-			   FREE(newdoc.post_data);
-			   FREE(newdoc.post_content_type);
+			   set_address(&newdoc, homepage);
+			   LYFreePostData(&newdoc);
 			   FREE(newdoc.bookmark);
 			   StrAllocCopy(startfile, homepage);
 			   newdoc.isHEAD = FALSE;
@@ -5815,16 +5725,16 @@ try_again:
 		    *  affect the traversal logic, since with traversal
 		    *  POST data can never occur. - kw
 		    */
-		   if (history[nhist - 1].post_data &&
-		       !history[nhist - 1].safe) {
-		       if (HText_POSTReplyLoaded((document *)&history[(nhist - 1)])) {
+		   if (HDOC(nhist - 1).post_data &&
+		       !HDOC(nhist - 1).safe) {
+		       if (HText_POSTReplyLoaded((DocInfo *)&history[(nhist - 1)])) {
 			   override_LYresubmit_posts = TRUE;
 			   goto try_again;
 		       }
 		       /*  Set newdoc fields, just in case the PREV_DOC
 			*  gets cancelled. - kw */
 		       if (!curdoc.address) {
-			   StrAllocCopy(newdoc.address, HTLoadedDocumentURL());
+			   set_address(&newdoc, HTLoadedDocumentURL());
 			   StrAllocCopy(newdoc.title, HTLoadedDocumentTitle());
 			   if (HTMainAnchor && HTMainAnchor->post_data) {
 			       StrAllocCopy(newdoc.post_data,
@@ -5838,7 +5748,7 @@ try_again:
 			   newdoc.safe = HTLoadedDocumentIsSafe();
 			   newdoc.internal_link = FALSE;
 		       } else {
-			   StrAllocCopy(newdoc.address, curdoc.address);
+			   copy_address(&newdoc, &curdoc);
 			   StrAllocCopy(newdoc.title, curdoc.title);
 			   StrAllocCopy(newdoc.post_data, curdoc.post_data);
 			   StrAllocCopy(newdoc.post_content_type,
@@ -5872,17 +5782,17 @@ try_again:
 			 (dump_output_immediately == FALSE) &&
 			 !(newdoc.bookmark && *newdoc.bookmark)) &&
 			((LYisLocalFile(newdoc.address) == TRUE) &&
-			 !(strcmp((HText_getTitle() ? HText_getTitle() : ""),
+			 !(strcmp(NonNull(HText_getTitle()),
 				  BOOKMARK_TITLE))) &&
 			(temp = HTParse(newdoc.address, "",
 				     PARSE_PATH+PARSE_PUNCTUATION)) != NULL) {
-			cp = wwwName(Home_Dir());
-			len = strlen(cp);
+			CONST char *name = wwwName(Home_Dir());
+			len = strlen(name);
 #ifdef VMS
-			if (!strncasecomp(temp, cp, len) &&
+			if (!strncasecomp(temp, name, len) &&
 			    strlen(temp) > len)
 #else
-			if (!strncmp(temp, cp, len) &&
+			if (!strncmp(temp, name, len) &&
 			    strlen(temp) > len)
 #endif /* VMS */
 			{
@@ -5904,14 +5814,9 @@ try_again:
 			    } else {
 				StrAllocCopy(cp, &temp[len]);
 			    }
-#ifdef VMS
-#define CompareBookmark(a,b) strcasecomp(a, b)
-#else
-#define CompareBookmark(a,b) strcmp(a, b)
-#endif /* VMS */
 			    for (i = 0; i <= MBM_V_MAXFILES; i++) {
 				if (MBM_A_subbookmark[i] &&
-				    !CompareBookmark(cp, MBM_A_subbookmark[i])) {
+				    LYSameFilename(cp, MBM_A_subbookmark[i])) {
 				    StrAllocCopy(BookmarkPage,
 						 MBM_A_subbookmark[i]);
 				    break;
@@ -5926,9 +5831,9 @@ try_again:
 				}
 				if ((temp = HTParse(newdoc.address, "",
 				 PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION))) {
-				    StrAllocCopy(newdoc.address, temp);
+				    set_address(&newdoc, temp);
 				    HTuncache_current_document();
-				    FREE(curdoc.address);
+				    free_address(&curdoc);
 				    StrAllocCat(newdoc.address,
 					    wwwName(Home_Dir()));
 				    StrAllocCat(newdoc.address, "/");
@@ -5943,8 +5848,7 @@ try_again:
 					StrAllocCopy(newdoc.style, curdoc.style);
 #endif
 				    StrAllocCopy(startrealm, newdoc.address);
-				    FREE(newdoc.post_data);
-				    FREE(newdoc.post_content_type);
+				    LYFreePostData(&newdoc);
 				    newdoc.isHEAD = FALSE;
 				    newdoc.safe = FALSE;
 				    FREE(temp);
@@ -5976,7 +5880,7 @@ try_again:
 			    FREE(traversal_link_to_add);
 			}
 			if (curdoc.address && curdoc.title &&
-			    strncmp(curdoc.address, "LYNXIMGMAP:", 11))
+			    !isLYNXIMGMAP(curdoc.address))
 			    /*
 			     *	Add the address we got to TRAVERSE_FOUND_FILE.
 			     */
@@ -5989,8 +5893,8 @@ try_again:
 		     *	positioning elements. - FM
 		     */
 		    if (newdoc.address && curdoc.address &&
-			!strncmp(newdoc.address, "LYNXDOWNLOAD:", 13)) {
-			StrAllocCopy(newdoc.address, curdoc.address);
+			isLYNXDOWNLOAD(newdoc.address)) {
+			copy_address(&newdoc, &curdoc);
 			StrAllocCopy(newdoc.title, (curdoc.title ?
 						    curdoc.title : ""));
 			StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
@@ -6049,7 +5953,7 @@ try_again:
 	    /*
 	     *	Set the files the same.
 	     */
-	    StrAllocCopy(curdoc.address, newdoc.address);
+	    copy_address(&curdoc, &newdoc);
 	    StrAllocCopy(curdoc.post_data, newdoc.post_data);
 	    StrAllocCopy(curdoc.post_content_type, newdoc.post_content_type);
 	    StrAllocCopy(curdoc.bookmark, newdoc.bookmark);
@@ -6196,7 +6100,7 @@ try_again:
 		    if (forced_HTML_mode &&
 			!dump_output_immediately &&
 			!curdoc.bookmark &&
-			!strncasecomp(curdoc.address, "file:", 5) &&
+			isFILE_URL(curdoc.address) &&
 			strlen(temp) > 1) {
 			/*
 			 *  We forced HTML for a local startfile which
@@ -6230,7 +6134,7 @@ try_again:
 		 *  Set up the crawl output stuff.
 		 */
 		if (curdoc.address && !lookup(curdoc.address)) {
-		    if (strncmp(curdoc.address, "LYNXIMGMAP:", 11))
+		    if (!isLYNXIMGMAP(curdoc.address))
 			crawl_ok = TRUE;
 		    add_to_table(curdoc.address);
 		}
@@ -7471,8 +7375,8 @@ new_cmd:  /*
 }
 
 PRIVATE int are_different ARGS2(
-	document *,	doc1,
-	document *,	doc2)
+	DocInfo *,	doc1,
+	DocInfo *,	doc2)
 {
     char *cp1, *cp2;
 
@@ -7493,24 +7397,18 @@ PRIVATE int are_different ARGS2(
      *	we're not tripped up by multiple anchors in the
      *	the same document from a POST form. -- FM
      */
-    if ((cp1 = strchr(doc1->address, '#')) != NULL)
-	*cp1 = '\0';
-    if ((cp2 = strchr(doc2->address, '#')) != NULL)
-	*cp2 = '\0';
+    cp1 = trimPoundSelector(doc1->address);
+    cp2 = trimPoundSelector(doc2->address);
     /*
      *	Are the base addresses different?
      */
     if (strcmp(doc1->address, doc2->address)) {
-	if (cp1)
-	    *cp1 = '#';
-	if (cp2)
-	    *cp2 = '#';
+	restorePoundSelector(cp1);
+	restorePoundSelector(cp2);
 	return(TRUE);
     }
-    if (cp1)
-	*cp1 = '#';
-    if (cp2)
-	*cp2 = '#';
+    restorePoundSelector(cp1);
+    restorePoundSelector(cp2);
 
     /*
      *	Do the docs have different contents?
@@ -7535,8 +7433,8 @@ PRIVATE int are_different ARGS2(
  */
 #ifndef DONT_TRACK_INTERNAL_LINKS
 PRIVATE int are_phys_different ARGS2(
-	document *,	doc1,
-	document *,	doc2)
+	DocInfo *,	doc1,
+	DocInfo *,	doc2)
 {
     char *cp1, *cp2, *ap1 = doc1->address, *ap2 = doc2->address;
 
@@ -7555,10 +7453,10 @@ PRIVATE int are_phys_different ARGS2(
     /*
      * Skip over possible LYNXIMGMAP parts. - kw
      */
-    if (0==strncmp(doc1->address, "LYNXIMGMAP:", 11))
-	ap1 += 11;
-    if (0==strncmp(doc2->address, "LYNXIMGMAP:", 11))
-	ap2 += 11;
+    if (isLYNXIMGMAP(doc1->address))
+	ap1 += LEN_LYNXIMGMAP;
+    if (isLYNXIMGMAP(doc2->address))
+	ap2 += LEN_LYNXIMGMAP;
     /*
      * If there isn't any real URL in doc2->address, but maybe just
      * a fragment, doc2 is assumed to be an internal reference in
@@ -7572,24 +7470,18 @@ PRIVATE int are_phys_different ARGS2(
      *	we're not tripped up by multiple anchors in the
      *	the same document from a POST form. -- FM
      */
-    if ((cp1 = strchr(doc1->address, '#')) != NULL)
-	*cp1 = '\0';
-    if ((cp2 = strchr(doc2->address, '#')) != NULL)
-	*cp2 = '\0';
+    cp1 = trimPoundSelector(doc1->address);
+    cp2 = trimPoundSelector(doc2->address);
     /*
      *	Are the base addresses different?
      */
     if (strcmp(ap1, ap2)) {
-	if (cp1)
-	    *cp1 = '#';
-	if (cp2)
-	    *cp2 = '#';
+	restorePoundSelector(cp1);
+	restorePoundSelector(cp2);
 	return(TRUE);
     }
-    if (cp1)
-	*cp1 = '#';
-    if (cp2)
-	*cp2 = '#';
+    restorePoundSelector(cp1);
+    restorePoundSelector(cp2);
 
     /*
      *	Do the docs have different contents?
@@ -7643,6 +7535,7 @@ PUBLIC void HTAddGotoURL ARGS1(
     if (!(url && *url))
 	return;
 
+    CTRACE((tfp, "HTAddGotoURL %s\n", url));
     StrAllocCopy(new, url);
 
     if (!Goto_URLs) {
@@ -7729,8 +7622,8 @@ PRIVATE void show_main_statusline ARGS2(
 	char *cp = NULL;
 
 	if (curlink.type == WWW_INTERN_LINK_TYPE &&
-	    strncmp(curlink.lname, "LYNXIMGMAP:", 11)) {
-	    cp = strchr(curlink.lname, '#');
+	    !isLYNXIMGMAP(curlink.lname)) {
+	    cp = findPoundSelector(curlink.lname);
 	}
 	if (!cp)
 	    cp = curlink.lname;
@@ -7824,7 +7717,7 @@ PRIVATE void exit_immediately_with_error_message ARGS2(
     if (state == NOT_FOUND)
     {
 	HTSprintf0(&buf, "%s\n%s %s\n",
-		   buf2 ? buf2 : "",
+		   NonNull(buf2),
 		   gettext("lynx: Can't access startfile"),
 		   /*
 		    * hack: if we fail in HTAccess.c
@@ -7837,7 +7730,7 @@ PRIVATE void exit_immediately_with_error_message ARGS2(
     if (state == NULLFILE)
     {
 	HTSprintf0(&buf, "%s\n%s\n%s\n",
-		   buf2 ? buf2 : "",
+		   NonNull(buf2),
 		   gettext("lynx: Start file could not be found or is not text/html or text/plain"),
 		   gettext("      Exiting..."));
     }
diff --git a/src/LYMap.c b/src/LYMap.c
index 9d4a7d13..f2a4add0 100644
--- a/src/LYMap.c
+++ b/src/LYMap.c
@@ -421,8 +421,8 @@ PRIVATE int LYLoadIMGmap ARGS4 (
     BOOL old_reloading = reloading;
     HTFormat old_format_out = HTOutputFormat;
 
-    if (!strncasecomp(arg, "LYNXIMGMAP:", 11)) {
-	address = (char * )(arg + 11);
+    if (isLYNXIMGMAP(arg)) {
+	address = (char *)(arg + LEN_LYNXIMGMAP);
     }
     if (!(address && strchr(address, ':'))) {
 	HTAlert(MISDIRECTED_MAP_REQUEST);
diff --git a/src/LYNews.c b/src/LYNews.c
index 01d2e41f..7d611170 100644
--- a/src/LYNews.c
+++ b/src/LYNews.c
@@ -195,7 +195,7 @@ PUBLIC char *LYNewsPost ARGS2(
      */
     LYaddstr(gettext("\n\n Please provide your mail address for the From: header\n"));
     sprintf(user_input, "From: %.*s", (int)sizeof(user_input) - 8,
-	    (personal_mail_address != NULL) ? personal_mail_address : "");
+	    NonNull(personal_mail_address));
     if (LYgetstr(user_input, VISIBLE,
 		 sizeof(user_input), NORECALL) < 0 ||
 	term_message) {
@@ -257,10 +257,9 @@ PUBLIC char *LYNewsPost ARGS2(
      *  Add Organization: header.
      */
     StrAllocCopy(cp, "Organization: ");
-    if (((org = getenv("ORGANIZATION")) != NULL) && *org != '\0') {
+    if ((org = LYGetEnv("ORGANIZATION")) != NULL) {
 	StrAllocCat(cp, org);
-    } else if (((org = getenv("NEWS_ORGANIZATION")) != NULL) &&
-	       *org != '\0') {
+    } else if ((org = LYGetEnv("NEWS_ORGANIZATION")) != NULL) {
 	StrAllocCat(cp, org);
     }
 #ifdef UNIX
diff --git a/src/LYOptions.c b/src/LYOptions.c
index 9f01ff6b..90648290 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -1160,7 +1160,7 @@ draw_options:
 		if (no_option_save) {
 #if defined(COLOR_CURSES)
 		    if (!has_colors()) {
-			char * terminal = getenv("TERM");
+			char * terminal = LYGetEnv("TERM");
 			if (terminal)
 			    HTUserMsg2(
 				COLOR_TOGGLE_DISABLED_FOR_TERM,
@@ -1214,7 +1214,7 @@ draw_options:
 #if defined(COLOR_CURSES)
 			again = (BOOL) (chosen == 2 && !has_colors());
 			if (again) {
-			    char * terminal = getenv("TERM");
+			    char * terminal = LYGetEnv("TERM");
 			    if (terminal)
 				HTUserMsg2(
 				    COLOR_TOGGLE_DISABLED_FOR_TERM,
@@ -1984,7 +1984,7 @@ draw_bookmark_list:
 
 		start_bold();
 		LYstrncpy(MBM_tmp_line,
-			  (!MBM_A_subbookmark[a] ? "" : MBM_A_subbookmark[a]),
+			  NonNull(MBM_A_subbookmark[a]),
 			  sizeof(MBM_tmp_line) - 1);
 		ch = LYgetstr(MBM_tmp_line, VISIBLE,
 			      sizeof(MBM_tmp_line), NORECALL);
@@ -2200,14 +2200,12 @@ static OptValues visited_links_values[] = {
 /*
  * Document Layout
  */
-#ifndef SH_EX	/* 1999/01/19 (Tue) */
 static char * DTD_recovery_string      = RC_TAGSOUP;
 static OptValues DTD_type_values[] = {
 	/* Old_DTD variable */
 	{ TRUE,		    "relaxed (TagSoup mode)",	 "tagsoup" },
 	{ FALSE,	    "strict (SortaSGML mode)",	 "sortasgml" },
 	{ 0, 0, 0 }};
-#endif
 
 static char * select_popups_string     = RC_SELECT_POPUPS;
 static char * images_string            = "images";
@@ -2459,7 +2457,7 @@ PRIVATE int gen_options PARAMS((char **newfile));
  */
 
 PUBLIC int postoptions ARGS1(
-    document *,		newdoc)
+    DocInfo *,		newdoc)
 {
     PostPair *data = 0;
     DocAddress WWWDoc;  /* need on exit */
@@ -2665,7 +2663,6 @@ PUBLIC int postoptions ARGS1(
 	    case_sensitive = (BOOL) code;
 	}
 
-#ifndef SH_EX	/* 1999/01/19 (Tue) */
 	/* HTML error tolerance: SELECT */
 	if (!strcmp(data[i].tag, DTD_recovery_string)
 	 && GetOptValues(DTD_type_values, data[i].value, &code)) {
@@ -2675,7 +2672,6 @@ PUBLIC int postoptions ARGS1(
 		need_reload = TRUE;
 	    }
 	}
-#endif
 
 	/* Select Popups: ON/OFF */
 	if (!strcmp(data[i].tag, select_popups_string)
@@ -3002,7 +2998,7 @@ PUBLIC int postoptions ARGS1(
      */
     if ((need_end_reload == TRUE &&
 	 (strncmp(newdoc->address, "http", 4) == 0 ||
-	  strncmp(newdoc->address, "lynxcgi:", 8) == 0))) {
+	  isLYNXCGI(newdoc->address) == 0))) {
 	/*
 	 *  An option has changed which may influence
 	 *  content negotiation, and the resource is from
@@ -3208,7 +3204,7 @@ PRIVATE int gen_options ARGS1(
     /*
      * I do C, not HTML.  Feel free to pretty this up.
      */
-    fprintf(fp0, "<form action=\"LYNXOPTIONS:\" method=\"post\">\n");
+    fprintf(fp0, "<form action=\"%s\" method=\"post\">\n", STR_LYNXOPTIONS);
     /*
      * use following with some sort of one shot secret key akin to NCSA
      * (or was it CUTE?) telnet one shot password to allow ftp to self.
@@ -3225,8 +3221,8 @@ PRIVATE int gen_options ARGS1(
     fprintf(fp0,"<p align=center>\n");
     if (!disable_all) {
 	fprintf(fp0,"<input type=\"submit\" value=\"%s\"> - \n", ACCEPT_CHANGES);
-	fprintf(fp0,"<input type=\"reset\" value=\"%s\">\n", RESET_CHANGES);
-	fprintf(fp0,"%s\n", CANCEL_CHANGES);
+	fprintf(fp0,"<input type=\"reset\" value=\"%s\"> - \n", RESET_CHANGES);
+	fprintf(fp0,"%s - \n", CANCEL_CHANGES);
     }
     fprintf(fp0, "<a href=\"%s%s\">%s</a>\n",
 		 helpfilepath, OPTIONS_HELP, TO_HELP);
@@ -3238,7 +3234,8 @@ PRIVATE int gen_options ARGS1(
 	    fprintf(fp0, "<input type=\"checkbox\" name=\"%s\">\n",
 			 save_options_string);
 	}
-	fprintf(fp0, "<br>(options marked with (!) will not be saved)\n");
+	fprintf(fp0, "<br>%s\n",
+			gettext("(options marked with (!) will not be saved)"));
     }
 
     /*
@@ -3447,13 +3444,11 @@ PRIVATE int gen_options ARGS1(
     PutOptValues(fp0, LYSelectPopups, bool_values);
     EndSelect(fp0);
 
-#ifndef SH_EX  /* 1999/01/19 (Tue) */
     /* HTML error recovery: SELECT */
     PutLabel(fp0, gettext("HTML error recovery"), DTD_recovery_string);
     BeginSelect(fp0, DTD_recovery_string);
     PutOptValues(fp0, Old_DTD, DTD_type_values);
     EndSelect(fp0);
-#endif
 
     /* Show Images: SELECT */
     PutLabel(fp0, gettext("Show images"), will_save_images());
@@ -3583,8 +3578,8 @@ PRIVATE int gen_options ARGS1(
     /* Bookmarks File Menu: LINK/INPUT */
     if (LYMultiBookmarks) {
 	PutLabel(fp0, gettext("Review/edit Bookmarks files"), mbm_string);
-	fprintf(fp0, "<a href=\"LYNXOPTIONS://MBM_MENU\">%s</a>\n",
-		    gettext("Goto multi-bookmark menu"));
+	fprintf(fp0, "<a href=\"%s//MBM_MENU\">%s</a>\n",
+		    STR_LYNXOPTIONS, gettext("Goto multi-bookmark menu"));
     } else {
 	PutLabel(fp0, gettext("Bookmarks file"), single_bookmark_string);
 	PutTextInput(fp0, single_bookmark_string,
@@ -3598,7 +3593,9 @@ PRIVATE int gen_options ARGS1(
     EndSelect(fp0);
 
     if (!no_lynxcfg_info) {
-	fprintf(fp0, "\n  Check your <a href=\"LYNXCFG:\">lynx.cfg</a> here\n");
+	fprintf(fp0, "\n  %s<a href=\"%s\">lynx.cfg</a>.\n",
+		     gettext("View the file "),
+		     STR_LYNXCFG);
     }
 
     fprintf(fp0,"\n</pre>\n");
@@ -3606,8 +3603,8 @@ PRIVATE int gen_options ARGS1(
     /* Submit/Reset */
     if (!disable_all) {
 	fprintf(fp0,"<p align=center>\n");
-	fprintf(fp0,"<input type=\"submit\" value=\"%s\">\n - ", ACCEPT_CHANGES);
-	fprintf(fp0,"<input type=\"reset\" value=\"%s\">\n", RESET_CHANGES);
+	fprintf(fp0,"<input type=\"submit\" value=\"%s\"> - \n", ACCEPT_CHANGES);
+	fprintf(fp0,"<input type=\"reset\" value=\"%s\"> - \n", RESET_CHANGES);
 	fprintf(fp0,"%s\n", CANCEL_CHANGES);
     }
 
diff --git a/src/LYOptions.h b/src/LYOptions.h
index a606a382..b0c3ffad 100644
--- a/src/LYOptions.h
+++ b/src/LYOptions.h
@@ -21,7 +21,7 @@ extern  int popup_choice PARAMS((
 	popup_choice(cur, line, column, (CONST char **)choices, length, disabled, mouse)
 
 #ifndef NO_OPTION_FORMS
-extern int postoptions PARAMS((document *newdoc));
+extern int postoptions PARAMS((DocInfo *newdoc));
 #endif /* !NO_OPTION_FORMS */
 
 #ifndef NO_OPTION_MENU
diff --git a/src/LYPrint.c b/src/LYPrint.c
index 360330a5..72e96659 100644
--- a/src/LYPrint.c
+++ b/src/LYPrint.c
@@ -106,7 +106,7 @@ PRIVATE void set_environ ARGS3(
 }
 
 PRIVATE char *suggested_filename ARGS1(
-	document *,	newdoc)
+	DocInfo *,	newdoc)
 {
     char *cp, *sug_filename = 0;
 
@@ -302,7 +302,7 @@ PRIVATE BOOLEAN confirm_by_pages ARGS3(
 }
 
 PRIVATE void send_file_to_file ARGS3(
-	document *,	newdoc,
+	DocInfo *,	newdoc,
 	char *,		content_base,
 	char *,		sug_filename)
 {
@@ -362,7 +362,7 @@ check_recall:
      */
     CTRACE((tfp, "LYPrint: filename is %s, action is `%c'\n", buffer, c));
 
-#if HAVE_POPEN
+#ifdef HAVE_POPEN
     if (*buffer == '|') {
 	if (no_shell) {
 	    HTUserMsg(SPAWNING_DISABLED);
@@ -447,7 +447,7 @@ check_recall:
     if (keypad_mode)
 	printlist(outfile_fp,FALSE);
 
-#if HAVE_POPEN
+#ifdef HAVE_POPEN
     if (LYIsPipeCommand(buffer))
 	pclose(outfile_fp);
     else
@@ -473,7 +473,7 @@ done:
 }
 
 PRIVATE void send_file_to_mail ARGS3(
-	document *,	newdoc,
+	DocInfo *,	newdoc,
 	char *,		content_base,
 	char *,		content_location)
 {
@@ -794,7 +794,7 @@ done:	/* send_file_to_mail() */
 }
 
 PRIVATE void send_file_to_printer ARGS4(
-	document *,	newdoc,
+	DocInfo *,	newdoc,
 	char *,		content_base,
 	char *,		sug_filename,
 	int,		printer_number)
@@ -882,19 +882,9 @@ check_again:
 	}
 	/*
 	 * Cancel if the user entered "/dev/null" on Unix, or an "nl:" path
-	 * (case-insensitive) on VMS.  - FM
+	 * on VMS.  - FM
 	 */
-#ifdef VMS
-	if (!strncasecomp(my_file, "nl:", 3) ||
-	    !strncasecomp(my_file, "/nl/", 4))
-#else
-#if defined(DOSPATH)	/* 1997/10/15 (Wed) 16:41:30 */
-	if (!strcmp(my_file, "nul"))
-#else
-	if (!strcmp(my_file, "/dev/null"))
-#endif /* DOSPATH */
-#endif /* VMS */
-	{
+	if (LYIsNullDevice(my_file)) {
 	    CancelPrint(PRINT_REQUEST_CANCELLED);
 	}
 	HTAddSugFilename(my_file);
@@ -968,7 +958,7 @@ done:	/* send_file_to_printer() */
 }
 
 PRIVATE void send_file_to_screen ARGS3(
-	document *,	newdoc,
+	DocInfo *,	newdoc,
 	char *,		content_base,
 	BOOLEAN,	Lpansi)
 {
@@ -1043,7 +1033,7 @@ done:	/* send_file_to_screen() */
 }
 
 PUBLIC int printfile ARGS1(
-	document *,	newdoc)
+	DocInfo *,	newdoc)
 {
     BOOLEAN Lpansi = FALSE;
     DocAddress WWWDoc;
@@ -1311,7 +1301,8 @@ PUBLIC int print_options ARGS3(
 
     if (child_lynx == FALSE && no_disk_save == FALSE && no_print == FALSE) {
 	fprintf(fp0,
-		"   <a href=\"LYNXPRINT://LOCAL_FILE/lines=%d\">%s</a>\n",
+		"   <a href=\"%s//LOCAL_FILE/lines=%d\">%s</a>\n",
+		STR_LYNXPRINT,
 		lines_in_file,
 		gettext("Save to a local file"));
     } else {
@@ -1319,17 +1310,20 @@ PUBLIC int print_options ARGS3(
     }
     if (child_lynx == FALSE && no_mail == FALSE && local_host_only == FALSE)
 	fprintf(fp0,
-		"   <a href=\"LYNXPRINT://MAIL_FILE/lines=%d\">%s</a>\n",
+		"   <a href=\"%s//MAIL_FILE/lines=%d\">%s</a>\n",
+		STR_LYNXPRINT,
 		lines_in_file,
 		gettext("Mail the file"));
 
-#ifndef DOSPATH
+#if defined(UNIX) || defined(VMS)
     fprintf(fp0,
-	    "   <a href=\"LYNXPRINT://TO_SCREEN/lines=%d\">%s</a>\n",
+	    "   <a href=\"%s//TO_SCREEN/lines=%d\">%s</a>\n",
+	    STR_LYNXPRINT,
 	    lines_in_file,
 	    gettext("Print to the screen"));
     fprintf(fp0,
-	    "   <a href=\"LYNXPRINT://LPANSI/lines=%d\">%s</a>\n",
+	    "   <a href=\"%s//LPANSI/lines=%d\">%s</a>\n",
+	    STR_LYNXPRINT,
 	    lines_in_file,
 	    gettext("Print out on a printer attached to your vt100 terminal"));
 #endif
@@ -1341,7 +1335,8 @@ PUBLIC int print_options ARGS3(
 	cur_printer = cur_printer->next, count++)
     if (no_print == FALSE || cur_printer->always_enabled) {
 	fprintf(fp0,
-		"   <a href=\"LYNXPRINT://PRINTER/number=%d/pagelen=%d/lines=%d\">",
+		"   <a href=\"%s//PRINTER/number=%d/pagelen=%d/lines=%d\">",
+		STR_LYNXPRINT,
 		count, cur_printer->pagelen, lines_in_file);
 	fprintf(fp0, (cur_printer->name ?
 		      cur_printer->name : "No Name Given"));
diff --git a/src/LYPrint.h b/src/LYPrint.h
index 0aee2a82..622b09f4 100644
--- a/src/LYPrint.h
+++ b/src/LYPrint.h
@@ -5,7 +5,7 @@
 #include <LYStructs.h>
 #endif /* LYSTRUCTS_H */
 
-extern int printfile PARAMS((document *newdoc));
+extern int printfile PARAMS((DocInfo *newdoc));
 extern int print_options PARAMS((char **newfile,
 				 CONST char *printed_url, int lines_in_file));
 extern char * GetFileName NOPARAMS;
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index ee3b3ba9..fda43d69 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -190,7 +190,7 @@ PRIVATE void add_item_to_list ARGS3(
 	}
 	if (*next_colon++) {
 	    colon = next_colon;
-	    if ((next_colon = strchr(colon,':')) != 0)
+	    if ((next_colon = strchr(colon, ':')) != 0)
 		*next_colon++ = '\0';
 	    cur_item->always_enabled = is_true(colon);
 	    if (next_colon) {
@@ -328,7 +328,7 @@ PUBLIC CONST char *lookup_color ARGS1(
 }
 #endif /* USE_COLOR_STYLE || USE_COLOR_TABLE */
 
-#if defined(USE_COLOR_TABLE)
+#if defined(USE_COLOR_TABLE) || defined(EXP_ASSUMED_COLOR)
 
 /*
  *  Exit routine for failed COLOR parsing.
@@ -353,7 +353,9 @@ The special strings 'nocolor' or 'default', or\n")
     fprintf (stderr, "%s\n%s\n", gettext("Offending line:"), error_line);
     exit_immediately(EXIT_FAILURE);
 }
+#endif /* defined(USE_COLOR_TABLE) || defined(EXP_ASSUMED_COLOR) */
 
+#if defined(USE_COLOR_TABLE)
 /*
  *  Process string buffer fields for COLOR setting.
  */
@@ -529,7 +531,7 @@ PRIVATE int assumed_color_fun ARGS1(
     if (default_fg == ERR_COLOR
      || default_bg == ERR_COLOR)
 	exit_with_color_syntax(temp);
-#if USE_SLANG
+#ifdef USE_SLANG
     /*
      * Sorry - the order of initialization of slang precludes setting the
      * default colors from the lynx.cfg file, since slang is already
@@ -1160,7 +1162,7 @@ PRIVATE int psrcspec_fun ARGS1(char*,s)
     };
     int found;
 
-    e = strchr(s,':');
+    e = strchr(s, ':');
     if (!e) {
 	CTRACE((tfp,"bad format of PRETTYSRC_SPEC setting value, ignored %s\n",s));
 	return 0;
@@ -1405,6 +1407,9 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_FUN(RC_PRINTER,              printer_fun),
      PARSE_SET(RC_QUIT_DEFAULT_YES,     LYQuitDefaultYes),
      PARSE_FUN(RC_REFERER_WITH_QUERY,   referer_with_query_fun),
+#ifdef EXP_CMD_LOGGING
+     PARSE_TIM(RC_REPLAYSECS,           ReplaySecs),
+#endif
      PARSE_SET(RC_REUSE_TEMPFILES,      LYReuseTempfiles),
 #ifndef NO_RULES
      PARSE_FUN(RC_RULE,                 HTSetConfiguration),
@@ -1609,6 +1614,88 @@ typedef BOOL (optidx_set_t) [ NOPTS_ ];
 	    (r)[i1]= (a)[i1] || (b)[i1]; \
     }
 
+/*
+ * For simple (boolean, string, integer, time) values, set the corresponding
+ * configuration variable.
+ */
+PUBLIC void LYSetConfigValue ARGS2(
+    char *,	name,
+    char *,	value)
+{
+    Config_Type *tbl = lookup_config(name);
+    ParseUnionPtr q = ParseUnionOf(tbl);
+
+    switch (tbl->type) {
+    case CONF_BOOL:
+	if (q->set_value != 0)
+	    *(q->set_value) = is_true (value);
+	break;
+
+    case CONF_FUN:
+	if (q->fun_value != 0)
+	    (*(q->fun_value)) (value);
+	break;
+
+    case CONF_TIME:
+	if (q->int_value != 0) {
+	    float ival;
+	    if (1 == sscanf (value, "%f", &ival)) {
+		*(q->int_value) = (int) SECS2Secs(ival);
+	    }
+	}
+	break;
+
+    case CONF_ENUM:
+	if (tbl->table != 0)
+	    LYgetEnum(tbl->table, value, q->int_value);
+	break;
+
+    case CONF_INT:
+	if (q->int_value != 0) {
+	    int ival;
+	    if (1 == sscanf (value, "%d", &ival))
+		*(q->int_value) = ival;
+	}
+	break;
+
+    case CONF_STR:
+	if (q->str_value != 0)
+	    StrAllocCopy(*(q->str_value), value);
+	break;
+
+    case CONF_ENV:
+    case CONF_ENV2:
+
+	if (tbl->type == CONF_ENV)
+	    LYLowerCase(name);
+	else
+	    LYUpperCase(name);
+
+	if (LYGetEnv (name) == 0) {
+#ifdef VMS
+	    Define_VMSLogical(name, value);
+#else
+	    if (q->str_value == 0)
+		q->str_value = typecalloc(char *);
+	    HTSprintf0 (q->str_value, "%s=%s", name, value);
+	    putenv (*(q->str_value));
+#endif
+	}
+	break;
+    case CONF_ADD_ITEM:
+	if (q->add_value != 0)
+	    add_item_to_list (value, q->add_value, FALSE);
+	break;
+
+#if defined(EXEC_LINKS) || defined(LYNXCGI_LINKS)
+    case CONF_ADD_TRUSTED:
+	add_trusted (value, q->def_value);
+	break;
+#endif
+    default:
+	break;
+    }
+}
 
 /*
  * Process the configuration file (lynx.cfg).
@@ -1735,63 +1822,16 @@ PRIVATE void do_read_cfg ARGS5(
 		? CONF_UNSPECIFIED
 		: tbl->type) {
 	case CONF_BOOL:
-	    if (q->set_value != 0)
-		*(q->set_value) = is_true (value);
-	    break;
-
 	case CONF_FUN:
-	    if (q->fun_value != 0)
-		(*(q->fun_value)) (value);
-	    break;
-
 	case CONF_TIME:
-	    if (q->int_value != 0) {
-		float ival;
-		if (1 == sscanf (value, "%f", &ival)) {
-#ifdef HAVE_NAPMS
-		    ival *= 1000;
-#endif
-		    *(q->int_value) = (int) ival;
-		}
-	    }
-	    break;
-
 	case CONF_ENUM:
-	    if (tbl->table != 0)
-		LYgetEnum(tbl->table, value, q->int_value);
-	    break;
-
 	case CONF_INT:
-	    if (q->int_value != 0) {
-		int ival;
-		if (1 == sscanf (value, "%d", &ival))
-		    *(q->int_value) = ival;
-	    }
-	    break;
-
 	case CONF_STR:
-	    if (q->str_value != 0)
-		StrAllocCopy(*(q->str_value), value);
-	    break;
-
 	case CONF_ENV:
 	case CONF_ENV2:
-
-	    if (tbl->type == CONF_ENV)
-		LYLowerCase(name);
-	    else
-		LYUpperCase(name);
-
-	    if (getenv (name) == 0) {
-#ifdef VMS
-		Define_VMSLogical(name, value);
-#else
-		if (q->str_value == 0)
-			q->str_value = typecalloc(char *);
-		HTSprintf0 (q->str_value, "%s=%s", name, value);
-		putenv (*(q->str_value));
-#endif
-	    }
+	case CONF_ADD_ITEM:
+	case CONF_ADD_TRUSTED:
+	    LYSetConfigValue(name, value);
 	    break;
 
 	case CONF_INCLUDE: {
@@ -1805,9 +1845,9 @@ PRIVATE void do_read_cfg ARGS5(
 	    char *cp1 = NULL;
 	    char *sep = NULL;
 
-	    if ( (p1 = strstr(value, sep=" for ")) != 0
-#if defined(UNIX) && !defined(__EMX__)
-		|| (p1 = strstr(value, sep=":")) != 0
+	    if ( (p1 = strstr(value, sep = " for ")) != 0
+#if defined(UNIX) && !defined(USE_DOS_DRIVES)
+		|| (p1 = strstr(value, sep = ":")) != 0
 #endif
 	    ) {
 		*p1 = '\0';
@@ -1903,16 +1943,6 @@ PRIVATE void do_read_cfg ARGS5(
 	    }
 	    break;
 
-	case CONF_ADD_ITEM:
-	    if (q->add_value != 0)
-		add_item_to_list (value, q->add_value, FALSE);
-	    break;
-
-#if defined(EXEC_LINKS) || defined(LYNXCGI_LINKS)
-	case CONF_ADD_TRUSTED:
-	    add_trusted (value, q->def_value);
-	    break;
-#endif
 	default:
 	    if (fp0 != 0) {
 		if (strchr(value, '&') || strchr(value, '<')) {
@@ -1977,7 +2007,7 @@ PUBLIC void read_cfg ARGS4(
  *  we create and load the page just in place and return to mainloop().
  */
 PUBLIC int lynx_cfg_infopage ARGS1(
-    document *,		       newdoc)
+    DocInfo *,		       newdoc)
 {
     static char tempfile[LY_MAXPATH] = "\0";
     DocAddress WWWDoc;  /* need on exit */
@@ -2010,8 +2040,8 @@ PUBLIC int lynx_cfg_infopage ARGS1(
 	 */
 	if (HTMainText && nhist > 0 &&
 	    !strcmp(HTLoadedDocumentTitle(), LYNXCFG_TITLE) &&
-	    !strcmp(HTLoadedDocumentURL(), history[nhist-1].address) &&
-	    LYIsUIPage(history[nhist-1].address, UIP_LYNXCFG) &&
+	    !strcmp(HTLoadedDocumentURL(), HDOC(nhist-1).address) &&
+	    LYIsUIPage(HDOC(nhist-1).address, UIP_LYNXCFG) &&
 	    (!lynxcfginfo_url ||
 	     strcmp(HTLoadedDocumentURL(), lynxcfginfo_url))) {
 	    /*  the page was pushed, so pop-up. */
@@ -2090,7 +2120,6 @@ PUBLIC int lynx_cfg_infopage ARGS1(
 	BeginInternalPage (fp0, LYNXCFG_TITLE, NULL);
 	fprintf(fp0, "<pre>\n");
 
-
 #ifndef NO_CONFIG_INFO
 	if (!no_lynxcfg_xinfo) {
 #if defined(HAVE_CONFIG_H) || defined(VMS)
@@ -2118,15 +2147,17 @@ PUBLIC int lynx_cfg_infopage ARGS1(
 
 #if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO)
 	    if (!no_compileopts_info) {
-		fprintf(fp0, "%s <a href=\"LYNXCOMPILEOPTS:\">%s</a>\n\n",
+		fprintf(fp0, "%s <a href=\"%s\">%s</a>\n\n",
 			SEE_ALSO,
+			STR_LYNXCFLAGS,
 			COMPILE_OPT_SEGMENT);
 	    }
 #endif
 
 	    /** a new experimental link ... **/
 	    if (user_mode == ADVANCED_MODE)
-		fprintf(fp0, "  <a href=\"LYNXCFG://reload\">%s</a>\n",
+		fprintf(fp0, "  <a href=\"%s//reload\">%s</a>\n",
+			     STR_LYNXCFG,
 			     gettext("RELOAD THE CHANGES"));
 
 
@@ -2182,7 +2213,7 @@ PUBLIC int lynx_cfg_infopage ARGS1(
  *  from getfile() cycle.
  */
 PUBLIC int lynx_compile_opts ARGS1(
-    document *,		       newdoc)
+    DocInfo *,		       newdoc)
 {
     static char tempfile[LY_MAXPATH] = "\0";
 #define PutDefs(table, N) fprintf(fp0, "%-35s %s\n", table[N].name, table[N].value)
diff --git a/src/LYReadCFG.h b/src/LYReadCFG.h
index e58a1074..87b73de9 100644
--- a/src/LYReadCFG.h
+++ b/src/LYReadCFG.h
@@ -54,10 +54,11 @@ extern void free_lynx_cfg NOPARAMS;
 extern BOOLEAN have_read_cfg;
 
 extern FILE *LYOpenCFG PARAMS((char *cfg_filename, char *parent_filename, char *dft_filename));
-extern int lynx_cfg_infopage PARAMS((document *newdoc));
-extern int lynx_compile_opts PARAMS((document *newdoc));
+extern int lynx_cfg_infopage PARAMS((DocInfo *newdoc));
+extern int lynx_compile_opts PARAMS((DocInfo *newdoc));
 extern int match_item_by_name PARAMS((lynx_list_item_type * ptr, char * name, BOOLEAN only_overriders));
 extern lynx_list_item_type *find_item_by_number PARAMS((lynx_list_item_type * list_ptr, char * number));
 extern void reload_read_cfg NOPARAMS; /* implemented in LYMain.c */
+extern void LYSetConfigValue PARAMS((char *name, char *value));
 
 #endif /* LYREADCFG_H */
diff --git a/src/LYSearch.c b/src/LYSearch.c
index 9e4f5b25..61517cb4 100644
--- a/src/LYSearch.c
+++ b/src/LYSearch.c
@@ -155,7 +155,7 @@ PRIVATE int check_prev_target_in_links ARGS2(
  *  variable
  */
 PUBLIC BOOL textsearch ARGS4(
-	document *,	cur_doc,
+	DocInfo *,	cur_doc,
 	char *,		prev_target,
 	int,		target_size,
 	int,		direction)
diff --git a/src/LYSearch.h b/src/LYSearch.h
index f917c615..e4dbd7a8 100644
--- a/src/LYSearch.h
+++ b/src/LYSearch.h
@@ -6,7 +6,7 @@
 #include <LYStructs.h>
 #endif /* LYSTRUCT_H */
 
-extern BOOL textsearch PARAMS((document *cur_doc,
+extern BOOL textsearch PARAMS((DocInfo *cur_doc,
 			       char *prev_target, int target_size, int direction));
 
 #define IN_FILE 1
diff --git a/src/LYShowInfo.c b/src/LYShowInfo.c
index 8b2337c6..9939a3e5 100644
--- a/src/LYShowInfo.c
+++ b/src/LYShowInfo.c
@@ -61,9 +61,9 @@ PUBLIC char *LYVersionDate NOARGS
  */
 
 PUBLIC int LYShowInfo ARGS4(
-	document *,	doc,
+	DocInfo *,	doc,
 	int,		size_of_file,
-	document *,	newdoc,
+	DocInfo *,	newdoc,
 	char *, 	owner_address)
 {
     static char tempfile[LY_MAXPATH] = "\0";
diff --git a/src/LYShowInfo.h b/src/LYShowInfo.h
index 58f2c533..f95247fa 100644
--- a/src/LYShowInfo.h
+++ b/src/LYShowInfo.h
@@ -8,7 +8,7 @@
 extern BOOL LYVersionIsRelease NOPARAMS;
 extern char *LYVersionStatus NOPARAMS;
 extern char *LYVersionDate NOPARAMS;
-extern int LYShowInfo PARAMS((document *doc, int size_of_file, document *newdoc,
+extern int LYShowInfo PARAMS((DocInfo *doc, int size_of_file, DocInfo *newdoc,
 							char *owner_address));
 
 #endif /* LYSHOWINFO_H */
diff --git a/src/LYStrings.c b/src/LYStrings.c
index 2bccd271..1af7339f 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -34,6 +34,10 @@
 #include <LYMainLoop.h>
 #endif
 
+#ifdef EXP_CMD_LOGGING
+#include <LYReadCFG.h>
+#endif
+
 #include <LYShowInfo.h>
 #include <LYLeaks.h>
 
@@ -242,7 +246,7 @@ PUBLIC int fancy_mouse ARGS3(
 	cmd = LYK_QUIT;
     }
 #endif /* NCURSES */
-#endif	/* _WINDOWS */
+#endif /* PDCURSES */
 
 /************************************************************************/
 #endif  /* USE_MOUSE */
@@ -532,12 +536,23 @@ PRIVATE int set_clicked_link ARGS4(
 	    } else if (mouse_err >= 0)
 		c = LAC_TO_LKC0(LYK_CHANGE_LINK);
 	}
+	else {
+	   if (2*y > LYlines){ 		/* Bottom Half of the screen */
+	      if (4*y < 3*LYlines){
+		c = LAC_TO_LKC0(LYK_DOWN_TWO);	/* Third quarter */
+	      } else
+		c = LAC_TO_LKC0(LYK_DOWN_HALF);	/* Fourth quarter */
+	   } else {			/* Upper Half of the screen */
+	      if (4*y < LYlines){
+		c = LAC_TO_LKC0(LYK_UP_HALF);	/* First quarter */
+	      } else
+		c = LAC_TO_LKC0(LYK_UP_TWO);	/* Second quarter */
+	   }
+	}
     }
     return c;
 }
 
-
-
 /*
  *  LYstrncpy() terminates strings with a null byte.
  *  Writes a null byte into the n+1 byte of dst.
@@ -744,7 +759,7 @@ PRIVATE int myGetChar NOARGS
 #endif
 
 #if !defined(GetChar)
-#if HAVE_KEYPAD
+#ifdef HAVE_KEYPAD
 #define GetChar() getch()
 #else
 #ifndef USE_GETCHAR
@@ -798,6 +813,9 @@ PRIVATE int sl_read_mouse_event ARGS1(
 	if (button == 0)  /* left */
 	  return set_clicked_link (mouse_x, mouse_y, FOR_PANEL, 1);
 
+        if (button == 1)  /* middle */
+	  return LYReverseKeymap (LYK_VIEW_BOOKMARK);
+
 	if (button == 2)   /* right */
 	  {
 	     /* Right button: go back to prev document.
@@ -1835,7 +1853,7 @@ re_read:
     if (done_esc) {
 	/* don't do keypad() switches below, we already got it - kw */
     } else {
-#if HAVE_KEYPAD
+#ifdef HAVE_KEYPAD
 	/*
 	 *  Convert keypad() mode keys into Lynx defined keys.
 	 */
@@ -2444,9 +2462,9 @@ PUBLIC void LYUpperCase ARGS1(
 }
 
 /*
- * Remove newlines from a string.
+ * Remove newlines from a string, returning true if we removed any.
  */
-PUBLIC void LYRemoveNewlines ARGS1(
+PUBLIC BOOLEAN LYRemoveNewlines ARGS1(
 	char *,		buffer)
 {
     if (buffer != 0) {
@@ -2455,7 +2473,9 @@ PUBLIC void LYRemoveNewlines ARGS1(
 	    if (buffer[i] != '\n' && buffer[i] != '\r')
 		buffer[j++] = buffer[i];
 	buffer[j] = 0;
+	return (i != j);
     }
+    return FALSE;
 }
 
 /*
@@ -2587,8 +2607,8 @@ PUBLIC BOOLEAN LYTrimStartfile ARGS1(
 	char *,		buffer)
 {
     LYTrimHead(buffer);
-    if (!strncasecomp(buffer, "lynxexec:", 9) ||
-	!strncasecomp(buffer, "lynxprog:", 9)) {
+    if (isLYNXEXEC(buffer) ||
+	isLYNXPROG(buffer)) {
 	/*
 	 *  The original implementations of these schemes expected
 	 *  white space without hex escaping, and did not check
@@ -2604,6 +2624,30 @@ PUBLIC BOOLEAN LYTrimStartfile ARGS1(
 }
 
 /*
+ * Escape unsafe characters in startfile, except for lynx internal URLs.
+ */
+PUBLIC void LYEscapeStartfile ARGS1(
+	char **,		buffer)
+{
+    if (!LYTrimStartfile(*buffer)) {
+	char *escaped = HTEscapeUnsafe(*buffer);
+	StrAllocCopy(*buffer, escaped);
+	FREE(escaped);
+    }
+}
+
+/*
+ * Trim all blanks from startfile, except for lynx internal URLs.
+ */
+PUBLIC void LYTrimAllStartfile ARGS1(
+	char *,		buffer)
+{
+    if (!LYTrimStartfile(buffer)) {
+	LYRemoveBlanks(buffer);
+    }
+}
+
+/*
 **  Display the current value of the string and allow the user
 **  to edit it.
 */
@@ -5680,20 +5724,46 @@ PUBLIC int LYReadCmdKey ARGS1(
 	char *buffer = 0;
 	char *src;
 	char *tmp;
+	unsigned len;
 
-	while (LYSafeGets(&buffer, cmd_script) != 0) {
+	while ((ch < 0) && LYSafeGets(&buffer, cmd_script) != 0) {
 	    LYTrimTrailing(buffer);
 	    src = LYSkipBlanks(buffer);
 	    tmp = LYSkipNonBlanks(src);
-	    if (tmp - src != 3
-	     || strncasecomp(src, "key", 3))
-		continue;
-	    src = LYSkipBlanks(tmp);
-	    if ((ch = LYStringToKeycode(src)) >= 0) {
-		LYrefresh();
+	    switch (len = (tmp - src)) {
+	    case 4:
+		if (!strncasecomp(src, "exit", 4))
+		    exit(0);
+		break;
+	    case 3:
+		if (!strncasecomp(src, "key", 3)) {
+		    ch = LYStringToKeycode(LYSkipBlanks(tmp));
+		} else if (!strncasecomp(src, "set", 3)) {
+		    src = LYSkipBlanks(tmp);
+		    tmp = src;
+		    while (*tmp != '\0') {
+			if (isspace(UCH(*tmp)) || *tmp == '=')
+			    break;
+			++tmp;
+		    }
+		    if (*tmp != '\0') {
+		    	*tmp++ = '\0';
+			tmp = LYSkipBlanks(tmp);
+		    }
+		    CTRACE((tfp, "LYSetConfigValue(%s, %s)\n", src, tmp));
+		    LYSetConfigValue(src, tmp);
+		}
 		break;
 	    }
 	}
+	if (feof(cmd_script)) {
+	    fclose(cmd_script);
+	    cmd_script = 0;    
+	}
+	if (ch >= 0) {
+	    LYSleepReplay();
+	    LYrefresh();
+	}
 	FREE(buffer);
     } else {
 	ch = LYgetch_for(mode);
diff --git a/src/LYStrings.h b/src/LYStrings.h
index 5a4e95b0..45ef8594 100644
--- a/src/LYStrings.h
+++ b/src/LYStrings.h
@@ -298,11 +298,13 @@ extern int map_string_to_keysym PARAMS((CONST char * src, int *lec));
 extern char *LYElideString PARAMS((
 	char *		str,
 	int		cut_pos));
+extern void LYEscapeStartfile PARAMS((
+	char **		buffer));
 extern void LYLowerCase PARAMS((
 	char *		buffer));
 extern void LYUpperCase PARAMS((
 	char *		buffer));
-extern void LYRemoveNewlines PARAMS((
+extern BOOLEAN LYRemoveNewlines PARAMS((
 	char *		buffer));
 extern void LYRemoveBlanks PARAMS((
 	char *		buffer));
@@ -320,6 +322,8 @@ extern char * LYTrimNewline PARAMS((
 	char *		buffer));
 extern void LYTrimTrailing PARAMS((
 	char *		buffer));
+extern void LYTrimAllStartfile PARAMS((
+	char *		buffer));
 extern BOOLEAN LYTrimStartfile PARAMS((
 	char *		buffer));
 extern void LYSetupEdit PARAMS((
diff --git a/src/LYStructs.h b/src/LYStructs.h
index 180a5ab1..4920ce63 100644
--- a/src/LYStructs.h
+++ b/src/LYStructs.h
@@ -35,43 +35,37 @@ extern LinkInfo links[MAXLINKS];
 extern int nlinks;
 
 typedef struct {
-   char * title;
-   char * address;
-   char * post_data;
-   char * post_content_type;
-   char * bookmark;
-   BOOL   safe;
-   BOOL   isHEAD;
-   int    link;
-   int    line;
-   BOOL   internal_link;	/* whether doc was reached via an internal
-				 (fragment) link. - kw */
-#ifdef USE_COLOR_STYLE
-   char * style;
-#endif
-} document;
-
-#ifndef HTFORMS_H
-#include <HTForms.h>
-#endif /* HTFORMS_H */
-
-typedef struct {
+    /* FIXME: see DocAddress */
     char * title;
     char * address;
     char * post_data;
     char * post_content_type;
     char * bookmark;
-    BOOL   safe;
     BOOL   isHEAD;
+    BOOL   safe;
+
     int    link;
     int    line;
     BOOL   internal_link;	/* whether doc was reached via an internal
 				 (fragment) link. - kw */
+#ifdef USE_COLOR_STYLE
+    char * style;
+#endif
+} DocInfo;
+
+#ifndef HTFORMS_H
+#include <HTForms.h>
+#endif /* HTFORMS_H */
+
+typedef struct {
+    DocInfo hdoc;
     int    intern_seq_start;	/* indicates which element on the history
 				   is the start of this sequence of
 				   "internal links", otherwise -1 */
 } HistInfo;
 
+#define HDOC(n) history[n].hdoc
+
 extern int Visited_Links_As;
 
 #define VISITED_LINKS_AS_FIRST_V 0
diff --git a/src/LYStyle.c b/src/LYStyle.c
index 496bf802..fde9473a 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.49 Tue, 01 Jan 2002 17:30:08 -0800 dickey @
+ * @Id: LYStyle.c 1.50 Sun, 06 Oct 2002 17:43:28 -0700 dickey @
  */
 #include <HTUtils.h>
 #include <HTML.h>
@@ -93,7 +93,10 @@ PRIVATE int colorPairs = 0;
 #  define M_BLINK	0
 #endif
 
-PRIVATE unsigned char our_pairs[2][MAX_BLINK][MAX_COLOR][MAX_COLOR];
+PRIVATE unsigned char our_pairs[2]
+				[MAX_BLINK]
+				[MAX_COLOR + 1]
+				[MAX_COLOR + 1];
 
 /*
  * Parse a string containing a combination of video attributes and color.
@@ -180,29 +183,30 @@ PRIVATE void parse_attributes ARGS5(
      * If we have colour, and space to create a new colour attribute,
      * and we have a valid colour description, then add this style
      */
-    if (lynx_has_color && colorPairs < COLOR_PAIRS-1 && fA != NO_COLOR)
-    {
-	int curPair;
+    if (lynx_has_color && colorPairs < COLOR_PAIRS-1 && fA != NO_COLOR) {
+	int curPair = 0;
+	int iFg = (1 + (fA >= 0 ? fA : 0));
+	int iBg = (1 + (bA >= 0 ? bA : 0));
+	int iBold = !!(cA & A_BOLD);
+	int iBlink = !!(cA & M_BLINK);
 
 	if (fA < MAX_COLOR
 	 && bA < MAX_COLOR
-	 && our_pairs[!!(cA & A_BOLD)][!!(cA & A_BLINK)][fA][bA])
-	    curPair = our_pairs[!!(cA & A_BOLD)][!!(cA & M_BLINK)][fA][bA] - 1;
-	else {
-	    curPair = ++colorPairs;
-	    init_pair((short)curPair, (short)fA, (short)bA);
-	    if (fA < MAX_COLOR
-	     && bA < MAX_COLOR
-	     && curPair < 255)
-		our_pairs[!!(cA & A_BOLD)][!!(cA & M_BLINK)][fA][bA] = curPair + 1;
+	 && (fA != default_fg || bA != default_bg)
+	 && curPair < 255) {
+	    if (our_pairs[iBold][iBlink][iFg][iBg] != 0) {
+		curPair = our_pairs[iBold][iBlink][iFg][iBg];
+	    } else {
+		curPair = ++colorPairs;
+		init_pair((short)curPair, (short)fA, (short)bA);
+		our_pairs[iBold][iBlink][iFg][iBg] = curPair;
+	    }
 	}
 	CTRACE2(TRACE_STYLE, (tfp, "CSS(CURPAIR):%d\n", curPair));
 	if (style < DSTYLE_ELEMENTS)
 	    setStyle(style, COLOR_PAIR(curPair)|cA, cA, mA);
 	setHashStyle(newstyle, COLOR_PAIR(curPair)|cA, cA, mA, element);
-    }
-    else
-    {
+    } else {
 	if (lynx_has_color && fA != NO_COLOR) {
 	    CTRACE2(TRACE_STYLE, (tfp, "CSS(NC): maximum of %d colorpairs exhausted\n", COLOR_PAIRS - 1));
 	}
@@ -254,12 +258,17 @@ PRIVATE void parse_style ARGS1(char*, param)
     unsigned n;
     BOOL found = FALSE;
 
-    char *buffer = strdup(param);
-    char *tmp = strchr(buffer, ':');
+    char *buffer = 0;
+    char *tmp = 0;
     char *element, *mono, *fg, *bg;
 
-    if(!tmp)
-    {
+    if (param == 0)
+	return;
+    StrAllocCopy(buffer, param);
+    if (buffer == 0)
+	return;
+
+    if ((tmp = strchr(buffer, ':')) == 0) {
 	fprintf (stderr, gettext("\
 Syntax Error parsing style in lss file:\n\
 [%s]\n\
diff --git a/src/LYTraversal.c b/src/LYTraversal.c
index 2a1ae04c..3beb48d0 100644
--- a/src/LYTraversal.c
+++ b/src/LYTraversal.c
@@ -107,7 +107,7 @@ PUBLIC void dump_traversal_history NOARGS
 	    gettext("here is a list of the history stack so that you may rebuild"));
 
     for (x = nhist-1; x >= 0; x--) {
-	fprintf(ifp,"%s\t%s\n", history[x].title, history[x].address);
+	fprintf(ifp, "%s\t%s\n", HDOC(x).title, HDOC(x).address);
     }
 
     LYCloseOutput(ifp);
diff --git a/src/LYUpload.c b/src/LYUpload.c
index a78018fa..1667e937 100644
--- a/src/LYUpload.c
+++ b/src/LYUpload.c
@@ -108,7 +108,7 @@ retry:
 	}
 	HTSprintf0(&filename, "%s/%s", directory, tmpbuf);
 
-#if HAVE_POPEN
+#ifdef HAVE_POPEN
 	if (LYIsPipeCommand(filename)) {
 	    HTAlert(CANNOT_WRITE_TO_FILE);
 	    _statusline(NEW_FILENAME_PROMPT);
@@ -151,7 +151,7 @@ retry:
 
     FREE(the_command);
     FREE(the_upload);
-#ifdef UNIX
+#if defined(MULTI_USER_UNIX)
     if (filename != 0)
 	chmod(filename, HIDE_CHMOD);
 #endif /* UNIX */
diff --git a/src/LYUtils.c b/src/LYUtils.c
index 53e4167e..8f3458c5 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -27,7 +27,7 @@
 #include <HTFile.h>
 #endif
 
-#if _WIN_CC
+#ifdef _WIN_CC
 extern int exec_command(char * cmd, int wait_flag); /* xsystem.c */
 #endif
 
@@ -185,7 +185,7 @@ PRIVATE LY_TEMP *FindTempfileByFP ARGS1(FILE *, fp)
 /*
  * Get an environment variable, rejecting empty strings
  */
-PRIVATE char *getenv_text ARGS1(char *, name)
+PUBLIC char *LYGetEnv ARGS1(CONST char *, name)
 {
     char *result = getenv(name);
     return non_empty(result) ? result : 0;
@@ -1014,7 +1014,7 @@ PUBLIC void LYhighlight ARGS3(
 	    if (avail_space > (int) sizeof(buffer) - 1)
 		avail_space = (int) sizeof(buffer) - 1;
 
-	    LYstrncpy(buffer, (text != NULL ? text : ""), avail_space);
+	    LYstrncpy(buffer, NonNull(text), avail_space);
 	    LYaddstr(buffer);
 
 	    len = strlen(buffer);
@@ -1589,14 +1589,14 @@ PUBLIC int HTCheckForInterrupt NOARGS
 
 #if defined(PDCURSES)
     nodelay(LYwin,TRUE);
-#endif /* DOSPATH */
+#endif /* PDCURSES */
     /*
      * 'c' contains whatever character we're able to read from keyboard
      */
     c = LYgetch();
 #if defined(PDCURSES)
     nodelay(LYwin,FALSE);
-#endif /* DOSPATH */
+#endif /* PDCURSES */
 
 #else /* VMS: */
     extern int typeahead();
@@ -1640,23 +1640,20 @@ PUBLIC int HTCheckForInterrupt NOARGS
 	** log. User search now in progress...
 	*/
     cmd = (LKC_TO_LAC(keymap,c));
-    switch (cmd)
-    {
+    switch (cmd) {
     case LYK_TRACE_TOGGLE :	/*  Toggle TRACE mode. */
-	   handle_LYK_TRACE_TOGGLE();
-	   break;
+	handle_LYK_TRACE_TOGGLE();
+	break;
     default :
 
 #ifdef DISP_PARTIAL
-	if (display_partial && (NumOfLines_partial > 2))
 	/* OK, we got several lines from new document and want to scroll... */
-	{
+	if (display_partial && (NumOfLines_partial > 2)) {
 	    BOOLEAN do_refresh;
 	    int res;
 	    int Newline_partial = LYGetNewline();
 
-	    switch (cmd)
-	    {
+	    switch (cmd) {
 	    case LYK_WHEREIS:	/* search within the document */
 	    case LYK_NEXT:	/* search for the next occurrence in the document */
 	    case LYK_PREV:	/* search for the previous occurrence in the document */
@@ -1751,20 +1748,21 @@ PUBLIC int HTCheckForInterrupt NOARGS
 PUBLIC BOOLEAN LYisAbsPath ARGS1(
 	CONST char *,	path)
 {
+    BOOLEAN result = FALSE;
+    if (non_empty(path)) {
 #ifdef VMS
-    return TRUE;
+	result = TRUE;
 #else
-    BOOLEAN result;
-#if defined(DOSPATH) || defined(__EMX__)
-    result = (BOOL) (LYIsPathSep(path[0])
-     || (isalpha(UCH(path[0]))
-      && (path[1] == ':')
-       && LYIsPathSep(path[2])));
+#if defined(USE_DOS_DRIVES)
+	result = (BOOL) (LYIsPathSep(path[0])
+	 || (LYIsDosDrive(path)
+	   && LYIsPathSep(path[2])));
 #else
-    result = (LYIsPathSep(path[0]));
+	result = (LYIsPathSep(path[0]));
 #endif /* DOSPATH */
-    return result;
 #endif
+    }
+    return result;
 }
 
 /*
@@ -1773,10 +1771,9 @@ PUBLIC BOOLEAN LYisAbsPath ARGS1(
 PUBLIC BOOLEAN LYisRootPath ARGS1(
 	char *,		path)
 {
-#if defined(DOSPATH) || defined(__EMX__)
+#if defined(USE_DOS_DRIVES)
     if (strlen(path) == 3
-     && isalpha(UCH(path[0]))
-     && path[1] == ':'
+     && LYIsDosDrive(path)
      && LYIsPathSep(path[2]))
 	return TRUE;
 #endif
@@ -1803,19 +1800,13 @@ PUBLIC BOOLEAN LYisLocalFile ARGS1(
 	return NO;
     }
 
-    if ((cp=strchr(host, ':')) != NULL)
+    if ((cp = strchr(host, ':')) != NULL)
 	*cp = '\0';
 
     if ((acc_method = HTParse(filename, "", PARSE_ACCESS))) {
 	if (0==strcmp("file", acc_method) &&
 	    (0==strcmp(host, "localhost") ||
-#ifdef VMS
-	     0==strcasecomp(host, HTHostName())
-#else
-	     0==strcmp(host, HTHostName())
-#endif /* VMS */
-	    ))
-	{
+	     LYSameFilename(host, HTHostName()))) {
 	    FREE(host);
 	    FREE(acc_method);
 	    return YES;
@@ -1849,18 +1840,11 @@ PUBLIC BOOLEAN LYisLocalHost ARGS1(
     if ((cp = strchr(host, ':')) != NULL)
 	*cp = '\0';
 
-#ifdef VMS
-    if ((0==strcasecomp(host, "localhost") ||
-	 0==strcasecomp(host, LYHostName) ||
-	 0==strcasecomp(host, HTHostName())))
-#else
-    if ((0==strcmp(host, "localhost") ||
-	 0==strcmp(host, LYHostName) ||
-	 0==strcmp(host, HTHostName())))
-#endif /* VMS */
-    {
-	    FREE(host);
-	    return YES;
+    if ((LYSameFilename(host, "localhost") ||
+	 LYSameFilename(host, LYHostName) ||
+	 LYSameFilename(host, HTHostName()))) {
+	FREE(host);
+	return YES;
     }
 
     FREE(host);
@@ -1935,12 +1919,7 @@ PUBLIC BOOLEAN LYisLocalAlias ARGS1(
 	*cp = '\0';
 
     while (NULL != (alias = (char *)HTList_nextObject(cur))) {
-#ifdef VMS
-	if (0==strcasecomp(host, alias))
-#else
-	if (0==strcmp(host, alias))
-#endif /* VMS */
-	{
+	if (LYSameFilename(host, alias)) {
 	    FREE(host);
 	    return YES;
 	}
@@ -1986,14 +1965,14 @@ PUBLIC int LYCheckForProxyURL ARGS1(
 	StrAllocCopy(cp2, cp);
 	*cp1 = ':';
 	StrAllocCat(cp2, "_proxy");
-	if (getenv(cp2) != NULL) {
+	if (LYGetEnv(cp2) != NULL) {
 	    FREE(cp2);
 	    return(PROXY_URL_TYPE);
 	}
 	FREE(cp2);
-#if defined (DOSPATH)
-	if (cp[1] == ':')
-	    return(NOT_A_URL_TYPE);	/* could be drive letter? - kw */
+#if defined (USE_DOS_DRIVES)
+	if (LYIsDosDrive(cp))
+	    return(NOT_A_URL_TYPE);
 #endif
 	cp1++;
 	if (!*cp) {
@@ -2078,13 +2057,13 @@ PUBLIC int is_url ARGS1(
 	result = NOT_A_URL_TYPE;
 
 #ifndef DISABLE_NEWS
-    } else if (compare_type(cp, "news:", 5)) {
+    } else if (compare_type(cp, STR_NEWS_URL, LEN_NEWS_URL)) {
 	result = NEWS_URL_TYPE;
 
-    } else if (compare_type(cp, "nntp:", 5)) {
+    } else if (compare_type(cp, STR_NNTP_URL, LEN_NNTP_URL)) {
 	result = NNTP_URL_TYPE;
 
-    } else if (compare_type(cp, "snews:", 6)) {
+    } else if (compare_type(cp, STR_SNEWS_URL, LEN_SNEWS_URL)) {
 	result = SNEWS_URL_TYPE;
 
     } else if (compare_type(cp, "newspost:", 9)) {
@@ -2112,15 +2091,15 @@ PUBLIC int is_url ARGS1(
 	result = NEWSREPLY_URL_TYPE;
 #endif
 
-    } else if (compare_type(cp, "mailto:", 7)) {
+    } else if (compare_type(cp, STR_MAILTO_URL, LEN_MAILTO_URL)) {
 	result = MAILTO_URL_TYPE;
 
 #ifndef DISABLE_BIBP
-    } else if (compare_type(cp, "bibp:", 5)) {
+    } else if (compare_type(cp, STR_BIBP_URL, LEN_BIBP_URL)) {
 	result = BIBP_URL_TYPE;
 #endif
 
-    } else if (compare_type(cp, "file:", 5)) {
+    } else if (compare_type(cp, STR_FILE_URL, LEN_FILE_URL)) {
 	if (LYisLocalFile(cp)) {
 	    result = FILE_URL_TYPE;
 	} else if (LYIsHtmlSep(cp[5]) && LYIsHtmlSep(cp[6])) {
@@ -2132,7 +2111,7 @@ PUBLIC int is_url ARGS1(
     } else if (compare_type(cp, "data:", 5)) {
 	result = DATA_URL_TYPE;
 
-    } else if (compare_type(cp, "lynxexec:", 9)) {
+    } else if (compare_type(cp, STR_LYNXEXEC, LEN_LYNXEXEC)) {
 	/*
 	 *  Special External Lynx type to handle execution
 	 *  of commands or scripts which require a pause to
@@ -2140,7 +2119,7 @@ PUBLIC int is_url ARGS1(
 	 */
 	result = LYNXEXEC_URL_TYPE;
 
-    } else if (compare_type(cp, "lynxprog:", 9)) {
+    } else if (compare_type(cp, STR_LYNXPROG, LEN_LYNXPROG)) {
 	/*
 	 *  Special External Lynx type to handle execution
 	 *  of commands, scripts or programs with do not
@@ -2148,74 +2127,74 @@ PUBLIC int is_url ARGS1(
 	 */
 	result = LYNXPROG_URL_TYPE;
 
-    } else if (compare_type(cp, "lynxcgi:", 8)) {
+    } else if (compare_type(cp, STR_LYNXCGI, LEN_LYNXCGI)) {
 	/*
 	 *  Special External Lynx type to handle cgi scripts.
 	 */
 	result = LYNXCGI_URL_TYPE;
 
-    } else if (compare_type(cp, "LYNXPRINT:", 10)) {
+    } else if (compare_type(cp, STR_LYNXPRINT, LEN_LYNXPRINT)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
 	result = LYNXPRINT_URL_TYPE;
 
-    } else if (compare_type(cp, "LYNXOPTIONS:", 12)) {
+    } else if (compare_type(cp, STR_LYNXOPTIONS, LEN_LYNXOPTIONS)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
 	result = LYNXOPTIONS_URL_TYPE;
 
-    } else if (compare_type(cp, "LYNXCFG:", 8)) {
+    } else if (compare_type(cp, STR_LYNXCFG, LEN_LYNXCFG)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
 	result = LYNXCFG_URL_TYPE;
 
-    } else if (compare_type(cp, "LYNXMESSAGES:", 13)) {
+    } else if (compare_type(cp, STR_LYNXMESSAGES, LEN_LYNXMESSAGES)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
 	result = LYNXMESSAGES_URL_TYPE;
 
-    } else if (compare_type(cp, "LYNXCOMPILEOPTS:", 16)) {
+    } else if (compare_type(cp, STR_LYNXCFLAGS, LEN_LYNXCFLAGS)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
 	result = LYNXCOMPILE_OPTS_URL_TYPE;
 
-    } else if (compare_type(cp, "LYNXDOWNLOAD:", 13)) {
+    } else if (compare_type(cp, STR_LYNXDOWNLOAD, LEN_LYNXDOWNLOAD)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
 	result = LYNXDOWNLOAD_URL_TYPE;
 
-    } else if (compare_type(cp, "LYNXDIRED:", 10)) {
+    } else if (compare_type(cp, STR_LYNXDIRED, LEN_LYNXDIRED)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
 	result = LYNXDIRED_URL_TYPE;
 
-    } else if (compare_type(cp, "LYNXHIST:", 9)) {
+    } else if (compare_type(cp, STR_LYNXHIST, LEN_LYNXHIST)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
 	result = LYNXHIST_URL_TYPE;
 
-    } else if (compare_type(cp, "LYNXKEYMAP:", 11)) {
+    } else if (compare_type(cp, STR_LYNXKEYMAP, LEN_LYNXKEYMAP)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
 	result = LYNXKEYMAP_URL_TYPE;
 
-    } else if (compare_type(cp, "LYNXIMGMAP:", 11)) {
+    } else if (compare_type(cp, STR_LYNXIMGMAP, LEN_LYNXIMGMAP)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
 	(void)is_url(&cp[11]);	/* forces lower/uppercase of next part */
 	result = LYNXIMGMAP_URL_TYPE;
 
-    } else if (compare_type(cp, "LYNXCOOKIE:", 11)) {
+    } else if (compare_type(cp, STR_LYNXCOOKIE, LEN_LYNXCOOKIE)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
@@ -2237,14 +2216,14 @@ PUBLIC int is_url ARGS1(
 	    result = LYCheckForProxyURL(filename);
 	}
 
-    } else if (compare_type(cp, "http:", 5)) {
+    } else if (compare_type(cp, STR_HTTP_URL, LEN_HTTP_URL)) {
 	result = HTTP_URL_TYPE;
 
-    } else if (compare_type(cp, "https:", 6)) {
+    } else if (compare_type(cp, STR_HTTPS_URL, LEN_HTTPS_URL)) {
 	result = HTTPS_URL_TYPE;
 
 #ifndef DISABLE_GOPHER
-    } else if (compare_type(cp, "gopher:", 7)) {
+    } else if (compare_type(cp, STR_GOPHER_URL, LEN_GOPHER_URL)) {
 	if (strlen(cp) >= 11
 	 && (cp1 = strchr(cp+11,'/')) != NULL) {
 
@@ -2263,27 +2242,27 @@ PUBLIC int is_url ARGS1(
 #endif
 
 #ifndef DISABLE_FTP
-    } else if (compare_type(cp, "ftp:", 4)) {
+    } else if (compare_type(cp, STR_FTP_URL, LEN_FTP_URL)) {
 	result = FTP_URL_TYPE;
 #endif
 
-    } else if (compare_type(cp, "wais:", 5)) {
+    } else if (compare_type(cp, STR_WAIS_URL, LEN_WAIS_URL)) {
 	result = WAIS_URL_TYPE;
 
-    } else if (compare_type(cp, "telnet:", 7)) {
+    } else if (compare_type(cp, STR_TELNET_URL, LEN_TELNET_URL)) {
 	result = TELNET_URL_TYPE;
 
-    } else if (compare_type(cp, "tn3270:", 7)) {
+    } else if (compare_type(cp, STR_TN3270_URL, LEN_TN3270_URL)) {
 	result = TN3270_URL_TYPE;
 
-    } else if (compare_type(cp, "rlogin:", 7)) {
+    } else if (compare_type(cp, STR_RLOGIN_URL, LEN_RLOGIN_URL)) {
 	result = RLOGIN_URL_TYPE;
 
-    } else if (compare_type(cp, "cso:", 4)) {
+    } else if (compare_type(cp, STR_CSO_URL, LEN_CSO_URL)) {
 	result = CSO_URL_TYPE;
 
 #ifndef DISABLE_FINGER
-    } else if (compare_type(cp, "finger:", 7)) {
+    } else if (compare_type(cp, STR_FINGER_URL, LEN_FINGER_URL)) {
 	result = FINGER_URL_TYPE;
 #endif
 
@@ -2345,19 +2324,19 @@ PUBLIC BOOLEAN LYFixCursesOnForAccess ARGS2(
 	 *  getfile() would indeed have turned curses off for it...
 	 */
 	if (strstr(addr, "://") != NULL &&
-	    (!strncmp(addr, "telnet:", 7) ||
-	     !strncmp(addr, "rlogin:", 7) ||
-	     !strncmp(addr, "tn3270:", 7) ||
-	     (strncmp(addr, "gopher:", 7) &&
+	    (isTELNET_URL(addr) ||
+	     isRLOGIN_URL(addr) ||
+	     isTN3270_URL(addr) ||
+	     (!isGOPHER_URL(addr) &&
 	      (cp1 = strchr(addr+11,'/')) != NULL &&
 	      (*(cp1+1) == 'T' || *(cp1+1) == '8')))) {
 	    /*
 	     *  If actual access that will be done is ok with curses off,
 	     *  then do nothing special, else force curses on. - kw
 	     */
-	    if (strncmp(physical, "telnet:", 7) &&
-		strncmp(physical, "rlogin:", 7) &&
-		strncmp(physical, "tn3270:", 7)) {
+	    if (!isTELNET_URL(physical) &&
+		!isRLOGIN_URL(physical) &&
+		!isTN3270_URL(physical)) {
 		start_curses();
 		HTAlert(
 		    gettext("Unexpected access protocol for this URL scheme."));
@@ -2427,9 +2406,9 @@ PUBLIC BOOLEAN LYCanDoHEAD ARGS1(
 	if (non_empty(acc_method)) {
 	    char *proxy;
 	    StrAllocCat(acc_method, "_proxy");
-	    proxy = getenv(acc_method);
-	    if (proxy && (!strncmp(proxy, "http:", 5) ||
-			  !strncmp(proxy, "lynxcgi:", 8)) &&
+	    proxy = LYGetEnv(acc_method);
+	    if (proxy && (isHTTP_URL(proxy) ||
+			  isLYNXCGI(proxy)) &&
 		!override_proxy(temp0)) {
 		FREE(temp0);
 		FREE(acc_method);
@@ -2836,6 +2815,7 @@ PUBLIC void HTAddSugFilename ARGS1(
 PUBLIC void change_sug_filename ARGS1(
 	char *,		fname)
 {
+    CONST char *cp2;
     char *temp = 0, *cp, *cp1, *end;
 #ifdef VMS
     char *dot;
@@ -2855,25 +2835,25 @@ PUBLIC void change_sug_filename ARGS1(
     /*
      *	Rename any temporary files.
      */
-    cp = wwwName(lynx_temp_space);
+    cp2 = wwwName(lynx_temp_space);
 #ifdef FNAMES_8_3
-    if (LYIsHtmlSep(*cp)) {
-	HTSprintf0(&temp, "file://localhost%s%04x", cp, GETPID());
+    if (LYIsHtmlSep(*cp2)) {
+	HTSprintf0(&temp, "file://localhost%s%04x", cp2, GETPID());
     } else {
-	HTSprintf0(&temp, "file://localhost/%s%04x", cp, GETPID());
+	HTSprintf0(&temp, "file://localhost/%s%04x", cp2, GETPID());
     }
 #else
-    if (LYIsHtmlSep(*cp)) {
-	HTSprintf0(&temp, "file://localhost%s%d", cp, (int)getpid());
+    if (LYIsHtmlSep(*cp2)) {
+	HTSprintf0(&temp, "file://localhost%s%d", cp2, (int)getpid());
     } else {
-	HTSprintf0(&temp, "file://localhost/%s%d", cp, (int)getpid());
+	HTSprintf0(&temp, "file://localhost/%s%d", cp2, (int)getpid());
     }
 #endif
     if (!strncmp(fname, temp, strlen(temp))) {
 	cp = strrchr(fname, '.');
 	if (strlen(cp) > (strlen(temp) - 4))
 	    cp = NULL;
-	StrAllocCopy(temp, (cp ? cp : ""));
+	StrAllocCopy(temp, NonNull(cp));
 	sprintf(fname, "temp%.*s", LY_MAXPATH - 10, temp);
     }
     FREE(temp);
@@ -3293,43 +3273,43 @@ PRIVATE CONST struct {
     { "outside_ftp",	&no_outside_ftp,	CAN_ANONYMOUS_OUTSIDE_DOMAIN_FTP },
     { "inside_rlogin",	&no_inside_rlogin,	CAN_ANONYMOUS_INSIDE_DOMAIN_RLOGIN },
     { "outside_rlogin",	&no_outside_rlogin,	CAN_ANONYMOUS_OUTSIDE_DOMAIN_RLOGIN },
-    { "suspend",	&no_suspend,		TRUE },
-    { "editor",		&no_editor,		TRUE },
-    { "shell",		&no_shell,		TRUE },
-    { "bookmark",	&no_bookmark,		TRUE },
-    { "multibook",	&no_multibook,		TRUE },
-    { "bookmark_exec",	&no_bookmark_exec,	TRUE },
-    { "option_save",	&no_option_save,	TRUE },
+    { "suspend",	&no_suspend,		FALSE },
+    { "editor",		&no_editor,		FALSE },
+    { "shell",		&no_shell,		FALSE },
+    { "bookmark",	&no_bookmark,		FALSE },
+    { "multibook",	&no_multibook,		FALSE },
+    { "bookmark_exec",	&no_bookmark_exec,	FALSE },
+    { "option_save",	&no_option_save,	FALSE },
     { "print",		&no_print,		CAN_ANONYMOUS_PRINT },
-    { "download",	&no_download,		TRUE },
-    { "disk_save",	&no_disk_save,		TRUE },
+    { "download",	&no_download,		FALSE },
+    { "disk_save",	&no_disk_save,		FALSE },
 #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
     { "exec",		&no_exec,		LOCAL_EXECUTION_LINKS_ALWAYS_OFF_FOR_ANONYMOUS },
 #endif
-    { "lynxcgi",	&no_lynxcgi,		TRUE },
-    { "exec_frozen",	&exec_frozen,		TRUE },
+    { "lynxcgi",	&no_lynxcgi,		FALSE },
+    { "exec_frozen",	&exec_frozen,		FALSE },
     { "goto",		&no_goto,		CAN_ANONYMOUS_GOTO },
     { "jump",		&no_jump,		CAN_ANONYMOUS_JUMP },
-    { "file_url",	&no_file_url,		TRUE },
+    { "file_url",	&no_file_url,		FALSE },
 #ifndef DISABLE_NEWS
-    { "news_post",	&no_newspost,		TRUE },
+    { "news_post",	&no_newspost,		FALSE },
     { "inside_news",	&no_inside_news,	CAN_ANONYMOUS_INSIDE_DOMAIN_READ_NEWS },
     { "outside_news",	&no_outside_news,	CAN_ANONYMOUS_OUTSIDE_DOMAIN_READ_NEWS },
 #endif
     { "mail",		&no_mail,		CAN_ANONYMOUS_MAIL },
-    { "dotfiles",	&no_dotfiles,		TRUE },
-    { "useragent",	&no_useragent,		TRUE },
+    { "dotfiles",	&no_dotfiles,		FALSE },
+    { "useragent",	&no_useragent,		FALSE },
 #ifdef SUPPORT_CHDIR
-    { "chdir",		&no_chdir,		TRUE },
+    { "chdir",		&no_chdir,		FALSE },
 #endif
 #ifdef DIRED_SUPPORT
-    { "dired_support",	&no_dired_support,	TRUE },
+    { "dired_support",	&no_dired_support,	FALSE },
 #ifdef OK_PERMIT
-    { "change_exec_perms", &no_change_exec_perms, TRUE },
+    { "change_exec_perms", &no_change_exec_perms, FALSE },
 #endif /* OK_PERMIT */
 #endif /* DIRED_SUPPORT */
 #ifdef USE_EXTERNALS
-    { "externals",	&no_externals,		TRUE },
+    { "externals",	&no_externals,		FALSE },
 #endif
     { "lynxcfg_info",	&no_lynxcfg_info,	CAN_ANONYMOUS_VIEW_LYNXCFG_INFO },
 #ifndef NO_CONFIG_INFO
@@ -3486,7 +3466,7 @@ PUBLIC void parse_restrictions ARGS1(
 	    }
 	}
 	if (!found) {
-	    printf("%s: %.*s", gettext("unknown restriction"), p-word, word);
+	    printf("%s: %.*s\n", gettext("unknown restriction"), p-word, word);
 	    exit(EXIT_FAILURE);
 	}
 	if (*p)
@@ -3633,7 +3613,7 @@ PUBLIC void LYCheckMail NOARGS
     struct stat st;
 
     if (firsttime) {
-	mf = getenv("MAIL");
+	mf = LYGetEnv("MAIL");
 	firsttime = FALSE;
 	time(&lasttime);
     }
@@ -3688,15 +3668,15 @@ PUBLIC void LYEnsureAbsoluteURL ARGS3(
     /*
      *	If it is not a URL then make it one.
      */
-    if (!strcasecomp(*href, "news:")) {
+    if (!strcasecomp(*href, STR_NEWS_URL)) {
 	StrAllocCat(*href, "*");
-    } else if (!strcasecomp(*href, "nntp:") ||
-	       !strcasecomp(*href, "snews:")) {
+    } else if (!strcasecomp(*href, STR_NEWS_URL) ||
+	       !strcasecomp(*href, STR_SNEWS_URL)) {
 	StrAllocCat(*href, "/*");
     }
     if (!is_url(*href)) {
 	CTRACE((tfp, "%s%s'%s' is not a URL\n",
-		    (name ? name : ""), (name ? " " : ""), *href));
+		    NonNull(name), (name ? " " : ""), *href));
 	LYConvertToURL(href, fixit);
     }
     if (non_empty(temp = HTParse(*href, "", PARSE_ALL)))
@@ -3724,14 +3704,15 @@ PUBLIC void LYConvertToURL ARGS2(
     if (!old_string || *old_string == '\0')
 	return;
 
-#if defined(DOSPATH) || defined(__EMX__)
+#if defined(USE_DOS_DRIVES)
     {
-	 char *cp_url = *AllocatedString;
-	 for(; *cp_url != '\0'; cp_url++)
-		if(*cp_url == '\\') *cp_url = '/';
-	 cp_url--;
-	 if(*cp_url == ':')
-		 StrAllocCat(*AllocatedString,"/");
+	char *cp_url = *AllocatedString;
+	for(; *cp_url != '\0'; cp_url++)
+	    if (*cp_url == '\\')
+		*cp_url = '/';
+	    cp_url--;
+	if (LYIsDosDrive(*AllocatedString) && *cp_url == ':')
+	    LYAddPathSep(AllocatedString);
     }
 #endif /* DOSPATH */
 
@@ -3740,7 +3721,7 @@ PUBLIC void LYConvertToURL ARGS2(
 
     if (*old_string != '/') {
 	char *fragment = NULL;
-#if defined(DOSPATH) || defined(__EMX__)
+#if defined(USE_DOS_DRIVES)
 	StrAllocCat(*AllocatedString,"/");
 #endif /* DOSPATH */
 #ifdef VMS
@@ -3772,8 +3753,7 @@ PUBLIC void LYConvertToURL ARGS2(
 	    }
 	    goto have_VMS_URL;
 	} else {
-	    if ((fragment = strchr(old_string, '#')) != NULL)
-		*fragment = '\0';
+	    fragment = trimPoundSelector(old_string);
 	    LYstrncpy(url_file, old_string, sizeof(url_file)-1);
 	}
 	url_file_dsc.dsc$w_length = (short) strlen(url_file);
@@ -3791,7 +3771,7 @@ PUBLIC void LYConvertToURL ARGS2(
 		StrAllocCat(*AllocatedString, cp);
 	    }
 	    if (fragment != NULL) {
-		*fragment = '#';
+		restorePoundSelector(fragment);
 		StrAllocCat(*AllocatedString, fragment);
 		fragment = NULL;
 	    }
@@ -3801,9 +3781,7 @@ PUBLIC void LYConvertToURL ARGS2(
 	     * Probably a directory.  Try converting that.
 	     */
 	    StrAllocCopy(cur_dir, dir_name);
-	    if (fragment != NULL) {
-		*fragment = '#';
-	    }
+	    restorePoundSelector(fragment);
 	    if (NULL != getcwd(dir_name, sizeof(dir_name)-1, 0)) {
 		/*
 		 * Yup, we got it!
@@ -3855,10 +3833,9 @@ PUBLIC void LYConvertToURL ARGS2(
 	     *	with the "http://" defaulted, if we can't
 	     *	rule out a bad VMS path.
 	     */
-	    if (fragment != NULL) {
-		*fragment = '#';
-		fragment = NULL;
-	    }
+	    restorePoundSelector(fragment);
+	    fragment = NULL;
+
 	    if (strchr(old_string, '[') ||
 		((cp = strchr(old_string, ':')) != NULL &&
 		 !isdigit(UCH(cp[1]))) ||
@@ -3892,7 +3869,7 @@ PUBLIC void LYConvertToURL ARGS2(
 have_VMS_URL:
 	CTRACE((tfp, "Trying: '%s'\n", *AllocatedString));
 #else /* not VMS: */
-#if defined(DOSPATH)
+#if defined(USE_DOS_DRIVES)
 #ifdef _WINDOWS
 	if (*old_string == '.') {
 	    char fullpath[MAX_PATH + 1];
@@ -3956,7 +3933,7 @@ have_VMS_URL:
 	     *	Concatenate and simplify, trimming any
 	     *	residual relative elements. - FM
 	     */
-#if defined (DOSPATH) || defined (__EMX__) || defined (WIN_EX)
+#if defined (USE_DOS_DRIVES)
 	    if (old_string[1] != ':' && old_string[1] != '|') {
 		StrAllocCopy(temp, wwwName(curdir));
 		LYAddHtmlSep(&temp);
@@ -3969,8 +3946,8 @@ have_VMS_URL:
 		    old_string[1] = ':';
 		StrAllocCopy(temp, old_string);
 
-		if (strlen(temp) == 2 && temp[1] == ':')
-		    StrAllocCat(temp, "/");
+		if (strlen(temp) == 2 && LYIsDosDrive(temp))
+		    LYAddPathSep(&temp);
 	    }
 #else
 	    StrAllocCopy(temp, curdir);
@@ -3984,7 +3961,7 @@ have_VMS_URL:
 		/*
 		 *  It is a subdirectory or file on the local system.
 		 */
-#if defined (DOSPATH) || defined (__EMX__)
+#if defined (USE_DOS_DRIVES)
 		/* Don't want to see DOS local paths like c: escaped  */
 		/* especially when we really have file://localhost/   */
 		/* at the beginning.  To avoid any confusion we allow */
@@ -4006,8 +3983,7 @@ have_VMS_URL:
 		StrAllocCopy(temp2, curdir);
 		LYAddPathSep(&temp2);
 		StrAllocCopy(cp, old_string);
-		if ((fragment = strchr(cp, '#')) != NULL)
-		    *fragment = '\0';	/* keep as pointer into cp string */
+		fragment = trimPoundSelector(cp);
 		HTUnEscape(cp);   /* unescape given path without fragment */
 		StrAllocCat(temp2, cp);		/* append to current dir  */
 		StrAllocCopy(cp2, temp2);	/* keep a copy in cp2	  */
@@ -4037,7 +4013,7 @@ have_VMS_URL:
 		    } else {
 			temp = HTEscape(temp2, URL_PATH);
 			if (fragment != NULL) {
-			    *fragment = '#';
+			    restorePoundSelector(fragment);
 			    StrAllocCat(temp, fragment);
 			}
 		    }
@@ -4067,7 +4043,7 @@ have_VMS_URL:
 		    } else {
 			temp = HTEscape(temp2, URL_PATH);
 			if (fragment != NULL) {
-			    *fragment = '#';
+			    restorePoundSelector(fragment);
 			    StrAllocCat(temp, fragment);
 			}
 		    }
@@ -4085,12 +4061,13 @@ have_VMS_URL:
 			    temp2 ? temp2 : temp));
 #ifdef WIN_EX  /* 1998/01/13 (Tue) 09:07:37 */
 		{
-		    char *p, *q, buff[LY_MAXPATH + 128];
+		    CONST char *p, *q;
+		    char buff[LY_MAXPATH + 128];
 
-		    p = (char *)Home_Dir();
+		    p = Home_Dir();
 		    q = temp2 ? temp2 : temp;
 
-		    if (strlen(q) == 3 && isalpha(UCH(q[0])) && q[1] == ':') {
+		    if (strlen(q) == 3 && LYIsDosDrive(q)) {
 			sprintf(buff,
 			    "'%s' not exist, Goto LynxHome '%s'.", q, p);
 			_statusline(buff);
@@ -4261,11 +4238,6 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3(
     int error;
 #endif /* INET6 */
 
-#ifdef _WINDOWS
-    int hoststat;
-    struct hostent  *phost;	/* Pointer to host - See netdb.h */
-#endif
-
     /*
      *	If it's a NULL or zero-length string,
      *	or if it begins with a slash or hash,
@@ -4298,13 +4270,13 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3(
 	 *  already be included in Path. - FM
 	 */
 	*Path = '\0';
-    } else if ((Fragment = strchr(Str, '#')) != NULL) {
+    } else {
 	/*
 	 *  No path, so check for a fragment and
 	 *  trim that, to be restored after filling
 	 *  in the Host[:port] field. - FM
 	 */
-	*Fragment = '\0';
+	Fragment = trimPoundSelector(Str);
     }
 
     /*
@@ -4530,7 +4502,7 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3(
 	    StrAllocCat(Host, Path);
 	} else if (Fragment) {
 	    StrAllocCat(Host, "/");
-	    *Fragment = '#';
+	    restorePoundSelector(Fragment);
 	    StrAllocCat(Host, Fragment);
 	}
 	StrAllocCopy(*AllocatedString, Host);
@@ -4820,28 +4792,83 @@ PUBLIC char * Current_Dir ARGS1(
     return pathname;
 }
 
+/*
+ * Verify that the given path refers to an existing directory, returning the
+ * string if the directory exists.  If not, return null.
+ */
+PRIVATE char * CheckDir ARGS1(
+    char *,	path)
+{
+    struct stat stat_info;
+    if (!LYisAbsPath(path)
+	|| (HTStat(path, &stat_info) < 0
+	 || !S_ISDIR(stat_info.st_mode))) {
+	path = NULL;
+    }
+    return path;
+}
+
+/*
+ * Lookup various possibilities for $HOME, and check that the directory exists.
+ */
+PRIVATE char *HomeEnv NOARGS
+{
+    char *result = CheckDir(LYGetEnv("HOME"));
+
+#if defined (USE_DOS_DRIVES)
+    if (result == 0) {
+	char *head;
+	char *leaf;
+	static char *temp = NULL;
+
+	/* Windows 2000 */
+	if ((result = LYGetEnv("USERPROFILE")) != 0) {
+	    HTSprintf0(&temp, "%s%sMy Documents", result, PATHSEP_STR);
+	    result = CheckDir(temp);
+	}
+	/* NT4 */
+	if (result == 0) {
+	    if ((head = LYGetEnv("HOMEDRIVE")) != 0) {
+		if ((leaf = LYGetEnv("HOMEPATH")) != 0) {
+		    HTSprintf0(&temp, "%s%s%s", head, PATHSEP_STR, leaf);
+		    result = CheckDir(temp);
+		}
+	    }
+	}
+	/* General M$ */
+	if (result == 0)
+	    result = CheckDir(LYGetEnv("TEMP"));
+	if (result == 0)
+	    result = CheckDir(LYGetEnv("TMP"));
+	if (result == 0) {
+	    if ((head = LYGetEnv("SystemDrive")) != 0) {
+		HTSprintf0(&temp, "%s%s", head, PATHSEP_STR);
+		result = CheckDir(temp);
+	    }
+	}
+	if (result == 0)
+	    result = CheckDir("C:" PATHSEP_STR);
+    }
+#endif
+
+    return result; 
+}
+
 PUBLIC CONST char * Home_Dir NOARGS
 {
     static CONST char *homedir = NULL;
     char *cp = NULL;
 
     if (homedir == NULL) {
-	if ((cp = getenv_text("HOME")) == NULL
-	 || !LYisAbsPath(cp)) {
-#if defined (DOSPATH) || defined (__EMX__) /* BAD!	WSB */
-	    if ((cp = getenv_text("TEMP")) == NULL
-	     && (cp = getenv_text("TMP")) == NULL) {
-		cp = "C:\\";
-	    }
-	    StrAllocCopy(HomeDir, cp);
-#else
+	if ((cp = HomeEnv()) == NULL) {
 #ifdef VMS
-	    if ((cp = getenv_text("SYS$LOGIN")) == NULL
-	     && (cp = getenv_text("SYS$SCRATCH")) == NULL) {
+	    if ((cp = LYGetEnv("SYS$LOGIN")) == NULL
+	     && (cp = LYGetEnv("SYS$SCRATCH")) == NULL) {
 		cp = "sys$scratch:";
 	    }
 	    StrAllocCopy(HomeDir, cp);
 #else
+#ifdef UNIX
 #ifdef HAVE_UTMP
 	    /*
 	     *	One could use getlogin() and getpwnam() here instead.
@@ -4858,21 +4885,9 @@ PUBLIC CONST char * Home_Dir NOARGS
 		 */
 		StrAllocCopy(HomeDir, "/tmp");
 	    }
-#ifdef UNIX
-	    if (non_empty(cp))
-		HTAlwaysAlert(NULL, gettext("Ignoring invalid HOME"));
 #endif
 #endif /* VMS */
-#endif /* DOSPATH */
 	} else {
-#if defined(_WINDOWS) || defined(DOSPATH)
-	    char *hp = getenv_text("HOMEDRIVE");
-	    if (hp != 0
-	     && (LYIsPathSep(*cp) || !LYisAbsPath(cp))) {
-		StrAllocCopy(HomeDir, hp);
-		StrAllocCat(HomeDir, cp);
-	    } else
-#endif
 	    StrAllocCopy(HomeDir, cp);
 	}
 	homedir = (CONST char *)HomeDir;
@@ -4880,6 +4895,10 @@ PUBLIC CONST char * Home_Dir NOARGS
 	atexit(LYHomeDir_free);
 #endif
     }
+    if (homedir == NULL) {
+	printf("%s\n", gettext("Cannot find HOME directory"));
+	exit(EXIT_FAILURE);
+    }
     return homedir;
 }
 
@@ -5453,7 +5472,7 @@ PUBLIC time_t LYmktime ARGS2(
 
 #if !defined(HAVE_PUTENV) && !defined(_WINDOWS)
 /*
- *  No putenv on the next so we use this code instead!
+ *  No putenv on the NeXT so we use this code instead!
  */
 
 /* Copyright (C) 1991 Free Software Foundation, Inc.
@@ -5548,7 +5567,17 @@ int remove ARGS1(char *, name)
 }
 #endif
 
-#if defined(UNIX)
+/*
+ * Default, for single-user systems such as Cygwin and OS/2 EMX:
+ */
+#define IsOurFile(name) TRUE
+#define OpenHiddenFile(name, mode) fopen(name, mode)
+
+#if defined(MULTI_USER_UNIX)
+
+#undef IsOurFile
+#undef OpenHiddenFile
+
 /*
  * Verify if this is really a file, not accessed by a link, except for the
  * special case of its directory being pointed to by a link from a directory
@@ -5567,7 +5596,7 @@ PRIVATE BOOL IsOurFile ARGS1(char *, name)
 	 * ( If this is not a single-user system, the other user is presumed by
 	 * some people busy trying to use a symlink attack on our files ;-)
 	 */
-#if defined(HAVE_LSTAT) && !(defined(DOSPATH) || defined(__EMX__))
+#if defined(HAVE_LSTAT)
 	char *path = 0;
 	char *leaf;
 
@@ -5669,11 +5698,7 @@ PRIVATE FILE *OpenHiddenFile ARGS2(char *, name, char *, mode)
     }
     return fp;
 }
-#else	/* !UNIX */
-# ifndef VMS
-#  define OpenHiddenFile(name, mode) fopen(name, mode)
-# endif
-#endif
+#endif /* MULTI_USER_UNIX */
 
 PUBLIC FILE *LYNewBinFile ARGS1(char *, name)
 {
@@ -5721,7 +5746,7 @@ PUBLIC FILE *LYAppendToTxtFile ARGS1(char *, name)
     return fp;
 }
 
-#ifdef UNIX
+#if defined(MULTI_USER_UNIX)
 /*
  *  Restore normal permissions to a copy of a file that we have created
  *  with temp file restricted permissions.  The normal umask should
@@ -5804,7 +5829,7 @@ PUBLIC FILE *LYOpenTemp ARGS3(
      * Verify if the given space looks secure enough.  Otherwise, make a
      * secure subdirectory of that.
      */
-#if defined(UNIX) && defined(HAVE_MKTEMP)
+#if defined(MULTI_USER_UNIX) && defined(HAVE_MKTEMP)
     if (lynx_temp_subspace == 0)
     {
 	BOOL make_it = FALSE;
@@ -5949,11 +5974,7 @@ PUBLIC FILE *LYOpenTempRewrite ARGS3(
 #endif
 
 	if (writable_exists) {
-#ifdef UNIX
 	    is_ours = IsOurFile(fname);
-#else
-	    is_ours = TRUE;	/* assume ok, if we get to here */
-#endif
 	}
 	CTRACE((tfp, "...%s%s\n",
 	       writable_exists ? CTRACE_EXISTS : "",
@@ -6174,7 +6195,7 @@ PUBLIC void LYCleanupTemp NOARGS
     while (ly_temp != 0) {
 	LYRemoveTemp(ly_temp->name);
     }
-#ifdef UNIX
+#if defined(MULTI_USER_UNIX)
     if (lynx_temp_subspace > 0) {
 	char result[LY_MAXPATH];
 	LYstrncpy(result, lynx_temp_space, sizeof(result)-1);
@@ -6379,18 +6400,18 @@ PUBLIC void LYUIPages_free NOARGS
  *  Convert local pathname to www name
  *  (do not bother about file://localhost prefix at this point).
  */
-PUBLIC  char * wwwName ARGS1(
+PUBLIC  CONST char * wwwName ARGS1(
 	CONST char *,	pathname)
 {
-    char *cp = NULL;
+    CONST char *cp = NULL;
 
-#ifdef DOSPATH
+#if defined(USE_DOS_DRIVES)
     cp = HTDOS_wwwName(pathname);
 #else
 #ifdef VMS
     cp = HTVMS_wwwName(pathname);
 #else
-    cp = (char *)pathname;
+    cp = pathname;
 #endif /* VMS */
 #endif /* DOSPATH */
 
@@ -6408,23 +6429,19 @@ PUBLIC BOOLEAN LYValidateFilename ARGS2(
 	char *,		result,
 	char *,		given)
 {
-    char *cp, *cp2;
+    char *cp;
+    CONST char *cp2;
 
     /*
      *  Cancel if the user entered "/dev/null" on Unix,
-     *  or an "nl:" path (case-insensitive) on VMS. - FM
+     *  or an "nl:" path on VMS. - FM
      */
-#ifdef VMS
-    if (!strncasecomp(given, "nl:", 3) ||
-	!strncasecomp(given, "/nl/", 4))
-#else
-    if (!strcmp(given, "/dev/null"))
-#endif /* VMS */
+    if (LYIsNullDevice(given))
     {
 	/* just ignore it */
 	return FALSE;
     }
-#if HAVE_POPEN
+#ifdef HAVE_POPEN
     if (LYIsPipeCommand(given)) {
 	if (no_shell) {
 	    HTUserMsg(SPAWNING_DISABLED);
@@ -6513,7 +6530,7 @@ PUBLIC int LYValidateOutput ARGS1(
     /*
      * Assume we can write to a pipe
      */
-#if HAVE_POPEN
+#ifdef HAVE_POPEN
     if (LYIsPipeCommand(filename))
 	return 'Y';
 #endif
@@ -6551,7 +6568,7 @@ PUBLIC void LYLocalFileToURL ARGS2(
 	char **,	target,
 	CONST char *,	source)
 {
-    char *leaf;
+    CONST char *leaf;
 
     StrAllocCopy(*target, "file://localhost");
 
@@ -6609,6 +6626,15 @@ PUBLIC void EndInternalPage ARGS1(
     fprintf(fp0, "</body>\n</html>");
 }
 
+PUBLIC char *trimPoundSelector ARGS1(
+	char *,		address)
+{
+    char *pound = findPoundSelector(address);
+    if (pound != 0)
+	*pound = '\0';
+    return pound;
+}
+
 /*
  * Trim a trailing path-separator to avoid confusing other programs when we concatenate
  * to it.  This only applies to local filesystems.
@@ -6624,12 +6650,6 @@ PUBLIC void LYTrimPathSep ARGS1(
 	path[len-1] = 0;
 }
 
-#if defined(DOSPATH) && !defined(__DJGPP__)
-#define PATHSEP_STR "\\"
-#else
-#define PATHSEP_STR "/"
-#endif
-
 /*
  * Add a trailing path-separator to avoid confusing other programs when we concatenate
  * to it.  This only applies to local filesystems.
@@ -6672,7 +6692,7 @@ PUBLIC char * LYLastPathSep ARGS1(
 	CONST char *,	path)
 {
     char *result;
-#ifdef DOSPATH
+#if defined(USE_DOS_DRIVES)
     if ((result = strrchr(path, '\\')) == 0)
 	result = strrchr(path, '/');
 #else
@@ -6841,6 +6861,11 @@ PUBLIC int LYSystem ARGS1(
     }
 #  endif
 
+    /*
+     * This chunk of code does not work, for two reasons:
+     * a) the Cygwin system() function edits out the backslashes
+     * b) it does not account for more than one parameter, e.g., +number
+     */
 #if defined(__CYGWIN__) && defined(DOSPATH)	/* 1999/02/26 (Fri) */
     {
 	char cmd[LY_MAXPATH];
@@ -6891,7 +6916,7 @@ PUBLIC int LYSystem ARGS1(
     }
 #endif
 
-#if _WIN_CC
+#ifdef _WIN_CC
     code = exec_command(command, TRUE);	/* Wait exec */
 #else
     if (restore_sigpipe_for_children)
@@ -6951,7 +6976,7 @@ PUBLIC int Cygwin_Shell NOARGS
     /* Init a startup structure */
     GetStartupInfo(&startUpInfo);
 
-    shell = getenv_text("COMSPEC");
+    shell = LYGetEnv("COMSPEC");
 
     /* Create the child process, specifying
      inherited handles. Pass the value of the
@@ -6963,7 +6988,7 @@ PUBLIC int Cygwin_Shell NOARGS
 			0, 0, &startUpInfo, &procInfo);
 
 	if (!code) {
-	    printf("shell = [%s], code = %d\n", shell, GetLastError());
+	    printf("shell = [%s], code = %ld\n", shell, GetLastError());
 	}
 
 	/* wait for the child to return (this is not a requirement
@@ -6980,10 +7005,10 @@ PUBLIC char *LYSysShell NOARGS
     char *shell = 0;
 #ifdef DOSPATH
 #ifdef WIN_EX
-    shell = getenv_text("SHELL");
+    shell = LYGetEnv("SHELL");
     if (shell) {
 	if (access(shell, 0) != 0)
-	    shell = getenv_text("COMSPEC");
+	    shell = LYGetEnv("COMSPEC");
     }
     if (shell == NULL) {
 	if (system_is_NT)
@@ -6992,9 +7017,9 @@ PUBLIC char *LYSysShell NOARGS
 	    shell = "command.com";
     }
 #else
-    shell = getenv_text("SHELL");
+    shell = LYGetEnv("SHELL");
     if (shell == NULL) {
-	shell = getenv_text("COMSPEC");
+	shell = LYGetEnv("COMSPEC");
     }
     if (shell == NULL) {
 	shell = "command.com";
@@ -7002,10 +7027,10 @@ PUBLIC char *LYSysShell NOARGS
 #endif /* WIN_EX */
 #else
 #ifdef __EMX__
-    if (getenv_text("SHELL") != NULL) {
-	shell = getenv_text("SHELL");
+    if (LYGetEnv("SHELL") != NULL) {
+	shell = LYGetEnv("SHELL");
     } else {
-	shell = (getenv_text("COMSPEC") == NULL) ? "cmd.exe" : getenv_text("COMSPEC");
+	shell = (LYGetEnv("COMSPEC") == NULL) ? "cmd.exe" : LYGetEnv("COMSPEC");
     }
 #else
 #ifdef VMS
@@ -7029,10 +7054,7 @@ PUBLIC char *LYSysShell NOARGS
  */
 PUBLIC char *LYgetXDisplay NOARGS
 {
-    char *cp;
-    if ((cp = getenv_text(DISPLAY)) == NULL)
-	cp = 0;
-    return cp;
+    return LYGetEnv(DISPLAY);
 }
 
 /*
@@ -7058,6 +7080,7 @@ PUBLIC void LYsetXDisplay ARGS1(
     }
 }
 
+#ifdef CAN_CUT_AND_PASTE
 #ifdef __EMX__
 
 static int proc_type = -1;
@@ -7272,6 +7295,7 @@ PUBLIC void get_clip_release()
     m_locked = 0;
 }
 #endif
+#endif /* CAN_CUT_AND_PASTE */
 
 #if defined(WIN_EX)
 
diff --git a/src/LYUtils.h b/src/LYUtils.h
index ce9e42f9..e1be5c52 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -16,7 +16,7 @@
 #define HTSYS_remove(path) HTVMS_remove(path)
 #endif /* VMS */
 
-#if defined(DOSPATH) || defined(__EMX__)
+#if defined(USE_DOS_DRIVES)
 #include <HTDOS.h>
 #define HTSYS_name(path) HTDOS_name(path)
 #endif
@@ -35,6 +35,36 @@
 
 #define LYIsPipeCommand(s) ((s)[0] == '|')
 
+#ifdef VMS
+#define TTY_DEVICE "tt:"
+#define NUL_DEVICE "nl:"
+#define LYIsNullDevice(s) (!strncasecomp(s, "nl:", 3) || !strncasecomp(s, "/nl/", 4))
+#define LYSameFilename(a,b) (!strcasecomp(a,b))
+#define LYSameHostname(a,b) (!strcasecomp(a,b))
+#else
+#if defined(DOSPATH) || defined(__EMX__)
+#define TTY_DEVICE "con"
+#define NUL_DEVICE "nul"
+#define LYIsNullDevice(s) LYSameFilename(s,NUL_DEVICE)
+#define LYSameFilename(a,b) (!strcasecomp(a,b))
+#define LYSameHostname(a,b) (!strcasecomp(a,b))
+#else
+#if defined(__CYGWIN__)
+#define TTY_DEVICE "/dev/tty"
+#define NUL_DEVICE "/dev/null"
+#define LYIsNullDevice(s) LYSameFilename(s,NUL_DEVICE)
+#define LYSameFilename(a,b) (!strcasecomp(a,b))
+#define LYSameHostname(a,b) (!strcasecomp(a,b))
+#else
+#define TTY_DEVICE "/dev/tty"
+#define NUL_DEVICE "/dev/null"
+#define LYIsNullDevice(s) LYSameFilename(s,NUL_DEVICE)
+#define LYSameFilename(a,b) (!strcmp(a,b))
+#define LYSameHostname(a,b) (!strcmp(a,b))
+#endif /* __CYGWIN__ */
+#endif /* DOSPATH */
+#endif /* VMS */
+
 /* See definitions in src/LYCharVals.h.  The hardcoded values...
    This prohibits binding C-c and C-g.  Maybe it is better to remove this? */
 #define LYCharIsINTERRUPT_HARD(ch)	\
@@ -46,10 +76,14 @@
 #define LYCharIsINTERRUPT_NO_letter(ch)	\
   (LYCharIsINTERRUPT(ch) && !isprint(ch))
 
-#if defined(DOSPATH) || defined(__EMX__)
+#if defined(USE_DOS_DRIVES)
+#define PATHSEP_STR "\\"
 #define LYIsPathSep(ch) ((ch) == '/' || (ch) == '\\')
+#define LYIsDosDrive(s) (isalpha(UCH((s)[0])) && (s)[1] == ':')
 #else
+#define PATHSEP_STR "/"
 #define LYIsPathSep(ch) ((ch) == '/')
+#define LYIsDosDrive(s) FALSE /* really nothing */
 #endif
 
 #ifdef EXP_ADDRLIST_PAGE
@@ -63,6 +97,9 @@
 
 #define LYIsHtmlSep(ch) ((ch) == '/')
 
+#define findPoundSelector(address) strchr(address, '#')
+#define restorePoundSelector(pound) if ((pound) != NULL) *(pound) = '#'
+
 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));
@@ -91,13 +128,15 @@ extern FILE *LYOpenTemp PARAMS((char *result, CONST char *suffix, CONST char *mo
 extern FILE *LYOpenTempRewrite PARAMS((char *result, CONST char *suffix, CONST char *mode));
 extern FILE *LYReopenTemp PARAMS((char *name));
 extern char *Current_Dir PARAMS((char * pathname));
+extern char *LYGetEnv PARAMS((CONST char * name));
 extern char *LYGetHiliteStr PARAMS(( int cur, int count));
 extern char *LYLastPathSep PARAMS((CONST char *path));
 extern char *LYPathLeaf PARAMS((char * pathname));
 extern char *LYSysShell NOPARAMS;
 extern char *LYgetXDisplay NOPARAMS;
 extern char *strip_trailing_slash PARAMS((char * my_dirname));
-extern char *wwwName PARAMS((CONST char *pathname));
+extern char *trimPoundSelector PARAMS((char * address));
+extern CONST char *wwwName PARAMS((CONST char *pathname));
 extern int HTCheckForInterrupt NOPARAMS;
 extern int LYCheckForProxyURL PARAMS((char *filename));
 extern int LYConsoleInputFD PARAMS((BOOLEAN need_selectable));
@@ -152,6 +191,15 @@ extern void size_change PARAMS((int sig));
 extern void statusline PARAMS((CONST char *text));
 extern void toggle_novice_line NOPARAMS;
 
+#ifdef __CYGWIN__
+extern int Cygwin_Shell PARAMS((void));
+#endif
+
+#ifdef _WIN_CC
+extern int exec_command(char * cmd, int wait_flag); /* xsystem.c */
+extern int xsystem(char *cmd);
+#endif
+
 /* Keeping track of User Interface Pages: */
 typedef enum {
     UIP_UNKNOWN=-1
@@ -206,8 +254,10 @@ extern void Define_VMSLogical PARAMS((char *LogicalName, char *LogicalValue));
 extern int putenv PARAMS((CONST char *string));
 #endif /* HAVE_PUTENV */
 
-#ifdef UNIX
+#if defined(MULTI_USER_UNIX)
 extern void LYRelaxFilePermissions PARAMS((CONST char * name));
+#else
+#define LYRelaxFilePermissions(name) /* nothing */
 #endif
 
 /*
@@ -275,6 +325,128 @@ typedef enum {
 
 } UrlTypes;
 
+/* common URLs */
+#define STR_BIBP_URL         "bibp:"
+#define LEN_BIBP_URL         5
+#define isBIBP_URL(addr)     !strncasecomp(addr, STR_BIBP_URL, LEN_BIBP_URL)
+
+#define STR_CSO_URL          "cso:"
+#define LEN_CSO_URL          4
+#define isCSO_URL(addr)      !strncasecomp(addr, STR_CSO_URL, LEN_CSO_URL)
+
+#define STR_FILE_URL         "file:"
+#define LEN_FILE_URL         5
+#define isFILE_URL(addr)     !strncasecomp(addr, STR_FILE_URL, LEN_FILE_URL)
+
+#define STR_FINGER_URL       "finger:"
+#define LEN_FINGER_URL       7
+#define isFINGER_URL(addr)   !strncasecomp(addr, STR_FINGER_URL, LEN_FINGER_URL)
+
+#define STR_FTP_URL          "ftp:"
+#define LEN_FTP_URL          4
+#define isFTP_URL(addr)      !strncasecomp(addr, STR_FTP_URL, LEN_FTP_URL)
+
+#define STR_GOPHER_URL       "gopher:"
+#define LEN_GOPHER_URL       7
+#define isGOPHER_URL(addr)   !strncasecomp(addr, STR_GOPHER_URL, LEN_GOPHER_URL)
+
+#define STR_HTTP_URL         "http:"
+#define LEN_HTTP_URL         5
+#define isHTTP_URL(addr)     !strncasecomp(addr, STR_HTTP_URL, LEN_HTTP_URL)
+
+#define STR_HTTPS_URL        "https:"
+#define LEN_HTTPS_URL        6
+#define isHTTPS_URL(addr)    !strncasecomp(addr, STR_HTTPS_URL, LEN_HTTPS_URL)
+
+#define STR_MAILTO_URL       "mailto:"
+#define LEN_MAILTO_URL       7
+#define isMAILTO_URL(addr)   !strncasecomp(addr, STR_MAILTO_URL, LEN_MAILTO_URL)
+
+#define STR_NEWS_URL         "news:"
+#define LEN_NEWS_URL         5
+#define isNEWS_URL(addr)     !strncasecomp(addr, STR_NEWS_URL, LEN_NEWS_URL)
+
+#define STR_NNTP_URL         "nntp:"
+#define LEN_NNTP_URL         5
+#define isNNTP_URL(addr)     !strncasecomp(addr, STR_NNTP_URL, LEN_NNTP_URL)
+
+#define STR_RLOGIN_URL       "rlogin:"
+#define LEN_RLOGIN_URL       7
+#define isRLOGIN_URL(addr)   !strncasecomp(addr, STR_RLOGIN_URL, LEN_RLOGIN_URL)
+
+#define STR_SNEWS_URL        "snews:"
+#define LEN_SNEWS_URL        6
+#define isSNEWS_URL(addr)    !strncasecomp(addr, STR_SNEWS_URL, LEN_SNEWS_URL)
+
+#define STR_TELNET_URL       "telnet:"
+#define LEN_TELNET_URL       7
+#define isTELNET_URL(addr)   !strncasecomp(addr, STR_TELNET_URL, LEN_TELNET_URL)
+
+#define STR_TN3270_URL       "tn3270:"
+#define LEN_TN3270_URL       7
+#define isTN3270_URL(addr)   !strncasecomp(addr, STR_TN3270_URL, LEN_TN3270_URL)
+
+#define STR_WAIS_URL         "wais:"
+#define LEN_WAIS_URL         5
+#define isWAIS_URL(addr)     !strncasecomp(addr, STR_WAIS_URL, LEN_WAIS_URL)
+
+/* internal URLs */
+#define STR_LYNXCFG          "LYNXCFG:"
+#define LEN_LYNXCFG          8
+#define isLYNXCFG(addr)      !strncasecomp(addr, STR_LYNXCFG, LEN_LYNXCFG)
+
+#define STR_LYNXCFLAGS       "LYNXCOMPILEOPTS:"
+#define LEN_LYNXCFLAGS       16
+#define isLYNXCFLAGS(addr)   !strncasecomp(addr, STR_LYNXCFLAGS, LEN_LYNXCFLAGS)
+
+#define STR_LYNXCGI          "lynxcgi:"
+#define LEN_LYNXCGI          8
+#define isLYNXCGI(addr)      !strncasecomp(addr, STR_LYNXCGI, LEN_LYNXCGI)
+
+#define STR_LYNXCOOKIE       "LYNXCOOKIE:"
+#define LEN_LYNXCOOKIE       11
+#define isLYNXCOOKIE(addr)   !strncasecomp(addr, STR_LYNXCOOKIE, LEN_LYNXCOOKIE)
+
+#define STR_LYNXDIRED        "LYNXDIRED:"
+#define LEN_LYNXDIRED        10
+#define isLYNXDIRED(addr)    !strncasecomp(addr, STR_LYNXDIRED, LEN_LYNXDIRED)
+
+#define STR_LYNXEXEC         "lynxexec:"
+#define LEN_LYNXEXEC         9
+#define isLYNXEXEC(addr)     !strncasecomp(addr, STR_LYNXEXEC, LEN_LYNXEXEC)
+
+#define STR_LYNXDOWNLOAD     "LYNXDOWNLOAD:"
+#define LEN_LYNXDOWNLOAD     13
+#define isLYNXDOWNLOAD(addr) !strncasecomp(addr, STR_LYNXDOWNLOAD, LEN_LYNXDOWNLOAD)
+
+#define STR_LYNXHIST         "LYNXHIST:"
+#define LEN_LYNXHIST         9
+#define isLYNXHIST(addr)     !strncasecomp(addr, STR_LYNXHIST, LEN_LYNXHIST)
+
+#define STR_LYNXKEYMAP       "LYNXKEYMAP:"
+#define LEN_LYNXKEYMAP       11
+#define isLYNXKEYMAP(addr)   !strncasecomp(addr, STR_LYNXKEYMAP, LEN_LYNXKEYMAP)
+
+#define STR_LYNXIMGMAP       "LYNXIMGMAP:"
+#define LEN_LYNXIMGMAP       11
+#define isLYNXIMGMAP(addr)   !strncasecomp(addr, STR_LYNXIMGMAP, LEN_LYNXIMGMAP)
+
+#define STR_LYNXMESSAGES     "LYNXMESSAGES:"
+#define LEN_LYNXMESSAGES     13
+#define isLYNXMESSAGES(addr) !strncasecomp(addr, STR_LYNXMESSAGES, LEN_LYNXMESSAGES)
+
+#define STR_LYNXOPTIONS      "LYNXOPTIONS:"
+#define LEN_LYNXOPTIONS      12
+#define isLYNXOPTIONS(addr)  !strncasecomp(addr, STR_LYNXOPTIONS, LEN_LYNXOPTIONS)
+
+#define STR_LYNXPRINT        "LYNXPRINT:"
+#define LEN_LYNXPRINT        10
+#define isLYNXPRINT(addr)    !strncasecomp(addr, STR_LYNXPRINT, LEN_LYNXPRINT)
+
+#define STR_LYNXPROG         "lynxprog:"
+#define LEN_LYNXPROG         9
+#define isLYNXPROG(addr)     !strncasecomp(addr, STR_LYNXPROG, LEN_LYNXPROG)
+
 /*
  *  For change_sug_filename().
  */
@@ -303,7 +475,7 @@ extern void LYCloselog NOPARAMS;
 #define HIDE_CHMOD 0600
 #define HIDE_UMASK 0077
 
-#if defined(DOSPATH) || defined(WIN_EX) || defined(__CYGWIN__)
+#if defined(DOSPATH) || defined(__CYGWIN__)
 #define TXT_R	"rt"
 #define TXT_W	"wt"
 #define TXT_A	"at+"
diff --git a/src/LYrcFile.c b/src/LYrcFile.c
index 790b4aa8..97179ca8 100644
--- a/src/LYrcFile.c
+++ b/src/LYrcFile.c
@@ -19,7 +19,6 @@
 #endif /* FNAMES_8_3 */
 
 #define MSG_ENABLE_LYNXRC N_("Normally disabled.  See ENABLE_LYNXRC in lynx.cfg\n")
-#define NonNull(string) ((string) != 0 ? (string) : "")
 #define putBool(value) ((value) ? "on" : "off")
 
 PUBLIC Config_Enum tbl_DTD_recovery[] = {
@@ -147,17 +146,21 @@ PUBLIC BOOL LYgetEnum ARGS3(
 {
     Config_Enum *found = 0;
     unsigned len = strlen(name);
+    int match = 0;
 
     if (len != 0) {
 	while (table->name != 0) {
 	    if (!strncasecomp(table->name, name, len)) {
-		if (found != 0)
-		    return FALSE; /* ambiguous, don't use this */
 		found = table;
+		if (!strcasecomp(table->name, name)) {
+		    match = 1;
+		    break;
+		}
+		++match;
 	    }
 	    table++;
 	}
-	if (found != 0) {
+	if (match == 1) {	/* if unambiguous */
 	    *result = found->value;
 	    return TRUE;
 	}
@@ -419,7 +422,7 @@ preferred_language specifies the language in MIME notation (e.g., en,\n\
 fr, may be a comma-separated list in decreasing preference)\n\
 which Lynx will indicate you prefer in requests to http servers.\n\
 If a file in that language is available, the server will send it.\n\
-Otherwise, the server will send the file in it's default language.\n\
+Otherwise, the server will send the file in its default language.\n\
 ")),
     MAYBE_SET(RC_RAW_MODE,              LYRawMode,          MSG_ENABLE_LYNXRC),
 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
diff --git a/src/LYrcFile.h b/src/LYrcFile.h
index 155fd152..b7144243 100644
--- a/src/LYrcFile.h
+++ b/src/LYrcFile.h
@@ -152,6 +152,7 @@
 #define RC_QUIT_DEFAULT_YES             "quit_default_yes"
 #define RC_RAW_MODE                     "raw_mode"
 #define RC_REFERER_WITH_QUERY           "referer_with_query"
+#define RC_REPLAYSECS                   "replaysecs"
 #define RC_REUSE_TEMPFILES              "reuse_tempfiles"
 #define RC_RULE                         "rule"
 #define RC_RULESFILE                    "rulesfile"
diff --git a/src/UCAux.c b/src/UCAux.c
index 51d0be20..ceb14615 100644
--- a/src/UCAux.c
+++ b/src/UCAux.c
@@ -333,10 +333,13 @@ PUBLIC void UCSetBoxChars ARGS5(
     int,	vert_in,
     int,	hori_in)
 {
+#ifndef WIDEC_CURSES
     if (cset >= -1 && LYCharSet_UC[cset].enc == UCT_ENC_UTF8) {
 	*pvert_out = (vert_in ? vert_in : '|');
 	*phori_out = (hori_in ? hori_in : '-');
-    } else {
+    } else
+#endif
+    {
 	*pvert_out = vert_in;
 	*phori_out = hori_in;
     }
diff --git a/src/Xsystem.c b/src/Xsystem.c
index 969f90d5..7746e7f6 100644
--- a/src/Xsystem.c
+++ b/src/Xsystem.c
@@ -1,4 +1,4 @@
-/* @Id: Xsystem.c 1.10 Sun, 01 Apr 2001 17:51:46 -0700 dickey @
+/* @Id: Xsystem.c 1.11 Sun, 06 Oct 2002 17:43:28 -0700 dickey @
  *	like system("cmd") but return with exit code of "cmd"
  *	for Turbo-C/MS-C/LSI-C
  *  This code is in the public domain.
@@ -24,6 +24,9 @@
  * NEAR for ms-c
  *
  */
+#include <LYUtils.h>
+
+#if 0
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -33,6 +36,7 @@
 #ifndef __CYGWIN__
 #include <dos.h>
 #endif
+#endif
 
 #include <LYStrings.h>
 
@@ -161,7 +165,7 @@ csystem(PRO * p, int flag)
     char SW[3];
     int rc;
 
-    if ((cmp = getenv("COMSPEC")) == 0)
+    if ((cmp = LYGetEnv("COMSPEC")) == 0)
 	return -2;
     SW[0] = (char) getswchar();
     SW[1] = 'c';
@@ -348,7 +352,7 @@ prog_go(PRO * p, int flag)
 	return csystem(p, flag);
 
     if (s < p->cmd) {		/* cmd has no PATH nor Drive */
-	ep = getenv("PATH");
+	ep = LYGetEnv("PATH");
 	LYstrncpy(cmdb, p->cmd, sizeof(cmdb) - 1);
 	for (;;) {
 	    if (extp) {		/* has extension */
@@ -398,7 +402,7 @@ tmpf(char *tp)
     char *ev;
     int i;
 
-    if ((ev = getenv("TMP")) != 0) {
+    if ((ev = LYGetEnv("TMP")) != 0) {
 	LYstrncpy(tplate, ev, sizeof(tplate) - 2 - strlen(tp));
 	i = strlen(ev);
 	if (i && ev[i - 1] != '\\' && ev[i - 1] != '/')
@@ -474,9 +478,6 @@ xsystem(char *cmd)
     int rdstdin, rdstdout;
     int rc = 0;
     static char *cmdline = 0;
-#if USECMDLINE
-    char *oldcmdline;
-#endif
 
 #ifdef SH_EX	/* 1997/11/01 (Sat) 10:04:03 add by JH7AYN */
     pif = cmd;
@@ -498,13 +499,10 @@ xsystem(char *cmd)
     psstdin = psstdout = rdstdin = rdstdout = -1;
     while (p) {
 #if USECMDLINE
-	if (!getenv("NOCMDLINE")) {
-	    oldcmdline = cmdline;
+	if (!LYGetEnv("NOCMDLINE")) {
 	    cmdline = xmalloc(strlen(p->cmd) + strlen(p->arg) + 10);
 	    sprintf(cmdline, "CMDLINE=%s %s", p->cmd, p->arg);
 	    putenv(cmdline);
-	    if (oldcmdline)
-		free(oldcmdline);
 	}
 #endif
 	if (p->next)
diff --git a/src/chrtrans/makefile.bcb b/src/chrtrans/makefile.bcb
index 95eb33f7..04b9585b 100644
--- a/src/chrtrans/makefile.bcb
+++ b/src/chrtrans/makefile.bcb
@@ -10,7 +10,7 @@
 # Borland C++ tools
 #
 IMPLIB  = Implib
-BCC32   = Bcc32 +BccW32.cfg 
+BCC32   = Bcc32 +BccW32.cfg
 TLINK32 = TLink32
 TLIB    = TLib
 BRC32   = Brc32
@@ -35,7 +35,7 @@ LNIEAT_dbmakeuctbdexe = -x
 Dep_char = .\makeuctb.exe
 
 char : BccW32.cfg $(Dep_char)
-  echo MakeNode 
+	echo MakeNode
 
 Dep_dbmakeuctbdexe = .\makeuctb.obj
 
@@ -47,8 +47,8 @@ Dep_dbmakeuctbdexe = .\makeuctb.obj
 	$(BCC32) -P- -c $(DEFS) $(INCLUDES) -o$@ makeuctb.c
 
 # Compiler configuration file
-BccW32.cfg : 
-   Copy &&|
+BccW32.cfg :
+	Copy &&|
 -R
 -v
 -vi
diff --git a/src/chrtrans/makefile.msc b/src/chrtrans/makefile.msc
index 409c07c7..a57d93c4 100644
--- a/src/chrtrans/makefile.msc
+++ b/src/chrtrans/makefile.msc
@@ -97,7 +97,7 @@ cp866u_uni.h:		cp866u_uni.tbl		makeuctb.exe
 cp869_uni.h:		cp869_uni.tbl		makeuctb.exe
 def7_uni.h:		def7_uni.tbl		makeuctb.exe
 dmcs_uni.h:		dmcs_uni.tbl		makeuctb.exe
-hp_uni.h:               hp_uni.tbl              makeuctb.exe 
+hp_uni.h:               hp_uni.tbl              makeuctb.exe
 iso01_uni.h:		iso01_uni.tbl		makeuctb.exe
 iso02_uni.h:		iso02_uni.tbl		makeuctb.exe
 iso03_uni.h:		iso03_uni.tbl		makeuctb.exe
diff --git a/src/makefile.in b/src/makefile.in
index 7add67d9..53066c09 100644
--- a/src/makefile.in
+++ b/src/makefile.in
@@ -38,7 +38,7 @@ WAISLIB		= # FIXME: set in parent makefile
 WWWINC		= WWW/Library/Implementation
 WWWLIB		= $(top_builddir)/WWW/Library/Implementation/libwww.a
 
-INTLLIB		= @INTLDIR_MAKE@@INTLLIBS@
+INTLLIB		= @INTLLIBS@
 INTLDIR_CPPFLAGS= @INTLDIR_CPPFLAGS@-I$(top_srcdir)/intl
 
 CPP_OPTS	= $(CPPFLAGS) $(DEFS) $(CHARSET_DEFS) \