about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GridText.c1362
-rw-r--r--src/HTInit.c2
-rw-r--r--src/LYBookmark.c2
-rw-r--r--src/LYCharUtils.c4
-rw-r--r--src/LYClean.c12
-rw-r--r--src/LYCurses.c28
-rw-r--r--src/LYDownload.c8
-rw-r--r--src/LYKeymap.c6
-rw-r--r--src/LYStrings.c4
-rw-r--r--src/LYUtils.c34
-rw-r--r--src/LYUtils.h4
11 files changed, 660 insertions, 806 deletions
diff --git a/src/GridText.c b/src/GridText.c
index 69c73f37..4787541a 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -1772,6 +1772,20 @@ PRIVATE void display_scrollbar ARGS1(
 #define display_scrollbar(text) /*nothing*/
 #endif /* USE_SCROLLBAR */
 
+/*
+ * Utility to let us use for-loops on the anchor-pointers.
+ */
+PRIVATE TextAnchor * next_anchor ARGS2(
+	HText *,	text,
+	TextAnchor *,	anchor_ptr)
+{
+    if (anchor_ptr == text->last_anchor)
+	anchor_ptr = NULL;
+    else
+	anchor_ptr = anchor_ptr->next;
+    return anchor_ptr;
+}
+
 /*	Output a page
 **	-------------
 */
@@ -2110,9 +2124,9 @@ PRIVATE void display_page ARGS3(
      *  Add the anchors to Lynx structures.
      */
     nlinks = 0;
-    for (Anchor_ptr=text->first_anchor;  Anchor_ptr != NULL &&
-		Anchor_ptr->line_num <= stop_before_for_anchors;
-					    Anchor_ptr = Anchor_ptr->next) {
+    for (Anchor_ptr = text->first_anchor;
+	 Anchor_ptr != NULL && Anchor_ptr->line_num <= stop_before_for_anchors;
+	 Anchor_ptr = next_anchor(text, Anchor_ptr)) {
 
 	if (Anchor_ptr->line_num >= line_number
 	 && Anchor_ptr->line_num < stop_before_for_anchors) {
@@ -2250,12 +2264,6 @@ PRIVATE void display_page ARGS3(
 	    }
 	}
 
-	if (Anchor_ptr == text->last_anchor)
-	    /*
-	     *  No more links in document. -FM
-	     */
-	    break;
-
 	if (nlinks == MAXLINKS) {
 	    /*
 	     *  Links array is full.  If interactive, tell user
@@ -3246,10 +3254,8 @@ PRIVATE void split_line ARGS2(
 
 	    if (!a2)
 		a2 = text->first_anchor;
-	    else if (a2 == text->last_anchor)
-		a2 = NULL;
 	    else
-		a2 = a2->next; /* 1st anchor on line we justify */
+		a2 = next_anchor(text, a2); /* 1st anchor on line we justify */
 
 	    if (a2)
 		for (; a2 && a2->line_num <= text->Lines-1;
@@ -4098,7 +4104,7 @@ check_WrapSource:
 	 && text->last_anchor != 0
 	 && (number = text->last_anchor->number) > 0) {
 	    limit -= (number > 99999
-	    		? 6
+			? 6
 			: (number > 9999
 			    ? 5
 			    : (number > 999
@@ -5347,8 +5353,8 @@ PRIVATE BOOL HText_endAnchor0 ARGS3(
 		}
 	    }
 	} else {
-    if (!number_links_on_left)
-	add_link_number(text, a, FALSE);
+	    if (!number_links_on_left)
+		add_link_number(text, a, FALSE);
 	    /*
 	     *  The anchor's content is not restricted to only
 	     *  white and special characters, so we'll show it
@@ -5603,8 +5609,8 @@ PRIVATE void HText_trimHightext ARGS3(
      *  create the hightext strings. -FM
      */
     for (anchor_ptr = text->first_anchor;
-	anchor_ptr;
-	prev_a = anchor_ptr, anchor_ptr=anchor_ptr->next) {
+	anchor_ptr != NULL;
+	prev_a = anchor_ptr, anchor_ptr = next_anchor(text, anchor_ptr)) {
 	int have_soft_newline_in_1st_line = 0;
 re_parse:
 	/*
@@ -5706,7 +5712,7 @@ re_parse:
 	if (line_ptr->data
 	 && anchor_ptr->extent > 0
 	 && anchor_ptr->line_pos >= 0) {
-	    LYSetHiText(anchor_ptr, 
+	    LYSetHiText(anchor_ptr,
 			&line_ptr->data[anchor_ptr->line_pos],
 			anchor_ptr->extent);
 	} else {
@@ -5731,13 +5737,16 @@ re_parse:
 	     && count_line >= stop_before) {
 		LYSetHiText(anchor_ptr, NULL, 0);
 		break;
+	    } else if (line_ptr2 == text->last_line) {
+		break;
 	    }
 
 	    /*
 	     * Double check that we have a line pointer, and if so, copy into
 	     * highlight text.
 	     */
-	    if (line_ptr2) {
+	    if (line_ptr2
+	     && line_ptr2->size) {
 		char *hi_string = NULL;
 		int hi_offset = line_ptr2->offset;
 
@@ -5796,12 +5805,6 @@ re_parse:
 	CTRACE((tfp, "GridText:     add link on line %d col %d [%d] %s\n",
 	       cur_line, anchor_ptr->line_pos,
 	       anchor_ptr->number, "in HText_trimHightext"));
-
-	/*
-	 *  If this is the last anchor, we're done!
-	 */
-	if (anchor_ptr == text->last_anchor)
-	    break;
     }
 }
 
@@ -6224,9 +6227,7 @@ PUBLIC BOOL HText_TAHasMoreLines ARGS2(
 	}
 	return NO;
     } else {
-	for (a = HTMainText->first_anchor; a; a = a->next) {
-	    if (a == HTMainText->last_anchor)
-		break;
+	for (a = HTMainText->first_anchor; a; a = next_anchor(HTMainText, a)) {
 	    if (a->link_type == INPUT_ANCHOR &&
 		links[curlink].l_form == a->input_field) {
 		return same_anchors(a, a->next, TRUE);
@@ -6837,15 +6838,13 @@ PUBLIC int HText_LinksInLines ARGS3(
 
     for (Anchor_ptr = text->first_anchor;
 		Anchor_ptr != NULL && Anchor_ptr->line_num <= end;
-			Anchor_ptr = Anchor_ptr->next) {
+			Anchor_ptr = next_anchor(text, Anchor_ptr)) {
 	if (Anchor_ptr->line_num >= start &&
 	    Anchor_ptr->line_num < end &&
 	    Anchor_ptr->show_anchor &&
 	    !(Anchor_ptr->link_type == INPUT_ANCHOR
 	      && Anchor_ptr->input_field->type == F_HIDDEN_TYPE))
 	    ++total;
-	if (Anchor_ptr == text->last_anchor)
-	    break;
     }
 
     return total;
@@ -8798,11 +8797,11 @@ PUBLIC void HText_endForm ARGS1(
 	 *  Support submission of a single text input field in
 	 *  the form via <return> instead of a submit button. -FM
 	 */
-	TextAnchor * a = text->first_anchor;
+	TextAnchor * a;
 	/*
 	 *  Go through list of anchors and get our input field. -FM
 	 */
-	while (a) {
+	for (a = text->first_anchor; a != NULL; a = next_anchor(text, a)) {
 	    if (a->link_type == INPUT_ANCHOR &&
 		a->input_field->number == HTFormNumber &&
 		a->input_field->type == F_TEXT_TYPE) {
@@ -8822,9 +8821,6 @@ PUBLIC void HText_endForm ARGS1(
 		    a->input_field->disabled = TRUE;
 		break;
 	    }
-	    if (a == text->last_anchor)
-		break;
-	    a = a->next;
 	}
     }
     /*
@@ -9161,27 +9157,24 @@ PUBLIC char * HText_setLastOptionValue ARGS7(
 	new_ptr->value_cs = (submit_value ? submit_val_cs : val_cs);
 
 	if (first_option) {
+	    FormInfo *last_input = text->last_anchor->input_field;
+
 	    StrAllocCopy(HTCurSelectedOptionValue, new_ptr->name);
-	    text->last_anchor->input_field->num_value = 0;
+	    last_input->num_value = 0;
 	    /*
 	     *  If this is the first option in a popup select list,
 	     *  HText_beginInput may have allocated the value and
 	     *  cp_submit_value fields, so free them now to avoid
 	     *  a memory leak. - kw
 	     */
-	    FREE(text->last_anchor->input_field->value);
-	    FREE(text->last_anchor->input_field->cp_submit_value);
-
-	    text->last_anchor->input_field->value =
-		text->last_anchor->input_field->select_list->name;
-	    text->last_anchor->input_field->orig_value =
-		text->last_anchor->input_field->select_list->name;
-	    text->last_anchor->input_field->cp_submit_value =
-		text->last_anchor->input_field->select_list->cp_submit_value;
-	    text->last_anchor->input_field->orig_submit_value =
-		text->last_anchor->input_field->select_list->cp_submit_value;
-	    text->last_anchor->input_field->value_cs =
-		new_ptr->value_cs;
+	    FREE(last_input->value);
+	    FREE(last_input->cp_submit_value);
+
+	    last_input->value             = last_input->select_list->name;
+	    last_input->orig_value        = last_input->select_list->name;
+	    last_input->cp_submit_value   = last_input->select_list->cp_submit_value;
+	    last_input->orig_submit_value = last_input->select_list->cp_submit_value;
+	    last_input->value_cs          = new_ptr->value_cs;
 	} else {
 	    int newlen = strlen(new_ptr->name);
 	    int curlen = strlen(HTCurSelectedOptionValue);
@@ -9197,18 +9190,16 @@ PUBLIC char * HText_setLastOptionValue ARGS7(
 	if (checked) {
 	    int curlen = strlen(new_ptr->name);
 	    int newlen = strlen(HTCurSelectedOptionValue);
+	    FormInfo *last_input = text->last_anchor->input_field;
 	    /*
 	     *  Set the default option as this one.
 	     */
-	    text->last_anchor->input_field->num_value = number;
-	    text->last_anchor->input_field->value = new_ptr->name;
-	    text->last_anchor->input_field->orig_value = new_ptr->name;
-	    text->last_anchor->input_field->cp_submit_value =
-				   new_ptr->cp_submit_value;
-	    text->last_anchor->input_field->orig_submit_value =
-				   new_ptr->cp_submit_value;
-	    text->last_anchor->input_field->value_cs =
-		new_ptr->value_cs;
+	    last_input->num_value	  = number;
+	    last_input->value		  = new_ptr->name;
+	    last_input->orig_value	  = new_ptr->name;
+	    last_input->cp_submit_value	  = new_ptr->cp_submit_value;
+	    last_input->orig_submit_value = new_ptr->cp_submit_value;
+	    last_input->value_cs	  = new_ptr->value_cs;
 	    StrAllocCopy(HTCurSelectedOptionValue, new_ptr->name);
 	    if (newlen > curlen)
 		StrAllocCat(HTCurSelectedOptionValue,
@@ -9298,9 +9289,9 @@ PUBLIC int HText_beginInput ARGS3(
 	if (!text->last_anchor) {
 	    I->checked = TRUE;
 	} else {
-	    TextAnchor * b = text->first_anchor;
+	    TextAnchor * b;
 	    int i2 = 0;
-	    while (b) {
+	    for (b = text->first_anchor; b != NULL; b = next_anchor(text, b)) {
 		if (b->link_type == INPUT_ANCHOR &&
 		    b->input_field->type == F_RADIO_TYPE &&
 		    b->input_field->number == HTFormNumber) {
@@ -9313,13 +9304,9 @@ PUBLIC int HText_beginInput ARGS3(
 			i2++;
 		    }
 		}
-		if (b == text->last_anchor) {
-		    if (i2 == 0)
-		       I->checked = TRUE;
-		    break;
-		}
-		b = b->next;
 	    }
+	    if (i2 == 0)
+	       I->checked = TRUE;
 	}
     }
 
@@ -9889,95 +9876,90 @@ PRIVATE BOOLEAN begin_submission_part ARGS5(
 }
 
 #ifdef EXP_FILE_UPLOAD
-PRIVATE BOOLEAN send_a_file ARGS6(
-    char **,	query,
-    BOOLEAN,	PlainText,
-    char *,	MultipartContentType,
-    char *,	Boundary,
-    char *,	name_used,
+PRIVATE char * load_a_file ARGS2(
+    BOOLEAN *,	use_mime,
     char *,	val_used)
 {
-    char *escaped1 = NULL;
     char *escaped2 = NULL;
     FILE *fd;
     size_t n, bytes;
-    BOOLEAN code = FALSE;
-    BOOLEAN use_mime = FALSE;
     char buffer[257];
     char base64buf[128];
 
     CTRACE((tfp, "Ok, about to convert %s to mime/thingy\n", val_used));
 
+    *use_mime = FALSE;
+
     if ((fd = fopen(val_used, BIN_R)) == 0) {
-	/* We can't open the file, what do we do? */
 	HTAlert(gettext("Can't open file for uploading"));
-	goto exit_disgracefully;
-    }
-    StrAllocCopy(escaped2, "");
-    while ((bytes = fread(buffer, sizeof(char), 256, fd)) != 0) {
-	buffer[bytes] = 0;
-	for (n = 0; n < bytes; ++n) {
-	    int ch = UCH(buffer[n]);
-	    if ((iscntrl(ch) && !isspace(ch))
-	     || (!iscntrl(ch) && !isprint(ch))) {
-		use_mime = TRUE;
+    } else {
+	StrAllocCopy(escaped2, "");
+	while ((bytes = fread(buffer, sizeof(char), 256, fd)) != 0) {
+	    buffer[bytes] = 0;
+	    for (n = 0; n < bytes; ++n) {
+		int ch = UCH(buffer[n]);
+		if ((iscntrl(ch) && !isspace(ch))
+		 || (!iscntrl(ch) && !isprint(ch))) {
+		    *use_mime = TRUE;
+		    break;
+		}
+	    }
+	    if (*use_mime)
 		break;
+	    StrAllocCat(escaped2, buffer);
+	}
+	if (*use_mime) {
+	    rewind(fd);
+	    StrAllocCopy(escaped2, "");
+	    while ((bytes = fread(buffer, sizeof(char), 45, fd)) != 0) {
+		base64_encode(base64buf, buffer, bytes);
+		StrAllocCat(escaped2, base64buf);
 	    }
 	}
-	if (use_mime)
-	    break;
-	StrAllocCat(escaped2, buffer);
-    }
-    if (use_mime) {
-	rewind(fd);
-	StrAllocCopy(escaped2, "");
-	while ((bytes = fread(buffer, sizeof(char), 45, fd)) != 0) {
-	    base64_encode(base64buf, buffer, bytes);
-	    StrAllocCat(escaped2, base64buf);
+	if (ferror(fd)) {
+	    HTAlert(gettext("Short read from file, problem?"));
+	    FREE(escaped2);
 	}
-    }
-    if (ferror(fd)) {
-	/* We got an error reading the file, what do we do? */
-	HTAlert(gettext("Short read from file, problem?"));
 	LYCloseInput(fd);
-	goto exit_disgracefully;
-    }
-    LYCloseInput(fd);
-    /* we need to modify the mime-type here - rp */
-    /* Note: could use LYGetFileInfo for that and for
-       other headers that should be transmitted - kw */
-
-    if (PlainText) {
-	StrAllocCopy(escaped1, name_used);
-    } else if (Boundary) {
-	StrAllocCopy(escaped1, "Content-Disposition: form-data");
-	HTSprintf(&escaped1, "; name=%s", name_used);
-	HTSprintf(&escaped1, "; filename=\"%s\"", val_used);
-	if (MultipartContentType) {
-	    StrAllocCat(escaped1, MultipartContentType);
-	    if (use_mime)
-		StrAllocCat(escaped1, "\r\nContent-Transfer-Encoding: base64");
-	}
-	StrAllocCat(escaped1, "\r\n\r\n");
-    } else {
-	escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
     }
+    return escaped2;
+}
+#endif /* EXP_FILE_UPLOAD */
 
-    HTSprintf(query,
-	      "%s%s%s%s%s",
-	      escaped1,
-	      (Boundary ? "" : "="),
-	      (PlainText ? "\n" : ""),
-	      escaped2,
-	      ((PlainText && *escaped2) ? "\n" : ""));
-    code = TRUE;
+PRIVATE void cannot_transcode ARGS2(
+    BOOL *,		had_warning,
+    CONST char *,	target_csname)
+{
+    if (*had_warning == NO) {
+	*had_warning = YES;
+	_user_message(CANNOT_TRANSCODE_FORM,
+	    target_csname ? target_csname : "UNKNOWN");
+	LYSleepAlert();
+    }
+}
 
-exit_disgracefully:
-    FREE(escaped1);
-    FREE(escaped2);
-    return code;
+#define SPECIAL_8BIT 1
+#define SPECIAL_FORM 2
+
+PRIVATE unsigned check_form_specialchars ARGS1(
+    char *,	value)
+{
+    unsigned result = 0;
+    char *p;
+
+    for (p = value;
+	 non_empty(p) && (result != (SPECIAL_8BIT|SPECIAL_FORM));
+	 p++) {
+	if ((*p == HT_NON_BREAK_SPACE) ||
+	    (*p == HT_EN_SPACE) ||
+	    (*p == LY_SOFT_HYPHEN)) {
+	    result |= SPECIAL_FORM;
+	} else if ((*p & 0x80) != 0) {
+	    result |= SPECIAL_8BIT;
+	}
+    }
+    return result;
 }
-#endif /* EXP_FILE_UPLOAD */
 
 /*
  *  HText_SubmitForm - generate submit data from form fields.
@@ -9993,34 +9975,35 @@ PUBLIC int HText_SubmitForm ARGS4(
 	char *,		link_name,
 	char *,		link_value)
 {
-    TextAnchor *anchor_ptr;
-    int form_number = submit_item->number;
-    FormInfo *form_ptr;
-    PerFormInfo *thisform;
-    char *query = NULL;
-    char *escaped1 = NULL, *escaped2 = NULL;
-    BOOLEAN first_one = TRUE;
-    char *last_textarea_name = NULL;
-    int textarea_lineno = 0;
-    char *previous_blanks = NULL;
+    BOOL had_chartrans_warning = NO;
+    BOOL have_accept_cs = NO;
+    BOOL success;
     BOOLEAN PlainText = FALSE;
     BOOLEAN SemiColon = FALSE;
+    BOOLEAN first_one = TRUE;
+    BOOLEAN use_mime;
+    CONST char *out_csname;
+    CONST char *target_csname = NULL;
+    PerFormInfo *thisform;
+    TextAnchor *anchor_ptr;
     char *Boundary = NULL;
     char *MultipartContentType = NULL;
     char *content_type_out = NULL;
-    int target_cs = -1;
-    CONST char *out_csname;
-    CONST char *target_csname = NULL;
+    char *copied_name_used = NULL;
+    char *copied_val_used = NULL;
+    char *escaped1 = NULL;
+    char *escaped2 = NULL;
+    char *last_textarea_name = NULL;
     char *name_used = "";
-    BOOL form_has_8bit = NO, form_has_special = NO;
-    BOOL field_has_8bit = NO, field_has_special = NO;
-    BOOL name_has_8bit = NO, name_has_special = NO;
-    BOOL have_accept_cs = NO;
-    BOOL success;
-    BOOL had_chartrans_warning = NO;
+    char *previous_blanks = NULL;
+    char *query = NULL;
     char *val_used = "";
-    char *copied_val_used = NULL;
-    char *copied_name_used = NULL;
+    int anchor_count = 0;
+    int anchor_limit = 0;
+    int form_number = submit_item->number;
+    int target_cs = -1;
+    int textarea_lineno = 0;
+    unsigned form_is_special = 0;
 
     CTRACE((tfp, "SubmitForm\n  link_name=%s\n  link_value=%s\n", link_name, link_value));
     if (!HTMainText)
@@ -10126,105 +10109,77 @@ PUBLIC int HText_SubmitForm ARGS4(
     }
 
     /*
-     *  Go through list of anchors and get size first.
+     * Go through list of anchors and get a "max." charset parameter - kw
      */
-    /*
-     *  also get a "max." charset parameter - kw
-     */
-    anchor_ptr = HTMainText->first_anchor;
-    while (anchor_ptr) {
-	if (anchor_ptr->link_type == INPUT_ANCHOR) {
-	    if (anchor_ptr->input_field->number == form_number &&
-			!anchor_ptr->input_field->disabled) {
-
-		char *p;
-		char * val;
-		form_ptr = anchor_ptr->input_field;
-		val = form_ptr->cp_submit_value != NULL ?
-				    form_ptr->cp_submit_value : form_ptr->value;
-		field_has_8bit = NO;
-		field_has_special = NO;
-
-		for (p = val;
-		     non_empty(p) && !(field_has_8bit && field_has_special);
-		     p++)
-		    if ((*p == HT_NON_BREAK_SPACE) ||
-			(*p == HT_EN_SPACE) ||
-			(*p == LY_SOFT_HYPHEN)) {
-			field_has_special = YES;
-		    } else if ((*p & 0x80) != 0) {
-			field_has_8bit = YES;
-		    }
-		for (p = form_ptr->name;
-		     non_empty(p) && !(name_has_8bit && name_has_special);
-		     p++)
-		    if ((*p == HT_NON_BREAK_SPACE) ||
-			(*p == HT_EN_SPACE) ||
-			(*p == LY_SOFT_HYPHEN)) {
-			name_has_special = YES;
-		    } else if ((*p & 0x80) != 0) {
-			name_has_8bit = YES;
-		    }
-
-		if (field_has_8bit || name_has_8bit)
-		    form_has_8bit = YES;
-		if (field_has_special || name_has_special)
-		    form_has_special = YES;
-
-		if (!field_has_8bit && !field_has_special) {
-		    /* already ok */
-		} else if (target_cs < 0) {
-		    /* already confused */
-		} else if (!field_has_8bit &&
-		    (LYCharSet_UC[target_cs].enc == UCT_ENC_8859 ||
-		     (LYCharSet_UC[target_cs].like8859 & UCT_R_8859SPECL))) {
-		    /* those specials will be trivial */
-		} else if (UCNeedNotTranslate(form_ptr->value_cs, target_cs)) {
-		    /* already ok */
-		} else if (UCCanTranslateFromTo(form_ptr->value_cs, target_cs)) {
-		    /* also ok */
-		} else if (UCCanTranslateFromTo(target_cs, form_ptr->value_cs)) {
-		    target_cs = form_ptr->value_cs;	/* try this */
-		    target_csname = NULL; /* will be set after loop */
-		} else {
-		    target_cs = -1; /* don't know what to do */
-		}
+    for (anchor_ptr = HTMainText->first_anchor;
+	 anchor_ptr != NULL;
+	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
 
-		/*  Same for name */
-		if (!name_has_8bit && !name_has_special) {
-		    /* already ok */
-		} else if (target_cs < 0) {
-		    /* already confused */
-		} else if (!name_has_8bit &&
-		    (LYCharSet_UC[target_cs].enc == UCT_ENC_8859 ||
-		     (LYCharSet_UC[target_cs].like8859 & UCT_R_8859SPECL))) {
-		    /* those specials will be trivial */
-		} else if (UCNeedNotTranslate(form_ptr->name_cs, target_cs)) {
-		    /* already ok */
-		} else if (UCCanTranslateFromTo(form_ptr->name_cs, target_cs)) {
-		    /* also ok */
-		} else if (UCCanTranslateFromTo(target_cs, form_ptr->name_cs)) {
-		    target_cs = form_ptr->value_cs;	/* try this */
-		    target_csname = NULL; /* will be set after loop */
-		} else {
-		    target_cs = -1; /* don't know what to do */
-		}
+	if (anchor_ptr->link_type != INPUT_ANCHOR)
+	    continue;
 
-	    } else if (anchor_ptr->input_field->number > form_number) {
-		break;
+	if (anchor_ptr->input_field->number == form_number &&
+		    !anchor_ptr->input_field->disabled) {
+
+	    FormInfo *form_ptr = anchor_ptr->input_field;
+	    char * val = form_ptr->cp_submit_value != NULL
+			    ? form_ptr->cp_submit_value
+			    : form_ptr->value;
+
+	    unsigned field_is_special = check_form_specialchars(val);
+	    unsigned name_is_special = check_form_specialchars(form_ptr->name);
+
+	    form_is_special = (field_is_special | name_is_special);
+
+	    if (field_is_special == 0) {
+		/* already ok */
+	    } else if (target_cs < 0) {
+		/* already confused */
+	    } else if ((field_is_special & SPECIAL_8BIT) == 0
+	     && (LYCharSet_UC[target_cs].enc == UCT_ENC_8859
+	      || (LYCharSet_UC[target_cs].like8859 & UCT_R_8859SPECL))) {
+		/* those specials will be trivial */
+	    } else if (UCNeedNotTranslate(form_ptr->value_cs, target_cs)) {
+		/* already ok */
+	    } else if (UCCanTranslateFromTo(form_ptr->value_cs, target_cs)) {
+		/* also ok */
+	    } else if (UCCanTranslateFromTo(target_cs, form_ptr->value_cs)) {
+		target_cs = form_ptr->value_cs;	/* try this */
+		target_csname = NULL; /* will be set after loop */
+	    } else {
+		target_cs = -1; /* don't know what to do */
+	    }
+
+	    /*  Same for name */
+	    if (name_is_special == 0) {
+		/* already ok */
+	    } else if (target_cs < 0) {
+		/* already confused */
+	    } else if ((name_is_special & SPECIAL_8BIT) == 0
+	     && (LYCharSet_UC[target_cs].enc == UCT_ENC_8859
+	      || (LYCharSet_UC[target_cs].like8859 & UCT_R_8859SPECL))) {
+		/* those specials will be trivial */
+	    } else if (UCNeedNotTranslate(form_ptr->name_cs, target_cs)) {
+		/* already ok */
+	    } else if (UCCanTranslateFromTo(form_ptr->name_cs, target_cs)) {
+		/* also ok */
+	    } else if (UCCanTranslateFromTo(target_cs, form_ptr->name_cs)) {
+		target_cs = form_ptr->value_cs;	/* try this */
+		target_csname = NULL; /* will be set after loop */
+	    } else {
+		target_cs = -1; /* don't know what to do */
 	    }
-	}
 
-	if (anchor_ptr == HTMainText->last_anchor)
+	    ++anchor_limit;
+	} else if (anchor_ptr->input_field->number > form_number) {
 	    break;
-
-	anchor_ptr = anchor_ptr->next;
+	}
     }
 
     if (target_csname == NULL && target_cs >= 0) {
-	if (form_has_8bit) {
+	if ((form_is_special & SPECIAL_8BIT) != 0) {
 	    target_csname = LYCharSet_UC[target_cs].MIMEname;
-	} else if (form_has_special) {
+	} else if ((form_is_special & SPECIAL_FORM) != 0) {
 	    target_csname = LYCharSet_UC[target_cs].MIMEname;
 	} else {
 	    target_csname = "us-ascii";
@@ -10283,8 +10238,9 @@ PUBLIC int HText_SubmitForm ARGS4(
 	 *  For multipart/form-data the equivalent will be done later,
 	 *  separately for each form field. - kw
 	 */
-	if (have_accept_cs ||
-	    (form_has_8bit || form_has_special)) {
+	if (have_accept_cs
+	 || ((form_is_special & SPECIAL_8BIT) != 0
+	  || (form_is_special & SPECIAL_FORM) != 0)) {
 	    if (target_cs >= 0 && target_csname) {
 		if (Boundary == NULL) {
 		    if ((HTMainText->node_anchor->charset &&
@@ -10297,11 +10253,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 		    }
 		}
 	    } else {
-		had_chartrans_warning = YES;
-		_user_message(
-		    CANNOT_TRANSCODE_FORM,
-		    target_csname ? target_csname : "UNKNOWN");
-		LYSleepAlert();
+		cannot_transcode(&had_chartrans_warning, target_csname);
 	    }
 	}
     }
@@ -10309,417 +10261,298 @@ PUBLIC int HText_SubmitForm ARGS4(
     out_csname = target_csname;
 
     /*
-     *  Reset anchor->ptr.
+     * Go through list of anchors and assemble URL query.
      */
-    anchor_ptr = HTMainText->first_anchor;
-    /*
-     *  Go through list of anchors and assemble URL query.
-     */
-    while (anchor_ptr) {
-	if (anchor_ptr->link_type == INPUT_ANCHOR) {
-	    if (anchor_ptr->input_field->number == form_number &&
-			!anchor_ptr->input_field->disabled) {
-		char *p;
-		int out_cs;
-		form_ptr = anchor_ptr->input_field;
+    for (anchor_ptr = HTMainText->first_anchor;
+	 anchor_ptr != NULL;
+	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
 
-		if (form_ptr->type != F_TEXTAREA_TYPE)
-		    textarea_lineno = 0;
+	if (anchor_ptr->link_type != INPUT_ANCHOR)
+	    continue;
 
-		switch(form_ptr->type) {
-		case F_RESET_TYPE:
-		    break;
+	if (anchor_ptr->input_field->number == form_number &&
+		    !anchor_ptr->input_field->disabled) {
+
+	    FormInfo *form_ptr = anchor_ptr->input_field;
+	    int out_cs;
+
+	    if (form_ptr->type != F_TEXTAREA_TYPE)
+		textarea_lineno = 0;
+
+	    ++anchor_count;
+	    switch(form_ptr->type) {
+	    case F_RESET_TYPE:
+		break;
 #ifdef EXP_FILE_UPLOAD
-		case F_FILE_TYPE:
-		    name_used = (form_ptr->name ? form_ptr->name : "");
-		    val_used = (form_ptr->value ? form_ptr->value : "");
-		    CTRACE((tfp,
-			    "I'd submit %s (from %s), but you've not finished it\n",
-			    val_used, name_used));
-		    break;
+	    case F_FILE_TYPE:
+		name_used = (form_ptr->name ? form_ptr->name : "");
+		val_used = (form_ptr->value ? form_ptr->value : "");
+		CTRACE((tfp, "SubmitForm[%d/%d]: I'd submit %s (from %s), but you've not finished it\n",
+			     anchor_count, anchor_limit,
+			     val_used, name_used));
+		break;
 #endif
-		case F_SUBMIT_TYPE:
-		case F_TEXT_SUBMIT_TYPE:
-		case F_IMAGE_SUBMIT_TYPE:
-		    if (!(non_empty(form_ptr->name) &&
-			  !strcmp(form_ptr->name, link_name))) {
-			CTRACE((tfp,
-				    "SubmitForm: skipping submit field with "));
-			CTRACE((tfp, "name \"%s\" for link_name \"%s\", %s.\n",
-				    form_ptr->name ? form_ptr->name : "???",
-				    link_name ? link_name : "???",
-				    non_empty(form_ptr->name) ?
-				    "not current link" : "no field name"));
-			break;
-		    }
-		    if (!(form_ptr->type == F_TEXT_SUBMIT_TYPE ||
-			(non_empty(form_ptr->value) &&
-			 !strcmp(form_ptr->value, link_value)))) {
-			CTRACE((tfp,
-				"SubmitForm: skipping submit field with "));
-			CTRACE((tfp,
-				"name \"%s\" for link_name \"%s\", %s!\n",
-				form_ptr->name ? form_ptr->name : "???",
-				link_name ? link_name : "???",
-				"values are different"));
-			break;
-		    }
-		    /* FALLTHRU */
-		case F_RADIO_TYPE:
-		case F_CHECKBOX_TYPE:
-		case F_TEXTAREA_TYPE:
-		case F_PASSWORD_TYPE:
-		case F_TEXT_TYPE:
-		case F_OPTION_LIST_TYPE:
-		case F_HIDDEN_TYPE:
-		    /*
-		     *	Be sure to actually look at the option submit value.
-		     */
-		    if (form_ptr->cp_submit_value != NULL) {
-			val_used = form_ptr->cp_submit_value;
-		    } else {
-			val_used = form_ptr->value;
-		    }
-
-		    /*
-		     *  Charset-translate value now, because we need
-		     *  to know the charset parameter for multipart
-		     *  bodyparts. - kw
-		     */
-		    field_has_8bit = NO;
-		    field_has_special = NO;
-		    for (p = val_used;
-			 non_empty(p) && !(field_has_8bit && field_has_special);
-			 p++) {
-			if ((*p == HT_NON_BREAK_SPACE) ||
-			    (*p == HT_EN_SPACE) ||
-			    (*p == LY_SOFT_HYPHEN)) {
-			    field_has_special = YES;
-			} else if ((*p & 0x80) != 0) {
-			    field_has_8bit = YES;
-			}
-		    }
+	    case F_SUBMIT_TYPE:
+	    case F_TEXT_SUBMIT_TYPE:
+	    case F_IMAGE_SUBMIT_TYPE:
+		if (!(non_empty(form_ptr->name) &&
+		      !strcmp(form_ptr->name, link_name))) {
+		    CTRACE((tfp, "SubmitForm[%d/%d]: skipping submit field with ",
+				 anchor_count, anchor_limit));
+		    CTRACE((tfp, "name \"%s\" for link_name \"%s\", %s.\n",
+				 form_ptr->name ? form_ptr->name : "???",
+				 link_name ? link_name : "???",
+				 non_empty(form_ptr->name) ?
+				 "not current link" : "no field name"));
+		    break;
+		}
+		if (!(form_ptr->type == F_TEXT_SUBMIT_TYPE ||
+		    (non_empty(form_ptr->value) &&
+		     !strcmp(form_ptr->value, link_value)))) {
+		    CTRACE((tfp, "SubmitForm[%d/%d]: skipping submit field with ",
+				 anchor_count, anchor_limit));
+		    CTRACE((tfp, "name \"%s\" for link_name \"%s\", %s!\n",
+				 form_ptr->name ? form_ptr->name : "???",
+				 link_name ? link_name : "???",
+				 "values are different"));
+		    break;
+		}
+		/* FALLTHRU */
+	    case F_RADIO_TYPE:
+	    case F_CHECKBOX_TYPE:
+	    case F_TEXTAREA_TYPE:
+	    case F_PASSWORD_TYPE:
+	    case F_TEXT_TYPE:
+	    case F_OPTION_LIST_TYPE:
+	    case F_HIDDEN_TYPE:
+		/*
+		 * Be sure to actually look at the option submit value.
+		 */
+		if (form_ptr->cp_submit_value != NULL) {
+		    val_used = form_ptr->cp_submit_value;
+		} else {
+		    val_used = form_ptr->value;
+		}
 
-		    if (field_has_8bit || field_has_special) {
-			/*  We should translate back. */
-			StrAllocCopy(copied_val_used, val_used);
-			success = LYUCTranslateBackFormData(&copied_val_used,
+		/*
+		 * Charset-translate value now, because we need to know the
+		 * charset parameter for multipart bodyparts.  - kw
+		 */
+		if (check_form_specialchars(val_used) != 0) {
+		    /*  We should translate back. */
+		    StrAllocCopy(copied_val_used, val_used);
+		    success = LYUCTranslateBackFormData(&copied_val_used,
 							form_ptr->value_cs,
 							target_cs, PlainText);
-			CTRACE((tfp, "SubmitForm: field \"%s\" %d %s -> %d %s %s\n",
-				    form_ptr->name ? form_ptr->name : "",
-				    form_ptr->value_cs,
-				    form_ptr->value_cs >= 0 ?
-				    LYCharSet_UC[form_ptr->value_cs].MIMEname :
-									  "???",
-				    target_cs,
-				    target_csname ? target_csname : "???",
-				    success ? "OK" : "FAILED"));
-			if (success) {
-			    val_used = copied_val_used;
-			}
-		    } else {  /* We can use the value directly. */
-			CTRACE((tfp, "SubmitForm: field \"%s\" %d %s OK\n",
-				    form_ptr->name ? form_ptr->name : "",
-				    target_cs,
-				    target_csname ? target_csname : "???"));
-			success = YES;
+		    CTRACE((tfp, "SubmitForm[%d/%d]: field \"%s\" %d %s -> %d %s %s\n",
+				 anchor_count, anchor_limit,
+				 form_ptr->name ? form_ptr->name : "",
+				 form_ptr->value_cs,
+				 form_ptr->value_cs >= 0
+				     ? LYCharSet_UC[form_ptr->value_cs].MIMEname
+				     : "???",
+				 target_cs,
+				 target_csname ? target_csname : "???",
+				 success ? "OK" : "FAILED"));
+		    if (success) {
+			val_used = copied_val_used;
 		    }
-		    if (!success) {
-			if (!had_chartrans_warning) {
-			    had_chartrans_warning = YES;
-			    _user_message(
-				CANNOT_TRANSCODE_FORM,
-				target_csname ? target_csname : "UNKNOWN");
-			    LYSleepAlert();
-			}
-			out_cs = form_ptr->value_cs;
+		} else {  /* We can use the value directly. */
+		    CTRACE((tfp, "SubmitForm[%d/%d]: field \"%s\" %d %s OK\n",
+				 anchor_count, anchor_limit,
+				 form_ptr->name ? form_ptr->name : "",
+				 target_cs,
+				 target_csname ? target_csname : "???"));
+		    success = YES;
+		}
+		if (!success) {
+		    cannot_transcode(&had_chartrans_warning, target_csname);
+		    out_cs = form_ptr->value_cs;
+		} else {
+		    out_cs = target_cs;
+		}
+		if (out_cs >= 0)
+		    out_csname = LYCharSet_UC[out_cs].MIMEname;
+		if (Boundary) {
+		    StrAllocCopy(MultipartContentType,
+				 "\r\nContent-Type: text/plain");
+		    if (!success && form_ptr->value_cs < 0) {
+			/*  This is weird. */
+			out_csname = "UNKNOWN-8BIT";
+		    } else if (!success) {
+			target_csname = NULL;
 		    } else {
-			out_cs = target_cs;
-		    }
-		    if (out_cs >= 0)
-			out_csname = LYCharSet_UC[out_cs].MIMEname;
-		    if (Boundary) {
-			StrAllocCopy(MultipartContentType,
-				     "\r\nContent-Type: text/plain");
-			if (!success && form_ptr->value_cs < 0) {
-			    /*  This is weird. */
-			    out_csname = "UNKNOWN-8BIT";
-			} else if (!success) {
-			    target_csname = NULL;
-			} else {
-			    if (!target_csname) {
-				target_csname = LYCharSet_UC[target_cs].MIMEname;
-			    }
+			if (!target_csname) {
+			    target_csname = LYCharSet_UC[target_cs].MIMEname;
 			}
-			if (strcmp(out_csname, "iso-8859-1"))
-			    HTSprintf(&MultipartContentType, "; charset=%s", out_csname);
 		    }
+		    if (strcmp(out_csname, "iso-8859-1"))
+			HTSprintf(&MultipartContentType, "; charset=%s", out_csname);
+		}
 
-		    /*
-		     *  Charset-translate name now, because we need
-		     *  to know the charset parameter for multipart
-		     *  bodyparts. - kw
-		     */
-		    if (form_ptr->type == F_TEXTAREA_TYPE) {
-			textarea_lineno++;
-			if (textarea_lineno > 1 &&
-			    last_textarea_name && form_ptr->name &&
-			    !strcmp(last_textarea_name, form_ptr->name)) {
-			    break;
-			}
-		    }
-		    name_used = (form_ptr->name ?
-				 form_ptr->name : "");
-
-		    name_has_8bit = NO;
-		    name_has_special = NO;
-		    for (p = name_used;
-			 non_empty(p) && !(name_has_8bit && name_has_special);
-			 p++) {
-			if ((*p == HT_NON_BREAK_SPACE) ||
-			    (*p == HT_EN_SPACE) ||
-			    (*p == LY_SOFT_HYPHEN)) {
-			    name_has_special = YES;
-			} else if ((*p & 0x80) != 0) {
-			    name_has_8bit = YES;
-			}
+		/*
+		 * Charset-translate name now, because we need to know the
+		 * charset parameter for multipart bodyparts.  - kw
+		 */
+		if (form_ptr->type == F_TEXTAREA_TYPE) {
+		    textarea_lineno++;
+		    if (textarea_lineno > 1 &&
+			last_textarea_name && form_ptr->name &&
+			!strcmp(last_textarea_name, form_ptr->name)) {
+			break;
 		    }
+		}
+		name_used = (form_ptr->name ?
+			     form_ptr->name : "");
 
-		    if (name_has_8bit || name_has_special) {
-			/*  We should translate back. */
-			StrAllocCopy(copied_name_used, name_used);
-			success = LYUCTranslateBackFormData(&copied_name_used,
+		if (check_form_specialchars(name_used) != 0) {
+		    /*  We should translate back. */
+		    StrAllocCopy(copied_name_used, name_used);
+		    success = LYUCTranslateBackFormData(&copied_name_used,
 							form_ptr->name_cs,
 							target_cs, PlainText);
-			CTRACE((tfp, "SubmitForm: name \"%s\" %d %s -> %d %s %s\n",
-				    form_ptr->name ? form_ptr->name : "",
-				    form_ptr->name_cs,
-				    form_ptr->name_cs >= 0 ?
-				    LYCharSet_UC[form_ptr->name_cs].MIMEname :
-									  "???",
-				    target_cs,
-				    target_csname ? target_csname : "???",
-				    success ? "OK" : "FAILED"));
-			if (success) {
-			    name_used = copied_name_used;
-			}
-			if (Boundary) {
-			    if (!success) {
-				StrAllocCopy(MultipartContentType, "");
-				target_csname = NULL;
-			    } else {
-				if (!target_csname)
-				    target_csname = LYCharSet_UC[target_cs].MIMEname;
-			    }
-			}
-		    } else {  /* We can use the name directly. */
-			CTRACE((tfp, "SubmitForm: name \"%s\" %d %s OK\n",
-				    form_ptr->name ? form_ptr->name : "",
-				    target_cs,
-				    target_csname ? target_csname : "???"));
-			success = YES;
-			if (Boundary) {
-			    StrAllocCopy(copied_name_used, name_used);
-			}
+		    CTRACE((tfp, "SubmitForm[%d/%d]: name \"%s\" %d %s -> %d %s %s\n",
+				 anchor_count, anchor_limit,
+				 form_ptr->name ? form_ptr->name : "",
+				 form_ptr->name_cs,
+				 form_ptr->name_cs >= 0
+				     ? LYCharSet_UC[form_ptr->name_cs].MIMEname
+				     : "???",
+				 target_cs,
+				 target_csname ? target_csname : "???",
+				 success ? "OK" : "FAILED"));
+		    if (success) {
+			name_used = copied_name_used;
 		    }
-		    if (!success) {
-			if (!had_chartrans_warning) {
-			    had_chartrans_warning = YES;
-			    _user_message(
-				CANNOT_TRANSCODE_FORM,
-				target_csname ? target_csname : "UNKNOWN");
-			    LYSleepAlert();
+		    if (Boundary) {
+			if (!success) {
+			    StrAllocCopy(MultipartContentType, "");
+			    target_csname = NULL;
+			} else {
+			    if (!target_csname)
+				target_csname = LYCharSet_UC[target_cs].MIMEname;
 			}
 		    }
+		} else {  /* We can use the name directly. */
+		    CTRACE((tfp, "SubmitForm[%d/%d]: name \"%s\" %d %s OK\n",
+				anchor_count, anchor_limit,
+				form_ptr->name ? form_ptr->name : "",
+				target_cs,
+				target_csname ? target_csname : "???"));
+		    success = YES;
 		    if (Boundary) {
-			/*
-			 *  According to RFC 1867, Non-ASCII field names
-			 *  "should be encoded according to the prescriptions
-			 *  of RFC 1522 [...].  I don't think RFC 1522 actually
-			 *  is meant to apply to parameters like this, and it
-			 *  is unknown whether any server would make sense of
-			 *  it, so for now just use some quoting/escaping and
-			 *  otherwise leave 8-bit values as they are.
-			 *  Non-ASCII characters in form field names submitted
-			 *  as multipart/form-data can only occur if the form
-			 *  provider specifically asked for it anyway. - kw
-			 */
-			HTMake822Word(&copied_name_used);
-			name_used = copied_name_used;
+			StrAllocCopy(copied_name_used, name_used);
 		    }
-
-		    break;
-		default:
-		    CTRACE((tfp, "SubmitForm: What type is %d?\n",
-				form_ptr->type));
-		    break;
 		}
-
-		switch(form_ptr->type) {
-
-		case F_RESET_TYPE:
-		    break;
-
-#ifdef EXP_FILE_UPLOAD
-		case F_FILE_TYPE:
-		    first_one = begin_submission_part(&query,
-						    first_one,
-						    SemiColon,
-						    PlainText,
-						    Boundary);
-		    if (!send_a_file(&query,
-				     PlainText,
-				     MultipartContentType,
-				     Boundary,
-				     name_used,
-				     val_used))
-			goto exit_disgracefully;
-		break;
-#endif /* EXP_FILE_UPLOAD */
-
-		case F_SUBMIT_TYPE:
-		case F_TEXT_SUBMIT_TYPE:
-		case F_IMAGE_SUBMIT_TYPE:
+		if (!success) {
+		    cannot_transcode(&had_chartrans_warning, target_csname);
+		}
+		if (Boundary) {
 		    /*
-		     *  If it has a non-zero length name (e.g., because
-		     *  its IMAGE_SUBMIT_TYPE is to be handled homologously
-		     *  to an image map, or a SUBMIT_TYPE in a set of
-		     *  multiple submit buttons, or a single type="text"
-		     *  that's been converted to a TEXT_SUBMIT_TYPE),
-		     *  include the name=value pair, or fake name.x=0 and
-		     *  name.y=0 pairs for IMAGE_SUBMIT_TYPE. -FM
+		     *  According to RFC 1867, Non-ASCII field names
+		     *  "should be encoded according to the prescriptions
+		     *  of RFC 1522 [...].  I don't think RFC 1522 actually
+		     *  is meant to apply to parameters like this, and it
+		     *  is unknown whether any server would make sense of
+		     *  it, so for now just use some quoting/escaping and
+		     *  otherwise leave 8-bit values as they are.
+		     *  Non-ASCII characters in form field names submitted
+		     *  as multipart/form-data can only occur if the form
+		     *  provider specifically asked for it anyway. - kw
 		     */
-		    if ((non_empty(form_ptr->name) &&
-			!strcmp(form_ptr->name, link_name)) &&
-		       (form_ptr->type == F_TEXT_SUBMIT_TYPE ||
-			(non_empty(form_ptr->value) &&
-			 !strcmp(form_ptr->value, link_value)))) {
-			int cdisp_name_startpos = 0;
-
-			first_one = begin_submission_part(&query,
-							  first_one,
-							  SemiColon,
-							  PlainText,
-							  Boundary);
+		    HTMake822Word(&copied_name_used);
+		    name_used = copied_name_used;
+		}
 
-			if (PlainText) {
-			    StrAllocCopy(escaped1, name_used);
-			} else if (Boundary) {
-			    StrAllocCopy(escaped1,
-				    "Content-Disposition: form-data; name=");
-			    cdisp_name_startpos = strlen(escaped1);
-			    StrAllocCat(escaped1, name_used);
-			    if (MultipartContentType)
-				StrAllocCat(escaped1, MultipartContentType);
-			    StrAllocCat(escaped1, "\r\n\r\n");
-			} else {
-			    escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
-			}
+		break;
+	    default:
+		CTRACE((tfp, "SubmitForm[%d/%d]: What type is %d?\n",
+			     anchor_count, anchor_limit,
+			     form_ptr->type));
+		break;
+	    }
 
-			if (PlainText || Boundary) {
-			    StrAllocCopy(escaped2,
-					 (val_used ?
-					  val_used : ""));
-			} else {
-			    escaped2 = HTEscapeSP(val_used, URL_XALPHAS);
-			}
+	    switch(form_ptr->type) {
 
-			if (form_ptr->type == F_IMAGE_SUBMIT_TYPE) {
-			    /*
-			     *  It's a clickable image submit button.
-			     *  Fake a 0,0 coordinate pair, which
-			     *  typically returns the image's default. -FM
-			     */
-			    if (Boundary) {
-				escaped1[cdisp_name_startpos] = '\0';
-				HTSprintf(&query,
-					"%s.x\r\n\r\n0\r\n--%s\r\n%s.y\r\n\r\n0",
-					escaped1,
-					Boundary,
-					escaped1);
-			    } else {
-				HTSprintf(&query,
-					"%s.x=0%s%s.y=0%s",
-					escaped1,
-					(PlainText ?
-					      "\n" : (SemiColon ?
-							    ";" : "&")),
-					escaped1,
-					((PlainText && *escaped1) ?
-							     "\n" : ""));
-			    }
-			} else {
-			    /*
-			     *  It's a standard submit button.
-			     *  Use the name=value pair. = FM
-			     */
-			    HTSprintf(&query,
-				    "%s%s%s%s%s",
-				    escaped1,
-				    (Boundary ? "" : "="),
-				    (PlainText ? "\n" : ""),
-				    escaped2,
-				    ((PlainText && *escaped2) ? "\n" : ""));
-			}
-			FREE(escaped1);
-			FREE(escaped2);
+	    case F_RESET_TYPE:
+		break;
+
+#ifdef EXP_FILE_UPLOAD
+	    case F_FILE_TYPE:
+		first_one = begin_submission_part(&query,
+						  first_one,
+						  SemiColon,
+						  PlainText,
+						  Boundary);
+		if ((escaped2 = load_a_file(&use_mime, val_used)) == NULL)
+		    goto exit_disgracefully;
+
+		/* FIXME: we need to modify the mime-type here - rp */
+		/* Note: could use LYGetFileInfo for that and for
+		   other headers that should be transmitted - kw */
+
+		if (PlainText) {
+		    StrAllocCopy(escaped1, name_used);
+		} else if (Boundary) {
+		    StrAllocCopy(escaped1, "Content-Disposition: form-data");
+		    HTSprintf(&escaped1, "; name=\"%s\"", name_used);
+		    HTSprintf(&escaped1, "; filename=\"%s\"", val_used);
+		    if (MultipartContentType) {
+			StrAllocCat(escaped1, MultipartContentType);
+			if (use_mime)
+			    StrAllocCat(escaped1, "\r\nContent-Transfer-Encoding: base64");
 		    }
-		    FREE(copied_name_used);
-		    FREE(copied_val_used);
-		    break;
+		    StrAllocCat(escaped1, "\r\n\r\n");
+		} else {
+		    escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
+		}
 
-		case F_RADIO_TYPE:
-		case F_CHECKBOX_TYPE:
-		    /*
-		     *  Only add if selected.
-		     */
-		    if (form_ptr->num_value) {
-			first_one = begin_submission_part(&query,
-							  first_one,
-							  SemiColon,
-							  PlainText,
-							  Boundary);
+		HTSprintf(&query,
+			  "%s%s%s%s%s",
+			  escaped1,
+			  (Boundary ? "" : "="),
+			  (PlainText ? "\n" : ""),
+			  escaped2,
+			  ((PlainText && *escaped2) ? "\n" : ""));
+		break;
+#endif /* EXP_FILE_UPLOAD */
 
-			if (PlainText) {
-			    StrAllocCopy(escaped1, name_used);
-			} else if (Boundary) {
-			    StrAllocCopy(escaped1,
-				     "Content-Disposition: form-data; name=");
-			    StrAllocCat(escaped1, name_used);
-			    if (MultipartContentType)
-				StrAllocCat(escaped1, MultipartContentType);
-			    StrAllocCat(escaped1, "\r\n\r\n");
-			} else {
-			    escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
-			}
+	    case F_SUBMIT_TYPE:
+	    case F_TEXT_SUBMIT_TYPE:
+	    case F_IMAGE_SUBMIT_TYPE:
+		/*
+		 *  If it has a non-zero length name (e.g., because
+		 *  its IMAGE_SUBMIT_TYPE is to be handled homologously
+		 *  to an image map, or a SUBMIT_TYPE in a set of
+		 *  multiple submit buttons, or a single type="text"
+		 *  that's been converted to a TEXT_SUBMIT_TYPE),
+		 *  include the name=value pair, or fake name.x=0 and
+		 *  name.y=0 pairs for IMAGE_SUBMIT_TYPE. -FM
+		 */
+		if ((non_empty(form_ptr->name) &&
+		    !strcmp(form_ptr->name, link_name)) &&
+		   (form_ptr->type == F_TEXT_SUBMIT_TYPE ||
+		    (non_empty(form_ptr->value) &&
+		     !strcmp(form_ptr->value, link_value)))) {
 
-			if (PlainText || Boundary) {
-			    StrAllocCopy(escaped2,
-					 (val_used ?
-					  val_used : ""));
-			} else {
-			    escaped2 = HTEscapeSP(val_used, URL_XALPHAS);
-			}
+		    first_one = begin_submission_part(&query,
+						      first_one,
+						      SemiColon,
+						      PlainText,
+						      Boundary);
 
-			HTSprintf(&query,
-				"%s%s%s%s%s",
-				escaped1,
-				(Boundary ?
-				       "" : "="),
-				(PlainText ?
-				      "\n" : ""),
-				escaped2,
-				((PlainText && *escaped2) ?
-						     "\n" : ""));
-			FREE(escaped1);
-			FREE(escaped2);
+		    if (PlainText) {
+			StrAllocCopy(escaped1, name_used);
+		    } else if (Boundary) {
+			StrAllocCopy(escaped1, "Content-Disposition: form-data");
+			HTSprintf(&escaped1, "; name=\"%s\"", name_used);
+			if (MultipartContentType)
+			    StrAllocCat(escaped1, MultipartContentType);
+			StrAllocCat(escaped1, "\r\n\r\n");
+		    } else {
+			escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
 		    }
-		    FREE(copied_name_used);
-		    FREE(copied_val_used);
-		    break;
 
-		case F_TEXTAREA_TYPE:
 		    if (PlainText || Boundary) {
 			StrAllocCopy(escaped2,
 				     (val_used ?
@@ -10728,38 +10561,35 @@ PUBLIC int HText_SubmitForm ARGS4(
 			escaped2 = HTEscapeSP(val_used, URL_XALPHAS);
 		    }
 
-		    if (!last_textarea_name ||
-			strcmp(last_textarea_name, form_ptr->name)) {
-			textarea_lineno = 1;
+		    if (form_ptr->type == F_IMAGE_SUBMIT_TYPE) {
 			/*
-			 *  Names are different so this is the first
-			 *  textarea or a different one from any before
-			 *  it.
+			 * It's a clickable image submit button.  Fake a 0,0
+			 * coordinate pair, which typically returns the image's
+			 * default.  -FM
 			 */
 			if (Boundary) {
-			    StrAllocCopy(previous_blanks, "\r\n");
-			} else {
-			    FREE(previous_blanks);
-			}
-			first_one = begin_submission_part(&query,
-							  first_one,
-							  SemiColon,
-							  PlainText,
-							  Boundary);
-
-			if (PlainText) {
-			    StrAllocCopy(escaped1, name_used);
-			} else if (Boundary) {
-			    StrAllocCopy(escaped1,
-				     "Content-Disposition: form-data; name=");
-			    StrAllocCat(escaped1, name_used);
-			    if (MultipartContentType)
-				StrAllocCat(escaped1, MultipartContentType);
-			    StrAllocCat(escaped1, "\r\n\r\n");
+			    *(strchr(escaped1, '=') + 1) = '\0';
+			    HTSprintf(&query,
+				    "%s.x\r\n\r\n0\r\n--%s\r\n%s.y\r\n\r\n0",
+				    escaped1,
+				    Boundary,
+				    escaped1);
 			} else {
-			    escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
+			    HTSprintf(&query,
+				    "%s.x=0%s%s.y=0%s",
+				    escaped1,
+				    (PlainText ?
+					  "\n" : (SemiColon ?
+							";" : "&")),
+				    escaped1,
+				    ((PlainText && *escaped1) ?
+							 "\n" : ""));
 			}
-
+		    } else {
+			/*
+			 * It's a standard submit button.  Use the name=value
+			 * pair.  = FM
+			 */
 			HTSprintf(&query,
 				"%s%s%s%s%s",
 				escaped1,
@@ -10767,54 +10597,27 @@ PUBLIC int HText_SubmitForm ARGS4(
 				(PlainText ? "\n" : ""),
 				escaped2,
 				((PlainText && *escaped2) ? "\n" : ""));
-			FREE(escaped1);
-			last_textarea_name = form_ptr->name;
-		    } else {
-			/*
-			 *  This is a continuation of a previous textarea
-			 *  add %0d%0a (\r\n) and the escaped string.
-			 */
-			if (escaped2[0] != '\0') {
-			    if (previous_blanks) {
-				StrAllocCat(query, previous_blanks);
-				FREE(previous_blanks);
-			    }
-			    if (PlainText) {
-				HTSprintf(&query, "%s\n", escaped2);
-			    } else if (Boundary) {
-				HTSprintf(&query, "%s\r\n", escaped2);
-			    } else {
-				HTSprintf(&query, "%%0d%%0a%s", escaped2);
-			    }
-			} else {
-			    if (PlainText) {
-				StrAllocCat(previous_blanks, "\n");
-			    } else if (Boundary) {
-				StrAllocCat(previous_blanks, "\r\n");
-			    } else {
-				StrAllocCat(previous_blanks, "%0d%0a");
-			    }
-			}
 		    }
-		    FREE(escaped2);
-		    FREE(copied_val_used);
-		    break;
+		}
+		break;
 
-		case F_PASSWORD_TYPE:
-		case F_TEXT_TYPE:
-		case F_OPTION_LIST_TYPE:
-		case F_HIDDEN_TYPE:
+	    case F_RADIO_TYPE:
+	    case F_CHECKBOX_TYPE:
+		/*
+		 *  Only add if selected.
+		 */
+		if (form_ptr->num_value) {
 		    first_one = begin_submission_part(&query,
 						      first_one,
 						      SemiColon,
 						      PlainText,
 						      Boundary);
+
 		    if (PlainText) {
-		       StrAllocCopy(escaped1, name_used);
+			StrAllocCopy(escaped1, name_used);
 		    } else if (Boundary) {
-			StrAllocCopy(escaped1,
-				    "Content-Disposition: form-data; name=");
-			StrAllocCat(escaped1, name_used);
+			StrAllocCopy(escaped1, "Content-Disposition: form-data");
+			HTSprintf(&escaped1, "; name=\"%s\"", name_used);
 			if (MultipartContentType)
 			    StrAllocCat(escaped1, MultipartContentType);
 			StrAllocCat(escaped1, "\r\n\r\n");
@@ -10837,22 +10640,132 @@ PUBLIC int HText_SubmitForm ARGS4(
 			    (PlainText ? "\n" : ""),
 			    escaped2,
 			    ((PlainText && *escaped2) ? "\n" : ""));
-		    FREE(escaped1);
-		    FREE(escaped2);
-		    FREE(copied_name_used);
-		    FREE(copied_val_used);
-		    break;
 		}
-	    } else if (anchor_ptr->input_field->number > form_number) {
 		break;
-	    }
-	}
 
-	if (anchor_ptr == HTMainText->last_anchor)
-	    break;
+	    case F_TEXTAREA_TYPE:
+		if (PlainText || Boundary) {
+		    StrAllocCopy(escaped2,
+				 (val_used ?
+				  val_used : ""));
+		} else {
+		    escaped2 = HTEscapeSP(val_used, URL_XALPHAS);
+		}
 
-	anchor_ptr = anchor_ptr->next;
+		if (!last_textarea_name ||
+		    strcmp(last_textarea_name, form_ptr->name)) {
+		    textarea_lineno = 1;
+		    /*
+		     * Names are different so this is the first textarea or a
+		     * different one from any before it.
+		     */
+		    if (Boundary) {
+			StrAllocCopy(previous_blanks, "\r\n");
+		    } else {
+			FREE(previous_blanks);
+		    }
+		    first_one = begin_submission_part(&query,
+						      first_one,
+						      SemiColon,
+						      PlainText,
+						      Boundary);
+
+		    if (PlainText) {
+			StrAllocCopy(escaped1, name_used);
+		    } else if (Boundary) {
+			StrAllocCopy(escaped1, "Content-Disposition: form-data");
+			HTSprintf(&escaped1, "; name=\"%s\"", name_used);
+			if (MultipartContentType)
+			    StrAllocCat(escaped1, MultipartContentType);
+			StrAllocCat(escaped1, "\r\n\r\n");
+		    } else {
+			escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
+		    }
+
+		    HTSprintf(&query,
+			    "%s%s%s%s%s",
+			    escaped1,
+			    (Boundary ? "" : "="),
+			    (PlainText ? "\n" : ""),
+			    escaped2,
+			    ((PlainText && *escaped2) ? "\n" : ""));
+		    last_textarea_name = form_ptr->name;
+		} else {
+		    /*
+		     * This is a continuation of a previous textarea.
+		     * Add %0d%0a (\r\n) and the escaped string.
+		     */
+		    if (escaped2[0] != '\0') {
+			if (previous_blanks) {
+			    StrAllocCat(query, previous_blanks);
+			    FREE(previous_blanks);
+			}
+			if (PlainText) {
+			    HTSprintf(&query, "%s\n", escaped2);
+			} else if (Boundary) {
+			    HTSprintf(&query, "%s\r\n", escaped2);
+			} else {
+			    HTSprintf(&query, "%%0d%%0a%s", escaped2);
+			}
+		    } else {
+			if (PlainText) {
+			    StrAllocCat(previous_blanks, "\n");
+			} else if (Boundary) {
+			    StrAllocCat(previous_blanks, "\r\n");
+			} else {
+			    StrAllocCat(previous_blanks, "%0d%0a");
+			}
+		    }
+		}
+		break;
+
+	    case F_PASSWORD_TYPE:
+	    case F_TEXT_TYPE:
+	    case F_OPTION_LIST_TYPE:
+	    case F_HIDDEN_TYPE:
+		first_one = begin_submission_part(&query,
+						  first_one,
+						  SemiColon,
+						  PlainText,
+						  Boundary);
+		if (PlainText) {
+		   StrAllocCopy(escaped1, name_used);
+		} else if (Boundary) {
+		    StrAllocCopy(escaped1, "Content-Disposition: form-data");
+		    HTSprintf(&escaped1, "; name=\"%s\"", name_used);
+		    if (MultipartContentType)
+			StrAllocCat(escaped1, MultipartContentType);
+		    StrAllocCat(escaped1, "\r\n\r\n");
+		} else {
+		    escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
+		}
+
+		if (PlainText || Boundary) {
+		    StrAllocCopy(escaped2,
+				 (val_used ?
+				  val_used : ""));
+		} else {
+		    escaped2 = HTEscapeSP(val_used, URL_XALPHAS);
+		}
+
+		HTSprintf(&query,
+			"%s%s%s%s%s",
+			escaped1,
+			(Boundary ? "" : "="),
+			(PlainText ? "\n" : ""),
+			escaped2,
+			((PlainText && *escaped2) ? "\n" : ""));
+		break;
+	    }
+	    FREE(escaped1);
+	    FREE(escaped2);
+	    FREE(copied_name_used);
+	    FREE(copied_val_used);
+	} else if (anchor_ptr->input_field->number > form_number) {
+	    break;
+	}
     }
+
     FREE(copied_name_used);
     if (Boundary) {
 	FREE(MultipartContentType);
@@ -10931,18 +10844,14 @@ PUBLIC void HText_DisableCurrentForm NOARGS
     /*
      *  Go through list of anchors and set the disabled flag.
      */
-    anchor_ptr = HTMainText->first_anchor;
-    while (anchor_ptr) {
+    for (anchor_ptr = HTMainText->first_anchor;
+	 anchor_ptr != NULL;
+	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
 	if (anchor_ptr->link_type == INPUT_ANCHOR &&
 	    anchor_ptr->input_field->number == HTFormNumber) {
 
 	    anchor_ptr->input_field->disabled = TRUE;
 	}
-
-	if (anchor_ptr == HTMainText->last_anchor)
-	    break;
-
-	anchor_ptr = anchor_ptr->next;
     }
 
     return;
@@ -10960,8 +10869,9 @@ PUBLIC void HText_ResetForm ARGS1(
     /*
      *  Go through list of anchors and reset values.
      */
-    anchor_ptr = HTMainText->first_anchor;
-    while (anchor_ptr != 0) {
+    for (anchor_ptr = HTMainText->first_anchor;
+	 anchor_ptr != NULL;
+	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
 	if (anchor_ptr->link_type == INPUT_ANCHOR) {
 	    if (anchor_ptr->input_field->number == form->number) {
 
@@ -10989,11 +10899,6 @@ PUBLIC void HText_ResetForm ARGS1(
 		break;
 	    }
 	}
-
-	if (anchor_ptr == HTMainText->last_anchor)
-	    break;
-
-	anchor_ptr = anchor_ptr->next;
     }
 }
 
@@ -11013,8 +10918,9 @@ PUBLIC BOOLEAN HText_HaveUserChangedForms NOARGS
      *  Go through list of anchors to check if any value was changed.
      *  This code based on HText_ResetForm()
      */
-    anchor_ptr = HTMainText->first_anchor;
-    while (anchor_ptr != 0) {
+    for (anchor_ptr = HTMainText->first_anchor;
+	 anchor_ptr != NULL;
+	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
 	if (anchor_ptr->link_type == INPUT_ANCHOR) {
 
 	    if (anchor_ptr->input_field->type == F_RADIO_TYPE ||
@@ -11041,10 +10947,6 @@ PUBLIC BOOLEAN HText_HaveUserChangedForms NOARGS
 		    return TRUE;
 	    }
 	}
-	if (anchor_ptr == HTMainText->last_anchor)
-	   break;
-
-	anchor_ptr = anchor_ptr->next;
     }
     return FALSE;
 }
@@ -11057,8 +10959,9 @@ PUBLIC void HText_activateRadioButton ARGS1(
 
     if (!HTMainText)
 	return;
-    anchor_ptr = HTMainText->first_anchor;
-    while (anchor_ptr) {
+    for (anchor_ptr = HTMainText->first_anchor;
+	 anchor_ptr != NULL;
+	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
 	if (anchor_ptr->link_type == INPUT_ANCHOR &&
 		anchor_ptr->input_field->type == F_RADIO_TYPE) {
 
@@ -11075,11 +10978,6 @@ PUBLIC void HText_activateRadioButton ARGS1(
 	    }
 
 	}
-
-	if (anchor_ptr == HTMainText->last_anchor)
-	    break;
-
-	anchor_ptr = anchor_ptr->next;
    }
 
    form->num_value = 1;
diff --git a/src/HTInit.c b/src/HTInit.c
index 4fb663a1..f1207e8d 100644
--- a/src/HTInit.c
+++ b/src/HTInit.c
@@ -1011,6 +1011,8 @@ PUBLIC void HTFileInit NOARGS
     HTSetSuffix(".text",	"text/plain", "8bit", 1.0);
     HTSetSuffix(".txt",		"text/plain", "8bit", 1.0);
 
+    HTSetSuffix(".php",		"text/html", "8bit", 1.0);
+    HTSetSuffix(".php3",	"text/html", "8bit", 1.0);
     HTSetSuffix(".html3",	"text/html", "8bit", 1.0);
     HTSetSuffix(".ht3",		"text/html", "8bit", 1.0);
     HTSetSuffix(".phtml",	"text/html", "8bit", 1.0);
diff --git a/src/LYBookmark.c b/src/LYBookmark.c
index d0bd7086..e6e49851 100644
--- a/src/LYBookmark.c
+++ b/src/LYBookmark.c
@@ -566,7 +566,7 @@ PUBLIC void remove_bookmark_link ARGS2(
     }
     LYCloseTempFP(nfp);
     nfp = NULL;
-#ifdef DOSPATH
+#if defined(DOSPATH) || defined(__EMX__)
     remove(filename_buffer);
 #endif /* DOSPATH */
 
diff --git a/src/LYCharUtils.c b/src/LYCharUtils.c
index 7c146c6e..0ff084f9 100644
--- a/src/LYCharUtils.c
+++ b/src/LYCharUtils.c
@@ -2242,9 +2242,7 @@ PUBLIC void LYHandleMETA ARGS4(
 	LYTrimTail(content);
 	LYLowerCase(content);
 
-	if ((cp = strstr(content, "text/html;")) != NULL &&
-	    (cp1 = strstr(content, "charset")) != NULL &&
-	    cp1 > cp) {
+	if ((cp1 = strstr(content, "charset")) != NULL) {
 	    BOOL chartrans_ok = NO;
 	    char *cp3 = NULL, *cp4;
 	    int chndl;
diff --git a/src/LYClean.c b/src/LYClean.c
index 1082ca88..a006084a 100644
--- a/src/LYClean.c
+++ b/src/LYClean.c
@@ -13,9 +13,9 @@
 #include <LYexit.h>
 #include <LYLeaks.h>
 
-#ifdef WATT32
+#ifdef DJGPP
 extern void sig_handler_watt(int);
-#endif /* WATT32 */
+#endif /* DJGPP */
 
 #ifdef VMS
 BOOLEAN HadVMSInterrupt = FALSE;
@@ -33,17 +33,17 @@ PUBLIC void cleanup_sig ARGS1(
 	/*
 	 * Need to rearm the signal.
 	 */
-#ifdef WATT32
+#ifdef DJGPP
 	if (wathndlcbrk) {
 	    sig_handler_watt(sig);	/* Use WATT-32 signal handler */
 	}				/* Requires patch to WATT-32 */
-#endif /* WATT32 */
+#endif /* DJGPP */
 	signal(SIGINT, cleanup_sig);
 	sigint = TRUE;
-#ifdef WATT32
+#ifdef DJGPP
 	_eth_release();
 	_eth_init();
-#endif /* WATT32 */
+#endif /* DJGPP */
 	return;
     }
 #endif /* IGNORE_CTRL_C */
diff --git a/src/LYCurses.c b/src/LYCurses.c
index aca351b3..57f4f3a8 100644
--- a/src/LYCurses.c
+++ b/src/LYCurses.c
@@ -1,17 +1,6 @@
 #include <HTUtils.h>
 #include <HTAlert.h>
 
-#ifdef __DJGPP__
-#include <conio.h>
-/* The conio.h distributed with GNU gettext package may redefine gettext() to
- * _conio_gettext().  Restore our definition.
- */
-#ifndef HAVE_GETTEXT
-#undef gettext
-#define gettext(s) s
-#endif /* HAVE_GETTEXT */
-#endif /* __DJGPP__ */
-
 #include <LYCurses.h>
 #include <LYStyle.h>
 #include <LYUtils.h>
@@ -874,11 +863,7 @@ PUBLIC void start_curses NOARGS
 #endif /* (VMS || REAL_UNIX_SYSTEM) && !__CYGWIN__  */
     }
 #ifdef __DJGPP__
-#ifdef WATT32
     _eth_init();
-#else
-    else sock_init();
-#endif /* WATT32 */
 #endif /* __DJGPP__ */
 
     slinit = 1;
@@ -1059,11 +1044,7 @@ PUBLIC void start_curses NOARGS
 #endif /* USE_COLOR_TABLE */
     }
 #ifdef __DJGPP__
-#ifdef WATT32
     _eth_init();
-#else
-    else sock_init();
-#endif /* WATT32 */
 #endif /* __DJGPP__ */
 #endif /* not VMS */
 
@@ -1256,14 +1237,15 @@ PUBLIC void stop_curses NOARGS
     if (LYCursesON)
 	echo();
 #ifdef __DJGPP__
-#ifdef WATT32
     _eth_release();
-#else
-    sock_exit();
-#endif /* WATT32 */
 #endif /* __DJGPP__ */
+
 #if defined(DOSPATH) && !(defined(USE_SLANG) || _WIN_CC)
+#ifdef __DJGPP__
+    ScreenClear();
+#else
     clrscr();
+#endif
 #else
 
     /*
diff --git a/src/LYDownload.c b/src/LYDownload.c
index f211652e..b2000e62 100644
--- a/src/LYDownload.c
+++ b/src/LYDownload.c
@@ -91,8 +91,12 @@ PUBLIC void LYDownload ARGS1(
     /* FIXME: use HTLocalName */
     if (!strncmp(file, "file://localhost", 16)) {
 #ifdef __DJGPP__
-	file += 17;
-	file = HTDOS_name(file);
+	if (!strncmp(file + 16, "/dev/", 5))
+	    file += 16;
+	else {
+	    file += 17;
+	    file = HTDOS_name(file);
+	}
 #else
 	file += 16;
 #endif /* __DJGPP__ */
diff --git a/src/LYKeymap.c b/src/LYKeymap.c
index 708f0e63..32af4a41 100644
--- a/src/LYKeymap.c
+++ b/src/LYKeymap.c
@@ -216,7 +216,7 @@ LYK_PREV_LINK,    LYK_NEXT_LINK,    LYK_ACTIVATE,   LYK_PREV_DOC,
 LYK_NEXT_PAGE,    LYK_PREV_PAGE,    LYK_HOME,       LYK_END,
 /* PGDOWN */      /* PGUP */        /* HOME */      /* END */
 
-#if (defined(_WINDOWS) || defined(__DJGPP__) || defined(__CYGWIN__))
+#if (defined(_WINDOWS) || defined(__DJGPP__))
 
 LYK_DWIMHELP,          0,              0,             0,
 /* F1*/
@@ -225,7 +225,7 @@ LYK_DWIMHELP,          0,              0,             0,
 LYK_DWIMHELP,     LYK_ACTIVATE,     LYK_HOME,       LYK_END,
 /* F1*/ 	  /* Do key */      /* Find key */  /* Select key */
 
-#endif /* _WINDOWS || __DJGPP__ || __CYGWIN__ */
+#endif /* _WINDOWS || __DJGPP__ */
 
 LYK_UP_TWO,       LYK_DOWN_TWO,     LYK_DO_NOTHING, LYK_FASTBACKW_LINK,
 /* Insert key */  /* Remove key */  /* DO_NOTHING*/ /* Back tab */
@@ -1174,7 +1174,7 @@ PUBLIC char *LYKeycodeToString ARGS2 (
 	else if (c >= 0400)
 	    sprintf(buf, "key-%#x", c);
 	else
-	    return 0;
+	    sprintf(buf, "%#x", c);
     }
     return buf;
 }
diff --git a/src/LYStrings.c b/src/LYStrings.c
index 730d7e38..2bccd271 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -2402,7 +2402,7 @@ PUBLIC void LYLowerCase ARGS1(
     for (i = 0; buffer[i]; i++)
 #ifdef SUPPORT_MULTIBYTE_EDIT	/* 1998/11/23 (Mon) 17:04:55 */
     {
-	if (buffer[i] & 0x80
+	if ((buffer[i] & 0x80) != 0
 	 && buffer[i+1] != 0) {
 	    if ((kanji_code == SJIS) && IS_SJIS_X0201KANA(UCH((buffer[i])))) {
 		continue;
@@ -2428,7 +2428,7 @@ PUBLIC void LYUpperCase ARGS1(
     for (i = 0; buffer[i]; i++)
 #ifdef SUPPORT_MULTIBYTE_EDIT	/* 1998/11/23 (Mon) 17:05:10 */
     {
-	if (buffer[i] & 0x80
+	if ((buffer[i] & 0x80) != 0
 	 && buffer[i+1] != 0) {
 	    if ((kanji_code == SJIS) && IS_SJIS_X0201KANA(UCH((buffer[i])))) {
 		continue;
diff --git a/src/LYUtils.c b/src/LYUtils.c
index 6baa52cd..53e4167e 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -652,7 +652,7 @@ highlight_hit_within_hightext:
 			TargetEmphasisON = TRUE;
 			LYaddstr(tmp);
 		    } else {
-			LYmove(hLine, (offset + 1));
+			LYmove(hLine, (offset + 2));
 		    }
 		    tmp[1] = '\0';
 		    written += 2;
@@ -1074,7 +1074,7 @@ PUBLIC void LYhighlight ARGS3(
 			 * For CJK strings, by Masanobu Kimura.
 			 */
 			if (HTCJK != NOCJK && is8bits(tmp[0])) {
-			    tmp[1] = LYGetHiliteStr(cur, 1)[++i];
+			    tmp[1] = hi_string[++i];
 			    LYaddstr(tmp);
 			    tmp[1] = '\0';
 			} else {
@@ -3139,21 +3139,6 @@ PRIVATE int fmt_tempname ARGS3(
 	CONST char *,	suffix)
 {
     int code;
-#if defined(HAVE_MKSTEMP)
-    int fd;
-    char interim[LY_MAXPATH];
-    sprintf(interim, "%.*sXXXXXX", LY_MAXPATH - 8, prefix);
-    if (strlen(interim) + strlen(suffix) < LY_MAXPATH - 2
-    && (fd = mkstemp(interim)) >= 0) {
-	sprintf(result, "%s%s", interim, suffix);
-	rename(interim, result);
-	chmod(result, HIDE_CHMOD); /* (yes, some mkstemps are broken ;-) */
-	close(fd);
-	code = TRUE;
-    } else {
-	code = FALSE;
-    }
-#else
 #ifdef USE_RAND_TEMPNAME
 #define SIZE_TEMPNAME ((MAX_TEMPNAME / BITS_PER_CHAR) + 1)
     static BOOL first = TRUE;
@@ -3240,7 +3225,6 @@ PRIVATE int fmt_tempname ARGS3(
 	sprintf(result, "%.*s", LY_MAXPATH-1, leaf);
 	code = FALSE;
     }
-#endif
     CTRACE((tfp, "-> '%s'\n", result));
     return (code);
 }
@@ -4382,13 +4366,7 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3(
 	FREE(MsgStr);
 	return GotHost;
     }
-    else if (LYCursesON &&
-#if defined(__DJGPP__) && !defined(WATT32)
-	HTCheckForInterrupt()
-#else /* normal systems */
-	(lynx_nsl_status == HT_INTERRUPTED)
-#endif
-	)
+    else if (LYCursesON && (lynx_nsl_status == HT_INTERRUPTED))
     {
 	/*
 	 *  Give the user chance to interrupt lookup cycles. - KW & FM
@@ -4493,11 +4471,7 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3(
 		/*
 		 *  Give the user chance to interrupt lookup cycles. - KW
 		 */
-#if defined(__DJGPP__) && !defined(WATT32)
-		if (LYCursesON && HTCheckForInterrupt())
-#else /* normal systems */
 		if (LYCursesON && (lynx_nsl_status == HT_INTERRUPTED))
-#endif
 		{
 		    CTRACE((tfp,
 	"LYExpandHostForURL: Interrupted while '%s' failed to resolve.\n",
@@ -7375,7 +7349,7 @@ PUBLIC char * w32_strerror(DWORD ercode)
 PUBLIC void LYOpenlog ARGS1(
 	CONST char *, banner)
 {
-#if defined(WATT32)
+#if defined(DJGPP)
     openlog("lynx", LOG_PID|LOG_NDELAY, LOG_LOCAL5);
 #else
     openlog("lynx", LOG_PID, LOG_LOCAL5);
diff --git a/src/LYUtils.h b/src/LYUtils.h
index f009994f..ce9e42f9 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -284,11 +284,7 @@ extern HTList *sug_filenames;
  * syslog() facility
  */
 #if !defined(VMS) && defined(SYSLOG_REQUESTED_URLS)
-#ifdef WATT32
-#include <sys/syslog.h>
-#else
 #include <syslog.h>
-#endif
 
 extern void LYOpenlog  PARAMS((CONST char *banner));
 extern void LYSyslog   PARAMS((char *arg));