about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>1999-02-18 10:30:13 -0500
committerThomas E. Dickey <dickey@invisible-island.net>1999-02-18 10:30:13 -0500
commitc5fef0d4ab035d8fd988270a39ed6f9d0e9b214c (patch)
tree24189287f1876ed78999a0e3722ed26a8f733d05 /src
parent8ce6b560f4fb325be3d34266c54c70eb8668e8e1 (diff)
downloadlynx-snapshots-c5fef0d4ab035d8fd988270a39ed6f9d0e9b214c.tar.gz
snapshot of project "lynx", label v2-8-2dev_17
Diffstat (limited to 'src')
-rw-r--r--src/GridText.c525
-rw-r--r--src/GridText.h6
-rw-r--r--src/HTAlert.c31
-rw-r--r--src/HTForms.h6
-rw-r--r--src/HTML.c10
-rw-r--r--src/LYBookmark.c6
-rw-r--r--src/LYCookie.c462
-rw-r--r--src/LYCookie.h10
-rw-r--r--src/LYEdit.c2
-rw-r--r--src/LYEdit.h2
-rw-r--r--src/LYEditmap.c270
-rw-r--r--src/LYForms.c10
-rw-r--r--src/LYGetFile.c6
-rw-r--r--src/LYGlobalDefs.h5
-rw-r--r--src/LYJump.c2
-rw-r--r--src/LYKeymap.c220
-rw-r--r--src/LYKeymap.h108
-rw-r--r--src/LYLocal.c39
-rw-r--r--src/LYMail.c39
-rw-r--r--src/LYMain.c11
-rw-r--r--src/LYMainLoop.c177
-rw-r--r--src/LYNews.c36
-rw-r--r--src/LYPrint.c6
-rw-r--r--src/LYReadCFG.c47
-rw-r--r--src/LYShowInfo.c4
-rw-r--r--src/LYStrings.c83
-rw-r--r--src/LYStrings.h22
-rw-r--r--src/LYUpload.c2
-rw-r--r--src/LYUtils.c48
-rw-r--r--src/LYrcFile.c42
-rw-r--r--src/UCAuto.c4
-rw-r--r--src/chrtrans/cp866u_uni.tbl8
-rw-r--r--src/chrtrans/iso9945_uni.tbl2
-rw-r--r--src/chrtrans/koi8u_uni.tbl14
-rw-r--r--src/makefile.in2
-rw-r--r--src/structdump.h28
36 files changed, 1640 insertions, 655 deletions
diff --git a/src/GridText.c b/src/GridText.c
index b30102c5..8ddc702e 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -35,6 +35,7 @@
 #include <LYCharSets.h>
 #include <LYCharUtils.h>	/* LYUCTranslateBack... */
 #include <UCMap.h>
+#include <LYEdit.h>
 #ifdef EXP_CHARTRANS_AUTOSWITCH
 #include <UCAuto.h>
 #endif /* EXP_CHARTRANS_AUTOSWITCH */
@@ -130,6 +131,7 @@ typedef struct _line {
 	unsigned	size;		/* Number of characters */
 	BOOL	split_after;		/* Can we split after? */
 	BOOL	bullet;			/* Do we bullet? */
+	BOOL	expansion_line;		/* TEXTAREA edit new line flag */
 #if defined(USE_COLOR_STYLE)
 	HTStyleChange	styles[MAX_STYLES_ON_LINE];
 	int	numstyles;
@@ -153,6 +155,7 @@ typedef struct _TextAnchor {
 	FormInfo *		input_field;	/* Info for form links */
 	BOOL			show_anchor;	/* Show the anchor? */
 	BOOL			inUnderline;	/* context is underlined */
+	BOOL			expansion_anch; /* TEXTAREA edit new anchor */
 	HTChildAnchor *		anchor;
 } TextAnchor;
 
@@ -3947,10 +3950,10 @@ PUBLIC void HText_FormDescNumber ARGS2(
 /*
  *  HTGetLinkInfo returns some link info based on the number.
  *
- *  If want_go is not NULL, caller requests to know a line number for
+ *  If want_go is not 0, caller requests to know a line number for
  *  the link indicated by number.  It will be returned in *go_line, and
  *  *linknum will be set to an index into the links[] array, to use after
- *  the line in *line has been made the new top screen line.
+ *  the line in *go_line has been made the new top screen line.
  *  *hightext and *lname are unchanged. - KW
  *
  *  If want_go is 0 and the number doesn't represent an input field, info
@@ -4112,6 +4115,263 @@ PUBLIC int HTGetLinkInfo ARGS6(
     return(NO);
 }
 
+PRIVATE BOOLEAN same_anchor_or_field ARGS5(
+    int,		numberA,
+    FormInfo *,		formA,
+    int,		numberB,
+    FormInfo *,		formB,
+    BOOLEAN,		ta_same)
+{
+    if (numberA > 0 || numberB > 0) {
+	if (numberA == numberB)
+	    return(YES);
+	else if (!ta_same)
+	    return(NO);
+    }
+    if (formA || formB) {
+	if (formA == formB) {
+	    return(YES);
+	} else if (!ta_same) {
+	    return(NO);
+	} else if (!(formA && formB)) {
+	    return(NO);
+	}
+    } else {
+	return(NO);
+    }
+    if (formA->type != formB->type ||
+	formA->type != F_TEXTAREA_TYPE || formB->type != F_TEXTAREA_TYPE) {
+	return(NO);
+    }
+    if (formA->number != formB->number)
+	return(NO);
+    if (!formA->name || !formB->name)
+	return(YES);
+    return(strcmp(formA->name, formB->name) == 0);
+}
+
+#define same_anchor_as_link(i,a) (i >= 0 && a &&\
+		same_anchor_or_field(links[i].anchor_number,\
+                (links[i].type == WWW_FORM_LINK_TYPE) ? links[i].form : NULL,\
+		a->number,\
+		(a->link_type == INPUT_ANCHOR) ? a->input_field : NULL,\
+		ta_skip))
+#define same_anchors(a1,a2) (a1 && a2 &&\
+		same_anchor_or_field(a1->number,\
+		(a1->link_type == INPUT_ANCHOR) ? a1->input_field : NULL,\
+		a2->number,\
+		(a2->link_type == INPUT_ANCHOR) ? a2->input_field : NULL,\
+		ta_skip))
+
+/*
+ *  HTGetLinkOrFieldStart - moving to previous or next link or form field.
+ *
+ *  On input,
+ *	curlink: current link, as index in links[] array (-1 if none)
+ *	direction: whether to move up or down (or stay where we are)
+ *	ta_skip: if FALSE, input fields belonging to the same textarea are
+ *		 are treated as different fields, as usual;
+ *		 if TRUE, fields of the same textarea are treated as a
+ *		 group for skipping.
+ *  The caller wants a information for positioning on the new link to be
+ *  deposited in *go_line and (if linknum is not NULL) *linknum.
+ *
+ *  On failure (no more links in the requested direction) returns NO
+ *  and doesn't change *go_line or *linknum.  Otherwise, LINK_DO_ARROWUP
+ *  may be returned, and *go_line and *linknum not changed, to indicate that
+ *  the caller should use a normal PREV_LINK or PREV_PAGE mechanism.
+ *  Otherwise:
+ *  The number (0-based counting) for the new top screen line will be returned
+ *  in *go_line, and *linknum will be set to an index into the links[] array,
+ *  to use after the line in *go_line has been made the new top screen
+ *  line. - kw
+ */
+PUBLIC int HTGetLinkOrFieldStart ARGS5(
+	int,		curlink,
+	int *,		go_line,
+	int *,		linknum,
+	int,		direction,
+	BOOLEAN,	ta_skip)
+{
+    TextAnchor *a;
+    int anchors_this_line = 0;
+    int prev_anchor_line = -1, prev_prev_anchor_line = -1;
+
+    struct agroup {
+	TextAnchor *anc;
+	int prev_anchor_line;
+	int anchors_this_line;
+	int anchors_this_group;
+    } previous, current;
+    struct agroup *group_to_go = NULL;
+
+    if (!HTMainText)
+	return(NO);
+
+    previous.anc = current.anc = NULL;
+    previous.prev_anchor_line = current.prev_anchor_line = -1;
+    previous.anchors_this_line = current.anchors_this_line = 0;
+    previous.anchors_this_group = current.anchors_this_group = 0;
+
+    for (a = HTMainText->first_anchor; a; a = a->next) {
+	/*
+	 *  Count anchors, first on current line if there is more
+	 *  than one.  We have to count all links, including form
+	 *  field anchors and others with a->number == 0, because
+	 *  they are or will be included in the links[] array.
+	 *  The exceptions are hidden form fields and anchors with
+	 *  show_anchor not set, because they won't appear in links[]
+	 *  and don't count towards nlinks. - KW
+	 */
+	if ((a->show_anchor) &&
+	    (a->link_type != INPUT_ANCHOR ||
+	     a->input_field->type != F_HIDDEN_TYPE)) {
+	    if (a->line_num == prev_anchor_line) {
+		anchors_this_line++;
+	    } else {
+		/*
+		 *  This anchor is on a different line than the previous one.
+		 *  Remember which was the line number of the previous anchor,
+		 *  for use in screen positioning later. - KW
+		 */
+		anchors_this_line = 1;
+		prev_prev_anchor_line = prev_anchor_line;
+		prev_anchor_line = a->line_num;
+	    }
+
+	    if (!same_anchors(current.anc, a)) {
+		previous.anc = current.anc;
+		previous.prev_anchor_line = current.prev_anchor_line;
+		previous.anchors_this_line = current.anchors_this_line;
+		previous.anchors_this_group = current.anchors_this_group;
+		current.anc = a;
+		current.prev_anchor_line = prev_prev_anchor_line;
+		current.anchors_this_line = anchors_this_line;
+		current.anchors_this_group = 1;
+	    } else {
+		current.anchors_this_group++;
+	    }
+	    if (curlink >= 0) {
+		if (same_anchor_as_link(curlink,a)) {
+		    if (direction == -1) {
+			group_to_go = &previous;
+			break;
+		    } else if (direction == 0) {
+			group_to_go = &current;
+			break;
+		    }
+		} else if (direction > 0 &&
+			   same_anchor_as_link(curlink,previous.anc)) {
+		    group_to_go = &current;
+		    break;
+		}
+	    } else {
+		if (a->line_num >= HTMainText->top_of_screen) {
+		    if (direction < 0) {
+			group_to_go = &previous;
+			break;
+		    } else if (direction == 0) {
+			if (previous.anc) {
+			    group_to_go = &previous;
+			    break;
+			} else {
+			    group_to_go = &current;
+			    break;
+			}
+		    } else {
+			group_to_go = &current;
+			break;
+		    }
+		}
+	    }
+	}
+    }
+    if (!group_to_go && curlink < 0 && direction <= 0) {
+	group_to_go = &current;
+    }
+    if (group_to_go) {
+	a = group_to_go->anc;
+	if (a) {
+	    int max_offset;
+	    /*
+	     *  We know where to go; most of the stuff below is just
+	     *  tweaks to try to position the new screen in a specific
+	     *  way.
+	     *
+	     *  In some cases going to a previous link can be done
+	     *  via the normal LYK_PREV_LINK action, which may give
+	     *  better positioning of the new screen. - kw
+	     */
+	    if (a->line_num < HTMainText->top_of_screen &&
+		a->line_num >= HTMainText->top_of_screen-(display_lines)) {
+		if ((curlink < 0 &&
+		     group_to_go->anchors_this_group == 1) ||
+		    (direction < 0 &&
+		     group_to_go != &current &&
+		     current.anc &&
+		     current.anc->line_num >= HTMainText->top_of_screen &&
+		     group_to_go->anchors_this_group == 1) ||
+		    (a->next &&
+		     a->next->line_num >= HTMainText->top_of_screen)) {
+		    return(LINK_DO_ARROWUP);
+		}
+	    }
+	    /*
+	     *  The fundamental limitation of the current anchors_this_line
+	     *  counter method is that we only can set *linknum to the right
+	     *  index into the future links[] array if the line with our link
+	     *  ends up being the first line with any links (that count) on
+	     *  the new screen.  Subject to that restriction we still have
+	     *  some vertical liberty (sometimes), and try to make the best
+	     *  of it.  It may be a question of taste though. - kw
+	     */
+	    if (a->line_num <= (display_lines)) {
+		max_offset = 0;
+	    } else if (a->line_num < HTMainText->top_of_screen) {
+		int screensback =
+		    (HTMainText->top_of_screen - a->line_num + (display_lines) - 1)
+		    / (display_lines);
+		max_offset = a->line_num - (HTMainText->top_of_screen -
+					    screensback * (display_lines));
+	    } else if (HTMainText->Lines - a->line_num <= (display_lines)) {
+		max_offset = a->line_num - (HTMainText->Lines - (display_lines));
+	    } else if (a->line_num >=
+		       HTMainText->top_of_screen+(display_lines)) {
+		int screensahead =
+		    (a->line_num - HTMainText->top_of_screen) / (display_lines);
+		max_offset = a->line_num - HTMainText->top_of_screen -
+		    screensahead * (display_lines);
+	    } else {
+		max_offset = SEARCH_GOAL_LINE - 1;
+	    }
+
+	    /* Stuff below should remain unchanged if line positioning
+	       is tweaked. - kw */
+	    if (max_offset < 0)
+		max_offset = 0;
+	    else if (max_offset >= display_lines)
+		max_offset = display_lines - 1;
+	    *go_line = a->line_num - max_offset;
+	    if (*go_line <= group_to_go->prev_anchor_line)
+		*go_line = group_to_go->prev_anchor_line + 1;
+
+#if 0
+	    if (*go_line > HTMainText->top_of_screen &&
+		*go_line < HTMainText->top_of_screen+(display_lines) &&
+		HTMainText->top_of_screen+(display_lines) <= a->line_num &&
+		HTMainText->top_of_screen+2*(display_lines) <= HTMainText->Lines)
+		*go_line = HTMainText->top_of_screen+(display_lines);
+#endif
+	    if (*go_line < 0)
+		*go_line = 0;
+	    if (linknum)
+		*linknum = group_to_go->anchors_this_line - 1;
+	    return(LINK_LINE_FOUND);
+	}
+    }
+    return(NO);
+}
+
 /*
  *  This function finds the line indicated by line_num in the
  *  HText structure indicated by text, and searches that line
@@ -8705,11 +8965,11 @@ PUBLIC BOOL HText_AreDifferent ARGS2(
  *  be allowed to expand in the event of a tag width change (eg, 99 -> 100)
  *  as controlled by arg6 (CHOP or NOCHOP).  Arg4 is either (the address
  *  of) a value which must match, in order for the tag to be incremented,
- *  or (the address of) a 0-value, which matches any value, and will cause
+ *  or (the address of) a 0-value, which will match any value, and cause
  *  any valid tag to be incremented.  Arg2 is a pointer to the first/only
- *  Anchor that exists on the line (if any); we may need to adjust their
- *  position(s) on the line.  Arg3 when non-0 indicates the number of new
- *  digits that were added to the 2nd line in a line crossing pair.
+ *  Anchor that exists on the line; we may need to adjust their position(s)
+ *  on the line.  Arg3 when non-0 indicates the number of new digits that
+ *  were added to the 2nd line in a line crossing pair.
  *
  *  All tags fields in a line which individually match an expected new value,
  *  are incremented.  Line crossing [tags] are handled (PITA).
@@ -8747,9 +9007,10 @@ PRIVATE int increment_tagged_htline ARGS6(
     int   pre_n;
     int   fixup = 0;
 
+
     /*
      *  Cleanup for the 2nd half of a line crosser, whose number of tag
-     *  digits grew by some number of places (usually 1, when it does
+     *  digits grew by some number of places (usually 1 when it does
      *  happen, though it *could* be more).  The tag chars were already
      *  rendered into the 2nd line of the pair, but the positioning and
      *  other effects haven't been rippled through any other anchors on
@@ -8767,22 +9028,23 @@ PRIVATE int increment_tagged_htline ARGS6(
 	}
 	fixup  = *lx_val;
 	*lx_val = 0;
-	st_anchor = st_anchor->next;
+	if (st_anchor) st_anchor = st_anchor->next;
     }
 
+
     /*
      *  Walk thru the line looking for tags (ie, "[nnn]" strings).
      */
-    while (*p != '\0') {
-	if (*p != '[') {
-	    *s++ = *p++;
-	    continue;
+    while  (*p != '\0') {
+	if (*p != '[')	{
+	   *s++ = *p++;
+	   continue;
 
 	} else {
 	    *s++ = *p++;
 	    t = p;
 	    n = 0;
-	    valid = TRUE;   /* p = t = byte after ']' */
+	    valid = TRUE;   /* p = t = byte after '[' */
 
 	    /*
 	     *  Make sure there are only digits between "[" and "]".
@@ -8817,12 +9079,12 @@ PRIVATE int increment_tagged_htline ARGS6(
 	     *   string are probably not possible, since little of the actual
 	     *   anchor-associated-text is retained in the TextAnchor or the
 	     *   FormInfo structs.  Fortunately, I think the current method is
-	     *   more than adequate to weed out 99.99% of any possible false
+	     *   more than adequate to weed out 99.999% of any possible false
 	     *   matches, just as it stands.  Caveat emptor.]
 	     */
 	    if ((valid) && (n > 0)) {
 		val = atoi (p);
-		if ((val == *old_val) || (*old_val == 0)) {
+		if ((val == *old_val) || (*old_val == 0)) {  /* 0 matches all */
 		    if (*old_val != 0)
 			(*old_val)++;
 		    val += incr;
@@ -8854,12 +9116,12 @@ PRIVATE int increment_tagged_htline ARGS6(
 		     */
 		    if (new_n -= n) {
 			nxt_anchor = st_anchor;
-			while ((nxt_anchor) 			  &&
+			while ((nxt_anchor)			      &&
 			    (nxt_anchor->line_num == a->line_num)) {
 			    nxt_anchor->line_pos += new_n;
 			    nxt_anchor = nxt_anchor->next;
 			}
-			st_anchor = st_anchor->next;
+			if (st_anchor) st_anchor = st_anchor->next;
 		    }
 		}
 	    }
@@ -8929,8 +9191,8 @@ PRIVATE int increment_tagged_htline ARGS6(
 			*lx_val = new_n - n;
 		    }
 		}
-		break;	/* had an lx'er, so we're done with this line */
-	    }
+	      break;  /* had an lx'er, so we're done with this line */
+	   }
 	}
     }
 
@@ -8958,7 +9220,7 @@ PRIVATE int increment_tagged_htline ARGS6(
  *  --KED  02/01/99
  */
 PUBLIC int HText_ExtEditForm ARGS1(
-	   struct link *,  form_link)
+           struct link *,  form_link)
 {
     struct stat stat_info;
 
@@ -8966,13 +9228,16 @@ PUBLIC int HText_ExtEditForm ARGS1(
     FILE       *fp;
 
     TextAnchor *anchor_ptr;
-    TextAnchor *start_anchor = NULL;
-    TextAnchor *end_anchor   = NULL;
-    BOOLEAN	firstanchor  = TRUE;
-    int 	entry_line   = form_link->anchor_line_num;
-    int 	exit_line    = 0;
-    int 	orig_cnt     = 0;
-    int 	line_cnt     = 1;
+    TextAnchor *start_anchor  = NULL;
+    TextAnchor *end_anchor    = NULL;
+    BOOLEAN	firstanchor   = TRUE;
+
+    char	ed_offset[10] = "\0";
+    int 	start_line    = 0;
+    int 	entry_line    = form_link->anchor_line_num;
+    int 	exit_line     = 0;
+    int 	orig_cnt      = 0;
+    int 	line_cnt      = 1;
 
     FormInfo   *form	 = form_link->form;
     char       *areaname = form->name;
@@ -8991,9 +9256,10 @@ PUBLIC int HText_ExtEditForm ARGS1(
     char       *cp;
     char       *p;
     char       *s;
-    int 	curr_tag;
-    int 	line_adj = 0;
-    int 	tag_adj  = 0;
+    int         curr_tag;
+    int         line_adj = 0;
+    int         tag_adj  = 0;
+    int         newlines = 0;
     int 	len;
     int 	i;
     int 	n;
@@ -9035,8 +9301,9 @@ PUBLIC int HText_ExtEditForm ARGS1(
 	    !strcmp (anchor_ptr->input_field->name, areaname))   {
 
 	    if (firstanchor) {
-		firstanchor = FALSE;
+		firstanchor  = FALSE;
 		start_anchor = anchor_ptr;
+		start_line   = anchor_ptr->line_num;
 	    }
 	    orig_cnt++;
 
@@ -9056,13 +9323,23 @@ PUBLIC int HText_ExtEditForm ARGS1(
     fclose (fp);
 
     CTRACE(tfp, "GridText: TEXTAREA name=|%s| dumped to tempfile\n", areaname);
+    CTRACE(tfp, "GridText: invoking editor (%s) on tempfile\n", editor);
 
     /*
-     *	Go edit the TEXTAREA temp file.
+     *	Go edit the TEXTAREA temp file, with the initial editor line
+     *  corresponding to the TEXTAREA line the cursor is on (if such
+     *  positioning is supported by the editor [as lynx knows it]).
      */
-    HTSprintf0 (&tbuf, "%s %s", editor, ed_temp);
+    if (((entry_line - start_line) > 0) && editor_can_position())
+#ifdef VMS
+       sprintf (ed_offset, "-%d", ((entry_line - start_line) + 1));
+    HTSprintf0 (&tbuf, "%s %s %s", editor, ed_temp, ed_offset);
+#else
+       sprintf (ed_offset, "+%d", ((entry_line - start_line) + 1));
+    HTSprintf0 (&tbuf, "%s %s %s", editor, ed_offset, ed_temp);
+#endif
 
-    LYSystem (tbuf);
+    LYSystem (tbuf);   /* finally the editor is called */
 
 #ifdef UNIX
     /*
@@ -9072,15 +9349,15 @@ PUBLIC int HText_ExtEditForm ARGS1(
     if (stat (tbuf, &stat_info) == 0)
        remove (tbuf);
 #endif
-    free (tbuf);
+    FREE (tbuf);
 
     CTRACE(tfp, "GridText: returned from editor (%s)\n", editor);
 
     /*
-     *	Read back the edited temp file.
+     *	Read back the edited temp file into our buffer.
      */
     if ((stat (ed_temp, &stat_info) < 0)   ||
-	!S_ISREG(stat_info.st_mode)	   ||
+	!S_ISREG(stat_info.st_mode)        ||
 	((size = stat_info.st_size) == 0)) {
 	size = 0;
 	ebuf = (char *) calloc (1, 1);
@@ -9100,9 +9377,6 @@ PUBLIC int HText_ExtEditForm ARGS1(
     while ((size != 0) && (isspace (ebuf[size-1]) || (ebuf[size-1] == '\0')))
 	ebuf[--size] = '\0';
 
-    if (size == 0)
-	ebuf[0] = '\0'; 
-
     /*
      *	Copy each line from the temp file into the corresponding anchor
      *  struct, removing any trailing whitespace, expanding any embedded
@@ -9133,7 +9407,7 @@ PUBLIC int HText_ExtEditForm ARGS1(
 	 *  Whack off trailing whitespace from the line.
 	 */
 	for (i = len, p = line + (len - 1); i != 0; p--, i--) {
-	    if (isspace(*p))
+	    if (isspace (*p))
 		*p = '\0';
 	    else
 		break;
@@ -9171,9 +9445,23 @@ PUBLIC int HText_ExtEditForm ARGS1(
 	     *  we leave any chars above 0x7f alone (ie, no translation is
 	     *  performed ... the assumption being that the charset used in
 	     *  the editor is compatible with the charset rendered by lynx).
+	     *
+	     *  [At some point in time, when/if lynx ever supports multibyte
+	     *   characters internally (eg, UCS-2, UCS-4, UTF-16, etc), this
+	     *   kind of thing may well cause problems.  But then, supporting
+	     *   such char sets will require massive changes in (most) all
+	     *   parts of the lynx code, so until then, we do the rational
+	     *   thing with chars that would otherwise foul the display, if
+	     *   left alone.  If you're implementing multibyte character set
+	     *   support, consider yourself to have been warned.]
 	     */
 	    for (p = line, s = tbuf; *s != '\0'; p++, s++)
-		*p = (*s < ' ') ? SPLAT : *s;
+#ifndef EBCDIC
+		*p = (((unsigned char)*s  < ' ')    ||
+		      ((unsigned char)*s == '\177')) ? SPLAT : *s;
+#else
+	        *p = ((unsigned char)*s  < ' ') ? SPLAT : *s;
+#endif
 	    *p = '\0';
 	}
 
@@ -9198,26 +9486,30 @@ PUBLIC int HText_ExtEditForm ARGS1(
 	     *   floating around in here, as it is.  IMNSHO.]
 	     */
 	    for (htline = HTMainText->last_line->next, i = 0;
-		i != end_anchor->line_num;
-		htline = htline->next, i++);
+		 end_anchor->line_num != i;            i++) {
+		htline = htline->next;
+		if (htline == HTMainText->last_line)
+		    break;
+	    }
 
 	    /*
 	     *  Clone and initialize the structs needed to add a new
 	     *  TEXTAREA anchor.
 	     */
-	    if (((a = (TextAnchor *) calloc (1, sizeof(*a)))	      == 0)  ||
+	    if (((a = (TextAnchor *) calloc (1, sizeof(*a)))          == 0)  ||
 		((f = (FormInfo   *) calloc (1, sizeof(*f)))	      == 0)  ||
 		((l = (HTLine	  *) calloc (1, LINE_SIZE(MAX_LINE))) == 0))
 		outofmem(__FILE__, "HText_ExtEditForm");
 
-	    /*  Init all the fields in the new TextAnchor.  */
-	    a->next	       = end_anchor->next;
-	    a->number	       = end_anchor->number;
-	    a->start	       = end_anchor->start +
-				 end_anchor->input_field->size + 1;
-	    a->line_pos	       = end_anchor->line_pos;
-	    a->extent	       = end_anchor->extent;
-	    a->line_num	       = end_anchor->line_num + 1;
+	    /*  Init all the fields in the new TextAnchor.                 */
+	    /*  [anything "special" needed based on ->show_anchor value ?] */
+	    a->next	        = end_anchor->next;
+	    a->number	        = end_anchor->number;
+	    a->start	        = end_anchor->start +
+				  end_anchor->input_field->size + 1;
+	    a->line_pos	        = end_anchor->line_pos;
+	    a->extent	        = end_anchor->extent;
+	    a->line_num	        = end_anchor->line_num + 1;
 	    StrAllocCopy (a->hightext,  end_anchor->hightext);
 	    StrAllocCopy (a->hightext2, end_anchor->hightext2);
 	    a->hightext2offset  = end_anchor->hightext2offset;
@@ -9225,26 +9517,30 @@ PUBLIC int HText_ExtEditForm ARGS1(
 	    a->input_field      = f;
 	    a->show_anchor      = end_anchor->show_anchor;
 	    a->inUnderline      = end_anchor->inUnderline;
-	    a->anchor		= end_anchor->anchor;
+	    a->expansion_anch   = TRUE;
+	    a->anchor	        = NULL;
 
 	    /*  Just the (seemingly) relevant fields in the new FormInfo.  */
+	    /*  [do we need to do anything "special" based on ->disabled]  */
 	    StrAllocCopy (f->name, end_anchor->input_field->name);
-	    f->number	       = end_anchor->input_field->number;
-	    f->type	       = end_anchor->input_field->type;
+	    f->number	        = end_anchor->input_field->number;
+	    f->type	        = end_anchor->input_field->type;
 	    StrAllocCopy (f->orig_value, "");
-	    f->size	       = end_anchor->input_field->size;
-	    f->maxlength       = end_anchor->input_field->maxlength;
-	    f->no_cache        = end_anchor->input_field->no_cache;
+	    f->size	        = end_anchor->input_field->size;
+	    f->maxlength        = end_anchor->input_field->maxlength;
+	    f->no_cache         = end_anchor->input_field->no_cache;
+	    f->disabled         = end_anchor->input_field->disabled;
 
 	    /*  Init all the fields in the new HTLine (but see the #if).   */
-	    l->next	       = htline->next;
-	    l->prev	       = htline;
-	    l->offset	       = htline->offset;
-	    l->size	       = htline->size;
+	    l->next	        = htline->next;
+	    l->prev	        = htline;
+	    l->offset	        = htline->offset;
+	    l->size	        = htline->size;
 	    l->split_after      = htline->split_after;
-	    l->bullet	       = htline->bullet;
+	    l->bullet	        = htline->bullet;
+	    l->expansion_line   = TRUE;
 #if defined(USE_COLOR_STYLE)
-	    /* dup styles[] if needed [no need in TEXTAREA (?); leave 0's] */
+	   /* dup styles[] if needed [no need in TEXTAREA (?); leave 0's] */
 	    l->numstyles        = htline->numstyles;
 #endif
 	    strcpy (l->data,      htline->data);
@@ -9256,6 +9552,15 @@ PUBLIC int HText_ExtEditForm ARGS1(
 	    }
 
 	    /*
+	     *  If we're at the tail end of the TextAnchor or HTLine list(s),
+	     *  the new node becomes the last node.
+	     */
+	    if (end_anchor == HTMainText->last_anchor)
+		HTMainText->last_anchor = a;
+	    if (htline == HTMainText->last_line)
+		HTMainText->last_line = l;
+
+	    /*
 	     *  Link in the new TextAnchor and make it current; link in
 	     *  the new HTLine.
 	     */
@@ -9264,9 +9569,12 @@ PUBLIC int HText_ExtEditForm ARGS1(
 
 	    htline->next->prev = l;
 	    htline->next = l;
-	    htline = l;
+	    htline = l->next;
+
+	    newlines++;
 	}
 
+
 	/*
 	 *  Finally copy the new line from the edit buffer into the anchor.
 	 */
@@ -9274,22 +9582,25 @@ PUBLIC int HText_ExtEditForm ARGS1(
 
 
 	/*
-	 *  And do the next line, for the next anchor ...
+	 *  Keep track of 1st blank line in any trailing blank lines, for
+	 *  later cursor repositioning.
 	 */
-	lp += len;
-	if (*lp) lp++;
-
 	if (len > 0)
 	    exit_line = 0;
 	else if (exit_line == 0)
 	    exit_line = anchor_ptr->line_num;
 
+	/*
+	 *  And do the next line of edited text, for the next anchor ...
+	 */
+	lp += len;
+	if (*lp) lp++;
+
 	end_anchor = anchor_ptr;
 	anchor_ptr = anchor_ptr->next;
-	curr_tag   = anchor_ptr->number;
 
-	if (htline != NULL)
-	    htline   = htline->next;
+	if (anchor_ptr)
+	   curr_tag = anchor_ptr->number;
 
 	line_cnt++;
     }
@@ -9306,15 +9617,23 @@ PUBLIC int HText_ExtEditForm ARGS1(
      *	[dunno if the char counts really need to be done, or if we're using
      *	 the exactly proper values ... seems to be OK though ...]
      */
-    if ((n = (line_cnt - 1) - orig_cnt) > 0) {
-	i = (end_anchor->input_field->size + 1) * n;
+    if (newlines > 0) {
+
+	CTRACE(tfp, "GridText: adjusting struct's to add %d new lines\n",
+		    newlines);
 
+	i = (end_anchor->input_field->size + 1) * newlines;
+
+	/*
+	 *  [*may* need to bypass bumping ->number if ->input_field->type
+	 *  is of F_HIDDEN_TYPE ... need to investigate further]
+	 */
 	while (anchor_ptr) {
 	    if (keypad_mode == LINKS_AND_FORM_FIELDS_ARE_NUMBERED)
-	       anchor_ptr->number += n;
-	    anchor_ptr->line_num  += n;
+		anchor_ptr->number += newlines;
+	    anchor_ptr->line_num  += newlines;
 	    anchor_ptr->start	  += i;
-	    anchor_ptr		   = anchor_ptr->next;
+	    anchor_ptr 	           = anchor_ptr->next;
 	}
 	anchor_ptr = end_anchor;
 
@@ -9340,39 +9659,61 @@ PUBLIC int HText_ExtEditForm ARGS1(
 	 *
 	 *  Yes, it *can* happen, but in real life, it probably won't be
 	 *  seen very much ...
+	 *
+	 *  [This may also be an artifact of bumping into the right hand
+	 *   screen edge (or RHS margin), since we don't even *think* about
+	 *   relocating an anchor to the following line, when [tag] digits
+	 *   expansion pushes things too far in that direction.]
 	 */
 	if (keypad_mode == LINKS_AND_FORM_FIELDS_ARE_NUMBERED) {
 	    lx = 0;
 	    while (htline != HTMainText->last_line->next) {
+
 		while (anchor_ptr) {
-		    if ((anchor_ptr->number - n) == curr_tag)
+		    if ((anchor_ptr->number - newlines) == curr_tag)
 			break;
 		    else
 			anchor_ptr = anchor_ptr->next;
 		}
-		line_adj = increment_tagged_htline (htline, anchor_ptr, &lx,
-						   &curr_tag, n, NOCHOP);
-		htline->size += line_adj;
-		tag_adj      += line_adj;
+
+		if (anchor_ptr) {
+		    line_adj = increment_tagged_htline (htline,   anchor_ptr,
+							&lx,	&curr_tag,
+							newlines, NOCHOP);
+		    htline->size += line_adj;
+		    tag_adj	 += line_adj;
+
+		} else {
+
+		    break;  /* out of anchors ... we're done */
+		}
+
 		htline = htline->next;
-	   }
+	    }
 	}
 
-	nlinks			       += n;
-	HTMainText->Lines	       += n;
-	HTMainText->last_anchor_number += n;
+	/*
+	 *  Fixup various global variables.
+	 */
+	nlinks			       += newlines;
+	HTMainText->Lines	       += newlines;
+	HTMainText->last_anchor_number += newlines;
 	HTMainText->chars	       += (i + tag_adj);
 
-	if (n) more = TRUE;
+	more = TRUE;
+
+	CTRACE(tfp, "GridText: TextAnchor and HTLine struct's adjusted\n");
     }
 
     CTRACE(tfp, "GridText: struct's adjusted - exiting HText_ExtEditForm()\n");
 
-    free (line);
-    free (ebuf);
-    free (tbuf);
+    FREE (line);
+    FREE (ebuf);
+    FREE (tbuf);
     LYRemoveTemp (ed_temp);
-    free (ed_temp);
+    FREE (ed_temp);
+
+    CTRACE(tfp, "GridText: exiting HText_ExtEditForm()\n");
 
     /*
      *  Return the offset needed to move the cursor from its current
diff --git a/src/GridText.h b/src/GridText.h
index 006c577c..16cca89c 100644
--- a/src/GridText.h
+++ b/src/GridText.h
@@ -149,6 +149,12 @@ extern int HTGetLinkInfo PARAMS((
 	int *		linknum,
 	char **		hightext,
 	char **		lname));
+extern int HTGetLinkOrFieldStart PARAMS((
+	int		curlink,
+	int *		go_line,
+	int *		linknum,
+	int		direction,
+	BOOLEAN		ta_skip));
 extern BOOL HText_getFirstTargetInLine PARAMS((
 	HText *		text,
 	int		line_num,
diff --git a/src/HTAlert.c b/src/HTAlert.c
index dc5626a2..8c041f40 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -197,30 +197,39 @@ PUBLIC BOOL HTLastConfirmCancelled NOARGS
 */
 PUBLIC BOOL HTConfirm ARGS1(CONST char *, Msg)
 {
+    char *msg_yes = gettext("yes");
+    char *msg_no  = gettext("no");
+    int result = -1;
+
     conf_cancelled = NO;
     if (dump_output_immediately) { /* Non-interactive, can't respond */
-	return(NO);
+	result = NO;
     } else {
-	int c;
+	char *msg = NULL;
 
-	_user_message(gettext("%s (y/n) "), Msg);
+	HTSprintf0(&msg, "%s (%c/%c) ", Msg, *msg_yes, *msg_no);
+	_statusline(msg);
+	FREE(msg);
 
-	while (1) {
-	    c = LYgetch();
+	while (result < 0) {
+	    int c = LYgetch();
 #ifdef VMS
 	    if (HadVMSInterrupt) {
 		HadVMSInterrupt = FALSE;
-		c = 'N';
+		c = *msg_no;
 	    }
 #endif /* VMS */
-	    if (TOUPPER(c) == 'Y')
-		return(YES);
-	    if (c == 7 || c == 3) /* remember we had ^G or ^C */
+	    if (c == 7 || c == 3) { /* remember we had ^G or ^C */
 		conf_cancelled = YES;
-	    if (TOUPPER(c) == 'N' || c == 7 || c == 3) /* ^G or ^C cancels */
+		result = NO;
+	    } else if (TOUPPER(c) == TOUPPER(*msg_yes)) {
+		result = YES;
+	    } else if (TOUPPER(c) == TOUPPER(*msg_no)) {
 		return(NO);
+	    }
 	}
     }
+    return (result);
 }
 
 /*	Prompt for answer and get text back.		HTPrompt()
@@ -504,7 +513,7 @@ PUBLIC BOOL HTConfirmCookie ARGS4(
 	HTSprintf(&message, ADVANCED_COOKIE_CONFIRMATION,
 		 server, namelen, name, valuelen, value);
 	_statusline(message);
-	free(message);
+	FREE(message);
     }
     while (1) {
 	if(!LYAcceptAllCookies) {
diff --git a/src/HTForms.h b/src/HTForms.h
index eb0784f2..ff7bc962 100644
--- a/src/HTForms.h
+++ b/src/HTForms.h
@@ -1,4 +1,3 @@
-
 #ifndef HTFORMS_H
 #define HTFORMS_H
 
@@ -92,7 +91,7 @@ typedef struct _FormInfo {
 typedef struct _PerFormInfo
 {
 	int			number;	   /* form number, see GridText.c */
-    /* except for the last two, the followign fields aren't actually used.. */ 
+    /* except for the last two, the followign fields aren't actually used.. */
 	int			disabled;  /* If YES, can't change values */
         struct _PerFormInfo *	next; 	   /* pointer to next form in doc */
         int			nfields;   /* number of fields */
@@ -124,7 +123,8 @@ typedef struct _PerFormInfo
 #define WWW_FORM_LINK_TYPE  1
 #define WWW_LINK_TYPE   2
 #define WWW_INTERN_LINK_TYPE   6 /* can be used as a bitflag... - kw */
-#define LINK_LINE_FOUND	8	/* used in follow_link_number - kw */
+#define LINK_LINE_FOUND	8	/* used in follow_link_number, others - kw */
+#define LINK_DO_ARROWUP	16	/* returned by HTGetLinkOrFieldStart - kw */
 
 /* #define different lynx modes */
 #define NORMAL_LYNX_MODE 1
diff --git a/src/HTML.c b/src/HTML.c
index 377f5ed6..567dd804 100644
--- a/src/HTML.c
+++ b/src/HTML.c
@@ -609,7 +609,7 @@ char class_string[TEMPSTRINGSIZE];
 #endif
 
 #ifdef USE_COLOR_STYLE
-static char *Style_className;
+static char *Style_className = NULL;
 static char myHash[128];
 static int hcode;
 #endif
@@ -2033,6 +2033,8 @@ PRIVATE void HTML_start_element ARGS6(
 	if (!me->style_change)	{
 	    if (HText_LastLineSize(me->text, FALSE)) {
 		HText_appendCharacter(me->text, '\r');
+	    } else {
+		HText_NegateLineOne(me->text);
 	    }
 	} else {
 	    UPDATE_STYLE;
@@ -6839,6 +6841,9 @@ PRIVATE void HTML_free ARGS1(HTStructured *, me)
 	}
 	styles[HTML_PRE]->alignment = HT_LEFT;
     }
+#ifdef USE_COLOR_STYLE
+    FREE(Style_className);
+#endif
     FREE(me->base_href);
     FREE(me->map_address);
     FREE(me->LastOptionValue);
@@ -6925,6 +6930,9 @@ PRIVATE void HTML_abort ARGS2(HTStructured *, me, HTError, e)
 	}
 	styles[HTML_PRE]->alignment = HT_LEFT;
     }
+#ifdef USE_COLOR_STYLE
+    FREE(Style_className);
+#endif
     FREE(me->base_href);
     FREE(me->map_address);
     FREE(me->textarea_name);
diff --git a/src/LYBookmark.c b/src/LYBookmark.c
index 612e5984..8c2b9932 100644
--- a/src/LYBookmark.c
+++ b/src/LYBookmark.c
@@ -34,7 +34,7 @@ show_bookmark_not_defined NOARGS
 	    BOOKMARK_FILE_NOT_DEFINED,
 	    key_for_func(LYK_OPTIONS));
     LYMBM_statusline(string_buffer);
-    free(string_buffer);
+    FREE(string_buffer);
 }
 
 /*
@@ -521,7 +521,7 @@ PUBLIC void remove_bookmark_link ARGS2(
      *	it is writable by the current process.
      *	Changed to copy  1998-04-26 -- gil
      */
-    if (LYCopyFile(newfile, filename_buffer) == 0) 
+    if (LYCopyFile(newfile, filename_buffer) == 0)
 	return;
     HTAlert(BOOKTEMP_COPY_FAIL);
 #else  /* !UNIX */
@@ -731,7 +731,7 @@ draw_bookmark_choices:
 	HTSprintf0(&shead_buffer,
 		MULTIBOOKMARKS_SHEAD_MASK, MBM_current, MBM_screens);
 	addstr(shead_buffer);
-	free(shead_buffer);
+	FREE(shead_buffer);
     } else {
 	addstr(MULTIBOOKMARKS_SHEAD);
     }
diff --git a/src/LYCookie.c b/src/LYCookie.c
index 12c9f260..9020d594 100644
--- a/src/LYCookie.c
+++ b/src/LYCookie.c
@@ -276,99 +276,6 @@ PRIVATE void store_cookie ARGS3(
     if (co == NULL)
 	return;
 
-    if (co->version != 0 || !LYAcceptAllCookies) {
-	/*
-	 * Apply sanity checks.
-	 *
-	 * Section 4.3.2, condition 1:  The value for the Path attribute is
-	 * not a prefix of the request-URI.
-	 */
-	if (strncmp(co->path, path, co->pathlen) != 0) {
-	    CTRACE(tfp, "store_cookie: Rejecting because '%s' is not a prefix of '%s'.\n",
-			co->path, path);
-	    freeCookie(co);
-	    co = NULL;
-	    return;
-	}
-	/*
-	 * The next 4 conditions do NOT apply if the domain is still
-	 * the default of request-host.
-	 */
-	if (strcmp(co->domain, hostname) != 0) {
-	    /*
-	     *  The hostname does not contain a dot.
-	     */
-	    if (strchr(hostname, '.') == NULL) {
-		CTRACE(tfp, "store_cookie: Rejecting because '%s' has no dot.\n",
-			    hostname);
-		freeCookie(co);
-		co = NULL;
-		return;
-	    }
-
-	    /*
-	     *  Section 4.3.2, condition 2: The value for the Domain attribute
-	     *  contains no embedded dots or does not start with a dot.
-	     *  (A dot is embedded if it's neither the first nor last character.)
-	     *  Note that we added a lead dot ourselves if a domain attribute
-	     *  value otherwise qualified. - FM
-	     */
-	    if (co->domain[0] != '.' || co->domain[1] == '\0') {
-		CTRACE(tfp, "store_cookie: Rejecting domain '%s'.\n",
-			    co->domain);
-		freeCookie(co);
-		co = NULL;
-		return;
-	    }
-	    ptr = strchr((co->domain + 1), '.');
-	    if (ptr == NULL || ptr[1] == '\0') {
-		CTRACE(tfp, "store_cookie: Rejecting domain '%s'.\n",
-			    co->domain);
-		freeCookie(co);
-		co = NULL;
-		return;
-	    }
-
-	    /*
-	     *  Section 4.3.2, condition 3: The value for the request-host does
-	     *  not domain-match the Domain attribute.
-	     */
-	    if (!host_matches(hostname, co->domain)) {
-		CTRACE(tfp, "store_cookie: Rejecting domain '%s' for host '%s'.\n",
-			    co->domain, hostname);
-		freeCookie(co);
-		co = NULL;
-		return;
-	    }
-
-	    /*
-	     *  Section 4.3.2, condition 4: The request-host is an HDN (not IP
-	     *  address) and has the form HD, where D is the value of the Domain
-	     *  attribute, and H is a string that contains one or more dots.
-	     */
-	    ptr = ((hostname + strlen(hostname)) - strlen(co->domain));
-	    if (strchr(hostname, '.') < ptr) {
-		if (!LYAcceptAllCookies) {
-		    char *msg = 0;
-		    HTSprintf0(&msg,
-			    INVALID_COOKIE_DOMAIN_CONFIRMATION,
-			    co->domain,
-			    hostname);
-		    if (!HTConfirm(msg)) {
-			CTRACE(tfp, "store_cookie: Rejecting domain '%s' for host '%s'.\n",
-				    co->domain,
-				    hostname);
-			freeCookie(co);
-			co = NULL;
-			FREE(msg);
-			return;
-		    }
-		    FREE(msg);
-		}
-	    }
-	}
-    }
-
     /*
      *	Ensure that the domain list exists.
      */
@@ -387,10 +294,147 @@ PRIVATE void store_cookie ARGS3(
 	de = (domain_entry *)hl->object;
 	if ((de != NULL && de->domain != NULL) &&
 	    !strcmp(co->domain, de->domain)) {
-	    cookie_list = de->cookie_list;
-	    break;
+		cookie_list = de->cookie_list;
+		break;
+	}
+    }
+
+    if(hl == NULL) {
+	de = NULL;
+	cookie_list = NULL;
+    }
+
+    /*
+     * Apply sanity checks.
+     *
+     * Section 4.3.2, condition 1:  The value for the Path attribute is
+     * not a prefix of the request-URI.
+     *
+     * If cookie checking for this domain is set to INVCHECK_LOOSE,
+     * then we want to bypass this check.  The user should be queried
+     * if set to INVCHECK_QUERY.
+     */
+    if (strncmp(co->path, path, co->pathlen) != 0) {
+	if((de != NULL && de->invcheck_bv != INVCHECK_LOOSE)
+	    || de == NULL) {
+		if(de != NULL && de->invcheck_bv == INVCHECK_STRICT) {
+		    CTRACE(tfp, "store_cookie: Rejecting because '%s' is not a prefix of '%s'.\n",
+			co->path, path);
+		    freeCookie(co);
+		    co = NULL;
+		    return;
+		} else if ((de != NULL
+		    && de->invcheck_bv == INVCHECK_QUERY)
+		    || de == NULL) {
+			char *msg = 0;
+			HTSprintf0(&msg,
+			    INVALID_COOKIE_PATH_CONFIRMATION,
+			    co->path, path);
+			if (!HTConfirm(msg)) {
+			    CTRACE(tfp, "store_cookie: Rejecting because '%s' is not a prefix of '%s'.\n",
+				co->path, path);
+			    freeCookie(co);
+			    co = NULL;
+			    FREE(msg);
+			    return;
+			}
+		}
+	}
+    }
+    /*
+     * The next 4 conditions do NOT apply if the domain is still
+     * the default of request-host.
+     */
+    if (strcmp(co->domain, hostname) != 0) {
+	/*
+	 *  The hostname does not contain a dot.
+	 */
+	if (strchr(hostname, '.') == NULL) {
+	    CTRACE(tfp, "store_cookie: Rejecting because '%s' has no dot.\n",
+		    hostname);
+	    freeCookie(co);
+	    co = NULL;
+	    return;
+	}
+
+	/*
+	 *  Section 4.3.2, condition 2: The value for the Domain attribute
+	 *  contains no embedded dots or does not start with a dot.
+	 *  (A dot is embedded if it's neither the first nor last character.)
+	 *  Note that we added a lead dot ourselves if a domain attribute
+	 *  value otherwise qualified. - FM
+	 */
+	if (co->domain[0] != '.' || co->domain[1] == '\0') {
+	    CTRACE(tfp, "store_cookie: Rejecting domain '%s'.\n",
+		    co->domain);
+	    freeCookie(co);
+	    co = NULL;
+	    return;
+	}
+	ptr = strchr((co->domain + 1), '.');
+	if (ptr == NULL || ptr[1] == '\0') {
+	    CTRACE(tfp, "store_cookie: Rejecting domain '%s'.\n",
+		    co->domain);
+	    freeCookie(co);
+	    co = NULL;
+	    return;
+	}
+
+	/*
+	 *  Section 4.3.2, condition 3: The value for the request-host does
+	 *  not domain-match the Domain attribute.
+	 */
+	if (!host_matches(hostname, co->domain)) {
+	    CTRACE(tfp, "store_cookie: Rejecting domain '%s' for host '%s'.\n",
+		    co->domain, hostname);
+	    freeCookie(co);
+	    co = NULL;
+	    return;
+	}
+
+	/*
+	 *  Section 4.3.2, condition 4: The request-host is an HDN (not IP
+	 *  address) and has the form HD, where D is the value of the Domain
+	 *  attribute, and H is a string that contains one or more dots.
+	 *
+	 *  If cookie checking for this domain is set to INVCHECK_LOOSE,
+	 *  then we want to bypass this check.  The user should be queried
+	 *  if set to INVCHECK_QUERY.
+	 */
+	ptr = ((hostname + strlen(hostname)) - strlen(co->domain));
+	if (strchr(hostname, '.') < ptr) {
+		if((de != NULL && de->invcheck_bv != INVCHECK_LOOSE)
+		    || de == NULL) {
+			if(de != NULL && de->invcheck_bv == INVCHECK_STRICT) {
+			    CTRACE(tfp, "store_cookie: Rejecting domain '%s' for host '%s'.\n",
+				co->domain,
+				hostname);
+			    freeCookie(co);
+			    co = NULL;
+			    return;
+			} else if ((de != NULL
+			    && de->invcheck_bv == INVCHECK_QUERY)
+			    || de == NULL) {
+				char *msg = 0;
+				HTSprintf0(&msg,
+				    INVALID_COOKIE_DOMAIN_CONFIRMATION,
+				    co->domain,
+				    hostname);
+				if (!HTConfirm(msg)) {
+				    CTRACE(tfp, "store_cookie: Rejecting domain '%s' for host '%s'.\n",
+					co->domain,
+					hostname);
+				    freeCookie(co);
+				    co = NULL;
+				    FREE(msg);
+				    return;
+				}
+				FREE(msg);
+			}
+		}
 	}
     }
+
     if (hl == NULL) {
 	/*
 	 *	Domain not found; add a new entry for this domain.
@@ -414,7 +458,7 @@ PRIVATE void store_cookie ARGS3(
 	else
 #endif
 	    de->bv = QUERY_USER;
-	de->invcheck_bv = QUERY_USER; /* should this go here? */
+	de->invcheck_bv = INVCHECK_QUERY; /* should this go here? */
 	cookie_list = de->cookie_list = HTList_new();
 	StrAllocCopy(de->domain, co->domain);
 	HTList_addObject(domain_list, de);
@@ -2598,29 +2642,24 @@ Delete_all_cookies_in_domain:
 }
 
 
-/*      cookie_add_acceptlist
-**      ---------------------
-**
-**   Is passed a comma-delimited string of domains to add to the
-**   "always accept" list for cookies.  The domains need to be identical
-**   to the form from which the cookie is received, with or without a
-**   leading ".".  - BJP
+/*      cookie_domain_flag_set
+**      ----------------------
+**      All purpose function to handle setting domain flags for a
+**      comma-delimited list of domains.  cookie_domain_flags handles
+**      invcheck behavior, as well as accept/reject behavior. - BJP
 */
 
-PUBLIC void cookie_add_acceptlist ARGS1(
-	char *, 	acceptstr)
+PUBLIC void cookie_domain_flag_set ARGS2(
+	char *, 	domainstr,
+	int, 	flag)
 {
     domain_entry *de = NULL;
     domain_entry *de2 = NULL;
     HTList *hl = NULL;
-    char **str = (char **)calloc(1, sizeof(acceptstr));
-    char *astr = NULL;
+    char *dstr = NULL;
     char *strsmall = NULL;
     int isexisting = FALSE;
 
-    if (str == NULL)
-	outofmem(__FILE__, "cookie_add_acceptlist");
-
     /*
      * Is this the first domain we're handling?  If so, initialize
      * domain_list.
@@ -2632,11 +2671,9 @@ PUBLIC void cookie_add_acceptlist ARGS1(
 	total_cookies = 0;
     }
 
-    StrAllocCopy(astr, acceptstr);
+    StrAllocCopy(dstr, domainstr);
 
-    *str = astr;
-
-    while ((strsmall = LYstrsep(str, ",")) != 0) {
+    while ((strsmall = LYstrsep(&dstr, ",")) != 0) {
 
 	/*
 	 * Check the list of existing domains to see if this is a
@@ -2659,174 +2696,55 @@ PUBLIC void cookie_add_acceptlist ARGS1(
 	    de = (domain_entry *)calloc(1, sizeof(domain_entry));
 
 	    if (de == NULL)
-		    outofmem(__FILE__, "cookie_add_acceptlist");
-
-	    de->bv = ACCEPT_ALWAYS;
-
-	    StrAllocCopy(de->domain, strsmall);
-	    de->cookie_list = HTList_new();
-	    HTList_addObject(domain_list, de);
-	} else {
-	    de2->bv = ACCEPT_ALWAYS;
-	}
-    }
-
-    FREE(str);
-    FREE(strsmall);
-    FREE(astr);
-}
-
-
-/*      cookie_add_rejectlist
-**      ---------------------
-**
-**   Is passed a comma-delimited string of domains to add to the
-**   "always reject" list for cookies.  The domains need to be identical
-**   to the form from which the cookie is received, with or without a
-**   leading ".".  - BJP
-*/
-
-PUBLIC void cookie_add_rejectlist ARGS1(
-	char *, 	rejectstr)
-{
-    domain_entry *de = NULL;
-    domain_entry *de2 = NULL;
-    HTList *hl = NULL;
-    char **str = (char **)calloc(1, sizeof(rejectstr));
-    char *rstr = NULL;
-    char *strsmall = NULL;
-    int isexisting = FALSE;
-
-    if (str == NULL)
-	outofmem(__FILE__, "cookie_add_rejectlist");
-
-    /*
-     * Is this the first domain we're handling?  If so, initialize
-     * domain_list.
-     */
-
-    if (domain_list == NULL) {
-	atexit(LYCookieJar_free);
-	domain_list = HTList_new();
-	total_cookies = 0;
-    }
-
-    StrAllocCopy(rstr, rejectstr);
-
-    *str = rstr;
-
-    while ((strsmall = LYstrsep(str, ",")) != 0) {
-
-	/*
-	 * Check the list of existing domains to see if this is a
-	 * re-setting of an already existing domains -- if so, just
-	 * change the behavior, if not, create a new domain entry.
-	 */
-
-	for (hl = domain_list; hl != NULL; hl = hl->next) {
-	    de2 = (domain_entry *)hl->object;
-	    if ((de2 != NULL && de2->domain != NULL) &&
-		!strcmp(strsmall, de2->domain)) {
-			isexisting = TRUE;
-			break;
-	    } else {
-		isexisting = FALSE;
+		    outofmem(__FILE__, "cookie_domain_flag_set");
+
+	    switch(flag) {
+		case (FLAG_ACCEPT_ALWAYS): de->bv = ACCEPT_ALWAYS;
+					   de->invcheck_bv = INVCHECK_QUERY;
+					   break;
+		case (FLAG_REJECT_ALWAYS): de->bv = REJECT_ALWAYS;
+					   de->invcheck_bv = INVCHECK_QUERY;
+					   break;
+		case (FLAG_QUERY_USER):    de->bv = QUERY_USER;
+					   de->invcheck_bv = INVCHECK_QUERY;
+					   break;
+		case (FLAG_FROM_FILE):     de->bv = FROM_FILE;
+					   de->invcheck_bv = INVCHECK_QUERY;
+					   break;
+		case (FLAG_INVCHECK_QUERY): de->invcheck_bv = INVCHECK_QUERY;
+					    de->bv = QUERY_USER;
+					    break;
+		case (FLAG_INVCHECK_STRICT): de->invcheck_bv = INVCHECK_STRICT;
+					     de->bv = QUERY_USER;
+					    break;
+		case (FLAG_INVCHECK_LOOSE): de->invcheck_bv = INVCHECK_LOOSE;
+					    de->bv = QUERY_USER;
+					    break;
 	    }
-	}
-
-	if(!isexisting) {
-	    de = (domain_entry *)calloc(1, sizeof(domain_entry));
-
-	    if (de == NULL)
-		    outofmem(__FILE__, "cookie_add_rejectlist");
-
-	    de->bv = REJECT_ALWAYS;
 
 	    StrAllocCopy(de->domain, strsmall);
 	    de->cookie_list = HTList_new();
 	    HTList_addObject(domain_list, de);
 	} else {
-	    de2->bv = REJECT_ALWAYS;
-	}
-    }
-
-    FREE(str);
-    FREE(strsmall);
-    FREE(rstr);
-}
-
-/*      cookie_set_invcheck
-**      -------------------
-**
-**   Is passed a comma-delimited string of domains and a particular
-**   behaviour to set their invcheck_bv to. - BJP
-*/
-
-PUBLIC void cookie_set_invcheck ARGS2(
-	char *, 	domains,
-        invcheck_behaviour,		setting)
-{
-    domain_entry *de = NULL;
-    domain_entry *de2 = NULL;
-    HTList *hl = NULL;
-    char **str = (char **)calloc(1, sizeof(domains));
-    char *dstr = NULL;
-    char *strsmall = NULL;
-    int isexisting = FALSE;
-
-    if (str == NULL)
-	outofmem(__FILE__, "cookie_set_invcheck");
-
-    /*
-     * Is this the first cookie we're handling?  If so, initialize
-     * domain_list.
-     */
-
-    if (domain_list == NULL) {
-	atexit(LYCookieJar_free);
-	domain_list = HTList_new();
-	total_cookies = 0;
-    }
-
-    StrAllocCopy(dstr, domains);
-
-    *str = dstr;
-
-    while ((strsmall = LYstrsep(str, ",")) != 0) {
-
-	/*
-	 * Check the list of existing cookies to see if this is a
-	 * re-setting of an already existing cookie -- if so, just
-	 * change the behavior, if not, create a new domain entry.
-	 */
-	for (hl = domain_list; hl != NULL; hl = hl->next) {
-	    de2 = (domain_entry *)hl->object;
-	    if ((de2 != NULL && de2->domain != NULL)
-	     && !strcmp(strsmall, de2->domain)) {
-		isexisting = TRUE;
-		break;
-	    } else {
-		isexisting = FALSE;
+	    switch(flag) {
+		case (FLAG_ACCEPT_ALWAYS): de2->bv = ACCEPT_ALWAYS;
+					   break;
+		case (FLAG_REJECT_ALWAYS): de2->bv = REJECT_ALWAYS;
+					   break;
+		case (FLAG_QUERY_USER): de2->bv = QUERY_USER;
+					   break;
+		case (FLAG_FROM_FILE): de2->bv = FROM_FILE;
+					   break;
+		case (FLAG_INVCHECK_QUERY): de2->invcheck_bv = INVCHECK_QUERY;
+					   break;
+		case (FLAG_INVCHECK_STRICT): de2->invcheck_bv = INVCHECK_STRICT;
+					   break;
+		case (FLAG_INVCHECK_LOOSE): de2->invcheck_bv = INVCHECK_LOOSE;
+					   break;
 	    }
 	}
-
-	if (!isexisting) {
-	    de = (domain_entry *)calloc(1, sizeof(domain_entry));
-
-	    if (de == NULL)
-		outofmem(__FILE__, "cookie_set_invcheck");
-
-	    de->invcheck_bv = setting;
-
-	    StrAllocCopy(de->domain, strsmall);
-	    de->cookie_list = HTList_new();
-	    HTList_addObject(domain_list, de);
-	} else {
-	    de2->invcheck_bv = setting;
-	}
     }
 
-    FREE(str);
     FREE(strsmall);
     FREE(dstr);
 }
diff --git a/src/LYCookie.h b/src/LYCookie.h
index 6f406287..104e44cc 100644
--- a/src/LYCookie.h
+++ b/src/LYCookie.h
@@ -8,6 +8,13 @@ typedef enum {ACCEPT_ALWAYS, REJECT_ALWAYS, QUERY_USER, FROM_FILE} behaviour;
 typedef enum {INVCHECK_QUERY,
 	      INVCHECK_STRICT,
 	      INVCHECK_LOOSE} invcheck_behaviour;
+typedef enum {FLAG_ACCEPT_ALWAYS,
+	      FLAG_REJECT_ALWAYS,
+	      FLAG_QUERY_USER,
+	      FLAG_FROM_FILE,
+	      FLAG_INVCHECK_QUERY,
+	      FLAG_INVCHECK_STRICT,
+	      FLAG_INVCHECK_LOOSE} cookie_domain_flags;
 
 struct _domain_entry {
     char *	domain;  /* Domain for which these cookies are valid */
@@ -37,5 +44,8 @@ extern void cookie_add_rejectlist PARAMS((
 extern void cookie_set_invcheck PARAMS((
 	char *	 	domains,
         invcheck_behaviour setting));
+extern void cookie_domain_flag_set PARAMS((
+	char * 		domainstr,
+	int 		flag));
 
 #endif /* LYCOOKIES_H */
diff --git a/src/LYEdit.c b/src/LYEdit.c
index acd3cffb..c05156f4 100644
--- a/src/LYEdit.c
+++ b/src/LYEdit.c
@@ -15,7 +15,7 @@
 
 #include <LYLeaks.h>
 
-PRIVATE BOOLEAN editor_can_position NOARGS
+PUBLIC BOOLEAN editor_can_position NOARGS
 {
 #ifdef VMS
     return (strstr(editor, "sedt") || strstr(editor, "SEDT"));
diff --git a/src/LYEdit.h b/src/LYEdit.h
index f8ee515d..3eaa0e73 100644
--- a/src/LYEdit.h
+++ b/src/LYEdit.h
@@ -5,4 +5,6 @@
 
 extern int edit_current_file PARAMS((char *newfile, int cur, int lineno));
 
+extern BOOLEAN editor_can_position NOPARAMS;
+
 #endif /* LYEDIT_H */
diff --git a/src/LYEditmap.c b/src/LYEditmap.c
index e9912a06..d7ebebb7 100644
--- a/src/LYEditmap.c
+++ b/src/LYEditmap.c
@@ -4,13 +4,14 @@
 
 #include <HTUtils.h>
 #include <LYStrings.h>
+#include <LYKeymap.h>		/* only for KEYMAP_SIZE - kw */
 
 PUBLIC int current_lineedit = 0;  /* Index into LYLineEditors[]   */
 
 /*
  * See LYStrings.h for the LYE definitions.
  */
-PRIVATE char DefaultEditBinding[]={
+PRIVATE char DefaultEditBinding[KEYMAP_SIZE-1]={
 
 LYE_NOP,        LYE_BOL,        LYE_DELPW,      LYE_ABORT,
 /* nul          ^A              ^B              ^C      */
@@ -100,17 +101,141 @@ LYE_CHAR,       LYE_CHAR,       LYE_CHAR,       LYE_CHAR,
 LYE_CHAR,       LYE_CHAR,       LYE_CHAR,       LYE_CHAR,
 
 /* 100..10F function key definitions in LYStrings.h */
-LYE_NOP,        LYE_NOP,        LYE_FORW,       LYE_BACK,
+LYE_FORM_PASS,  LYE_FORM_PASS,  LYE_FORW,       LYE_BACK,
 /* UPARROW      DNARROW         RTARROW         LTARROW     */
 
-LYE_NOP,        LYE_NOP,        LYE_BOL,        LYE_EOL,
+LYE_FORM_PASS,  LYE_FORM_PASS,  LYE_BOL,        LYE_EOL,
 /* PGDOWN       PGUP            HOME            END         */
 
+#if (defined(_WINDOWS) || defined(__DJGPP__))
+
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+/* F1 */
+
+#else
+
 LYE_NOP,        LYE_TAB,        LYE_BOL,        LYE_EOL,
 /* F1           Do key          Find key        Select key  */
 
-LYE_NOP,        LYE_DELP,       LYE_NOP,        LYE_NOP,
-/* Insert key   Remove key      MOUSE_KEY       DO_NOTHING  */
+#endif /* _WINDOWS || __DJGPP__ */
+
+LYE_NOP,        LYE_DELP,       LYE_NOP,        LYE_FORM_PASS,
+/* Insert key   Remove key      DO_NOTHING      Back tab */
+
+/* 110..18F */
+#if (defined(_WINDOWS) || defined(__DJGPP__)) && defined(USE_SLANG) && !defined(DJGPP_KEYHANDLER)
+
+LYE_DELP,       LYE_ENTER,      LYE_NOP,        LYE_NOP,
+/* Backspace    Enter */
+
+#else
+
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+
+#endif /* USE_SLANG &&(_WINDOWS || __DJGPP) && !DJGPP_KEYHANDLER */
+
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+/*             MOUSE_KEY  */
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+/* 190..20F */
+
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+/* 210..28F */
+
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+/* 290..293 */
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
 };
 
 /*
@@ -121,9 +246,10 @@ LYE_NOP,        LYE_DELP,       LYE_NOP,        LYE_NOP,
              /*                 ^K=delete-to-EOL,    ^X=delete-to-BOL,    */
              /*                 ^R=delete-prev-word, ^T=delete-next-word, */
              /*                 ^^=upper-case-line,  ^_=lower-case-line   */
+/* Why the difference for tab? - kw */
 
 #ifdef EXP_ALT_BINDINGS
-PRIVATE char BetterEditBinding[]={
+PRIVATE char BetterEditBinding[KEYMAP_SIZE-1]={
 
 LYE_NOP,        LYE_BOL,        LYE_BACK,       LYE_ABORT,
 /* nul          ^A              ^B              ^C      */
@@ -213,17 +339,141 @@ LYE_CHAR,       LYE_CHAR,       LYE_CHAR,       LYE_CHAR,
 LYE_CHAR,       LYE_CHAR,       LYE_CHAR,       LYE_CHAR,
 
 /* 100..10E function key definitions in LYStrings.h */
-LYE_NOP,        LYE_NOP,        LYE_FORW,       LYE_BACK,
+LYE_FORM_PASS,  LYE_FORM_PASS,  LYE_FORW,       LYE_BACK,
 /* UPARROW      DNARROW         RTARROW         LTARROW     */
 
-LYE_NOP,        LYE_NOP,        LYE_BOL,        LYE_EOL,
+LYE_FORM_PASS,  LYE_FORM_PASS,  LYE_BOL,        LYE_EOL,
 /* PGDOWN       PGUP            HOME            END         */
 
+#if (defined(_WINDOWS) || defined(__DJGPP__))
+
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+/* F1 */
+
+#else
+
 LYE_NOP,        LYE_TAB,        LYE_BOL,        LYE_EOL,
 /* F1           Do key          Find key        Select key  */
 
-LYE_NOP,        LYE_DELP,       LYE_NOP,        LYE_NOP,
-/* Insert key   Remove key      MOUSE_KEY       DO_NOTHING  */
+#endif /* _WINDOWS || __DJGPP__ */
+
+LYE_NOP,        LYE_DELP,       LYE_NOP,        LYE_FORM_PASS,
+/* Insert key   Remove key      DO_NOTHING      Back tab */
+
+/* 110..18F */
+#if (defined(_WINDOWS) || defined(__DJGPP__)) && defined(USE_SLANG) && !defined(DJGPP_KEYHANDLER)
+
+LYE_DELP,       LYE_ENTER,      LYE_NOP,        LYE_NOP,
+/* Backspace    Enter */
+
+#else
+
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+
+#endif /* USE_SLANG &&(_WINDOWS || __DJGPP) && !DJGPP_KEYHANDLER */
+
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+/*             MOUSE_KEY  */
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+/* 190..20F */
+
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+/* 210..28F */
+
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
+/* 290..293 */
+LYE_NOP,        LYE_NOP,        LYE_NOP,        LYE_NOP,
 };
 #endif
 
diff --git a/src/LYForms.c b/src/LYForms.c
index 4ba50547..e2addfef 100644
--- a/src/LYForms.c
+++ b/src/LYForms.c
@@ -375,6 +375,8 @@ again:
 	action = EditBinding(ch);
 	if (action == LYE_ENTER)
 	    break;
+	if (action == LYE_FORM_PASS)
+	    break;
 	if (action == LYE_LKCMD) {
 	    _statusline(ENTER_LYNX_COMMAND);
 	    ch = LYgetch();
@@ -399,17 +401,17 @@ again:
 	if (keymap[ch + 1] == LYK_REFRESH)
 	    break;
 	switch (ch) {
+#ifdef NOTDEFINED	/* The first four are mapped to LYE_FORM_PASS now */
 	    case DNARROW:
 	    case UPARROW:
 	    case PGUP:
 	    case PGDOWN:
-#ifdef NOTDEFINED
 	    case HOME:
 	    case END_KEY:
 	    case FIND_KEY:
 	    case SELECT_KEY:
-#endif /* NOTDEFINED */
 		goto breakfor;
+#endif /* NOTDEFINED */
 
 	    /*
 	     *  Left arrrow in column 0 deserves special treatment here,
@@ -456,7 +458,9 @@ again:
 		LYRefreshEdit(&MyEdit);
 	}
     }
+#ifdef NOTDEFINED
 breakfor:
+#endif /* NOTDEFINED */
     if (Edited) {
 	char  *p;
 
@@ -998,7 +1002,7 @@ redraw:
 			    char *msg = 0;
 			    HTSprintf0(&msg, OPTION_ALREADY_CURRENT, (number + 1));
 			    HTUserMsg(msg);
-			    free(msg);
+			    FREE(msg);
 			    if (disabled) {
 				_statusline(FORM_LINK_OPTION_LIST_UNM_MSG);
 			    } else {
diff --git a/src/LYGetFile.c b/src/LYGetFile.c
index 0f55b9b3..a87371ff 100644
--- a/src/LYGetFile.c
+++ b/src/LYGetFile.c
@@ -119,7 +119,7 @@ Try_Redirected_URL:
 			char *msg = 0;
 			HTSprintf0(&msg, PORT_INVALID, (unsigned long)value);
 			HTAlert(msg);
-			free(msg);
+			FREE(msg);
 			FREE(temp);
 			return(NULLFILE);
 		    }
@@ -407,7 +407,7 @@ Try_Redirected_URL:
 				EXECUTION_DISABLED_FOR_FILE,
 				key_for_func(LYK_OPTIONS));
 			HTAlert(buf);
-			free(buf);
+			FREE(buf);
 		     }
 #else /* no exec_links */
 		     HTUserMsg(EXECUTION_NOT_COMPILED);
@@ -1212,7 +1212,7 @@ PUBLIC BOOLEAN exec_ok ARGS3(
 		    BADCHAR_IN_EXEC_LINK,
 		    *cp);
 	    HTAlert(buf);
-	    free(buf);
+	    FREE(buf);
 	    return FALSE;
 	}
     }
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index 613b5045..9b788aaa 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -317,6 +317,11 @@ extern char *LYCookieRejectDomains;     /* domains to reject all cookies */
 extern char *LYCookieStrictCheckDomains; /* domains to check strictly    */
 extern char *LYCookieLooseCheckDomains; /* domains to check loosely      */
 extern char *LYCookieQueryCheckDomains; /* domains to check w/a query    */
+extern char *LYCookieSAcceptDomains;    /* domains to accept all cookies */
+extern char *LYCookieSRejectDomains;    /* domains to reject all cookies */
+extern char *LYCookieSStrictCheckDomains;/* domains to check strictly    */
+extern char *LYCookieSLooseCheckDomains;/* domains to check loosely      */
+extern char *LYCookieSQueryCheckDomains;/* domains to check w/a query    */
 #ifdef EXP_PERSISTENT_COOKIES
 extern BOOLEAN persistent_cookies;
 extern char *LYCookieFile;              /* file to store cookies in      */
diff --git a/src/LYJump.c b/src/LYJump.c
index 5cce7529..e1a4e0c9 100644
--- a/src/LYJump.c
+++ b/src/LYJump.c
@@ -192,7 +192,7 @@ PUBLIC char *LYJump ARGS1(int, key)
 	char *msg = 0;
 	HTSprintf0(&msg, KEY_NOT_MAPPED_TO_JUMP_FILE, key);
 	HTAlert(msg);
-	free(msg);
+	FREE(msg);
 	return NULL;
     }
     if (!jtp->table)
diff --git a/src/LYKeymap.c b/src/LYKeymap.c
index 3800a879..0663a95d 100644
--- a/src/LYKeymap.c
+++ b/src/LYKeymap.c
@@ -46,13 +46,13 @@ unsigned short keymap[KEYMAP_SIZE] = {
 0,
 /* EOF */
 
-0,                  LYK_HOME,       LYK_PREV_PAGE,     0,
+LYK_DO_NOTHING,     LYK_HOME,       LYK_PREV_PAGE,     0,
 /* nul */           /* ^A */        /* ^B */       /* ^C */
 
 LYK_ABORT,          LYK_END,        LYK_NEXT_PAGE,     0,
 /* ^D */            /* ^E */        /* ^F */       /* ^G */
 
-LYK_HISTORY,      LYK_NEXT_LINK,    LYK_ACTIVATE,  LYK_COOKIE_JAR,
+LYK_HISTORY,    LYK_FASTFORW_LINK,  LYK_ACTIVATE,  LYK_COOKIE_JAR,
 /* bs */            /* ht */        /* nl */       /* ^K */
 
 LYK_REFRESH,      LYK_ACTIVATE,     LYK_DOWN_TWO,      0,
@@ -164,9 +164,18 @@ LYK_TAG_LINK,     LYK_PREV_DOC,   LYK_VIEW_BOOKMARK,   0,
 LYK_NOCACHE,            0,          LYK_INTERRUPT,     0,
 /* x */              /* y */          /* z */       /* { */
 
+#if (defined(_WINDOWS) || defined(__DJGPP__))
+
+LYK_PIPE,               0,              0,             0,
+/* | */               /* } */         /* ~ */
+
+#else
+
 LYK_PIPE,               0,              0,          LYK_HISTORY,
 /* | */               /* } */         /* ~ */       /* del */
 
+#endif /* _WINDOWS || __DJGPP__ */
+
 /* 80..9F (illegal ISO-8859-1) 8-bit characters. */
    0,                  0,              0,             0,
    0,                  0,              0,             0,
@@ -203,49 +212,38 @@ LYK_PIPE,               0,              0,          LYK_HISTORY,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
 
-/* 100..10E function key definitions in LYStrings.h */
+/* 100..10F function key definitions in LYStrings.h */
 LYK_PREV_LINK,    LYK_NEXT_LINK,    LYK_ACTIVATE,   LYK_PREV_DOC,
 /* UPARROW */     /* DNARROW */     /* RTARROW */   /* LTARROW */
 
 LYK_NEXT_PAGE,    LYK_PREV_PAGE,    LYK_HOME,       LYK_END,
 /* PGDOWN */      /* PGUP */        /* HOME */      /* END */
 
-#if defined(__DJGPP__) ||  defined(_WINDOWS)
-#ifdef USE_SLANG
-LYK_END,          LYK_HOME,         LYK_PREV_PAGE,     0,
-/* END */ 	  /* HOME */          /* PGUP */       /* B2 Key */
-
-LYK_END,          LYK_NEXT_PAGE,       0,
-/* END */         /* PGDOWN */
+#if (defined(_WINDOWS) || defined(__DJGPP__))
 
+LYK_HELP,              0,              0,             0,
+/* F1*/
 #else
-   0,             LYK_HELP,            0,              0,
-/* F0 */ 	  /* F1 */          /* F2 */        /* F3 */
 
-   0,                  0,              0,
-
-#endif /* USE_SLANG */
-#else
 LYK_HELP,         LYK_ACTIVATE,     LYK_HOME,       LYK_END,
 /* F1*/ 	  /* Do key */      /* Find key */  /* Select key */
 
-LYK_UP_TWO,       LYK_DOWN_TWO,
-/* Insert key */  /* Remove key */
+#endif /* _WINDOWS || __DJGPP__ */
 
-LYK_DO_NOTHING,
-/* DO_NOTHING*/
-#endif /* __DJGPP__ || _WINDOWS */
-/* 10F..18F */
+LYK_UP_TWO,       LYK_DOWN_TWO,     LYK_DO_NOTHING, LYK_FASTBACKW_LINK,
+/* Insert key */  /* Remove key */  /* DO_NOTHING*/ /* Back tab */
 
-   0,
-#if defined(USE_SLANG) && !defined(DJGPP_KEYHANDLER)
+/* 110..18F */
+
+#if (defined(_WINDOWS) || defined(__DJGPP__)) && defined(USE_SLANG) && !defined(DJGPP_KEYHANDLER)
    LYK_HISTORY,        LYK_ACTIVATE,   0,             0,
    /* Backspace */     /* Enter */
 #else
    0,                  0,              0,             0,
-#endif /* USE_SLANG */
-   0,                  0,              0,             0,
+#endif /* USE_SLANG &&(_WINDOWS || __DJGPP) && !DJGPP_KEYHANDLER */
    0,                  0,              0,             0,
+   0,             LYK_DO_NOTHING,      0,             0,
+               /* 0x11d: MOUSE_KEY */
    0,                  0,              0,             0,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
@@ -253,16 +251,12 @@ LYK_DO_NOTHING,
 #ifdef DJGPP_KEYHANDLER
    0,                  LYK_ABORT,      0,             0,
                        /* ALT_X */
-   0,                  0,              0,             0,
-   0,                  0,              0,             0,
-   0,                  0,              0,             LYK_HELP,
-                                                      /* F1 */
 #else
    0,                  0,              0,             0,
+#endif /* DJGPP_KEYHANDLER */
    0,                  0,              0,             0,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
-#endif /* DJGPP_KEYHANDLER */
    0,                  0,              0,             0,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
@@ -296,17 +290,27 @@ LYK_DO_NOTHING,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
+#if (defined(_WINDOWS) || defined(__DJGPP__)) && !defined(USE_SLANG) /* PDCurses */
    LYK_ABORT,          0,              0,             0,
    /* ALT_X */
    0,                  0,              0,             0,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
-   0,                  0,              0,           LYK_ACTIVATE,
-                                                    /* KP_ENTER */
+   0,                  0,              LYK_WHEREIS,   LYK_ACTIVATE,
+                                       /* KP_SLASH    KP_ENTER */
    0,                  0,              0,           LYK_IMAGE_TOGGLE,
                                                     /* KP_* */
    LYK_PREV_PAGE,      LYK_NEXT_PAGE,  0,             0,
    /* KP_- */          /* KP_+ */
+#else
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+#endif /* (_WINDOWS || __DJGPP__) && !USE_SLANG */
    0,                  0,              0,             0,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
@@ -318,12 +322,7 @@ LYK_DO_NOTHING,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
-#if defined(USE_SLANG) && !defined(DJGPP_KEYHANDLER)
-   0,                  LYK_HELP,       0,             0,
-                       /* F1 */
-#else
    0,                  0,              0,             0,
-#endif /* USE_SLANG */
    0,                  0,              0,             0,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
@@ -509,7 +508,7 @@ LYK_TAG_LINK,      LYK_UPLOAD,         0,             0,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
 
-/* 100..10E function key definitions in LYStrings.h */
+/* 100..10F function key definitions in LYStrings.h */
    0,                   0,             0,              0,
 /* UPARROW */     /* DNARROW */     /* RTARROW */   /* LTARROW */
 
@@ -519,11 +518,113 @@ LYK_TAG_LINK,      LYK_UPLOAD,         0,             0,
    0,                  0,              0,              0,
 /* F1*/ 	  /* Do key */      /* Find key */  /* Select key */
 
-   0,                  0,
-/* Insert key */  /* Remove key */
+   0,                  0,           LYK_DO_NOTHING,    0,
+/* Insert key */  /* Remove key */  /* DO_NOTHING */ /* Back tab */
+
+/* 110..18F */
+
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+/* 190..20F */
+
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+/* 210..28F */
 
-LYK_DO_NOTHING,
-/* DO_NOTHING*/
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   0,                  0,              0,             0,
+   /* 290...293 */
+   0,                  0,              0,             0,
 };
 #endif /* DIRED_SUPPORT && OK_OVERRIDE */
 
@@ -558,6 +659,8 @@ PRIVATE struct rmap revmap[] = {
 { "END",		"go to the end of the current document" },
 { "PREV_LINK",		"make the previous link current" },
 { "NEXT_LINK",		"make the next link current" },
+{ "FASTBACKW_LINK",	"previous link or text area, only stops on links" },
+{ "FASTFORW_LINK",	"next link or text area, only stops on links" },
 { "UP_LINK",		"move up the page to a previous link" },
 { "DOWN_LINK",		"move down the page to another link" },
 { "RIGHT_LINK",		"move right to another link" },
@@ -570,7 +673,7 @@ PRIVATE struct rmap revmap[] = {
 { "HELP",		"display help on using the browser" },
 { "INDEX",		"display an index of potentially useful documents" },
 { "NOCACHE",		"force submission of form or link with no-cache" },
-{ "INTERRUPT",		"interrupt network transmission" },
+{ "INTERRUPT",		"interrupt network connection or transmission" },
 { "MAIN_MENU",		"return to the first screen (home page)" },
 { "OPTIONS",		"display and change option settings" },
 { "INDEX_SEARCH",	"allow searching of an index" },
@@ -641,7 +744,12 @@ PRIVATE CONST char *funckey[] = {
   "Find key",
   "Select key",
   "Insert key",
-  "Remove key"
+  "Remove key",
+  "(DO_NOTHING)",		/* should normally not appear in list */
+  "Back Tab",
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  "mouse pseudo key",		/* normally not mapped to keymap[] action? */
 };
 
 PRIVATE char *pretty ARGS1 (int, c)
@@ -649,22 +757,23 @@ PRIVATE char *pretty ARGS1 (int, c)
 	static char buf[30];
 
 	if (c == '\t')
-		sprintf(buf, "&lt;tab&gt;       ");
+		sprintf(buf, "&lt;tab&gt;      ");
 	else if (c == '\r')
-		sprintf(buf, "&lt;return&gt;    ");
+		sprintf(buf, "&lt;return&gt;   ");
 	else if (c == ' ')
-		sprintf(buf, "&lt;space&gt;     ");
+		sprintf(buf, "&lt;space&gt;    ");
 	else if (c == '<')
-		sprintf(buf, "&lt;           ");
+		sprintf(buf, "&lt;          ");
 	else if (c == '>')
-		sprintf(buf, "&gt;           ");
+		sprintf(buf, "&gt;          ");
 	else if (c == 0177)
-		sprintf(buf, "&lt;delete&gt;    ");
+		sprintf(buf, "&lt;delete&gt;   ");
 	else if (c > ' ' && c <= 0377)
 		sprintf(buf, "%c", c);
 	else if (c < ' ')
 		sprintf(buf, "^%c", c|0100);
-	else if (c >= 0400 && (c - 0400) < (int) TABLESIZE(funckey))
+	else if (c >= 0400 && (c - 0400) < (int) TABLESIZE(funckey)
+		 && funckey[c-0400])
 		sprintf(buf, "%s", funckey[c-0400]);
 	else if (c >= 0400)
 		sprintf(buf, "%#x", c);
@@ -687,7 +796,7 @@ PRIVATE char * format_binding ARGS2(
      && revmap[the_key].name != 0
      && revmap[the_key].doc != 0
      && (formatted = pretty(i-1)) != 0) {
-	HTSprintf0(&buf, "%-12s%-14s%s\n", formatted,
+	HTSprintf0(&buf, "%-11s %-13s %s\n", formatted,
 		revmap[the_key].name,
 		revmap[the_key].doc);
 	return buf;
@@ -755,9 +864,12 @@ PRIVATE int LYLoadKeymap ARGS4 (
     for (i = 1; i < KEYMAP_SIZE; i++) {
 	/*
 	 *  LYK_PIPE not implemented yet.
+	 *
+	 *  Don't show CHANGE_LINK if mouse not enabled.
 	 */
 	if ((i >= 0400 || i <= ' ' || !isalpha(i-1)) &&
-	    strcmp(revmap[keymap[i]].name, "PIPE")) {
+	    strcmp(revmap[keymap[i]].name, "PIPE") &&
+	    (LYUseMouse || strcmp(revmap[keymap[i]].name, "CHANGE_LINK"))) {
 	    print_binding(target, i);
 	}
     }
diff --git a/src/LYKeymap.h b/src/LYKeymap.h
index 12736985..044de878 100644
--- a/src/LYKeymap.h
+++ b/src/LYKeymap.h
@@ -56,65 +56,67 @@ extern unsigned short key_override[];
 #define       LYK_END           23
 #define       LYK_PREV_LINK     24
 #define       LYK_NEXT_LINK     25
-#define       LYK_UP_LINK       26
-#define       LYK_DOWN_LINK     27
-#define       LYK_RIGHT_LINK    28
-#define       LYK_LEFT_LINK     29
-#define       LYK_HISTORY       30
-#define       LYK_PREV_DOC      31
-#define       LYK_ACTIVATE      32
-#define       LYK_GOTO          33
-#define       LYK_ECGOTO        34
-#define       LYK_HELP          35
-#define       LYK_INDEX         36
-#define       LYK_NOCACHE       37
-#define       LYK_INTERRUPT     38
-#define       LYK_MAIN_MENU     39
-#define       LYK_OPTIONS       40
-#define       LYK_INDEX_SEARCH  41
-#define       LYK_WHEREIS       42
-#define       LYK_NEXT          43
-#define       LYK_COMMENT       44
-#define       LYK_EDIT          45
-#define       LYK_INFO          46
-#define       LYK_PRINT         47
-#define       LYK_ADD_BOOKMARK  48
-#define       LYK_DEL_BOOKMARK  49
-#define       LYK_VIEW_BOOKMARK 50
-#define       LYK_VLINKS        51
-#define       LYK_SHELL         52
-#define       LYK_DOWNLOAD      53
-#define       LYK_TRACE_TOGGLE  54
-#define       LYK_TRACE_LOG     55
-#define       LYK_IMAGE_TOGGLE  56
-#define       LYK_INLINE_TOGGLE 57
-#define       LYK_HEAD          58
-#define       LYK_DO_NOTHING    59
-#define       LYK_TOGGLE_HELP   60
-#define       LYK_JUMP          61
-#define       LYK_KEYMAP        62
-#define       LYK_LIST          63
-#define       LYK_TOOLBAR       64
-#define       LYK_HISTORICAL    65
-#define       LYK_MINIMAL       66
-#define       LYK_SOFT_DQUOTES  67
-#define       LYK_RAW_TOGGLE    68
-#define       LYK_COOKIE_JAR    69
-#define       LYK_F_LINK_NUM    70
-#define       LYK_CLEAR_AUTH    71
-#define       LYK_SWITCH_DTD    72
-#define       LYK_ELGOTO        73
-#define       LYK_CHANGE_LINK   74
-#define	      LYK_EDIT_TEXTAREA 75
+#define       LYK_FASTBACKW_LINK 26
+#define       LYK_FASTFORW_LINK 27
+#define       LYK_UP_LINK       28
+#define       LYK_DOWN_LINK     29
+#define       LYK_RIGHT_LINK    30
+#define       LYK_LEFT_LINK     31
+#define       LYK_HISTORY       32
+#define       LYK_PREV_DOC      33
+#define       LYK_ACTIVATE      34
+#define       LYK_GOTO          35
+#define       LYK_ECGOTO        36
+#define       LYK_HELP          37
+#define       LYK_INDEX         38
+#define       LYK_NOCACHE       39
+#define       LYK_INTERRUPT     40
+#define       LYK_MAIN_MENU     41
+#define       LYK_OPTIONS       42
+#define       LYK_INDEX_SEARCH  43
+#define       LYK_WHEREIS       44
+#define       LYK_NEXT          45
+#define       LYK_COMMENT       46
+#define       LYK_EDIT          47
+#define       LYK_INFO          48
+#define       LYK_PRINT         49
+#define       LYK_ADD_BOOKMARK  50
+#define       LYK_DEL_BOOKMARK  51
+#define       LYK_VIEW_BOOKMARK 52
+#define       LYK_VLINKS        53
+#define       LYK_SHELL         54
+#define       LYK_DOWNLOAD      55
+#define       LYK_TRACE_TOGGLE  56
+#define       LYK_TRACE_LOG     57
+#define       LYK_IMAGE_TOGGLE  58
+#define       LYK_INLINE_TOGGLE 59
+#define       LYK_HEAD          60
+#define       LYK_DO_NOTHING    61
+#define       LYK_TOGGLE_HELP   62
+#define       LYK_JUMP          63
+#define       LYK_KEYMAP        64
+#define       LYK_LIST          65
+#define       LYK_TOOLBAR       66
+#define       LYK_HISTORICAL    67
+#define       LYK_MINIMAL       68
+#define       LYK_SOFT_DQUOTES  69
+#define       LYK_RAW_TOGGLE    70
+#define       LYK_COOKIE_JAR    71
+#define       LYK_F_LINK_NUM    72
+#define       LYK_CLEAR_AUTH    73
+#define       LYK_SWITCH_DTD    74
+#define       LYK_ELGOTO        75
+#define       LYK_CHANGE_LINK   76
+#define       LYK_EDIT_TEXTAREA 77
 
 #ifdef USE_EXTERNALS
-#define       LYK_EXTERN        76
+#define       LYK_EXTERN        78
 #if defined(VMS) || defined(DIRED_SUPPORT)
-#define       LYK_DIRED_MENU    77
+#define       LYK_DIRED_MENU    79
 #endif /* VMS || DIRED_SUPPORT */
 #else  /* USE_EXTERNALS */
 #if defined(VMS) || defined(DIRED_SUPPORT)
-#define       LYK_DIRED_MENU    76
+#define       LYK_DIRED_MENU    78
 #endif /* VMS || DIRED_SUPPORT */
 #endif /* !defined(USE_EXTERNALS) */
 
diff --git a/src/LYLocal.c b/src/LYLocal.c
index 8d0c2aba..5bc34d36 100644
--- a/src/LYLocal.c
+++ b/src/LYLocal.c
@@ -285,11 +285,11 @@ PRIVATE BOOLEAN ok_localname ARGS2(char*, dst, char*, src)
 
     if (!ok_stat(s, &dir_info)
      || !ok_file_or_dir(&dir_info)) {
-	free(s);
+	FREE(s);
 	return FALSE;
     }
     strcpy(dst, s);
-    free(s);
+    FREE(s);
     return TRUE;
 }
 
@@ -465,7 +465,7 @@ PRIVATE BOOLEAN modify_tagged ARGS1(
 	    cp = HTfullURL_toFile(cp);
 	    StrAllocCopy(savepath, cp);
 	}
-	free(cp);
+	FREE(cp);
 
 	if (!ok_stat(savepath, &dir_info)) {
 	    FREE(savepath);
@@ -713,7 +713,7 @@ PUBLIC BOOLEAN local_modify ARGS2(
     if (!HTList_isEmpty(tagged)) {
 	cp = HTpartURL_toFile(doc->address);
 	strcpy(testpath, cp);
-	free(cp);
+	FREE(cp);
 
 	count = modify_tagged(testpath);
 
@@ -745,7 +745,7 @@ PUBLIC BOOLEAN local_modify ARGS2(
     if (strchr("NLP", ans) != NULL) {
 	cp = HTfullURL_toFile(links[doc->link].lname);
 	strcpy(testpath, cp);
-	free(cp);
+	FREE(cp);
 
 	if (ans == 'N') {
 	    return(modify_name(testpath));
@@ -878,7 +878,7 @@ PUBLIC BOOLEAN local_create ARGS1(
 
     cp = HTfullURL_toFile(doc->address);
     strcpy(testpath,cp);
-    free(cp);
+    FREE(cp);
 
     if (ans == 'F') {
 	return(create_file(testpath));
@@ -895,7 +895,6 @@ PUBLIC BOOLEAN local_create ARGS1(
 PRIVATE BOOLEAN remove_single ARGS1(
 	char *, 	testpath)
 {
-    int c;
     int code = 0;
     char *cp;
     char *tmpbuf = 0;
@@ -919,23 +918,23 @@ PRIVATE BOOLEAN remove_single ARGS1(
 	/*** Course, it's probably broken for screen sizes other 80, too     ***/
 	if (strlen(cp) < 37) {
 	    HTSprintf0(&tmpbuf,
-		       gettext("Remove '%s' and all of its contents (y or n): "), cp);
+		       gettext("Remove '%s' and all of its contents: "), cp);
 	} else {
 	    HTSprintf0(&tmpbuf,
-		       gettext("Remove directory and all of its contents (y or n): "));
+		       gettext("Remove directory and all of its contents: "));
 	}
     } else if (S_ISREG(dir_info.st_mode)) {
 	if (strlen(cp) < 60) {
-	    HTSprintf0(&tmpbuf, gettext("Remove file '%s' (y or n): "), cp);
+	    HTSprintf0(&tmpbuf, gettext("Remove file '%s': "), cp);
 	} else {
-	    HTSprintf0(&tmpbuf, gettext("Remove file (y or n): "));
+	    HTSprintf0(&tmpbuf, gettext("Remove file: "));
 	}
 #ifdef S_IFLNK
     } else if (S_ISLNK(dir_info.st_mode)) {
 	if (strlen(cp) < 50) {
-	    HTSprintf0(&tmpbuf, gettext("Remove symbolic link '%s' (y or n): "), cp);
+	    HTSprintf0(&tmpbuf, gettext("Remove symbolic link '%s': "), cp);
 	} else {
-	    HTSprintf0(&tmpbuf, gettext("Remove symbolic link (y or n): "));
+	    HTSprintf0(&tmpbuf, gettext("Remove symbolic link: "));
 	}
 #endif
     } else {
@@ -943,10 +942,8 @@ PRIVATE BOOLEAN remove_single ARGS1(
 	FREE(tmpbuf);
 	return 0;
     }
-    _statusline(tmpbuf);
 
-    c = LYgetch();
-    if (TOUPPER(c) == 'Y') {
+    if (HTConfirm(tmpbuf) == YES) {
 	HTSprintf0(&tmpbuf,"remove %s",testpath);
 	args[0] = "rm";
 	args[1] = "-rf";
@@ -982,7 +979,7 @@ PUBLIC BOOLEAN local_remove ARGS1(
     if (is_url(cp) == FILE_URL_TYPE) {
 	tp = HTfullURL_toFile(cp);
 	strcpy(testpath, tp);
-	free(tp);
+	FREE(tp);
 
 	if ((i = strlen(testpath)) && testpath[i - 1] == '/')
 	    testpath[(i - 1)] = '\0';
@@ -1049,7 +1046,7 @@ PRIVATE BOOLEAN permit_location ARGS3(
 
 	cp = HTfullURL_toFile(strip_trailing_slash(srcpath));
 	strcpy(local_src, cp);
-	free(cp);
+	FREE(cp);
 
 	/*
 	 *  A couple of sanity tests.
@@ -1183,7 +1180,7 @@ PRIVATE BOOLEAN permit_location ARGS3(
 		return(0);
 
 	strcpy(tmpdst, destpath);	/* operate only on filename */
-	free(destpath);
+	FREE(destpath);
 	destpath = tmpdst;
 
 	/*
@@ -1622,7 +1619,7 @@ PUBLIC int dired_options ARGS2(
 	cp = HTfullURL_toFile(links[doc->link].lname);
 	strcpy(path, cp);
 	LYTrimPathSep(path);
-	free(cp);
+	FREE(cp);
 
 	if (!ok_lstat(path, &dir_info)) {
 	    LYCloseTempFP(fp0);
@@ -1838,7 +1835,7 @@ PUBLIC BOOLEAN local_install ARGS3(
 	    int err;
 	    args[src] = HTfullURL_toFile(name);
 	    err = (LYExecv(INSTALL_PATH, args, tmpbuf) <= 0);
-	    free(args[src]);
+	    FREE(args[src]);
 	    if (err)
 		return ((count == 0) ? -1 : count);
 	    count++;
diff --git a/src/LYMail.c b/src/LYMail.c
index af4b2a6d..c2b13b49 100644
--- a/src/LYMail.c
+++ b/src/LYMail.c
@@ -1552,15 +1552,9 @@ PUBLIC void reply_by_mail ARGS4(
 	     */
 	    BOOLEAN is_preparsed = (LYPreparsedSource &&
 				    HTisDocumentSource());
-	    if (is_preparsed)
-		_statusline(INC_PREPARSED_MSG_PROMPT);
-	    else
-		_statusline(INC_ORIG_MSG_PROMPT);
-	    c = 0;
-	    while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
-		   !term_letter && c != 7   && c != 3)
-		c = LYgetch();
-	    if (TOUPPER(c) == 'Y') {
+	    if (HTConfirm(is_preparsed
+	    	? INC_PREPARSED_MSG_PROMPT
+		: INC_ORIG_MSG_PROMPT) == YES) {
 		/*
 		 *  The 1 will add the reply "> " in front of every line.
 		 */
@@ -1676,29 +1670,26 @@ PUBLIC void reply_by_mail ARGS4(
     signal(SIGINT, SIG_IGN);
 #endif /* !VMS */
     LYStatusLine = (LYlines - 1);
-    if (body)
-	_statusline(SEND_MESSAGE_PROMPT);
-    else
-	_statusline(SEND_COMMENT_PROMPT);
+    c = HTConfirm (body ? SEND_MESSAGE_PROMPT : SEND_COMMENT_PROMPT);
     LYStatusLine = -1;
-    c = 0;
-    while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
-	   !term_letter && c != 7   && c != 3)
-	c = LYgetch();
-    if (TOUPPER(c) != 'Y') {
+    if (c != YES) {
 	clear();  /* clear the screen */
 	goto cleanup;
     }
     if ((body == NULL && LynxSigFile != NULL) &&
 	(fp = fopen(LynxSigFile, "r")) != NULL) {
 	LYStatusLine = (LYlines - 1);
-	_user_message(APPEND_SIG_FILE, LynxSigFile);
-	c = 0;
+	if (term_letter) {
+	    _user_message(APPEND_SIG_FILE, LynxSigFile);
+	    c = 0;
+	} else {
+	    char *msg = NULL;
+	    HTSprintf0(&msg, APPEND_SIG_FILE, LynxSigFile);
+	    c = HTConfirm(msg);
+	    FREE(msg);
+	}
 	LYStatusLine = -1;
-	while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
-	       !term_letter && c != 7	&& c != 3)
-	    c = LYgetch();
-	if (TOUPPER(c) == 'Y') {
+	if (c == YES) {
 	    if ((fd = fopen(my_tmpfile, "a")) != NULL) {
 		fputs("-- \n", fd);
 		while (fgets(user_input, sizeof(user_input), fp) != NULL) {
diff --git a/src/LYMain.c b/src/LYMain.c
index 4bed8652..6db448a7 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -344,6 +344,11 @@ PUBLIC char *LYCookieRejectDomains = NULL; /* domains to reject all cookies */
 PUBLIC char *LYCookieStrictCheckDomains = NULL; /* check strictly  */
 PUBLIC char *LYCookieLooseCheckDomains = NULL;  /* check loosely   */
 PUBLIC char *LYCookieQueryCheckDomains = NULL;  /* check w/a query */
+PUBLIC char *LYCookieSAcceptDomains = NULL; /* domains to accept all cookies */
+PUBLIC char *LYCookieSRejectDomains = NULL; /* domains to reject all cookies */
+PUBLIC char *LYCookieSStrictCheckDomains = NULL; /* check strictly  */
+PUBLIC char *LYCookieSLooseCheckDomains = NULL;  /* check loosely   */
+PUBLIC char *LYCookieSQueryCheckDomains = NULL;  /* check w/a query */
 #ifdef EXP_PERSISTENT_COOKIES
 BOOLEAN persistent_cookies = TRUE;
 PUBLIC char *LYCookieFile = NULL;          /* default cookie file */
@@ -466,6 +471,11 @@ PRIVATE void free_lynx_globals NOARGS
 #ifdef EXP_PERSISTENT_COOKIES
     FREE(LYCookieFile);
 #endif
+    FREE(LYCookieAcceptDomains);
+    FREE(LYCookieRejectDomains);
+    FREE(LYCookieLooseCheckDomains);
+    FREE(LYCookieStrictCheckDomains);
+    FREE(LYCookieQueryCheckDomains);
     FREE(LYUserAgent);
     FREE(LYUserAgentDefault);
     FREE(LYHostName);
@@ -491,6 +501,7 @@ PRIVATE void free_lynx_globals NOARGS
     FREE(URLDomainSuffixes);
     FREE(XLoadImageCommand);
     FREE(lynx_version_putenv_command);
+    FREE(lynx_temp_space);
     FREE(LYTraceLogPath);
     FREE(lynx_cfg_file);
 #if defined(USE_HASH)
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index 0d68c81d..a4ad942e 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -68,7 +68,7 @@ PRIVATE int are_phys_different PARAMS((document *doc1, document *doc2));
 #endif
 
 #define FASTTAB
-#ifdef FASTTAB
+
 PRIVATE int sametext ARGS2(
 	char *, 	een,
 	char *, 	twee)
@@ -77,7 +77,6 @@ PRIVATE int sametext ARGS2(
 	return (strcmp(een, twee) == 0);
     return TRUE;
 }
-#endif /* FASTTAB */
 
 PUBLIC	HTList * Goto_URLs = NULL;  /* List of Goto URLs */
 
@@ -2408,6 +2407,176 @@ new_cmd:  /*
 	    }
 	    break;
 
+	case LYK_FASTFORW_LINK:
+	{
+	    int samepage = 0, nextlink = curdoc.link;
+	    if (nlinks > 1) {
+
+		/*
+		 *  If in textarea, move to first link or field
+		 *  after it if there is one on this screen. - kw
+		 */
+		if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
+		    links[curdoc.link].form->type == F_TEXTAREA_TYPE) {
+		    int thisgroup = links[curdoc.link].form->number;
+		    char *thisname = links[curdoc.link].form->name;
+
+		    if (curdoc.link < nlinks-1 &&
+			!(links[nlinks-1].type == WWW_FORM_LINK_TYPE &&
+			  links[nlinks-1].form->type == F_TEXTAREA_TYPE &&
+			  links[nlinks-1].form->number == thisgroup &&
+			  sametext(links[nlinks-1].form->name, thisname))) {
+			do nextlink++;
+			while
+			    (links[nextlink].type == WWW_FORM_LINK_TYPE &&
+			     links[nextlink].form->type == F_TEXTAREA_TYPE &&
+			     links[nextlink].form->number == thisgroup &&
+			     sametext(links[nextlink].form->name, thisname));
+			samepage = 1;
+		    } else if (!more && Newline == 1 && curdoc.link > 0) {
+			nextlink = 0;
+			samepage = 1;
+		    }
+		} else if (curdoc.link < nlinks-1) {
+		    nextlink++;
+		    samepage = 1;
+		} else if (!more && Newline == 1 && curdoc.link > 0) {
+		    nextlink = 0;
+		    samepage = 1;
+		}
+	    }
+	    if (samepage) {
+		highlight(OFF, curdoc.link, prev_target);
+		curdoc.link = nextlink;
+		break;		/* and we are done. */
+
+	    /*
+	     *	At the bottom of list and there is only one page.
+	     *	Move to the top link on the page.
+	     */
+	    } else if (!more && Newline == 1 && curdoc.link == nlinks-1) {
+		highlight(OFF, curdoc.link, prev_target);
+		curdoc.link = 0;
+
+	    } else if (more &&	/* need a later page */
+		       HTGetLinkOrFieldStart(curdoc.link,
+					     &Newline, &newdoc.link,
+					     +1, TRUE) != NO) {
+		Newline++;	/* our line counting starts with 1 not 0 */
+		/* nothing more to do here */
+
+	    } else if (old_c != real_c) {
+		old_c = real_c;
+		HTInfoMsg(NO_LINKS_BELOW);
+	    }
+	    break;
+	}
+	case LYK_FASTBACKW_LINK:
+	{
+	    int samepage = 0, nextlink = curdoc.link;
+	    int res;
+	    if (nlinks > 1) {
+
+		/*
+		 *  If in textarea, move to first link or textarea group
+		 *  before it if there is one on this screen. - kw
+		 */
+		if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
+		    links[curdoc.link].form->type == F_TEXTAREA_TYPE) {
+		    int thisgroup = links[curdoc.link].form->number;
+		    char *thisname = links[curdoc.link].form->name;
+
+		    if (curdoc.link > 0 &&
+			!(links[0].type == WWW_FORM_LINK_TYPE &&
+			  links[0].form->type == F_TEXTAREA_TYPE &&
+			  links[0].form->number == thisgroup &&
+			  sametext(links[0].form->name, thisname))) {
+			do nextlink--;
+			while
+			    (links[nextlink].type == WWW_FORM_LINK_TYPE &&
+			     links[nextlink].form->type == F_TEXTAREA_TYPE &&
+			     links[nextlink].form->number == thisgroup &&
+			     sametext(links[nextlink].form->name, thisname));
+			samepage = 1;
+
+		    } else if (!more && Newline == 1 &&
+			       (links[0].type == WWW_FORM_LINK_TYPE &&
+				links[0].form->type == F_TEXTAREA_TYPE &&
+				links[0].form->number == thisgroup &&
+				sametext(links[0].form->name, thisname)) &&
+			       !(links[nlinks-1].type == WWW_FORM_LINK_TYPE &&
+				 links[nlinks-1].form->type == F_TEXTAREA_TYPE &&
+				 links[nlinks-1].form->number == thisgroup &&
+				 sametext(links[nlinks-1].form->name, thisname))) {
+			nextlink = nlinks - 1;
+			samepage = 1;
+
+		    } else if (!more && Newline == 1 && curdoc.link > 0) {
+			nextlink = 0;
+			samepage = 1;
+		    }
+		} else if (curdoc.link > 0) {
+		    nextlink--;
+		    samepage = 1;
+		} else if (!more && Newline == 1) {
+		    nextlink = nlinks - 1;
+		    samepage = 1;
+		}
+	    }
+	    if (samepage) {
+		/*
+		 *  If the link as determined so far is part of a
+		 *  group of textarea fields, try to use the first
+		 *  of them that's on the screen instead. - kw
+		 */
+		if (nextlink > 0 &&
+		    links[nextlink].type == WWW_FORM_LINK_TYPE &&
+		    links[nextlink].form->type == F_TEXTAREA_TYPE) {
+		    int thisgroup = links[nextlink].form->number;
+		    char *thisname = links[nextlink].form->name;
+		    if (links[0].type == WWW_FORM_LINK_TYPE &&
+			links[0].form->type == F_TEXTAREA_TYPE &&
+			links[0].form->number == thisgroup &&
+			sametext(links[0].form->name, thisname)) {
+			nextlink = 0;
+		    } else
+			while
+			    (nextlink > 1 &&
+			     links[nextlink-1].type == WWW_FORM_LINK_TYPE &&
+			     links[nextlink-1].form->type == F_TEXTAREA_TYPE &&
+			     links[nextlink-1].form->number == thisgroup &&
+			     sametext(links[nextlink-1].form->name, thisname)) {
+			    nextlink--;
+			}
+		}
+		highlight(OFF, curdoc.link, prev_target);
+		curdoc.link = nextlink;
+		break;		/* and we are done. */
+
+	    } else if (Newline > 1 &&	/* need a previous page */
+		       (res = HTGetLinkOrFieldStart(curdoc.link,
+						    &Newline, &newdoc.link,
+						    -1, TRUE)) != NO) {
+		if (res == LINK_DO_ARROWUP) {
+		    /*
+		     *  It says we should use the normal PREV_LINK
+		     *  mechanism, so we'll do that. - kw
+		     */
+		    if (nlinks > 0)
+			curdoc.link = 0;
+		    cmd = LYK_PREV_LINK;
+		    goto new_cmd;
+		}
+		Newline++;	/* our line counting starts with 1 not 0 */
+		/* nothing more to do here */
+
+	    } else if (old_c != real_c) {
+		old_c = real_c;
+		HTInfoMsg(NO_LINKS_ABOVE);
+	    }
+	    break;
+	}
+
 	case LYK_UP_LINK:
 	    if (curdoc.link > 0 &&
 		(links[0].ly != links[curdoc.link].ly ||
@@ -4196,7 +4365,7 @@ if (!LYUseFormsOptions) {
 		    if (is_url(cp) == FILE_URL_TYPE) {
 			cp = HTfullURL_toFile(cp);
 			StrAllocCopy(tp, cp);
-			free(cp);
+			FREE(cp);
 
 			if (stat(tp, &dir_info) == -1) {
 			    HTAlert(NO_STATUS);
@@ -4851,7 +5020,7 @@ check_add_bookmark_to_self:
 	case LYK_SHELL:  /* shell escape */
 	    if (!no_shell) {
 		stop_curses();
-		printf(SPAWNING_MSG);
+		printf("%s\r\n", SPAWNING_MSG);
 		LYSystem(LYSysShell());
 		start_curses();
 		refresh_screen = TRUE;	/* for an HText_pageDisplay() */
diff --git a/src/LYNews.c b/src/LYNews.c
index 5cfd41db..6b988b55 100644
--- a/src/LYNews.c
+++ b/src/LYNews.c
@@ -283,12 +283,9 @@ PUBLIC char *LYNewsPost ARGS2(
 	    /*
 	     *  Ask if the user wants to include the original message.
 	     */
-	    _statusline(INC_ORIG_MSG_PROMPT);
-	    c = 0;
-	    while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
-		   !term_message && c != 7 && c != 3)
-		c = LYgetch();
-	    if (TOUPPER(c) == 'Y')
+	    if (term_message) {
+		_statusline(INC_ORIG_MSG_PROMPT);
+	    } else if (HTConfirm(INC_ORIG_MSG_PROMPT) == YES) {
 		/*
 		 *  The 1 will add the reply ">" in front of every line.
 		 *  We're assuming that if the display character set is
@@ -297,6 +294,7 @@ PUBLIC char *LYNewsPost ARGS2(
 		 *  converted to 7-bit equivalents. - FM
 		 */
 		print_wwwfile_to_fd(fd, 1);
+	    }
 	}
 	LYCloseTempFP(fd);		/* Close the temp file. */
 	scrollok(stdscr, FALSE);	/* Stop scrolling.	*/
@@ -367,26 +365,20 @@ PUBLIC char *LYNewsPost ARGS2(
      *  whether to append the sig file. - FM
      */
     LYStatusLine = (LYlines - 1);
-    _statusline(POST_MSG_PROMPT);
-    c = 0;
+    c = HTConfirm(POST_MSG_PROMPT);
     LYStatusLine = -1;
-    while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
-	   !term_message && c != 7   && c != 3)
-	c = LYgetch();
-    if (TOUPPER(c) != 'Y') {
+    if (c != YES) {
 	clear();  /* clear the screen */
 	goto cleanup;
     }
-    if ((LynxSigFile != NULL) &&
-	(fp = fopen(LynxSigFile, "r")) != NULL) {
+    if ((LynxSigFile != NULL) && (fp = fopen(LynxSigFile, "r")) != NULL) {
+	char *msg = NULL;
+	HTSprintf0(&msg, APPEND_SIG_FILE, LynxSigFile);
+
 	LYStatusLine = (LYlines - 1);
-	_user_message(APPEND_SIG_FILE, LynxSigFile);
-	c = 0;
-	LYStatusLine = -1;
-	while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
-	       !term_message && c != 7   && c != 3)
-	    c = LYgetch();
-	if (TOUPPER(c) == 'Y') {
+	if (term_message) {
+	    _user_message(APPEND_SIG_FILE, LynxSigFile);
+	} else if (HTConfirm(msg) == YES) {
 	    if ((fd = LYAppendToTxtFile (my_tempfile)) != NULL) {
 		fputs("-- \n", fd);
 		while (fgets(user_input, sizeof(user_input), fp) != NULL) {
@@ -396,6 +388,8 @@ PUBLIC char *LYNewsPost ARGS2(
 	    }
 	}
 	fclose(fp);
+	FREE(msg);
+	LYStatusLine = -1;
     }
     clear();  /* clear the screen */
 
diff --git a/src/LYPrint.c b/src/LYPrint.c
index e5b35ae7..3aa2a359 100644
--- a/src/LYPrint.c
+++ b/src/LYPrint.c
@@ -280,7 +280,7 @@ PRIVATE BOOLEAN confirm_by_pages ARGS3(
 
 	HTSprintf0(&msg, prompt, pages);
 	_statusline(msg);
-	free(msg);
+	FREE(msg); 
 
 	c = LYgetch();
 #ifdef VMS
@@ -740,7 +740,7 @@ PRIVATE void send_file_to_mail ARGS3(
     }
     /*
      * If we are using MIME headers, add content-base and content-location if
-     * we have them.  This will always be the case if the document is source. 
+     * we have them.  This will always be the case if the document is source.
      * - kw
      */
     if (use_mime) {
@@ -926,7 +926,7 @@ check_again:
      * [could use unsetenv(), but it's not portable]
      */
     SET_ENVIRON(LYNX_PRINT_TITLE,   "", "");
-    SET_ENVIRON(LYNX_PRINT_URL,     "","");
+    SET_ENVIRON(LYNX_PRINT_URL,     "", "");
     SET_ENVIRON(LYNX_PRINT_DATE,    "", "");
     SET_ENVIRON(LYNX_PRINT_LASTMOD, "", "");
 
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index 090cff98..88a04803 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -855,14 +855,14 @@ static Config_Type Config_Table [] =
 #ifdef USE_COLOR_TABLE
      PARSE_FUN("color", CONF_FUN, color_fun),
 #endif
-     PARSE_STR("cookie_accept_domains", CONF_STR, LYCookieAcceptDomains),
+     PARSE_STR("cookie_accept_domains", CONF_STR, LYCookieSAcceptDomains),
 #ifdef EXP_PERSISTENT_COOKIES
      PARSE_STR("cookie_file", CONF_STR, LYCookieFile),
 #endif /* EXP_PERSISTENT_COOKIES */
-     PARSE_STR("cookie_loose_invalid_domains", CONF_STR, LYCookieLooseCheckDomains),
-     PARSE_STR("cookie_query_invalid_domains", CONF_STR, LYCookieQueryCheckDomains),
-     PARSE_STR("cookie_reject_domains", CONF_STR, LYCookieRejectDomains),
-     PARSE_STR("cookie_strict_invalid_domains", CONF_STR, LYCookieStrictCheckDomains),
+     PARSE_STR("cookie_loose_invalid_domains", CONF_STR, LYCookieSLooseCheckDomains),
+     PARSE_STR("cookie_query_invalid_domains", CONF_STR, LYCookieSQueryCheckDomains),
+     PARSE_STR("cookie_reject_domains", CONF_STR, LYCookieSRejectDomains),
+     PARSE_STR("cookie_strict_invalid_domains", CONF_STR, LYCookieSStrictCheckDomains),
      PARSE_ENV("cso_proxy", CONF_ENV, 0 ),
 #ifdef VMS
      PARSE_STR("CSWING_PATH", CONF_STR, LYCSwingPath),
@@ -1040,7 +1040,7 @@ PUBLIC void free_lynx_cfg NOARGS
 	case CONF_ENV:
 	    if (q->str_value != 0) {
 		FREE(*(q->str_value));
-		free((char *)q->str_value);
+		FREE((char *)q->str_value);
 	    }
 	    break;
 	default:
@@ -1292,24 +1292,49 @@ PUBLIC void read_cfg ARGS4(
      * And for query/strict/loose invalid cookie checking. - BJP
      */
 
+    if (LYCookieSAcceptDomains != NULL) {
+	cookie_domain_flag_set(LYCookieSAcceptDomains, FLAG_ACCEPT_ALWAYS);
+	FREE(LYCookieSAcceptDomains);
+    }
+
+    if (LYCookieSRejectDomains != NULL) {
+	cookie_domain_flag_set(LYCookieSRejectDomains, FLAG_REJECT_ALWAYS);
+	FREE(LYCookieSRejectDomains);
+    }
+
+    if (LYCookieSStrictCheckDomains != NULL) {
+	cookie_domain_flag_set(LYCookieSStrictCheckDomains, FLAG_INVCHECK_STRICT);
+	FREE(LYCookieSStrictCheckDomains);
+    }
+
+    if (LYCookieSLooseCheckDomains != NULL) {
+	cookie_domain_flag_set(LYCookieSLooseCheckDomains, FLAG_INVCHECK_LOOSE);
+	FREE(LYCookieSLooseCheckDomains);
+    }
+
+    if (LYCookieSQueryCheckDomains != NULL) {
+	cookie_domain_flag_set(LYCookieSQueryCheckDomains, FLAG_INVCHECK_QUERY);
+	FREE(LYCookieSQueryCheckDomains);
+    }
+
     if (LYCookieAcceptDomains != NULL) {
-	cookie_add_acceptlist(LYCookieAcceptDomains);
+	cookie_domain_flag_set(LYCookieAcceptDomains, FLAG_ACCEPT_ALWAYS);
     }
 
     if (LYCookieRejectDomains != NULL) {
-	cookie_add_rejectlist(LYCookieRejectDomains);
+	cookie_domain_flag_set(LYCookieRejectDomains, FLAG_REJECT_ALWAYS);
     }
 
     if (LYCookieStrictCheckDomains != NULL) {
-	cookie_set_invcheck(LYCookieStrictCheckDomains, INVCHECK_STRICT);
+	cookie_domain_flag_set(LYCookieStrictCheckDomains, FLAG_INVCHECK_STRICT);
     }
 
     if (LYCookieLooseCheckDomains != NULL) {
-	cookie_set_invcheck(LYCookieLooseCheckDomains, INVCHECK_LOOSE);
+	cookie_domain_flag_set(LYCookieLooseCheckDomains, FLAG_INVCHECK_LOOSE);
     }
 
     if (LYCookieQueryCheckDomains != NULL) {
-	cookie_set_invcheck(LYCookieQueryCheckDomains, INVCHECK_QUERY);
+	cookie_domain_flag_set(LYCookieQueryCheckDomains, FLAG_INVCHECK_QUERY);
     }
 
 }
diff --git a/src/LYShowInfo.c b/src/LYShowInfo.c
index 962a7329..bfc0c85a 100644
--- a/src/LYShowInfo.c
+++ b/src/LYShowInfo.c
@@ -153,14 +153,14 @@ PUBLIC int showinfo ARGS4(
 
 	s = HTfullURL_toFile(doc->address);
 	strcpy(temp, s);
-	free(s);
+	FREE(s);
 
 	fprintf(fp0, "   <em>%4s</em>  %s\n", gettext("Name:"), temp);
 	fprintf(fp0, "   <em>%4s</em>  %s\n", gettext("URL:"), doc->address);
 
 	s = HTfullURL_toFile(links[doc->link].lname);
 	strcpy(temp, s);
-	free(s);
+	FREE(s);
 
 	if (lstat(temp, &dir_info) == -1) {
 	    CTRACE(tfp, "lstat(%s) failed, errno=%d\n", temp, errno);
diff --git a/src/LYStrings.c b/src/LYStrings.c
index f8d0fe3c..d74e2310 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -701,6 +701,8 @@ PRIVATE void expand_substring (char* dst, char* first, char* last)
 		if (s == 0)
 		    s = first + strlen(first);
 		first = expand_tiname(first, s-first, &dst);
+		if (*first)
+		    first++;
 	    } else if (ch == '?') {		/* ASCII delete? */
 		*dst++ = 127;
 	    } else if ((ch & 0x3f) < 0x20) {	/* ASCII control char? */
@@ -1091,7 +1093,7 @@ PUBLIC int LYgetch NOARGS
      return sl_read_mouse_event ();
 #endif
 
-   if ((keysym > DO_NOTHING) || (keysym < 0))
+   if ((keysym+1 >= KEYMAP_SIZE) || (keysym < 0))
      return 0;
 
    return keysym;
@@ -1103,7 +1105,7 @@ PUBLIC int LYgetch_for ARGS1(
     return LYgetch();
 }
 
-#else /* !USE_KEYMAPS */
+#else	/* NOT  defined(USE_KEYMAPS) && defined(USE_SLANG) */
 
 /*
  *  LYgetch() translates some escape sequences and may fake noecho.
@@ -1372,10 +1374,10 @@ re_read:
 	   c = CH_DEL;		   /* backspace key (delete, not Ctrl-H)  S/390 -- gil -- 2041 */
 	   break;
 #endif /* KEY_BACKSPACE */
-#if defined(KEY_F) && !defined(__DJGPP__) && !defined(_WINDOWS)
 	case KEY_F(1):
 	   c = F1;		   /* VTxxx Help */
 	   break;
+#if defined(KEY_F) && !defined(__DJGPP__) && !defined(_WINDOWS)
 	case KEY_F(16):
 	   c = DO_KEY;		   /* VTxxx Do */
 	   break;
@@ -1405,6 +1407,33 @@ re_read:
 	   c = REMOVE_KEY;	   /* VTxxx Remove */
 	   break;
 #endif /* KEY_DC */
+#ifdef KEY_BTAB
+	case KEY_BTAB:
+	   c = BACKTAB_KEY;	   /* Back tab, often Shift-Tab */
+	   break;
+#endif /* KEY_BTAB */
+
+/* The following maps PDCurses keys away from lynx reserved values */
+#if (defined(_WINDOWS) || defined(__DJGPP__)) && !defined(USE_SLANG)
+	case KEY_F(2):
+	   c = 0x213;
+	   break;
+	case KEY_F(3):
+	   c = 0x214;
+	   break;
+	case KEY_F(4):
+	   c = 0x215;
+	   break;
+	case KEY_F(5):
+	   c = 0x216;
+	   break;
+	case KEY_F(6):
+	   c = 0x217;
+	   break;
+	case KEY_F(7):
+	   c = 0x218;
+	   break;
+#endif /* PDCurses */
 #ifdef NCURSES_MOUSE_VERSION
 	case KEY_MOUSE:
 	    if (code == FOR_CHOICE) {
@@ -1504,6 +1533,29 @@ re_read:
 	case K_EEnd:
 	   c = END_KEY;
 	   break;
+	case K_F1:		   /* F1 key */
+	   c = F1;
+	   break;
+	case K_Insert:		   /* Insert key */
+	case K_EInsert:
+	   c = INSERT_KEY;
+	   break;
+	case K_Delete:		   /* Delete key */
+	case K_EDelete:
+	   c = REMOVE_KEY;
+	   break;
+	case K_Alt_Escape:	   /* Alt-Escape */
+	   c = 0x1a7;
+	   break;
+	case K_Control_At:	   /* CTRL-@ */
+	   c = 0x1a8;
+	   break;
+	case K_Alt_Backspace:	   /* Alt-Backspace */
+	   c = 0x1a9;
+	   break;
+	case K_BackTab:		   /* BackTab */
+	   c = BACKTAB_KEY;
+	   break;
 	}
     }
 #endif /* DGJPP_KEYHANDLER */
@@ -1538,6 +1590,15 @@ re_read:
 	case SL_KEY_C1:		   /* lower left of keypad */
 	   c = END_KEY;
 	   break;
+	case SL_KEY_F(1):	   /* F1 key */
+	   c = F1;
+	   break;
+	case SL_KEY_IC:		   /* Insert key */
+	   c = INSERT_KEY;
+	   break;
+	case SL_KEY_DELETE:	   /* Delete key */
+	   c = REMOVE_KEY;
+	   break;
 	}
     }
 #endif /* USE_SLANG && __DJGPP__ && !DJGPP_KEYHANDLER && !USE_KEYMAPS */
@@ -1554,7 +1615,7 @@ re_read:
     }
 }
 
-#endif				       /* NOT USE_KEYMAPS */
+#endif	/* NOT  defined(USE_KEYMAPS) && defined(USE_SLANG) */
 
 /*
  * Convert a null-terminated string to lowercase
@@ -1770,7 +1831,8 @@ PUBLIC int LYEdit1 ARGS4(
 	     return(ch);
     case LYE_CHAR:
 #ifdef EXP_KEYBOARD_LAYOUT
-	if (map_active && ch < 128 && LYKbLayouts[current_layout][ch])
+	if (map_active && ch < 128 && ch >= 0 &&
+	    LYKbLayouts[current_layout][ch])
 	    ch = UCTransUniChar((long) LYKbLayouts[current_layout][ch],
 		current_char_set);
 #endif
@@ -2075,7 +2137,8 @@ again:
 	switch (EditBinding(ch)) {
 	case LYE_TAB:
 	    ch = '\t';
-	    /* fall through */
+	    /* This used to fall through to the next case before
+	     tab completion was introduced */
 	    res = LYFindInCloset(MyEdit.buffer);
 	    if (res != 0) {
 		LYEdit1(&MyEdit, '\0', LYE_ERASE, FALSE);
@@ -2123,6 +2186,14 @@ again:
 	     */
 	    break;
 
+	case LYE_FORM_PASS:
+	    /*
+	     *	Used in form_getstr() to end line editing and
+	     *	pass on the input char/lynxkeycode.  Here it
+	     *	is just ignored. - kw
+	     */
+	    break;
+
 	default:
 	    LYLineEdit(&MyEdit, ch, FALSE);
 	}
diff --git a/src/LYStrings.h b/src/LYStrings.h
index 7c346fc2..4114fa7b 100644
--- a/src/LYStrings.h
+++ b/src/LYStrings.h
@@ -97,8 +97,18 @@ extern char * SNACat PARAMS((
 #define SELECT_KEY	267	/* 0x10B */
 #define INSERT_KEY	268	/* 0x10C */
 #define REMOVE_KEY	269	/* 0x10D */
-#define MOUSE_KEY	270	/* 0x10E */
-#define DO_NOTHING	271	/* 0x10F */
+#define DO_NOTHING	270	/* 0x10E */
+#define BACKTAB_KEY	271	/* 0x10F */
+#define MOUSE_KEY	0x11d	/* 0x11D */
+/*  *** NOTE: ***
+    If you add definitions for new lynxkeycodes to the above list that
+    need to be mapped to LYK_* lynxactioncodes -
+    - AT LEAST the tables keymap[] and key_override[] in LYKeymap.c
+      have to be changed/reviewed, AS WELL AS the lineedit binding
+      tables in LYEditmap.c !
+    - KEYMAP_SIZE, defined in LYKeymap.h, may need to be changed !
+*/
+
 
 #  define FOR_PANEL	0
 #  define FOR_CHOICE	1
@@ -136,11 +146,15 @@ typedef struct _EditFieldData {
 
 #define LYE_NOP 0		  /* Do Nothing            */
 #define LYE_CHAR  (LYE_NOP   +1)  /* Insert printable char */
-#define LYE_ENTER (LYE_CHAR  +1)  /* Input complete, return char */
+#define LYE_ENTER (LYE_CHAR  +1)  /* Input complete, return char/lynxkeycode */
 #define LYE_TAB   (LYE_ENTER +1)  /* Input complete, return TAB  */
 #define LYE_ABORT (LYE_TAB   +1)  /* Input cancelled       */
 
-#define LYE_DELN  (LYE_ABORT +1)  /* Delete next/curr char */
+#define LYE_FORM_PASS (LYE_ABORT +1)  /* In form fields: input complete,
+					 return char / lynxkeycode;
+					 Elsewhere: Do Nothing */
+
+#define LYE_DELN  (LYE_FORM_PASS +1)  /* Delete next/curr char */
 #define LYE_DELC  (LYE_DELN)      /* Obsolete (DELC case was equiv to DELN) */
 #define LYE_DELP  (LYE_DELN  +1)  /* Delete prev      char */
 #define LYE_DELNW (LYE_DELP  +1)  /* Delete next word      */
diff --git a/src/LYUpload.c b/src/LYUpload.c
index 9f970890..3ccb4728 100644
--- a/src/LYUpload.c
+++ b/src/LYUpload.c
@@ -205,7 +205,7 @@ PUBLIC int LYUpload_options ARGS2(
     cp = HTfullURL_toFile(directory);
     strcpy(curloc,cp);
     LYTrimPathSep(curloc);
-    free(cp);
+    FREE(cp);
 #endif /* VMS */
 
     LYLocalFileToURL(newfile, tempfile);
diff --git a/src/LYUtils.c b/src/LYUtils.c
index 2c9a92a0..ecced083 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -1721,7 +1721,7 @@ PUBLIC void free_and_clear ARGS1(
 	char **,	pointer)
 {
     if (*pointer) {
-	free(*pointer);
+	FREE(*pointer);
 	*pointer = 0;
     }
     return;
@@ -2188,8 +2188,35 @@ PUBLIC int HTCheckForInterrupt NOARGS
     else if (display_partial && (NumOfLines_partial > 2))
     /* OK, we got several lines from new document and want to scroll... */
     {
+	int res;
 	switch (keymap[c+1])
 	{
+	case LYK_FASTBACKW_LINK :
+	    if (Newline_partial <= (display_lines)+1) {
+		Newline_partial -= display_lines ;
+	    } else if ((res =
+			HTGetLinkOrFieldStart(-1,
+					      &Newline_partial, NULL,
+					      -1, TRUE)) == LINK_LINE_FOUND) {
+		Newline_partial++;
+	    } else if (res == LINK_DO_ARROWUP) {
+		Newline_partial -= display_lines ;
+	    }
+	    break;
+	case LYK_FASTFORW_LINK :
+	    if (HText_canScrollDown()) {
+		/* This is not an exact science... - kw */
+		if ((res =
+		     HTGetLinkOrFieldStart(HText_LinksInLines(HTMainText,
+							      Newline_partial,
+							      display_lines)
+					   - 1,
+					   &Newline_partial, NULL,
+					   +1, TRUE)) == LINK_LINE_FOUND) {
+		    Newline_partial++;
+		}
+	    }
+	    break;
 	case LYK_PREV_PAGE :
 	    if (Newline_partial > 1)
 		Newline_partial -= display_lines ;
@@ -4725,7 +4752,11 @@ PUBLIC CONST char * Home_Dir NOARGS
     char *cp = NULL;
 
     if (homedir == NULL) {
-	if ((cp = getenv("HOME")) == NULL || *cp == '\0') {
+	if ((cp = getenv("HOME")) == NULL || *cp == '\0'
+#ifdef UNIX
+	    || *cp != '/'
+#endif /* UNIX */
+	    ) {
 #if defined (DOSPATH) || defined (__EMX__) /* BAD!	WSB */
 	    if ((cp = getenv("TEMP")) == NULL || *cp == '\0') {
 		if ((cp = getenv("TMP")) == NULL || *cp == '\0') {
@@ -4764,6 +4795,10 @@ PUBLIC CONST char * Home_Dir NOARGS
 		 */
 		StrAllocCopy(HomeDir, "/tmp");
 	    }
+#ifdef UNIX
+	    if (cp && *cp)
+		HTAlwaysAlert(NULL, gettext("Ignoring invalid HOME"));
+#endif
 #endif /* VMS */
 #endif /* DOSPATH */
 	} else {
@@ -5422,7 +5457,7 @@ PUBLIC int putenv ARGS1(
       new_environ[size] = (char *) string;
       new_environ[size + 1] = NULL;
       if (last_environ != NULL)
-	free ((char *) last_environ);
+	FREE ((char *) last_environ);
       last_environ = new_environ;
       environ = new_environ;
     }
@@ -5494,7 +5529,7 @@ PRIVATE BOOL IsOurFile ARGS1(char *, name)
 		break;
 	    }
 	} while (leaf != path);
-	free(path);
+	FREE(path);
 #endif
 	return !linked;
     }
@@ -5847,8 +5882,8 @@ PUBLIC void LYRemoveTemp ARGS1(
 		CTRACE_FLUSH(tfp);
 		if (p->file != 0)
 		    fclose(p->file);
-		free(p->name);
-		free(p);
+		FREE(p->name);
+		FREE(p);
 		break;
 	    }
 	}
@@ -6251,6 +6286,7 @@ PUBLIC int LYSystem ARGS1(
 
     fflush(stdout);
     fflush(stderr);
+    CTRACE_FLUSH(tfp);
 
 #ifdef __DJGPP__
     __djgpp_set_ctrl_c(0);
diff --git a/src/LYrcFile.c b/src/LYrcFile.c
index af1f9041..e0c1304c 100644
--- a/src/LYrcFile.c
+++ b/src/LYrcFile.c
@@ -408,11 +408,11 @@ PUBLIC void read_rc NOPARAMS
 	 */
 	} else if (FIND_KEYWORD(cp, "cookie_accept_domains")) {
 	    cp = SkipEquals(cp);
-	    cookie_add_acceptlist(cp);
-	    if(LYCookieAcceptDomains != NULL) { 
-		StrAllocCat(LYCookieAcceptDomains, ","); 
-	    } 
-	    StrAllocCat(LYCookieAcceptDomains, cp); 
+	    cookie_domain_flag_set(cp, FLAG_ACCEPT_ALWAYS);
+	    if(LYCookieAcceptDomains != NULL) {
+		StrAllocCat(LYCookieAcceptDomains, ",");
+	    }
+	    StrAllocCat(LYCookieAcceptDomains, cp);
 
 
 	/*
@@ -420,11 +420,11 @@ PUBLIC void read_rc NOPARAMS
 	 */
 	} else if (FIND_KEYWORD(cp, "cookie_reject_domains")) {
 	    cp = SkipEquals(cp);
-	    cookie_add_rejectlist(cp);
-	    if(LYCookieRejectDomains != NULL) { 
-		StrAllocCat(LYCookieRejectDomains, ","); 
-	    } 
-	    StrAllocCat(LYCookieRejectDomains, cp); 
+	    cookie_domain_flag_set(cp, FLAG_REJECT_ALWAYS);
+	    if(LYCookieRejectDomains != NULL) {
+		StrAllocCat(LYCookieRejectDomains, ",");
+	    }
+	    StrAllocCat(LYCookieRejectDomains, cp);
 
 	/*
 	 *  Cookie domains to perform loose checks?
@@ -432,7 +432,7 @@ PUBLIC void read_rc NOPARAMS
 	} else if (FIND_KEYWORD(cp, "cookie_loose_invalid_domains")) {
 	    cp = SkipEquals(cp);
 	    StrAllocCopy(LYCookieLooseCheckDomains, cp);
-	    cookie_set_invcheck(LYCookieLooseCheckDomains, INVCHECK_LOOSE);
+	    cookie_domain_flag_set(cp, FLAG_INVCHECK_LOOSE);
 
 	/*
 	 *  Cookie domains to perform strict checks?
@@ -440,7 +440,7 @@ PUBLIC void read_rc NOPARAMS
 	} else if (FIND_KEYWORD(cp, "cookie_strict_invalid_domains")) {
 	    cp = SkipEquals(cp);
 	    StrAllocCopy(LYCookieStrictCheckDomains, cp);
-	    cookie_set_invcheck(LYCookieStrictCheckDomains, INVCHECK_STRICT);
+	    cookie_domain_flag_set(cp, FLAG_INVCHECK_STRICT);
 
 	/*
 	 *  Cookie domains to query user over invalid cookies?
@@ -448,11 +448,11 @@ PUBLIC void read_rc NOPARAMS
 	} else if (FIND_KEYWORD(cp, "cookie_query_invalid_domains")) {
 	    cp = SkipEquals(cp);
 	    StrAllocCopy(LYCookieQueryCheckDomains, cp);
-	    cookie_set_invcheck(LYCookieQueryCheckDomains, INVCHECK_QUERY);
+	    cookie_domain_flag_set(cp, FLAG_INVCHECK_QUERY);
 
 #ifdef EXP_PERSISTENT_COOKIES
 	/*
-	 *  File in which to store persistent cookies. 
+	 *  File in which to store persistent cookies.
 	 */
 	} else if (FIND_KEYWORD(cp, "cookie_file")) {
 	    cp = SkipEquals(cp);
@@ -493,7 +493,7 @@ PUBLIC void read_rc NOPARAMS
 	} else if (FIND_KEYWORD(cp, "partial_thres")) {
 	    cp = SkipEquals(cp);
 	    if (atoi(cp) != 0)
-	        partial_threshold = atoi(cp);
+		partial_threshold = atoi(cp);
 #endif /* DISP_PARTIAL */
 
 	/*
@@ -902,12 +902,12 @@ PUBLIC int save_rc NOPARAMS
 # override any settings made here.  If a single domain is specified in\n\
 # both cookie_accept_domains and in cookie_reject_domains, the rejection\n\
 # will take precedence.\n"));
-    fprintf(fp, "cookie_accept_domains=%s\n", 
-		    (LYCookieAcceptDomains == NULL ? ""  
-		    : LYCookieAcceptDomains)); 
-    fprintf(fp, "cookie_reject_domains=%s\n\n", 
-		    (LYCookieRejectDomains == NULL ? ""  
-		    : LYCookieRejectDomains)); 
+    fprintf(fp, "cookie_accept_domains=%s\n",
+		    (LYCookieAcceptDomains == NULL ? ""
+		    : LYCookieAcceptDomains));
+    fprintf(fp, "cookie_reject_domains=%s\n\n",
+		    (LYCookieRejectDomains == NULL ? ""
+		    : LYCookieRejectDomains));
 
 
     fprintf(fp, gettext("\
diff --git a/src/UCAuto.c b/src/UCAuto.c
index 903944e2..5a976eb4 100644
--- a/src/UCAuto.c
+++ b/src/UCAuto.c
@@ -150,11 +150,11 @@ PUBLIC void UCChangeTerminalCodepage ARGS2(
 	    }
 
 	    remove(old_font);
-	    free(old_font);
+	    FREE(old_font);
 	    old_font = 0;
 
 	    remove(old_umap);
-	    free(old_umap);
+	    FREE(old_umap);
 	    old_umap = 0;
 	}
 	return;
diff --git a/src/chrtrans/cp866u_uni.tbl b/src/chrtrans/cp866u_uni.tbl
index 0b14123e..99c30de6 100644
--- a/src/chrtrans/cp866u_uni.tbl
+++ b/src/chrtrans/cp866u_uni.tbl
@@ -1,5 +1,5 @@
 #
-#The MIME name of this charset. 
+#The MIME name of this charset.
 Mcp866u
 
 #Name as a Display Charset (used on Options screen)
@@ -13,10 +13,8 @@ OUkrainian Cyrillic (cp866u)
 #    Unicode version: 2.0
 #    Table version: 2.00
 #    Table format:  Format A
-#    General notes: based on Cyrillic (cp866) table.
-#                   Original file: cp866_uni.tbl (authors: 
-#                           Lori Brownell <loribr@microsoft.com>
-#                           K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: based on Cyrillic (cp866) table,
+#                   have different mapping in 0xF2-0xF9 region.
 #
 #    Format: Three tab-separated columns
 #        Column #1 is the cp866_DOSCyrillicUkrainian code (in hex)
diff --git a/src/chrtrans/iso9945_uni.tbl b/src/chrtrans/iso9945_uni.tbl
index 100ae92c..18cf2ffe 100644
--- a/src/chrtrans/iso9945_uni.tbl
+++ b/src/chrtrans/iso9945_uni.tbl
@@ -2,7 +2,7 @@
 Miso-9945-2
 
 #Name as a Display Charset (used on Options screen)
-OUkrainian (ISO-9945-2)
+OUkrainian Cyrillic (ISO-9945-2)
 
 #Codepage number
 #?
diff --git a/src/chrtrans/koi8u_uni.tbl b/src/chrtrans/koi8u_uni.tbl
index e3458dba..2c13845b 100644
--- a/src/chrtrans/koi8u_uni.tbl
+++ b/src/chrtrans/koi8u_uni.tbl
@@ -12,8 +12,18 @@ Mkoi8-u
 # (verified against RFC2319).
 # KOI8-U home page: <http://www.net.ua/KOI8-U>
 #
-#hex unicode # description     
-#--- U+---- # ---------------     
+# Quoted from RFC2319:
+#   The upper part of the KOI8-U Character Set contains all Russian
+#   letters defined in KOI8-R and four Ukrainian letters (#164, #180 -
+#   ukr. ie, #166, #182 - ukr. i, #167, #183 - ukr. yi, #173, #189 - ukr.
+#   ghe  with upturn) which locations are compliant with ISO-IR-111.
+#
+#   BOX DRAWINGS elements in the other positions (that are not used by
+#   Ukrainian letters) are the same as in KOI8-R character set.
+#
+#
+#hex unicode # description
+#--- U+---- # ---------------
 0x80 U+2500 # BOX DRAWINGS  LIGHT HORIZONTAL
 0x81 U+2502 # BOX DRAWINGS  LIGHT VERTICAL
 0x82 U+250C # BOX DRAWINGS  LIGHT DOWN AND RIGHT
diff --git a/src/makefile.in b/src/makefile.in
index 56b8c944..6934d250 100644
--- a/src/makefile.in
+++ b/src/makefile.in
@@ -102,7 +102,7 @@ lint:
 	$(LINT) $(LINTOPTS) $(CPP_OPTS) *.c  > $(top_builddir)/lint.lynx
 
 clean:
-	rm -f lynx$x core *.[ob] *.bak
+	rm -f lynx$x core *.core *.leaks *.[ob] *.bak
 	cd chrtrans && $(MAKE) clean
 
 distclean: clean
diff --git a/src/structdump.h b/src/structdump.h
index 8b058189..42b9a07d 100644
--- a/src/structdump.h
+++ b/src/structdump.h
@@ -57,6 +57,7 @@ CTRACE(tfp, "\n" \
             "      input_field=|%s|\n"   \
             "      show_anchor=%1x\n"    \
             "      inUnderline=%1x\n"    \
+            "   expansion_anch=%1x\n"    \
             "          *anchor=0x%08x\n" \
             "}\n", \
             (A), sizeof(*((A))), \
@@ -64,8 +65,8 @@ CTRACE(tfp, "\n" \
             (A)->extent, (A)->line_num, \
             (A)->hightext, (A)->hightext, (A)->hightext2, (A)->hightext2, \
             (A)->hightext2offset, (A)->link_type, \
-            (A)->input_field, (A)->input_field, \
-            (A)->show_anchor, (A)->inUnderline, (A)->anchor); \
+            (A)->input_field, (A)->input_field, (A)->show_anchor, \
+            (A)->inUnderline, (A)->expansion_anch, (A)->anchor); \
 CTRACE_FLUSH(tfp);
 
 
@@ -118,20 +119,21 @@ CTRACE_FLUSH(tfp);
 #define   DUMPSTRUCT_LINE(L,X) \
 CTRACE(tfp, "\n" \
             "KED: htline_ptr=0x%08x  sizeof=%d  ["X"]\n" \
-            "HTLine struct {\n"      \
-            "        *next=0x%08x\n" \
-            "        *prev=0x%08x\n" \
-            "       offset=%d\n"     \
-            "         size=%d\n"     \
-            "  split_after=%1x\n"    \
-            "       bullet=%1x\n"    \
-            "nodef U_C_S\n"          \
-            "       data[]=0x%08x\n" \
-            "         data=|%s|\n"   \
+            "HTLine  struct {\n"      \
+            "         *next=0x%08x\n" \
+            "         *prev=0x%08x\n" \
+            "        offset=%d\n"     \
+            "          size=%d\n"     \
+            "   split_after=%1x\n"    \
+            "        bullet=%1x\n"    \
+            "expansion_line=%1x\n"    \
+            "w/o U_C_S def\n"         \
+            "        data[]=0x%08x\n" \
+            "          data=|%s|\n"   \
             "}\n", \
             (L), sizeof(*((L))), \
             (L)->next, (L)->prev, (L)->offset, (L)->size, (L)->split_after, \
-            (L)->bullet, (L)->data, (L)->data); \
+            (L)->bullet, (L)->expansion_line, (L)->data, (L)->data); \
 CTRACE_FLUSH(tfp);
 
 #endif /* STRUCTDUMP_H */