about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2002-12-02 02:37:01 -0500
committerThomas E. Dickey <dickey@invisible-island.net>2002-12-02 02:37:01 -0500
commitf6e997b7f73d01db84665bc924ba2d065e314e43 (patch)
treee5a6682d03360506ad1db6b3d1f5934a5911db50 /src
parent0cb11571ef3a2820a888b47eaa0ea3083e3b9b0f (diff)
downloadlynx-snapshots-f6e997b7f73d01db84665bc924ba2d065e314e43.tar.gz
snapshot of project "lynx", label v2-8-5dev_11
Diffstat (limited to 'src')
-rw-r--r--src/GridText.c545
-rw-r--r--src/GridText.h5
-rw-r--r--src/HTAlert.c31
-rw-r--r--src/HTFWriter.c30
-rw-r--r--src/HTML.c129
-rw-r--r--src/LYBookmark.c51
-rw-r--r--src/LYCharSets.c7
-rw-r--r--src/LYCharSets.h4
-rw-r--r--src/LYCharUtils.c5
-rw-r--r--src/LYCookie.c13
-rw-r--r--src/LYCurses.c2
-rw-r--r--src/LYDownload.h6
-rw-r--r--src/LYGetFile.c6
-rw-r--r--src/LYGlobalDefs.h8
-rw-r--r--src/LYList.c10
-rw-r--r--src/LYLocal.c395
-rw-r--r--src/LYMail.c94
-rw-r--r--src/LYMain.c19
-rw-r--r--src/LYMainLoop.c89
-rw-r--r--src/LYMainLoop.h2
-rw-r--r--src/LYOptions.c25
-rw-r--r--src/LYReadCFG.c41
-rw-r--r--src/LYStrings.c13
-rw-r--r--src/LYStrings.h2
-rw-r--r--src/LYStructs.h6
-rw-r--r--src/LYUtils.c79
-rw-r--r--src/LYrcFile.h19
-rw-r--r--src/UCdomap.c6
-rw-r--r--src/UCdomap.h7
29 files changed, 874 insertions, 775 deletions
diff --git a/src/GridText.c b/src/GridText.c
index a76c7faa..54bd8ebd 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -104,8 +104,6 @@ struct _HTStream {			/* only know it as object */
 #define UTF8_XNEGLEN(c) (c&0xC0? 0 :c&32? 1 :c&16? 2 :c&8? 3 :c&4? 4 :c&2? 5:0)
 #define UTF_XLEN(c) UTF8_XNEGLEN(((char)~(c)))
 
-extern BOOL HTPassHighCtrlRaw;
-
 #ifdef KANJI_CODE_OVERRIDE
 PUBLIC HTkcode last_kcode = NOKANJI;	/* 1997/11/14 (Fri) 09:09:26 */
 #endif
@@ -151,8 +149,9 @@ PUBLIC int LYsb_begin = -1;
 PUBLIC int LYsb_end = -1;
 #endif
 
-#if defined(USE_COLOR_STYLE)
-#define MAX_STYLES_ON_LINE 64
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
 
     /*try to fit in 2 shorts*/
 typedef struct {
@@ -161,49 +160,39 @@ typedef struct {
 	    /* horizontal position of this change */
 	unsigned short	style;		/* which style to change to */
 } HTStyleChange;
-#endif
 
-typedef struct _line {
-	struct _line	*next;
-	struct _line	*prev;
-	unsigned	offset;		/* Implicit initial spaces */
-	unsigned	size;		/* Number of characters */
 #if defined(USE_COLOR_STYLE)
-	HTStyleChange* styles;
-	int	numstyles;
+#define MAX_STYLES_ON_LINE   64
+  /* buffers used when current line is being aggregated, in split_line() */
+static HTStyleChange stylechanges_buffers[2][MAX_STYLES_ON_LINE];
 #endif
-	char	data[1];		/* Space for terminator at least! */
-} HTLine;
 
-#if defined(USE_COLOR_STYLE)
-typedef struct _HTStyleChangePool {
-	HTStyleChange	data[4092];
-	struct _HTStyleChangePool* next;
-	int free_items;
-} HTStyleChangePool;
-
-/*these are used when current line is being aggregated. */
-HTStyleChange stylechanges_buffers[2][MAX_STYLES_ON_LINE];
-int stylechanges_buffers_free;/*this is an index of the free buffer.
-    Can be 0 or 1*/
-
-/* These are generic macros for any pools (provided those structures have the
-same members as HTStyleChangePool).  Pools are used for allocation of groups of
+#define POOL_SIZE (8192 - 4*sizeof(void*) - sizeof(struct _HTPool*) + sizeof(int)) / sizeof(HTStyleChange)
+
+typedef struct _HTPool {
+    HTStyleChange   data[POOL_SIZE];
+    struct _HTPool* prev;
+    int used;
+} HTPool;
+
+/************************************************************************
+These are generic macros for any pools (provided those structures have the
+same members as HTPool).  Pools are used for allocation of groups of
 objects of the same type T.  Pools are represented as a list of structures of
 type P (called pool chunks here).  Structure P has an array of N objects of
 type T named 'data' (the number N in the array can be chosen arbitrary),
-pointer to the next pool chunk named 'pool', and the number of free items in
-that pool chunk named 'free_items'.  Here is a definition of the structure P:
+pointer to the previous pool chunk named 'prev', and the number of used items
+in that pool chunk named 'used'.  Here is a definition of the structure P:
 	struct P
 	{
 	    T data[N];
-	    struct P* next;
-	    int free_items;
+	    struct P* prev;
+	    int used;
 	};
  It's recommended that sizeof(P) be memory page size minus 32 in order malloc'd
 chunks to fit in machine page size.
- Allocation of 'n' items in the pool is implemented by decrementing member
-'free_items' by 'n' if 'free_items' >= 'n', or allocating a new pool chunk and
+ Allocation of 'n' items in the pool is implemented by incrementing member
+'used' by 'n' if (used+n <= N), or malloc a new pool chunk and
 allocating 'n' items in that new chunk.  It's the task of the programmer to
 assert that 'n' is <= N.  Only entire pool may be freed - this limitation makes
 allocation algorithms trivial and fast - so the use of pools is limited to
@@ -214,6 +203,9 @@ speed due to the simple algorithms used.  Due to the fact that memory is
 'allocated' in array, alignment overhead is minimal.  Allocating strings in a
 pool provided their length will never exceed N and is much smaller than N seems
 to be very efficient.
+ [Several types of memory-hungry objects are stored in the pool now:  styles,
+lines, anchors, and FormInfo. Arrays of HTStyleChange are stored as is,
+other objects are aligned to sizeof(void*) bytes and stored using a cast.]
 
  Pool are referenced by pointer to the chunk that contains free slots. Macros
 that allocate memory in pools update that pointer if needed.
@@ -222,7 +214,7 @@ ALLOC_IN_POOL.
  Here is a description of those macros as C++ functions (with names mentioned
 above and with use of C++ references)
 
-void ALLOC_IN_POOL( P*& pool, pool_type, int toalloc, T*& ptr)
+void ALLOC_IN_POOL( P*& pool, pool_type, int toalloc, T*& ptr, int align=1)
     - allocates 'toalloc' items in the pool of type 'pool_type' pointed by
     'pool', sets the pointer 'ptr' to the "allocated" memory and updates 'pool'
     if necessary. Sets 'ptr' to NULL if fails.
@@ -231,67 +223,104 @@ void POOL_NEW( pool_type  , P*& ptr)
     Initializes a pool of type 'pool_type' pointed by 'ptr', updating 'ptr'.
     Sets 'ptr' to NULL if fails.
 
-void POOL_FREE( pool_type , P* ptr)
-    Frees a pool of type 'pool_type' pointed by ptr.
+void POOL_FREE( pool_type , P*& ptr)
+    Frees a pool of type 'pool_type' pointed by ptr. Sets ptr to NULL.
 
-      - VH */
+      - VH
 
+*************************************************************************/
 /*
-void ALLOC_IN_POOL( P*& pool, pool_type, int toalloc, T*& ptr)
-    - allocates 'toalloc' items in the pool of type 'pool_type' pointed by
-    'pool', sets the pointer 'ptr' to the "allocated" memory and updates 'pool'
-    if necessary. Sets 'ptr' to NULL if fails.
-*/
-#define ALLOC_IN_POOL(pool,pool_type,toalloc,ptr)     \
-if (!pool)  \
-    ptr = NULL; \
-else { \
-    if ((pool)->free_items > toalloc) { \
-	(pool)->free_items -= toalloc; \
-	ptr = (pool)->data + (pool)->free_items; \
-    } else { \
-	pool_type* newpool = (pool_type*)malloc(sizeof(pool_type)); \
-	if (!newpool) { \
-	    ptr = NULL; \
-	} else { \
-	    newpool->next = pool; \
-	    newpool->free_items = sizeof newpool->data/ \
-		    sizeof newpool->data[0] - toalloc; \
-	    pool = newpool; \
-	    ptr = newpool->data + sizeof newpool->data/sizeof newpool->data[0] - toalloc; \
-	} \
-    } \
-}
-/*
-void POOL_NEW( pool_type  , P*& ptr)
-    Initializes a pool of type 'pool_type' pointed by 'ptr', updating 'ptr'.
-    Sets 'ptr' to NULL if fails.
-*/
-#define POOL_NEW(pool_type,ptr) \
-    { \
-	pool_type* newpool = (pool_type*)malloc(sizeof(pool_type)); \
-	if (!newpool) { \
-	    ptr = NULL; \
-	} else { \
-	    newpool->next = NULL; \
-	    newpool->free_items = sizeof newpool->data/sizeof newpool->data[0]; \
-	    ptr = newpool; \
-	} \
+ * void ALLOC_IN_POOL( P*& pool, pool_type, int toalloc, T*& ptr, int align=1)
+ *     - allocates 'toalloc' items in the pool of type 'pool_type' pointed by
+ *     'pool', sets the pointer 'ptr' to the "allocated" memory and updates
+ *     'pool' if necessary.  Sets 'ptr' to NULL if fails.
+ */
+#define ALLOC_IN_POOL(pool,pool_type,toalloc,ptr,align) \
+    if (!pool) {					\
+	ptr = NULL;					\
+    } else {						\
+	if (align)					\
+	    pool->used += (pool->used % align);		\
+	if (POOL_SIZE - pool->used >= toalloc) { 	\
+	    ptr = pool->data + pool->used;		\
+	    pool->used += toalloc;			\
+	} else {					\
+	    pool_type* newpool = (pool_type*)LY_CALLOC(1, sizeof(pool_type)); \
+	    if (!newpool) {				\
+		ptr = NULL;				\
+	    } else {					\
+		newpool->prev = pool;			\
+		newpool->used = toalloc;		\
+		ptr = newpool->data;			\
+		pool = newpool;				\
+	   }						\
+	}						\
     }
 /*
-void POOL_FREE( pool_type , P* ptr)
-    Frees a pool of type 'pool_type' pointed by ptr.
-*/
-#define POOL_FREE(pool_type,xptr) \
-    { \
-	pool_type* ptr = xptr; \
-	do { \
-	    pool_type* prevpool = ptr; \
-	    ptr = ptr->next; \
-	    FREE(prevpool); \
-	} while (ptr); \
+ * void POOL_NEW( pool_type  , P*& ptr)
+ *     Initializes a pool of type 'pool_type' pointed by 'ptr', updating 'ptr'.
+ *     Sets 'ptr' to NULL if fails.
+ */
+#define POOL_NEW(pool_type,ptr)				\
+    {							\
+	ptr = (pool_type*)LY_CALLOC(1, sizeof(pool_type)); \
+	if (ptr) {					\
+	    ptr->prev = NULL;				\
+	    ptr->used = 0;				\
+	}						\
     }
+/*
+ * void POOL_FREE( pool_type, P*& ptr)
+ *     Frees a pool of type 'pool_type' pointed by ptr. Sets ptr to NULL.
+ */
+#define POOL_FREE(pool_type,ptr)			\
+    {							\
+	pool_type* cur = ptr;				\
+	pool_type* prev;				\
+	while (cur) {					\
+	    prev = cur->prev;				\
+	    FREE(cur);					\
+	    cur = prev;					\
+	}						\
+	ptr = NULL;					\
+    }
+/**************************************************************************/
+
+#define _sz_        sizeof(HTStyleChange)      /* 4 */
+#define _align_     (sizeof(void*)/_sz_)       /*64bit OS!*/
+#define _round_(x)  (x%_sz_ ? x/_sz_ + 1: x/_sz_)
+
+#define POOLallocstyles(ptr, N)     ALLOC_IN_POOL(HTMainText->pool,HTPool,\
+					N,				\
+					ptr,				\
+					1)
+#define POOLallocHTLine(ptr, size)  { HTStyleChange* _tmp_;		\
+				      ALLOC_IN_POOL(HTMainText->pool,HTPool,\
+					_round_(LINE_SIZE(size)),	\
+					_tmp_,				\
+					_align_);			\
+				      ptr = (HTLine*)_tmp_;		\
+				    }
+#define POOLtypecalloc(T,ptr)	    { HTStyleChange* _tmp_;		\
+				      ALLOC_IN_POOL(HTMainText->pool,HTPool,\
+					_round_(sizeof(T)),		\
+					_tmp_,				\
+					_align_);			\
+				      ptr = (T*)_tmp_;			\
+				    }
+
+typedef struct _line {
+	struct _line    *next;
+	struct _line    *prev;
+	unsigned short	offset;	/* Implicit initial spaces */
+	unsigned short	size;	/* Number of characters */
+#if defined(USE_COLOR_STYLE)
+	HTStyleChange*  styles;
+	unsigned short  numstyles;
 #endif
+	char	data[1];	/* Space for terminator at least! */
+} HTLine;
+
 
 #define LINE_SIZE(l) (sizeof(HTLine)+(l))	/* Allow for terminator */
 #define allocHTLine(l) (HTLine *)calloc(1, LINE_SIZE(l))
@@ -300,15 +329,16 @@ typedef struct _TextAnchor {
 	struct _TextAnchor *	next;
 	struct _TextAnchor *	prev;		/* www_user_search only! */
 	int			number;		/* For user interface */
-	int			line_pos;	/* Bytes/chars - extent too */
-	int			extent;		/* (see HText_trimHightext) */
 	int			line_num;	/* Place in document */
-	HiliteList		lites;
-	int			link_type;	/* Normal, internal, or form? */
-	FormInfo *		input_field;	/* Info for form links */
+	short			line_pos;	/* Bytes/chars - extent too */
+	short			extent;		/* (see HText_trimHightext) */
 	BOOL			show_anchor;	/* Show the anchor? */
 	BOOL			inUnderline;	/* context is underlined */
 	BOOL			expansion_anch; /* TEXTAREA edit new anchor */
+	char			link_type;	/* Normal, internal, or form? */
+	FormInfo *		input_field;	/* Info for form links */
+	HiliteList		lites;
+
 	HTChildAnchor *		anchor;
 } TextAnchor;
 
@@ -325,27 +355,13 @@ typedef struct {
 */
 struct _HText {
 	HTParentAnchor *	node_anchor;
-#ifdef SOURCE_CACHE
-	/*
-	 * Parse settings when this HText was generated.
-	 */
-	BOOLEAN			clickable_images;
-	BOOLEAN			pseudo_inline_alts;
-	BOOLEAN			verbose_img;
-	BOOLEAN			raw_mode;
-	BOOLEAN			historical_comments;
-	BOOLEAN			minimal_comments;
-	BOOLEAN			soft_dquotes;
-	int			old_dtd;
-	int			keypad_mode;
-	int			disp_lines;	/* Screen size */
-	int			disp_cols;	/* Used for reports only */
-#endif
+
 	HTLine *		last_line;
 	int			Lines;		/* Number of them */
-	TextAnchor *		first_anchor;	/* Singly linked list */
+	TextAnchor *		first_anchor;	/* double-linked on demand */
 	TextAnchor *		last_anchor;
 	TextAnchor *		last_anchor_before_stbl;
+	TextAnchor *		last_anchor_before_split;
 	HTList *		forms;		/* also linked internally */
 	int			last_anchor_number;	/* user number */
 	BOOL			source;		/* Is the text source? */
@@ -389,20 +405,36 @@ struct _HText {
 	enum grid_state       { S_text, S_esc, S_dollar, S_paren,
 				S_nonascii_text, S_dollar_paren,
 				S_jisx0201_text }
-				state;			/* Escape sequence? */
-	int			kanji_buf;		/* Lead multibyte */
-	int			in_sjis;		/* SJIS flag */
-	int			halted;			/* emergency halt */
-
-	BOOL			have_8bit_chars;   /* Any non-ASCII chars? */
-	LYUCcharset *		UCI;		   /* node_anchor UCInfo */
-	int			UCLYhndl;	   /* charset we are fed */
+				state;		/* Escape sequence? */
+	int			kanji_buf;	/* Lead multibyte */
+	int			in_sjis;	/* SJIS flag */
+	int			halted;		/* emergency halt */
+
+	BOOL			have_8bit_chars; /* Any non-ASCII chars? */
+	LYUCcharset *		UCI;		/* node_anchor UCInfo */
+	int			UCLYhndl;	/* charset we are fed */
 	UCTransParams		T;
 
-	HTStream *		target;			/* Output stream */
-	HTStreamClass		targetClass;		/* Output routines */
-#if defined(USE_COLOR_STYLE)
-	HTStyleChangePool*	styles_pool;
+	HTStream *		target;		/* Output stream */
+	HTStreamClass		targetClass;	/* Output routines */
+
+	HTPool*			pool;		/* this HText memory pool */
+
+#ifdef SOURCE_CACHE
+	/*
+	* Parse settings when this HText was generated.
+	*/
+	BOOL			clickable_images;
+	BOOL			pseudo_inline_alts;
+	BOOL			verbose_img;
+	BOOL			raw_mode;
+	BOOL			historical_comments;
+	BOOL			minimal_comments;
+	BOOL			soft_dquotes;
+	short			old_dtd;
+	short			keypad_mode;
+	short			disp_lines;	/* Screen size */
+	short			disp_cols;	/* Used for reports only */
 #endif
 };
 
@@ -560,9 +592,9 @@ PRIVATE void LYAddHiText ARGS3(
     unsigned want = ++(a->lites.hl_len) * sizeof(HiliteInfo);
 
     if (have != NULL) {
-	have = realloc(have, want);
+	have = (HiliteInfo *) realloc(have, want);
     } else {
-	have = malloc(want);
+	have = (HiliteInfo *) malloc(want);
     }
     a->lites.hl_info = have;
 
@@ -696,7 +728,7 @@ PRIVATE void * LY_check_calloc ARGS2(
     }
     n = HTList_count(loaded_texts);
     for (i = n - 1; i > 0; i--) {
-	HText * t = HTList_objectAt(loaded_texts, i);
+	HText * t = (HText *) HTList_objectAt(loaded_texts, i);
 	if (t == HTMainText)
 	    t = NULL;		/* shouldn't happen */
 	{
@@ -853,6 +885,9 @@ PUBLIC HText *	HText_new ARGS1(
 #endif /* VMS && VAXC && !__DECC */
     }
 
+    POOL_NEW(HTPool, self->pool);
+    if (!self->pool)
+	outofmem(__FILE__, "HText_New");
     line = self->last_line = allocHTLine(MAX_LINE);
     if (line == NULL)
 	outofmem(__FILE__, "HText_New");
@@ -860,14 +895,11 @@ PUBLIC HText *	HText_new ARGS1(
     line->offset = line->size = 0;
 #ifdef USE_COLOR_STYLE
     line->numstyles = 0;
-    POOL_NEW(HTStyleChangePool,self->styles_pool);
-    if (!self->styles_pool)
-	outofmem(__FILE__, "HText_New");
-    stylechanges_buffers_free = 0;
     line->styles = stylechanges_buffers[0];
 #endif
     self->Lines = 0;
     self->first_anchor = self->last_anchor = NULL;
+    self->last_anchor_before_split = NULL;
     self->style = &default_style;
     self->top_of_screen = 0;
     self->node_anchor = anchor;
@@ -1033,26 +1065,6 @@ PUBLIC void HText_free ARGS1(
 	return;
 
     HTAnchor_setDocument(self->node_anchor, (HyperDoc *)0);
-#if defined(USE_COLOR_STYLE)
-    POOL_FREE(HTStyleChangePool,self->styles_pool);
-#endif
-    while (YES) {	/* Free off line array */
-	HTLine * l = self->last_line;
-	if (l) {
-	    l->next->prev = l->prev;
-	    l->prev->next = l->next;	/* Unlink l */
-	    self->last_line = l->prev;
-	    if (l != self->last_line) {
-		FREE(l);
-	    } else {
-		free(l);
-	    }
-	}
-	if (l == self->last_line) {	/* empty */
-	    l = self->last_line = NULL;
-	    break;
-	}
-    }
 
     while (self->first_anchor) {		/* Free off anchor array */
 	TextAnchor * l = self->first_anchor;
@@ -1102,13 +1114,9 @@ PUBLIC void HText_free ARGS1(
 	    FREE(l->input_field->submit_title);
 
 	    FREE(l->input_field->accept_cs);
-
-	    FREE(l->input_field);
 	}
 
 	LYSetHiText(l, NULL, 0);
-
-	FREE(l);
     }
     FormList_delete(self->forms);
 
@@ -1166,6 +1174,7 @@ PUBLIC void HText_free ARGS1(
 	    HTMainAnchor = NULL;
     }
 
+    POOL_FREE(HTPool, self->pool);
     FREE(self);
 }
 
@@ -1769,19 +1778,6 @@ 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
 **	-------------
@@ -1846,6 +1842,7 @@ PRIVATE void display_page ARGS3(
 	 *  an xterm is temporarily made very small. - kw */
 	return;
     }
+
     last_screen = text->Lines - (display_lines - 2);
     line = text->last_line->prev;
 
@@ -2123,7 +2120,7 @@ PRIVATE void display_page ARGS3(
     nlinks = 0;
     for (Anchor_ptr = text->first_anchor;
 	 Anchor_ptr != NULL && Anchor_ptr->line_num <= stop_before_for_anchors;
-	 Anchor_ptr = next_anchor(text, Anchor_ptr)) {
+	 Anchor_ptr = Anchor_ptr->next) {
 
 	if (Anchor_ptr->line_num >= line_number
 	 && Anchor_ptr->line_num < stop_before_for_anchors) {
@@ -2167,7 +2164,7 @@ PRIVATE void display_page ARGS3(
 #ifndef DONT_TRACK_INTERNAL_LINKS
 			if (Anchor_ptr->link_type == INTERNAL_LINK_ANCHOR) {
 			    link_dest_intl = HTAnchor_followTypedLink(
-				(HTAnchor *)Anchor_ptr->anchor, LINK_INTERNAL);
+				(HTAnchor *)Anchor_ptr->anchor, HTInternalLink);
 			    if (link_dest_intl && link_dest_intl != link_dest) {
 
 				CTRACE((tfp,
@@ -2430,20 +2427,19 @@ PRIVATE void move_anchors_in_region ARGS7(
     int,		shift)		/* Likewise */
 {
     /*
-     *  Update anchor positions for anchors that start on this line.
-     *  Note: we rely on a->line_pos counting bytes, not
-     *  characters.  That's one reason why HText_trimHightext
-     *  has to be prevented from acting on these anchors in
-     *  partial display mode before we get a chance to
-     *  deal with them here.
+     * Update anchor positions for anchors that start on this line.  Note:  we
+     * rely on a->line_pos counting bytes, not characters.  That's one reason
+     * why HText_trimHightext has to be prevented from acting on these anchors
+     * in partial display mode before we get a chance to deal with them here.
      */
     TextAnchor *a;
     int head_processed = *prev_head_processed;
 
-    /* We need to know whether (*prev_anchor)->line_pos is "in new
-       coordinates" or in old ones.  If prev_anchor' head was touched
-       on the previous iteraction, we set head_processed.  The tail
-       may need to be treated now. */
+    /*
+     * We need to know whether (*prev_anchor)->line_pos is "in new coordinates"
+     * or in old ones.  If prev_anchor' head was touched on the previous
+     * iteration, we set head_processed.  The tail may need to be treated now.
+     */
     for (a = *prev_anchor;
 	 a && a->line_num <= line_number;
 	 a = a->next, head_processed = 0) {
@@ -2492,7 +2488,7 @@ PRIVATE void move_anchors_in_region ARGS7(
  *  Some necessary changes for anchors starting on this line are also done
  *  here if needed.
  *  Returns a newly allocated HTLine* if changes were made
- *    (caller has to free the old one).
+ *    (lines allocated in pool, caller should not free the old one).
  *  Returns NULL if no changes needed.  (Remove-spaces code may be buggy...)
  * - kw
  */
@@ -2536,7 +2532,7 @@ PRIVATE HTLine * insert_blanks_in_line ARGS7(
     if (!prev_anchor)
 	prev_anchor = text->first_anchor;
     head_processed = (prev_anchor && prev_anchor->line_num < line_number);
-    memcpy(mod_line, line, LINE_SIZE(1));
+    memcpy(mod_line, line, LINE_SIZE(0));
     t = newdata = mod_line->data;
     ip = 0;
     while (ip <= ninserts) {
@@ -2637,7 +2633,6 @@ PRIVATE void split_line ARGS2(
 	unsigned,	split)
 {
     HTStyle * style = text->style;
-    HTLine * temp;
     int spare;
     int indent = text->in_line_1 ?
 	  text->style->indent1st : text->style->leftIndent;
@@ -2657,10 +2652,12 @@ PRIVATE void split_line ARGS2(
     HTLine * line = (HTLine *)LY_CALLOC(1, LINE_SIZE(MAX_LINE)+2);
 
     /*
-     *  Make new line.
+     *  Set new line.
      */
     if (line == NULL)
 	outofmem(__FILE__, "split_line_1");
+    memset(line, 0, LINE_SIZE(0));
+
     ctrl_chars_on_this_line = 0; /*reset since we are going to a new line*/
     utfxtra_on_this_line = 0;	/*reset too, we'll count them*/
     text->LastChar = ' ';
@@ -2852,7 +2849,10 @@ PRIVATE void split_line ARGS2(
 #endif
 
 #if defined(USE_COLOR_STYLE)
-    line->styles = stylechanges_buffers[stylechanges_buffers_free = (stylechanges_buffers_free + 1) &1];
+    if (previous->styles == stylechanges_buffers[0])
+	line->styles = stylechanges_buffers[1];
+    else
+	line->styles = stylechanges_buffers[0];
     line->numstyles = 0;
     {
 	HTStyleChange *from = previous->styles + previous->numstyles - 1;
@@ -2946,18 +2946,20 @@ PRIVATE void split_line ARGS2(
     }
 #endif /*USE_COLOR_STYLE*/
 
-    temp = (HTLine *)LY_CALLOC(1, LINE_SIZE(previous->size));
-    if (temp == NULL)
+    {
+    HTLine* temp;
+    POOLallocHTLine(temp, previous->size);
+    if (!temp)
 	outofmem(__FILE__, "split_line_2");
     memcpy(temp, previous, LINE_SIZE(previous->size));
 #if defined(USE_COLOR_STYLE)
-    ALLOC_IN_POOL((text->styles_pool),HTStyleChangePool,previous->numstyles,temp->styles);
-    memcpy(temp->styles, previous->styles, sizeof(HTStyleChange)*previous->numstyles);
+    POOLallocstyles(temp->styles, previous->numstyles);
     if (!temp->styles)
 	outofmem(__FILE__, "split_line_2");
+    memcpy(temp->styles, previous->styles, sizeof(HTStyleChange)*previous->numstyles);
 #endif
-    FREE(previous);
     previous = temp;
+    }
 
     previous->prev->next = previous;	/* Link in new line */
     previous->next->prev = previous;	/* Could be same node of course */
@@ -3085,7 +3087,6 @@ PRIVATE void split_line ARGS2(
      */
 
     if (s > 0) {			/* if not completely empty */
-	TextAnchor * prev_a = NULL;
 	int moved = 0;
 
 	/* In the algorithm below we move or not move anchors between
@@ -3097,11 +3098,16 @@ PRIVATE void split_line ARGS2(
 	 */
 	/* Our operations can make a non-empty all-whitespace link
 	   empty.  So what? */
-	for (a = text->first_anchor; a; prev_a = a, a = a->next) {
+	if ((a = text->last_anchor_before_split) == 0)
+	    a = text->first_anchor;
+
+	for ( ; a; a = a->next) {
 	    if (a->line_num == CurLine) {
 		int len = a->extent, n = a->number, start = a->line_pos;
 		int end = start + len;
 
+		text->last_anchor_before_split = a;
+
 		/* Which anchors do we leave on the previous line?
 		   a) empty finished (We need a cut-off value.
 		      "Just because": those before s;
@@ -3236,8 +3242,6 @@ PRIVATE void split_line ARGS2(
 	    previous->next->prev = jline;
 	    previous->prev->next = jline;
 
-	    FREE(previous);
-
 	    previous = jline;
 	}
 	{ /* (ht_num_runs==1) */
@@ -3252,11 +3256,10 @@ PRIVATE void split_line ARGS2(
 	    if (!a2)
 		a2 = text->first_anchor;
 	    else
-		a2 = next_anchor(text, a2); /* 1st anchor on line we justify */
+		a2 = a2->next; /* 1st anchor on line we justify */
 
-	    if (a2)
-		for (; a2 && a2->line_num <= text->Lines-1;
-		    last_anchor_of_previous_line = a2, a2 = a2->next);
+	    for (; a2 && a2->line_num <= text->Lines-1;
+		last_anchor_of_previous_line = a2, a2 = a2->next);
 	}
     } else {
 	if (REALLY_CAN_JUSTIFY(text) ) {
@@ -4122,8 +4125,8 @@ check_WrapSource:
      *  Check for end of line.
      */
     actual = ((indent + (int)line->offset + (int)line->size) +
-       ((line->size > 0) &&
-	(int)(line->data[line->size-1] == LY_SOFT_HYPHEN ? 1 : 0)));
+	      ((line->size > 0) &&
+	       (int)(line->data[line->size-1] == LY_SOFT_HYPHEN ? 1 : 0)));
 
     if (text->T.output_utf8) {
 	actual += (UTFXTRA_ON_THIS_LINE - ctrl_chars_on_this_line + UTF_XLEN(ch));
@@ -4516,7 +4519,6 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2(
 	    lines_changed++;
 	    if (line == first_line)
 		first_line = mod_line;
-	    free(line);
 	    line = mod_line;
 #ifdef DISP_PARTIAL
 	    /*
@@ -4902,8 +4904,9 @@ PUBLIC int HText_beginAnchor ARGS3(
 	BOOL,			underline,
 	HTChildAnchor *,	anc)
 {
-    TextAnchor * a = typecalloc(TextAnchor);
+    TextAnchor * a;
 
+    POOLtypecalloc(TextAnchor, a);
     if (a == NULL)
 	outofmem(__FILE__, "HText_beginAnchor");
     a->inUnderline = underline;
@@ -4922,7 +4925,7 @@ PUBLIC int HText_beginAnchor ARGS3(
     text->last_anchor = a;
 
 #ifndef DONT_TRACK_INTERNAL_LINKS
-    if (HTAnchor_followTypedLink((HTAnchor*)anc, LINK_INTERNAL)) {
+    if (HTAnchor_followTypedLink((HTAnchor*)anc, HTInternalLink)) {
 	a->number = ++(text->last_anchor_number);
 	a->link_type = INTERNAL_LINK_ANCHOR;
     } else
@@ -5526,7 +5529,6 @@ PUBLIC void HText_endAppend ARGS1(
 	 */
 	next_to_the_last_line->next = line_ptr;
 	line_ptr->prev = next_to_the_last_line;
-	FREE(text->last_line);
 	text->last_line = next_to_the_last_line;
 	text->Lines--;
 	CTRACE((tfp, "GridText: New bottom line: `%s'\n",
@@ -5607,7 +5609,7 @@ PRIVATE void HText_trimHightext ARGS3(
      */
     for (anchor_ptr = text->first_anchor;
 	anchor_ptr != NULL;
-	prev_a = anchor_ptr, anchor_ptr = next_anchor(text, anchor_ptr)) {
+	prev_a = anchor_ptr, anchor_ptr = anchor_ptr->next) {
 	int have_soft_newline_in_1st_line = 0;
 re_parse:
 	/*
@@ -5817,23 +5819,33 @@ PUBLIC HTParentAnchor * HText_nodeAnchor ARGS1(
 /*				GridText specials
 **				=================
 */
+
 /*
- *  HTChildAnchor() returns the anchor with index N.
- *  The index corresponds to the [number] we print for the anchor.
+ *  HText_childNextNumber() returns the anchor with index [number],
+ *  using a pointer from the previous number (=optimization) or NULL.
  */
-PUBLIC HTChildAnchor * HText_childNumber ARGS1(
-	int,		number)
+PUBLIC HTChildAnchor * HText_childNextNumber ARGS2(
+	int,		number,
+	void**,		prev)
 {
-    TextAnchor * a;
+    /* Sorry, TextAnchor is not declared outside this file, use a cast. */
+    TextAnchor * a = *prev;
 
-    if (!(HTMainText && HTMainText->first_anchor) || number <= 0)
+    if (!HTMainText || number <= 0)
 	return (HTChildAnchor *)0;	/* Fail */
+    if (number == 1 || !a)
+	a = HTMainText->first_anchor;
 
-    for (a = HTMainText->first_anchor; a; a = a->next) {
-	if (a->number == number)
-	    return(a->anchor);
-    }
-    return (HTChildAnchor *)0;	/* Fail */
+    /* a strange thing:  positive a->number's are sorted,
+     * and between them several a->number's may be 0 -- skip them
+     */
+    for( ; a && a->number != number; a = a->next)
+	;
+
+    if (!a)
+	return (HTChildAnchor *)0;	/* Fail */
+    *prev = (void*)a;
+    return a->anchor;
 }
 
 /*
@@ -6122,7 +6134,7 @@ PUBLIC int HTGetLinkInfo ARGS6(
 #ifndef DONT_TRACK_INTERNAL_LINKS
 			if (a->link_type == INTERNAL_LINK_ANCHOR) {
 			    link_dest_intl = HTAnchor_followTypedLink(
-				(HTAnchor *)a->anchor, LINK_INTERNAL);
+				(HTAnchor *)a->anchor, HTInternalLink);
 			    if (link_dest_intl && link_dest_intl != link_dest) {
 
 				CTRACE((tfp, "HTGetLinkInfo: unexpected typed link to %s!\n",
@@ -6224,7 +6236,7 @@ PUBLIC BOOL HText_TAHasMoreLines ARGS2(
 	}
 	return NO;
     } else {
-	for (a = HTMainText->first_anchor; a; a = next_anchor(HTMainText, a)) {
+	for (a = HTMainText->first_anchor; a; a = a->next) {
 	    if (a->link_type == INPUT_ANCHOR &&
 		links[curlink].l_form == a->input_field) {
 		return same_anchors(a, a->next, TRUE);
@@ -6469,11 +6481,12 @@ PUBLIC BOOL HText_getFirstTargetInLine ARGS7(
      *  Make sure we have an HText structure, that line_num is
      *  in its range, and that we have a target string. -FM
      */
-    if (!(text
-       && line_num >= 0
-       && line_num <= text->Lines
-       && non_empty(target)))
+    if (!(text &&
+	line_num >= 0 &&
+	line_num <= text->Lines &&
+	non_empty(target))) {
 	return(FALSE);
+    }
 
     /*
      *  Find the line and set up its data and offset -FM
@@ -6834,8 +6847,8 @@ PUBLIC int HText_LinksInLines ARGS3(
 	return total;
 
     for (Anchor_ptr = text->first_anchor;
-		Anchor_ptr != NULL && Anchor_ptr->line_num <= end;
-			Anchor_ptr = next_anchor(text, Anchor_ptr)) {
+	 Anchor_ptr != NULL && Anchor_ptr->line_num <= end;
+	 Anchor_ptr = Anchor_ptr->next) {
 	if (Anchor_ptr->line_num >= start &&
 	    Anchor_ptr->line_num < end &&
 	    Anchor_ptr->show_anchor &&
@@ -7012,7 +7025,7 @@ PUBLIC BOOL HText_POSTReplyLoaded ARGS1(
 }
 
 PUBLIC BOOL HTFindPoundSelector ARGS1(
-	char *,		selector)
+	CONST char *,		selector)
 {
     TextAnchor * a;
 
@@ -7748,7 +7761,7 @@ PRIVATE BOOL anchor_has_target ARGS2(
 		return TRUE;
 	    }
 	    FREE(stars);
-       } else if (a->input_field->type == F_OPTION_LIST_TYPE) {
+	} else if (a->input_field->type == F_OPTION_LIST_TYPE) {
 	    /*
 	     *  Search the option strings that are displayed
 	     *  when the popup is invoked. -FM
@@ -8503,18 +8516,15 @@ PUBLIC void HText_RemovePreviousLine ARGS1(
 	HText *,	text)
 {
     HTLine *line, *previous;
-    char *data;
 
     if (!(text && text->Lines > 1))
 	return;
 
     line = text->last_line->prev;
-    data = line->data;
     previous = line->prev;
     previous->next = text->last_line;
     text->last_line->prev = previous;
     text->Lines--;
-    FREE(line);
 }
 
 /*
@@ -8797,7 +8807,7 @@ PUBLIC void HText_endForm ARGS1(
 	/*
 	 *  Go through list of anchors and get our input field. -FM
 	 */
-	for (a = text->first_anchor; a != NULL; a = next_anchor(text, a)) {
+	for (a = text->first_anchor; a != NULL; a = a->next) {
 	    if (a->link_type == INPUT_ANCHOR &&
 		a->input_field->number == HTFormNumber &&
 		a->input_field->type == F_TEXT_TYPE) {
@@ -9249,8 +9259,8 @@ PUBLIC int HText_beginInput ARGS3(
 	BOOL,			underline,
 	InputFieldData *,	I)
 {
-    TextAnchor * a = typecalloc(TextAnchor);
-    FormInfo * f = typecalloc(FormInfo);
+    TextAnchor * a;
+    FormInfo * f;
     CONST char *cp_option = NULL;
     char *IValue = NULL;
     unsigned char *tmp = NULL;
@@ -9261,6 +9271,8 @@ PUBLIC int HText_beginInput ARGS3(
 
     CTRACE((tfp, "GridText: Entering HText_beginInput\n"));
 
+    POOLtypecalloc(TextAnchor, a);
+    POOLtypecalloc(FormInfo, f);
     if (a == NULL || f == NULL)
 	outofmem(__FILE__, "HText_beginInput");
 
@@ -9287,7 +9299,7 @@ PUBLIC int HText_beginInput ARGS3(
 	} else {
 	    TextAnchor * b;
 	    int i2 = 0;
-	    for (b = text->first_anchor; b != NULL; b = next_anchor(text, b)) {
+	    for (b = text->first_anchor; b != NULL; b = b->next) {
 		if (b->link_type == INPUT_ANCHOR &&
 		    b->input_field->type == F_RADIO_TYPE &&
 		    b->input_field->number == HTFormNumber) {
@@ -9474,8 +9486,6 @@ PUBLIC int HText_beginInput ARGS3(
 	     */
 	    CTRACE((tfp,
 		  "GridText: No name present in input field; not displaying\n"));
-	    FREE(a);
-	    FREE(f);
 	    FREE(IValue);
 	    return(0);
 	}
@@ -9957,6 +9967,16 @@ PRIVATE unsigned check_form_specialchars ARGS1(
     return result;
 }
 
+PRIVATE CONST char *guess_content_type ARGS1(CONST char *, filename)
+{
+    HTAtom *encoding;
+    CONST char *desc;
+    HTFormat format = HTFileFormat (filename, &encoding, &desc);
+    return (format != 0 && non_empty(format->name))
+	    ? format->name
+	    : "text/plain";
+}
+
 /*
  *  HText_SubmitForm - generate submit data from form fields.
  *  For mailto forms, send the data.
@@ -10111,7 +10131,7 @@ PUBLIC int HText_SubmitForm ARGS4(
      */
     for (anchor_ptr = HTMainText->first_anchor;
 	 anchor_ptr != NULL;
-	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
+	 anchor_ptr = anchor_ptr->next) {
 
 	if (anchor_ptr->link_type != INPUT_ANCHOR)
 	    continue;
@@ -10263,7 +10283,7 @@ PUBLIC int HText_SubmitForm ARGS4(
      */
     for (anchor_ptr = HTMainText->first_anchor;
 	 anchor_ptr != NULL;
-	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
+	 anchor_ptr = anchor_ptr->next) {
 
 	if (anchor_ptr->link_type != INPUT_ANCHOR)
 	    continue;
@@ -10373,7 +10393,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 		    out_csname = LYCharSet_UC[out_cs].MIMEname;
 		if (Boundary) {
 		    StrAllocCopy(MultipartContentType,
-				 "\r\nContent-Type: text/plain");
+				 "\r\nContent-Type: %s");
 		    if (!success && form_ptr->value_cs < 0) {
 			/*  This is weird. */
 			out_csname = "UNKNOWN-8BIT";
@@ -10482,8 +10502,9 @@ PUBLIC int HText_SubmitForm ARGS4(
 						  SemiColon,
 						  PlainText,
 						  Boundary);
-		if ((escaped2 = load_a_file(&use_mime, val_used)) == NULL)
-		    goto exit_disgracefully;
+		if ((escaped2 = load_a_file(&use_mime, val_used)) == NULL) {
+		    StrAllocCopy(escaped2, "");
+		}
 
 		/* FIXME: we need to modify the mime-type here - rp */
 		/* Note: could use LYGetFileInfo for that and for
@@ -10496,7 +10517,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 		    HTSprintf(&escaped1, "; name=\"%s\"", name_used);
 		    HTSprintf(&escaped1, "; filename=\"%s\"", val_used);
 		    if (MultipartContentType) {
-			StrAllocCat(escaped1, MultipartContentType);
+			HTSprintf(&escaped1, MultipartContentType, guess_content_type(val_used));
 			if (use_mime)
 			    StrAllocCat(escaped1, "\r\nContent-Transfer-Encoding: base64");
 		    }
@@ -10545,7 +10566,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 			StrAllocCopy(escaped1, "Content-Disposition: form-data");
 			HTSprintf(&escaped1, "; name=\"%s\"", name_used);
 			if (MultipartContentType)
-			    StrAllocCat(escaped1, MultipartContentType);
+			    HTSprintf(&escaped1, MultipartContentType, "text/plain");
 			StrAllocCat(escaped1, "\r\n\r\n");
 		    } else {
 			escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
@@ -10617,7 +10638,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 			StrAllocCopy(escaped1, "Content-Disposition: form-data");
 			HTSprintf(&escaped1, "; name=\"%s\"", name_used);
 			if (MultipartContentType)
-			    StrAllocCat(escaped1, MultipartContentType);
+			    HTSprintf(&escaped1, MultipartContentType, "text/plain");
 			StrAllocCat(escaped1, "\r\n\r\n");
 		    } else {
 			escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
@@ -10674,7 +10695,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 			StrAllocCopy(escaped1, "Content-Disposition: form-data");
 			HTSprintf(&escaped1, "; name=\"%s\"", name_used);
 			if (MultipartContentType)
-			    StrAllocCat(escaped1, MultipartContentType);
+			    HTSprintf(&escaped1, MultipartContentType, "text/plain");
 			StrAllocCat(escaped1, "\r\n\r\n");
 		    } else {
 			escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
@@ -10732,7 +10753,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 		    StrAllocCopy(escaped1, "Content-Disposition: form-data");
 		    HTSprintf(&escaped1, "; name=\"%s\"", name_used);
 		    if (MultipartContentType)
-			StrAllocCat(escaped1, MultipartContentType);
+			HTSprintf(&escaped1, MultipartContentType, "text/plain");
 		    StrAllocCat(escaped1, "\r\n\r\n");
 		} else {
 		    escaped1 = HTEscapeSP(name_used, URL_XALPHAS);
@@ -10773,7 +10794,7 @@ PUBLIC int HText_SubmitForm ARGS4(
     }
     FREE(previous_blanks);
 
-    CTRACE((tfp, "QUERY (%d) >> \n%s\n", strlen(query), query));
+    CTRACE((tfp, "QUERY (%d) >> \n%s\n", (int) strlen(query), query));
 
     if (submit_item->submit_method == URL_MAIL_METHOD) {
 	HTUserMsg2(gettext("Submitting %s"), submit_item->submit_action);
@@ -10815,18 +10836,6 @@ PUBLIC int HText_SubmitForm ARGS4(
 	FREE(query);
 	return 1;
     }
-#ifdef EXP_FILE_UPLOAD
-exit_disgracefully:
-    FREE(escaped1);
-    FREE(escaped2);
-    FREE(previous_blanks);
-    FREE(copied_name_used);
-    FREE(copied_val_used);
-    FREE(MultipartContentType);
-    FREE(query);
-    FREE(content_type_out);
-    return 0;
-#endif
 }
 
 PUBLIC void HText_DisableCurrentForm NOARGS
@@ -10842,7 +10851,7 @@ PUBLIC void HText_DisableCurrentForm NOARGS
      */
     for (anchor_ptr = HTMainText->first_anchor;
 	 anchor_ptr != NULL;
-	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
+	 anchor_ptr = anchor_ptr->next) {
 	if (anchor_ptr->link_type == INPUT_ANCHOR &&
 	    anchor_ptr->input_field->number == HTFormNumber) {
 
@@ -10867,7 +10876,7 @@ PUBLIC void HText_ResetForm ARGS1(
      */
     for (anchor_ptr = HTMainText->first_anchor;
 	 anchor_ptr != NULL;
-	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
+	 anchor_ptr = anchor_ptr->next) {
 	if (anchor_ptr->link_type == INPUT_ANCHOR) {
 	    if (anchor_ptr->input_field->number == form->number) {
 
@@ -10916,7 +10925,7 @@ PUBLIC BOOLEAN HText_HaveUserChangedForms NOARGS
      */
     for (anchor_ptr = HTMainText->first_anchor;
 	 anchor_ptr != NULL;
-	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
+	 anchor_ptr = anchor_ptr->next) {
 	if (anchor_ptr->link_type == INPUT_ANCHOR) {
 
 	    if (anchor_ptr->input_field->type == F_RADIO_TYPE ||
@@ -10957,7 +10966,7 @@ PUBLIC void HText_activateRadioButton ARGS1(
 	return;
     for (anchor_ptr = HTMainText->first_anchor;
 	 anchor_ptr != NULL;
-	 anchor_ptr = next_anchor(HTMainText, anchor_ptr)) {
+	 anchor_ptr = anchor_ptr->next) {
 	if (anchor_ptr->link_type == INPUT_ANCHOR &&
 		anchor_ptr->input_field->type == F_RADIO_TYPE) {
 
@@ -11703,9 +11712,10 @@ PRIVATE void insert_new_textarea_anchor ARGS2(
      *  Clone and initialize the struct's needed to add a new TEXTAREA
      *  anchor.
      */
-    if (((a = typecalloc(TextAnchor)) == 0) ||
-	((f = typecalloc(FormInfo)) == 0) ||
-	((l = allocHTLine(MAX_LINE)) == 0))
+    POOLallocHTLine(l, MAX_LINE);
+    POOLtypecalloc(TextAnchor, a);
+    POOLtypecalloc(FormInfo, f);
+    if (a == NULL || l == NULL || f == NULL)
 	outofmem(__FILE__, "insert_new_textarea_anchor");
 
     /*  Init all the fields in the new TextAnchor.                 */
@@ -12526,9 +12536,10 @@ PUBLIC int HText_InsertFile ARGS1(
 	    break;
     }
 
-    if (((a = typecalloc(TextAnchor)) == 0) ||
-	((f = typecalloc(FormInfo)) == 0) ||
-	((l = allocHTLine(MAX_LINE)) == 0))
+    POOLallocHTLine(l, MAX_LINE);
+    POOLtypecalloc(TextAnchor, a);
+    POOLtypecalloc(FormInfo, f);
+    if (a == NULL || l == NULL || f == NULL)
 	outofmem(__FILE__, "HText_InsertFile");
 
     /*  Init all the fields in the new TextAnchor.                 */
diff --git a/src/GridText.h b/src/GridText.h
index 760d88ae..7f2ce6af 100644
--- a/src/GridText.h
+++ b/src/GridText.h
@@ -64,7 +64,8 @@ extern HTParentAnchor * HTMainAnchor;	/* Anchor for HTMainText */
 #if defined(VMS) && defined(VAXC) && !defined(__DECC)
 extern int HTVirtualMemorySize;
 #endif /* VMS && VAXC && !__DECC */
-extern HTChildAnchor * HText_childNumber PARAMS((int n));
+
+extern HTChildAnchor * HText_childNextNumber PARAMS((int n, void** prev));
 extern void HText_FormDescNumber PARAMS((int n, char **desc));
 
 /*	Is there any file left?
@@ -111,7 +112,7 @@ extern void HText_setMainTextOwner PARAMS((CONST char * owner));
 extern void print_wwwfile_to_fd PARAMS((FILE * fp, BOOLEAN is_reply));
 extern BOOL HText_select PARAMS((HText *text));
 extern BOOL HText_POSTReplyLoaded PARAMS((DocInfo *doc));
-extern BOOL HTFindPoundSelector PARAMS((char *selector));
+extern BOOL HTFindPoundSelector PARAMS((CONST char *selector));
 extern int HTGetRelLinkNum PARAMS((int num, int rel, int cur));
 extern int HTGetLinkInfo PARAMS((
 	int		number,
diff --git a/src/HTAlert.c b/src/HTAlert.c
index 90d65ed0..a8049e04 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -180,15 +180,15 @@ PRIVATE char *sprint_bytes ARGS3(
 #ifdef EXP_READPROGRESS
 #define TIME_HMS_LENGTH (16)
 PRIVATE char *sprint_tbuf ARGS2(
-       char *,         s,
-       long,           t)
+	char *,	       s,
+	long,	       t)
 {
     if (t > 3600)
-       sprintf (s, "%ldh%ldm%lds", t / 3600, (t / 60) % 60, t % 60);
+	sprintf (s, "%ldh%ldm%lds", t / 3600, (t / 60) % 60, t % 60);
     else if (t > 60)
-       sprintf (s, "%ldm%lds", t / 60, t % 60);
+	sprintf (s, "%ldm%lds", t / 60, t % 60);
     else
-       sprintf (s, "%ld sec", t);
+	sprintf (s, "%ld sec", t);
     return s;
 }
 #endif /* EXP_READPROGRESS */
@@ -244,15 +244,18 @@ PUBLIC void HTReadProgress ARGS2(
 	total_last = total;
 
 	/*
-	 * Optimal refresh time:  every 0.2 sec, use interpolation.  Transfer
-	 * rate is not constant when we have partial content in a proxy, so
-	 * interpolation lies - will check every second at least for sure.
+	 * Optimal refresh time:  every 0.2 sec
 	 */
-#ifdef HAVE_GETTIMEOFDAY
+#if defined(HAVE_GETTIMEOFDAY) || (defined(HAVE_FTIME) && defined(HAVE_SYS_TIMEB_H))
 	if (now >= last + 0.2)
 	    renew = 1;
 #else
-	if (((bytes - bytes_last) > (transfer_rate / 5)) || (now != last)) {
+	/*
+	 * Use interpolation.  (The transfer rate may be not constant
+	 * when we have partial content in a proxy.  We adjust transfer_rate
+	 * once a second to minimize interpolation error below.)
+	 */
+	if ((now != last) || ((bytes - bytes_last) > (transfer_rate / 5))) {
 	    renew = 1;
 	    bytes_last += (transfer_rate / 5);	/* until we got next second */
 	}
@@ -263,7 +266,7 @@ PUBLIC void HTReadProgress ARGS2(
 		if (bytes_last != bytes)
 		    last_active = now;
 		bytes_last = bytes;
-		transfer_rate = (long)(bytes / (now - first)); /* more accurate here */
+		transfer_rate = (long)(bytes / (now - first)); /* more accurate value */
 	    }
 
 	    if (total > 0)
@@ -286,13 +289,13 @@ PUBLIC void HTReadProgress ARGS2(
 #ifdef EXP_READPROGRESS
 	    if (LYTransferRate == rateEtaBYTES
 	     || LYTransferRate == rateEtaKB) {
-                char tbuf[TIME_HMS_LENGTH];
+		char tbuf[TIME_HMS_LENGTH];
 		if (now - last_active >= 5)
-                    HTSprintf (&line,
+		    HTSprintf (&line,
 			       gettext(" (stalled for %s)"),
 			       sprint_tbuf (tbuf, (long)(now - last_active)));
 		if (total > 0 && transfer_rate)
-                    HTSprintf (&line,
+		    HTSprintf (&line,
 			       gettext(", ETA %s"),
 			       sprint_tbuf (tbuf, (long)((total - bytes)/transfer_rate)));
 	    }
diff --git a/src/HTFWriter.c b/src/HTFWriter.c
index 819c25b9..ea0c61c2 100644
--- a/src/HTFWriter.c
+++ b/src/HTFWriter.c
@@ -190,11 +190,9 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
 			path[len-3] = '\0';
 			remove(path);
 		    }
-#ifdef BZIP2_PATH
 		} else if (len > 4 && !strcasecomp(&path[len-3], "bz2")) {
 		    path[len-4] = '\0';
 		    remove(path);
-#endif /* BZIP2_PATH */
 		} else if (len > 2 && !strcasecomp(&path[len-1], "Z")) {
 		    path[len-2] = '\0';
 		    remove(path);
@@ -1020,6 +1018,7 @@ PUBLIC HTStream* HTCompressed ARGS3(
     BOOL can_present = FALSE;
     char fnam[LY_MAXPATH];
     char temp[LY_MAXPATH];	/* actually stores just a suffix */
+    CONST char *program;
     CONST char *suffix;
     char *uncompress_mask = NULL;
     char *compress_suffix = "";
@@ -1048,39 +1047,36 @@ PUBLIC HTStream* HTCompressed ARGS3(
 	     *	We have a presentation mapping for it. - FM
 	     */
 	    can_present = TRUE;
-#ifdef GZIP_PATH
-	    if (!strcasecomp(anchor->content_encoding, "x-gzip") ||
-		!strcasecomp(anchor->content_encoding, "gzip")) {
+	    if ((!strcasecomp(anchor->content_encoding, "x-gzip") ||
+		 !strcasecomp(anchor->content_encoding, "gzip")) &&
+		 (program = HTGetProgramPath(ppGZIP)) != NULL) {
 		/*
 		 *  It's compressed with the modern gzip. - FM
 		 */
-		StrAllocCopy(uncompress_mask, GZIP_PATH);
+		StrAllocCopy(uncompress_mask, program);
 		StrAllocCat(uncompress_mask, " -d --no-name %s");
 		compress_suffix = "gz";
 		break;
 	    }
-#endif /* GZIP_PATH */
-#ifdef BZIP2_PATH
-	    if (!strcasecomp(anchor->content_encoding, "x-bzip2") ||
-		!strcasecomp(anchor->content_encoding, "bzip2")) {
-		StrAllocCopy(uncompress_mask, BZIP2_PATH);
+	    if ((!strcasecomp(anchor->content_encoding, "x-bzip2") ||
+		 !strcasecomp(anchor->content_encoding, "bzip2")) &&
+		(program = HTGetProgramPath(ppBZIP2)) != NULL) {
+		StrAllocCopy(uncompress_mask, program);
 		StrAllocCat(uncompress_mask, " -d %s");
 		compress_suffix = "bz2";
 		break;
 	    }
-#endif /* BZIP2_PATH */
-#ifdef UNCOMPRESS_PATH
-	    if (!strcasecomp(anchor->content_encoding, "x-compress") ||
-		       !strcasecomp(anchor->content_encoding, "compress")) {
+	    if ((!strcasecomp(anchor->content_encoding, "x-compress") ||
+		 !strcasecomp(anchor->content_encoding, "compress")) &&
+		(program = HTGetProgramPath(ppUNCOMPRESS)) != NULL) {
 		/*
 		 *  It's compressed the old fashioned Unix way. - FM
 		 */
-		StrAllocCopy(uncompress_mask, UNCOMPRESS_PATH);
+		StrAllocCopy(uncompress_mask, program);
 		StrAllocCat(uncompress_mask, " %s");
 		compress_suffix = "Z";
 		break;
 	    }
-#endif /* UNCOMPRESS_PATH */
 	    break;
 	}
     }
diff --git a/src/HTML.c b/src/HTML.c
index 7bae9995..9698e568 100644
--- a/src/HTML.c
+++ b/src/HTML.c
@@ -77,6 +77,7 @@
 #include <HTAccess.h>
 #endif
 
+#include <LYCurses.h>
 #include <LYJustify.h>
 
 #include <LYexit.h>
@@ -84,13 +85,6 @@
 
 #define STACKLEVEL(me) ((me->stack + MAX_NESTING - 1) - me->sp)
 
-extern BOOL HTPassEightBitRaw;
-
-extern BOOLEAN HT_Is_Gopher_URL;
-
-/* from Curses.h */
-extern int LYcols;
-
 struct _HTStream {
     CONST HTStreamClass *	isa;
 #ifdef SOURCE_CACHE
@@ -661,7 +655,6 @@ PUBLIC void HTML_write ARGS3(HTStructured *, me, CONST char*, s, int, l)
  *  context an internal link makes no sense (e.g., IMG SRC=).
  */
 
-#ifndef DONT_TRACK_INTERNAL_LINKS
 /* A flag is used to keep track of whether an "URL reference" encountered
    had a real "URL" or not.  In the latter case, it will be marked as
    "internal".	The flag is set before we start messing around with the
@@ -672,14 +665,8 @@ PUBLIC void HTML_write ARGS3(HTStructured *, me, CONST char*, s, int, l)
 
 /* Last argument to pass to HTAnchor_findChildAndLink() calls,
    just an abbreviation. - kw */
-#define INTERN_LT (HTLinkType *)(intern_flag ? LINK_INTERNAL : NULL)
+#define INTERN_LT (HTLinkType *)(intern_flag ? HTInternalLink : NULL)
 
-#else  /* !DONT_TRACK_INTERNAL_LINKS */
-
-#define CHECK_FOR_INTERN(flag,s)  /* do nothing */ ;
-#define INTERN_LT (HTLinkType *)NULL
-
-#endif /* DONT_TRACK_INTERNAL_LINKS */
 
 #ifdef USE_COLOR_STYLE
 # if !OPT_SCN
@@ -3020,82 +3007,87 @@ PRIVATE int HTML_start_element ARGS6(
 		   value[HTML_A_NAME] && *value[HTML_A_NAME]) {
 	    StrAllocCopy(id_string, value[HTML_A_NAME]);
 	}
-	if (id_string) {
+	if (id_string)
 	    TRANSLATE_AND_UNESCAPE_TO_STD(&id_string);
-	    if (*id_string == '\0') {
-		FREE(id_string);
-	    }
-	}
 
 	/*
 	 *  Handle the reference. - FM
 	 */
 	if (present && present[HTML_A_HREF]) {
-#ifndef DONT_TRACK_INTERNAL_LINKS
-	    if (present[HTML_A_ISMAP])
-		intern_flag = FALSE;
-	    else
-		CHECK_FOR_INTERN(intern_flag,value[HTML_A_HREF]);
-#endif
 	    /*
-	     *	Prepare to do housekeeping on the reference. - FM
+	     * Set to know we are making the content bold.
 	     */
-	    if (!value[HTML_A_HREF] || *value[HTML_A_HREF] == '\0') {
-		StrAllocCopy(href, me->node_anchor->address);
-	    } else if (*value[HTML_A_HREF] == '#') {
-		StrAllocCopy(href, me->node_anchor->address);
-		if (strlen(value[HTML_A_HREF]) > 1) {
-		    StrAllocCat(href, value[HTML_A_HREF]);
-		}
-	    } else {
+	    me->inBoldA = TRUE;
+
+	    CHECK_FOR_INTERN(intern_flag,value[HTML_A_HREF]);
+	    if (present[HTML_A_ISMAP]) /*???*/
+		intern_flag = FALSE;
+
+	    if (intern_flag) {
+		/*** FAST WAY: ***/
 		StrAllocCopy(href, value[HTML_A_HREF]);
-	    }
-	    url_type = LYLegitimizeHREF(me, &href, TRUE, TRUE);
+		if (href && *href)
+		    TRANSLATE_AND_UNESCAPE_TO_STD(&href);
+		if (!href || !*href)
+		    StrAllocCopy(href, "#"); /*extreme case*/
 
-	    /*
-	     *	Deal with our ftp gateway kludge. - FM
-	     */
-	    if (!url_type && !strncmp(href, "/foo/..", 7) &&
-		(isFTP_URL(me->node_anchor->address) ||
-		 isFILE_URL(me->node_anchor->address))) {
-		for (i = 0; (href[i] = href[i+7]) != 0; i++)
-		    ;
-	    }
+	    } else {
+		/*
+		 * Prepare to do housekeeping on the reference.	 - FM
+		 */
+		if (!value[HTML_A_HREF] || *value[HTML_A_HREF] == '\0') {
+		    StrAllocCopy(href, me->node_anchor->address);
+		} else if (*value[HTML_A_HREF] == '#') {
+		    StrAllocCopy(href, me->node_anchor->address);
+		    if (strlen(value[HTML_A_HREF]) > 1) {
+			StrAllocCat(href, value[HTML_A_HREF]);
+		    }
+		} else {
+		    StrAllocCopy(href, value[HTML_A_HREF]);
+		}
+		url_type = LYLegitimizeHREF(me, &href, TRUE, TRUE);
 
-	    /*
-	     *	Set to know we are making the content bold.
-	     */
-	    me->inBoldA = TRUE;
+		/*
+		 * Deal with our ftp gateway kludge.  - FM
+		 */
+		if (!url_type && !strncmp(href, "/foo/..", 7) &&
+		      (isFTP_URL(me->node_anchor->address) ||
+		       isFILE_URL(me->node_anchor->address))) {
+		    for (i = 0; (href[i] = href[i+7]) != 0; i++)
+			;
+		}
 
-	    /*
-	     *	Check whether a base tag is in effect. - FM
-	     */
-	    if ((me->inBASE && *href != '\0' && *href != '#') &&
-		(temp = HTParse(href, me->base_href, PARSE_ALL)) &&
-		*temp != '\0')
 		/*
-		 *  Use reference related to the base.
+		 * Check whether a base tag is in effect.  - FM
 		 */
-		StrAllocCopy(href, temp);
-	    FREE(temp);
+		if ((me->inBASE && *href != '\0' && *href != '#') &&
+		     (temp = HTParse(href, me->base_href, PARSE_ALL)) &&
+		      *temp != '\0')
+		    /*
+		     * Use reference related to the base.
+		     */
+		    StrAllocCopy(href, temp);
+		FREE(temp);
 
-	    /*
-	     *	Check whether to fill in localhost. - FM
-	     */
-	    LYFillLocalFileURL(&href,
-			       ((*href != '\0' && *href != '#' &&
-				 me->inBASE) ?
-			       me->base_href : me->node_anchor->address));
+	        /*
+		 * Check whether to fill in localhost.  - FM
+		 */
+		 LYFillLocalFileURL(&href,
+				    ((*href != '\0' && *href != '#' &&
+				     me->inBASE)
+				     ? me->base_href
+				     : me->node_anchor->address));
+	    }
 	} else {
 	    if (bold_name_anchors == TRUE) {
 		me->inBoldA = TRUE;
 	    }
 	}
-#ifndef DONT_TRACK_INTERNAL_LINKS
+
 	if (present && present[HTML_A_TYPE] && value[HTML_A_TYPE]) {
 	    StrAllocCopy(temp, value[HTML_A_TYPE]);
 	    if (!intern_flag && href &&
-		!strcasecomp(value[HTML_A_TYPE], HTAtom_name(LINK_INTERNAL)) &&
+		!strcasecomp(value[HTML_A_TYPE], HTAtom_name(HTInternalLink)) &&
 		!LYIsUIPage3(me->node_anchor->address, UIP_LIST_PAGE, 0) &&
 		!LYIsUIPage3(me->node_anchor->address, UIP_ADDRLIST_PAGE, 0) &&
 		!isLYNXIMGMAP(me->node_anchor->address)) {
@@ -3108,7 +3100,6 @@ PRIVATE int HTML_start_element ARGS6(
 		FREE(temp);
 	    }
 	}
-#endif /* DONT_TRACK_INTERNAL_LINKS */
 
 	me->CurrentA = HTAnchor_findChildAndLink(
 			me->node_anchor,			/* Parent */
diff --git a/src/LYBookmark.c b/src/LYBookmark.c
index bdab256b..baa40d80 100644
--- a/src/LYBookmark.c
+++ b/src/LYBookmark.c
@@ -1,5 +1,6 @@
 #include <HTUtils.h>
 #include <HTAlert.h>
+#include <HTFile.h>
 #include <LYUtils.h>
 #include <LYStrings.h>
 #include <LYBookmark.h>
@@ -264,15 +265,18 @@ PUBLIC void save_bookmark_link ARGS2(
      *	If the link will be added to the same
      *	bookmark file, get confirmation. - FM
      */
-    if (LYMultiBookmarks != MBM_OFF &&
-	strstr(HTLoadedDocumentURL(),
-	       (*BookmarkPage == '.' ?
-		    (BookmarkPage+1) : BookmarkPage)) != NULL) {
-	LYMBM_statusline(MULTIBOOKMARKS_SELF);
-	c = LYgetch_single();
-	if (c != 'L') {
-	    FREE(bookmark_URL);
-	    return;
+    if (LYMultiBookmarks != MBM_OFF) {
+	CONST char *url = HTLoadedDocumentURL();
+	CONST char *page = (*BookmarkPage == '.')
+			    ? (BookmarkPage + 1)
+			    : BookmarkPage;
+	if (strstr(url, page) != NULL) {
+	    LYMBM_statusline(MULTIBOOKMARKS_SELF);
+	    c = LYgetch_single();
+	    if (c != 'L') {
+		FREE(bookmark_URL);
+		return;
+	    }
 	}
     }
 
@@ -634,22 +638,25 @@ PUBLIC void remove_bookmark_link ARGS2(
 	if (errno == EXDEV) {
 	    static CONST char MV_FMT[] = "%s %s %s";
 	    char *buffer = 0;
-	    HTAddParam(&buffer, MV_FMT, 1, MV_PATH);
-	    HTAddParam(&buffer, MV_FMT, 2, newfile);
-	    HTAddParam(&buffer, MV_FMT, 3, filename_buffer);
-	    HTEndParam(&buffer, MV_FMT, 3);
-	    if (LYSystem(buffer) == 0) {
+	    CONST char *program;
+
+	    if ((program = HTGetProgramPath(ppMV)) != NULL) {
+		HTAddParam(&buffer, MV_FMT, 1, program);
+		HTAddParam(&buffer, MV_FMT, 2, newfile);
+		HTAddParam(&buffer, MV_FMT, 3, filename_buffer);
+		HTEndParam(&buffer, MV_FMT, 3);
+		if (LYSystem(buffer) == 0) {
 #ifdef MULTI_USER_UNIX
-		if (regular)
-		    chmod(filename_buffer, stat_buf.st_mode & 07777);
+		    if (regular)
+			chmod(filename_buffer, stat_buf.st_mode & 07777);
 #endif
-		FREE(buffer);
-		return;
-	    } else {
-		FREE(buffer);
-		keep_tempfile = TRUE;
-		goto failure;
+		    FREE(buffer);
+		    return;
+		}
 	    }
+	    FREE(buffer);
+	    keep_tempfile = TRUE;
+	    goto failure;
 	}
 	CTRACE((tfp, "rename(): %s", LYStrerror(errno)));
 #endif /* _WINDOWS */
diff --git a/src/LYCharSets.c b/src/LYCharSets.c
index e13b156b..a9ccbf54 100644
--- a/src/LYCharSets.c
+++ b/src/LYCharSets.c
@@ -4,6 +4,7 @@
 
 #include <LYGlobalDefs.h>
 #include <UCMap.h>
+#include <UCdomap.h>
 #include <UCDefs.h>
 #include <LYCharSets.h>
 #include <GridText.h>
@@ -12,17 +13,11 @@
 
 #include <LYLeaks.h>
 
-extern BOOL HTPassEightBitRaw;
-extern BOOL HTPassEightBitNum;
-extern BOOL HTPassHighCtrlRaw;
-extern BOOL HTPassHighCtrlNum;
 PUBLIC HTkcode kanji_code = NOKANJI;
 PUBLIC BOOLEAN LYHaveCJKCharacterSet = FALSE;
 PUBLIC BOOLEAN DisplayCharsetMatchLocale = TRUE;
 PUBLIC BOOL force_old_UCLYhndl_on_reload = FALSE;
 PUBLIC int forced_UCLYhdnl;
-extern void UCInit NOARGS;
-extern int UCInitialized;
 PUBLIC int LYNumCharsets = 0;  /* Will be initialized later by UC_Register. */
 PUBLIC int current_char_set = -1; /* will be intitialized later in LYMain.c */
 PUBLIC CONST char** p_entity_values = NULL; /* Pointer, for HTML_put_entity()*/
diff --git a/src/LYCharSets.h b/src/LYCharSets.h
index e1c03d7f..051e9c90 100644
--- a/src/LYCharSets.h
+++ b/src/LYCharSets.h
@@ -11,6 +11,10 @@
 #include <UCMap.h>
 #endif /* !UCMAP_H */
 
+extern BOOL HTPassEightBitRaw;
+extern BOOL HTPassEightBitNum;
+extern BOOL HTPassHighCtrlRaw;
+extern BOOL HTPassHighCtrlNum;
 extern BOOLEAN LYHaveCJKCharacterSet;
 extern BOOLEAN DisplayCharsetMatchLocale;
 
diff --git a/src/LYCharUtils.c b/src/LYCharUtils.c
index 9f0a66a0..752934d5 100644
--- a/src/LYCharUtils.c
+++ b/src/LYCharUtils.c
@@ -38,11 +38,6 @@
 #include <LYexit.h>
 #include <LYLeaks.h>
 
-extern BOOL HTPassEightBitRaw;
-extern BOOL HTPassEightBitNum;
-extern BOOL HTPassHighCtrlRaw;
-extern BOOL HTPassHighCtrlNum;
-
 /*
  *  Used for nested lists. - FM
  */
diff --git a/src/LYCookie.c b/src/LYCookie.c
index 34d6b967..d5cf0f38 100644
--- a/src/LYCookie.c
+++ b/src/LYCookie.c
@@ -1931,8 +1931,8 @@ PUBLIC void LYLoadCookies ARGS1 (
 	tok_ptr = buf;
 	tok_out = LYstrsep(&tok_ptr, "\t");
 	for (tok_loop = 0; tok_out && tok_values[tok_loop].s; tok_loop++) {
-	    CTRACE((tfp, "\t%d:%p:%p:[%s]\n",
-		tok_loop, tok_values[tok_loop].s, tok_out, tok_out));
+	    CTRACE((tfp, "\t%d:[%03d]:[%s]\n",
+		tok_loop, tok_out - buf, tok_out));
 	    LYstrncpy(tok_values[tok_loop].s, tok_out, tok_values[tok_loop].n);
 	    /*
 	     * It looks like strtok ignores a leading delimiter,
@@ -2066,7 +2066,8 @@ PUBLIC void LYStoreCookies ARGS1 (
 	    if ((co = (cookie *)cl->object) == NULL)
 		continue;
 
-	    CTRACE((tfp, "LYStoreCookies: %ld cf %ld ", (long) now, (long) co->expires));
+	    CTRACE((tfp, "LYStoreCookies: %ld cf %ld ",
+		   (long) now, (long) co->expires));
 
 	    if ((co->flags & COOKIE_FLAG_DISCARD)) {
 		CTRACE((tfp, "not stored - DISCARD\n"));
@@ -2080,11 +2081,11 @@ PUBLIC void LYStoreCookies ARGS1 (
 	    }
 
 	    fprintf(cookie_handle, "%s\t%s\t%s\t%s\t%ld\t%s\t%s%s%s\n",
-		de->domain,
+		    de->domain,
 		    (de->domain[0] == '.') ? "TRUE" : "FALSE",
 		    co->path,
-		co->flags & COOKIE_FLAG_SECURE ? "TRUE" : "FALSE",
-		(long) co->expires, co->name,
+		    co->flags & COOKIE_FLAG_SECURE ? "TRUE" : "FALSE",
+		    (long) co->expires, co->name,
 		    (co->quoted ? "\"" : ""),
 		    NonNull(co->value),
 		    (co->quoted ? "\"" : ""));
diff --git a/src/LYCurses.c b/src/LYCurses.c
index d3a1cff7..7fe777f4 100644
--- a/src/LYCurses.c
+++ b/src/LYCurses.c
@@ -1963,7 +1963,6 @@ TRACEBACK if it can be captured, and any other relevant information.\n"));
  */
 PUBLIC int ttopen NOARGS
 {
-	extern	void cleanup_sig();
 	int	iosb[2];
 	int	status;
 	static unsigned long condition;
@@ -2281,7 +2280,6 @@ PUBLIC int DCLsystem ARGS1(
 	char *,		command)
 {
      int status;
-     extern void controlc();
 
      VMSsignal(SIGINT, SIG_IGN);
      status = spawn_DCLprocess(command);
diff --git a/src/LYDownload.h b/src/LYDownload.h
index aeed2b19..b7d75ae7 100644
--- a/src/LYDownload.h
+++ b/src/LYDownload.h
@@ -1,4 +1,3 @@
-
 #ifndef LYDOWNLOAD_H
 #define LYDOWNLOAD_H
 
@@ -9,5 +8,8 @@
 extern void LYDownload PARAMS((char *line));
 extern int LYdownload_options PARAMS((char **newfile, char *data_file));
 
-#endif /* LYDOWNLOAD_H */
+#ifdef VMS
+extern BOOLEAN LYDidRename;
+#endif
 
+#endif /* LYDOWNLOAD_H */
diff --git a/src/LYGetFile.c b/src/LYGetFile.c
index 2cf6c794..e8aeb252 100644
--- a/src/LYGetFile.c
+++ b/src/LYGetFile.c
@@ -36,10 +36,6 @@
 PRIVATE int fix_httplike_urls PARAMS((DocInfo *doc, UrlTypes type));
 
 #ifdef VMS
-extern BOOLEAN LYDidRename;
-#endif /* VMS */
-
-#ifdef VMS
 #define STRNADDRCOMP strncasecomp
 #else
 #define STRNADDRCOMP strncmp
@@ -1581,7 +1577,7 @@ PRIVATE int fix_httplike_urls ARGS2(
 	}
 	if (type == HTTP_URL_TYPE ||
 	    type == HTTPS_URL_TYPE) {
-	    if ((slash-2) - strchr(doc->address, ':')) {
+	    if ((slash-2) != strchr(doc->address, ':')) {
 		/*
 		 *  Turns out we were not looking at the right slash after all,
 		 *  there must have been more than one "://" which is valid
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index 3cd16f87..821e9f94 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -57,10 +57,6 @@ extern BOOLEAN UseFixedRecords; /* convert binary files to FIXED 512 records */
 extern char *list_format;
 #endif /* !VMS */
 
-#ifdef VMS
-extern char *LYCSwingPath;
-#endif /* VMS */
-
 #ifdef DIRED_SUPPORT
 
 typedef enum {
@@ -144,8 +140,8 @@ extern char star_string[MAX_LINE + 1]; /* from GridText.c */
  ((n) >= MAX_LINE ? star_string : &star_string[(MAX_LINE-1)] - (n))
 
 typedef enum {
-    SHOW_COLOR_UNKNOWN = 0
-    , SHOW_COLOR_NEVER
+    SHOW_COLOR_UNKNOWN = -1
+    , SHOW_COLOR_NEVER = 0	/* positive numbers are index in LYOptions.c */
     , SHOW_COLOR_OFF
     , SHOW_COLOR_ON
     , SHOW_COLOR_ALWAYS
diff --git a/src/LYList.c b/src/LYList.c
index 20c28d8d..e9777988 100644
--- a/src/LYList.c
+++ b/src/LYList.c
@@ -48,6 +48,7 @@ PUBLIC int showlist ARGS2(
     char *LinkTitle = NULL;  /* Rel stored as property of link, not of dest */
     BOOLEAN intern_w_post = FALSE;
     char *desc = "unknown field or link";
+    void* helper;
 
     refs = HText_sourceAnchors(HTMainText);
     hidden_links = HText_HiddenLinkCount(HTMainText);
@@ -102,8 +103,9 @@ PUBLIC int showlist ARGS2(
 	if (LYHiddenLinks == HIDDENLINKS_IGNORE)
 	    hidden_links = 0;
     }
+    helper = NULL; /* init */
     for (cnt = 1; cnt <= refs; cnt++) {
-	HTChildAnchor *child = HText_childNumber(cnt);
+	HTChildAnchor *child = HText_childNextNumber(cnt, &helper);
 	HTAnchor *dest_intl = NULL;
 	HTAnchor *dest;
 	HTParentAnchor *parent;
@@ -134,7 +136,7 @@ PUBLIC int showlist ARGS2(
 	}
 #ifndef DONT_TRACK_INTERNAL_LINKS
 	dest_intl = HTAnchor_followTypedLink((HTAnchor *)child,
-						       LINK_INTERNAL);
+						       HTInternalLink);
 #endif
 	dest = dest_intl ?
 	    dest_intl : HTAnchor_followMainLink((HTAnchor *)child);
@@ -256,6 +258,7 @@ PUBLIC void printlist ARGS2(
     int refs, hidden_links;
     char *address = NULL;
     char *desc = gettext("unknown field or link");
+    void* helper;
 
     refs = HText_sourceAnchors(HTMainText);
     if (refs <= 0 && LYHiddenLinks != HIDDENLINKS_SEPARATE)
@@ -270,8 +273,9 @@ PUBLIC void printlist ARGS2(
 	    if (LYHiddenLinks == HIDDENLINKS_IGNORE)
 		hidden_links = 0;
 	}
+       helper = NULL; /* init */
 	for (cnt = 1; cnt <= refs; cnt++) {
-	    HTChildAnchor *child = HText_childNumber(cnt);
+	    HTChildAnchor *child = HText_childNextNumber(cnt, &helper);
 	    HTAnchor *dest;
 	    HTParentAnchor *parent;
 	    CONST char *title;
diff --git a/src/LYLocal.c b/src/LYLocal.c
index c627315c..db733817 100644
--- a/src/LYLocal.c
+++ b/src/LYLocal.c
@@ -326,7 +326,7 @@ PRIVATE BOOLEAN ok_localname ARGS2(char*, dst, CONST char*, src)
  *  Execute DIRED command, return -1 or 0 on failure, 1 success.
  */
 PRIVATE int LYExecv ARGS3(
-	char *,		path,
+	CONST char *,	path,
 	char **,	argv,
 	char *,		msg)
 {
@@ -425,104 +425,112 @@ PRIVATE int LYExecv ARGS3(
 PRIVATE int make_directory ARGS1(char *, path)
 {
     int code;
-#ifdef MKDIR_PATH
-    char *args[5];
-    char *msg = 0;
-
-    HTSprintf0(&msg,"make directory %s", path);
-    args[0] = "mkdir";
-    args[1] = path;
-    args[2] = (char *) 0;
-    code = (LYExecv(MKDIR_PATH, args, msg) <= 0) ? -1 : 1;
-    FREE(msg);
-#else
+    CONST char *program;
+
+    if ((program = HTGetProgramPath(ppMKDIR)) != NULL) {
+	char *args[5];
+	char *msg = 0;
+
+	HTSprintf0(&msg,"make directory %s", path);
+	args[0] = "mkdir";
+	args[1] = path;
+	args[2] = (char *) 0;
+	code = (LYExecv(program, args, msg) <= 0) ? -1 : 1;
+	FREE(msg);
+    } else {
 #ifdef _WINDOWS
-    code = mkdir(path) ? -1 : 1;
+	code = mkdir(path) ? -1 : 1;
 #else
-    code = mkdir(path, 0777) ? -1 : 1;
-#endif
+	code = mkdir(path, 0777) ? -1 : 1;
 #endif
+    }
     return (code);
 }
 
 PRIVATE int remove_file ARGS1(char *, path)
 {
     int code;
-#ifdef RM_PATH
-    char *args[5];
-    char *tmpbuf = NULL;
-
-    args[0] = "rm";
-    args[1] = "-rf";
-    args[2] = path;
-    args[3] = (char *) 0;
-    HTSprintf0(&tmpbuf, gettext("remove %s"), path);
-    code = LYExecv(RM_PATH, args, tmpbuf);
-    FREE(tmpbuf);
-#else
-    code = remove(path) ? -1 : 1;
-#endif
+    CONST char *program;
+
+    if ((program = HTGetProgramPath(ppRM)) != NULL) {
+	char *args[5];
+	char *tmpbuf = NULL;
+
+	args[0] = "rm";
+	args[1] = "-rf";
+	args[2] = path;
+	args[3] = (char *) 0;
+	HTSprintf0(&tmpbuf, gettext("remove %s"), path);
+	code = LYExecv(program, args, tmpbuf);
+	FREE(tmpbuf);
+    } else {
+	code = remove(path) ? -1 : 1;
+    }
     return (code);
 }
 
 PRIVATE int touch_file ARGS1(char *, path)
 {
     int code;
-#ifdef TOUCH_PATH
-    char *args[5];
-    char *msg = NULL;
-
-    HTSprintf0(&msg, gettext("touch %s"), path);
-    args[0] = "touch";
-    args[1] = path;
-    args[2] = (char *) 0;
-    code = (LYExecv(TOUCH_PATH, args, msg) <= 0) ? -1 : 1;
-    FREE(msg);
-#else
-    FILE *fp;
-    if ((fp = fopen(path, "w")) != 0) {
-	fclose(fp);
-	code = 1;
+    CONST char *program;
+
+    if ((program = HTGetProgramPath(ppTOUCH)) != NULL) {
+	char *args[5];
+	char *msg = NULL;
+
+	HTSprintf0(&msg, gettext("touch %s"), path);
+	args[0] = "touch";
+	args[1] = path;
+	args[2] = (char *) 0;
+	code = (LYExecv(program, args, msg) <= 0) ? -1 : 1;
+	FREE(msg);
     } else {
-	code = -1;
+	FILE *fp;
+	if ((fp = fopen(path, "w")) != 0) {
+	    fclose(fp);
+	    code = 1;
+	} else {
+	    code = -1;
+	}
     }
-#endif
     return (code);
 }
 
 PRIVATE int move_file ARGS2(char *, source, char *, target)
 {
     int code;
-#ifdef MV_PATH
-    char *msg = 0;
-    char *args[5];
-
-    HTSprintf0(&msg, gettext("move %s to %s"), source, target);
-    args[0] = "mv";
-    args[1] = source;
-    args[2] = target;
-    args[3] = (char *) 0;
-    code = (LYExecv(MV_PATH, args, msg) <= 0) ? -1 : 1;
-    FREE(msg);
-#else
-    struct stat sb;
-    char *actual = 0;
-    /* the caller sets up a target directory; we need a file path */
-    if (stat(target, &sb) == 0
-     && S_ISDIR(sb.st_mode)) {
-	HTSprintf0(&actual, "%s/%s", target, LYPathLeaf(source));
-	CTRACE((tfp, "move_file source=%s, target=%s\n", source, target));
-	target = actual;
-    }
-    if ((code = rename(source, target)) != 0)
-	if ((code = LYCopyFile(source, target)) >= 0)
-	    code = remove(source);
-    if (code == 0)
-	code = 1;
-    if (actual != target) {
-    	FREE(actual);
+    CONST char *program;
+
+    if ((program = HTGetProgramPath(ppMV)) != NULL) {
+	char *msg = 0;
+	char *args[5];
+
+	HTSprintf0(&msg, gettext("move %s to %s"), source, target);
+	args[0] = "mv";
+	args[1] = source;
+	args[2] = target;
+	args[3] = (char *) 0;
+	code = (LYExecv(program, args, msg) <= 0) ? -1 : 1;
+	FREE(msg);
+    } else {
+	struct stat sb;
+	char *actual = 0;
+	/* the caller sets up a target directory; we need a file path */
+	if (stat(target, &sb) == 0
+	 && S_ISDIR(sb.st_mode)) {
+	    HTSprintf0(&actual, "%s/%s", target, LYPathLeaf(source));
+	    CTRACE((tfp, "move_file source=%s, target=%s\n", source, target));
+	    target = actual;
+	}
+	if ((code = rename(source, target)) != 0)
+	    if ((code = LYCopyFile(source, target)) >= 0)
+		code = remove(source);
+	if (code == 0)
+	    code = 1;
+	if (actual != target) {
+	    FREE(actual);
+	}
     }
-#endif
     return code;
 }
 
@@ -856,12 +864,12 @@ PRIVATE int modify_location ARGS1(
      *	Change the location of the file or directory.
      */
     if (S_ISDIR(dir_info.st_mode)) {
-#ifndef MV_PATH
-	HTAlert(COULD_NOT_ACCESS_DIR);
-	return 0;
-#else
-	cp = gettext("Enter new location for directory: ");
-#endif
+	if (HTGetProgramPath(ppMV) != NULL) {
+	    cp = gettext("Enter new location for directory: ");
+	} else {
+	    HTAlert(COULD_NOT_ACCESS_DIR);
+	    return 0;
+	}
     } else if (S_ISREG(dir_info.st_mode)) {
 	cp = gettext("Enter new location for file: ");
     } else {
@@ -1244,6 +1252,7 @@ PRIVATE int permit_location ARGS3(
     char *cp;
     char tmpdst[LY_MAXPATH];
     struct stat dir_info;
+    CONST char *program;
 
     if (srcpath) {
 	/*
@@ -1451,11 +1460,10 @@ PRIVATE int permit_location ARGS3(
 	    cp = cr;
 	}
 
-#ifdef CHMOD_PATH
 	/*
 	 *  Call chmod().
 	 */
-	{
+	if ((program = HTGetProgramPath(ppCHMOD)) != NULL) {
 	    char *args[5];
 	    char amode[10];
 	    char *tmpbuf = NULL;
@@ -1466,16 +1474,15 @@ PRIVATE int permit_location ARGS3(
 	    args[1] = amode;
 	    args[2] = destpath;
 	    args[3] = (char *) 0;
-	    if (LYExecv(CHMOD_PATH, args, tmpbuf) <= 0) {
+	    if (LYExecv(program, args, tmpbuf) <= 0) {
 		FREE(tmpbuf);
 		return (-1);
 	    }
 	    FREE(tmpbuf);
+	} else {
+	    if (chmod(destpath, new_mode) < 0)
+		return (-1);
 	}
-#else
-	if (chmod(destpath, new_mode) < 0)
-	    return (-1);
-#endif /* UNIX */
 	LYforce_no_cache = TRUE;	/* Force update of dired listing. */
 	return 1;
     }
@@ -1615,121 +1622,135 @@ PRIVATE char *build_command ARGS3(
 	char *,		arg)
 {
     char *buffer = NULL;
+    CONST char *program;
+    CONST char *tar_path = HTGetProgramPath(ppTAR);
 
-#ifdef UNCOMPRESS_PATH
     if ((arg = match_op("DECOMPRESS", line)) != 0) {
 #define FMT_UNCOMPRESS "%s %s"
-	HTAddParam(&buffer, FMT_UNCOMPRESS, 1, UNCOMPRESS_PATH);
-	HTAddParam(&buffer, FMT_UNCOMPRESS, 2, arg);
-	HTEndParam(&buffer, FMT_UNCOMPRESS, 2);
+	if ((program = HTGetProgramPath(ppUNCOMPRESS)) != NULL) {
+	    HTAddParam(&buffer, FMT_UNCOMPRESS, 1, program);
+	    HTAddParam(&buffer, FMT_UNCOMPRESS, 2, arg);
+	    HTEndParam(&buffer, FMT_UNCOMPRESS, 2);
+	}
 	return buffer;
     }
-#endif /* UNCOMPRESS_PATH */
 
 #if defined(OK_UUDECODE) && !defined(ARCHIVE_ONLY)
     if ((arg = match_op("UUDECODE", line)) != 0) {
 #define FMT_UUDECODE "%s %s"
-	HTAddParam(&buffer, FMT_UUDECODE, 1, UUDECODE_PATH);
-	HTAddParam(&buffer, FMT_UUDECODE, 2, arg);
-	HTEndParam(&buffer, FMT_UUDECODE, 2);
-	HTAlert(gettext("Warning!  UUDecoded file will exist in the directory you started Lynx."));
+	if ((program = HTGetProgramPath(ppUUDECODE)) != NULL) {
+	    HTAddParam(&buffer, FMT_UUDECODE, 1, program);
+	    HTAddParam(&buffer, FMT_UUDECODE, 2, arg);
+	    HTEndParam(&buffer, FMT_UUDECODE, 2);
+	    HTAlert(gettext("Warning!  UUDecoded file will exist in the directory you started Lynx."));
+	}
 	return buffer;
     }
 #endif /* OK_UUDECODE && !ARCHIVE_ONLY */
 
 #ifdef OK_TAR
+    if (tar_path != NULL) {
 # ifndef ARCHIVE_ONLY
 #  ifdef OK_GZIP
-    if ((arg = match_op("UNTAR_GZ", line)) != 0) {
+	if ((arg = match_op("UNTAR_GZ", line)) != 0) {
 #define FMT_UNTAR_GZ "cd %s; %s -qdc %s |  %s -xf -"
-	dirname = DirectoryOf(arg);
-	HTAddParam(&buffer, FMT_UNTAR_GZ, 1, dirname);
-	HTAddParam(&buffer, FMT_UNTAR_GZ, 2, GZIP_PATH);
-	HTAddParam(&buffer, FMT_UNTAR_GZ, 3, arg);
-	HTAddParam(&buffer, FMT_UNTAR_GZ, 4, TAR_PATH);
-	HTEndParam(&buffer, FMT_UNTAR_GZ, 4);
-	return buffer;
-    }
+	    if ((program = HTGetProgramPath(ppGZIP)) != NULL) {
+		dirname = DirectoryOf(arg);
+		HTAddParam(&buffer, FMT_UNTAR_GZ, 1, dirname);
+		HTAddParam(&buffer, FMT_UNTAR_GZ, 2, program);
+		HTAddParam(&buffer, FMT_UNTAR_GZ, 3, arg);
+		HTAddParam(&buffer, FMT_UNTAR_GZ, 4, tar_path);
+		HTEndParam(&buffer, FMT_UNTAR_GZ, 4);
+	    }
+	    return buffer;
+	}
 #  endif /* OK_GZIP */
-#  ifdef ZCAT_PATH
-    if ((arg = match_op("UNTAR_Z", line)) != 0) {
+	if ((arg = match_op("UNTAR_Z", line)) != 0) {
 #define FMT_UNTAR_Z "cd %s; %s %s |  %s -xf -"
-	dirname = DirectoryOf(arg);
-	HTAddParam(&buffer, FMT_UNTAR_Z, 1, dirname);
-	HTAddParam(&buffer, FMT_UNTAR_Z, 2, ZCAT_PATH);
-	HTAddParam(&buffer, FMT_UNTAR_Z, 3, arg);
-	HTAddParam(&buffer, FMT_UNTAR_Z, 4, TAR_PATH);
-	HTEndParam(&buffer, FMT_UNTAR_Z, 4);
-	return buffer;
-    }
-#   endif /* ZCAT_PATH */
-    if ((arg = match_op("UNTAR", line)) != 0) {
+	    if ((program = HTGetProgramPath(ppZCAT)) != NULL) {
+		dirname = DirectoryOf(arg);
+		HTAddParam(&buffer, FMT_UNTAR_Z, 1, dirname);
+		HTAddParam(&buffer, FMT_UNTAR_Z, 2, program);
+		HTAddParam(&buffer, FMT_UNTAR_Z, 3, arg);
+		HTAddParam(&buffer, FMT_UNTAR_Z, 4, tar_path);
+		HTEndParam(&buffer, FMT_UNTAR_Z, 4);
+	    }
+	    return buffer;
+	}
+	if ((arg = match_op("UNTAR", line)) != 0) {
 #define FMT_UNTAR "cd %s; %s -xf %s"
-	dirname = DirectoryOf(arg);
-	HTAddParam(&buffer, FMT_UNTAR, 1, dirname);
-	HTAddParam(&buffer, FMT_UNTAR, 2, TAR_PATH);
-	HTAddParam(&buffer, FMT_UNTAR, 3, arg);
-	HTEndParam(&buffer, FMT_UNTAR, 3);
-	return buffer;
-    }
+	    dirname = DirectoryOf(arg);
+	    HTAddParam(&buffer, FMT_UNTAR, 1, dirname);
+	    HTAddParam(&buffer, FMT_UNTAR, 2, tar_path);
+	    HTAddParam(&buffer, FMT_UNTAR, 3, arg);
+	    HTEndParam(&buffer, FMT_UNTAR, 3);
+	    return buffer;
+	}
 # endif /* !ARCHIVE_ONLY */
 
 # ifdef OK_GZIP
-    if ((arg = match_op("TAR_GZ", line)) != 0) {
+	if ((arg = match_op("TAR_GZ", line)) != 0) {
 #define FMT_TAR_GZ "cd %s; %s -cf - %s | %s -qc >%s%s"
-	dirname = DirectoryOf(arg);
-	HTAddParam(&buffer, FMT_TAR_GZ, 1, dirname);
-	HTAddParam(&buffer, FMT_TAR_GZ, 2, TAR_PATH);
-	HTAddParam(&buffer, FMT_TAR_GZ, 3, LYPathLeaf(arg));
-	HTAddParam(&buffer, FMT_TAR_GZ, 4, GZIP_PATH);
-	HTAddParam(&buffer, FMT_TAR_GZ, 5, LYonedot(LYPathLeaf(arg)));
-	HTAddParam(&buffer, FMT_TAR_GZ, 6, EXT_TAR_GZ);
-	HTEndParam(&buffer, FMT_TAR_GZ, 6);
-	return buffer;
-    }
+	    if ((program = HTGetProgramPath(ppGZIP)) != NULL) {
+		dirname = DirectoryOf(arg);
+		HTAddParam(&buffer, FMT_TAR_GZ, 1, dirname);
+		HTAddParam(&buffer, FMT_TAR_GZ, 2, tar_path);
+		HTAddParam(&buffer, FMT_TAR_GZ, 3, LYPathLeaf(arg));
+		HTAddParam(&buffer, FMT_TAR_GZ, 4, program);
+		HTAddParam(&buffer, FMT_TAR_GZ, 5, LYonedot(LYPathLeaf(arg)));
+		HTAddParam(&buffer, FMT_TAR_GZ, 6, EXT_TAR_GZ);
+		HTEndParam(&buffer, FMT_TAR_GZ, 6);
+	    }
+	    return buffer;
+	}
 # endif /* OK_GZIP */
 
-# ifdef COMPRESS_PATH
-    if ((arg = match_op("TAR_Z", line)) != 0) {
+	if ((arg = match_op("TAR_Z", line)) != 0) {
 #define FMT_TAR_Z "cd %s; %s -cf - %s | %s >%s%s"
-	dirname = DirectoryOf(arg);
-	HTAddParam(&buffer, FMT_TAR_Z, 1, dirname);
-	HTAddParam(&buffer, FMT_TAR_Z, 2, TAR_PATH);
-	HTAddParam(&buffer, FMT_TAR_Z, 3, LYPathLeaf(arg));
-	HTAddParam(&buffer, FMT_TAR_Z, 4, COMPRESS_PATH);
-	HTAddParam(&buffer, FMT_TAR_Z, 5, LYonedot(LYPathLeaf(arg)));
-	HTAddParam(&buffer, FMT_TAR_Z, 6, EXT_TAR_Z);
-	HTEndParam(&buffer, FMT_TAR_Z, 6);
-	return buffer;
-    }
-# endif /* COMPRESS_PATH */
+	    if ((program = HTGetProgramPath(ppCOMPRESS)) != NULL) {
+		dirname = DirectoryOf(arg);
+		HTAddParam(&buffer, FMT_TAR_Z, 1, dirname);
+		HTAddParam(&buffer, FMT_TAR_Z, 2, tar_path);
+		HTAddParam(&buffer, FMT_TAR_Z, 3, LYPathLeaf(arg));
+		HTAddParam(&buffer, FMT_TAR_Z, 4, program);
+		HTAddParam(&buffer, FMT_TAR_Z, 5, LYonedot(LYPathLeaf(arg)));
+		HTAddParam(&buffer, FMT_TAR_Z, 6, EXT_TAR_Z);
+		HTEndParam(&buffer, FMT_TAR_Z, 6);
+	    }
+	    return buffer;
+	}
 
-    if ((arg = match_op("TAR", line)) != 0) {
+	if ((arg = match_op("TAR", line)) != 0) {
 #define FMT_TAR "cd %s; %s -cf %s.tar %s"
-	dirname = DirectoryOf(arg);
-	HTAddParam(&buffer, FMT_TAR, 1, dirname);
-	HTAddParam(&buffer, FMT_TAR, 2, TAR_PATH);
-	HTAddParam(&buffer, FMT_TAR, 3, LYonedot(LYPathLeaf(arg)));
-	HTAddParam(&buffer, FMT_TAR, 4, LYPathLeaf(arg));
-	HTEndParam(&buffer, FMT_TAR, 4);
-	return buffer;
+	    dirname = DirectoryOf(arg);
+	    HTAddParam(&buffer, FMT_TAR, 1, dirname);
+	    HTAddParam(&buffer, FMT_TAR, 2, tar_path);
+	    HTAddParam(&buffer, FMT_TAR, 3, LYonedot(LYPathLeaf(arg)));
+	    HTAddParam(&buffer, FMT_TAR, 4, LYPathLeaf(arg));
+	    HTEndParam(&buffer, FMT_TAR, 4);
+	    return buffer;
+	}
     }
 #endif /* OK_TAR */
 
 #ifdef OK_GZIP
     if ((arg = match_op("GZIP", line)) != 0) {
 #define FMT_GZIP "%s -q %s"
-	HTAddParam(&buffer, FMT_GZIP, 1, GZIP_PATH);
-	HTAddParam(&buffer, FMT_GZIP, 2, arg);
-	HTEndParam(&buffer, FMT_GZIP, 2);
+	if ((program = HTGetProgramPath(ppGZIP)) != NULL) {
+	    HTAddParam(&buffer, FMT_GZIP, 1, program);
+	    HTAddParam(&buffer, FMT_GZIP, 2, arg);
+	    HTEndParam(&buffer, FMT_GZIP, 2);
+	}
 	return buffer;
     }
 #ifndef ARCHIVE_ONLY
     if ((arg = match_op("UNGZIP", line)) != 0) {
 #define FMT_UNGZIP "%s -d %s"
-	HTAddParam(&buffer, FMT_UNGZIP, 1, GZIP_PATH);
-	HTAddParam(&buffer, FMT_UNGZIP, 2, arg);
-	HTEndParam(&buffer, FMT_UNGZIP, 2);
+	if ((program = HTGetProgramPath(ppGZIP)) != NULL) {
+	    HTAddParam(&buffer, FMT_UNGZIP, 1, program);
+	    HTAddParam(&buffer, FMT_UNGZIP, 2, arg);
+	    HTEndParam(&buffer, FMT_UNGZIP, 2);
+	}
 	return buffer;
     }
 #endif /* !ARCHIVE_ONLY */
@@ -1738,36 +1759,40 @@ PRIVATE char *build_command ARGS3(
 #ifdef OK_ZIP
     if ((arg = match_op("ZIP", line)) != 0) {
 #define FMT_ZIP "cd %s; %s -rq %s.zip %s"
-	dirname = DirectoryOf(arg);
-	HTAddParam(&buffer, FMT_ZIP, 1, dirname);
-	HTAddParam(&buffer, FMT_ZIP, 2, ZIP_PATH);
-	HTAddParam(&buffer, FMT_ZIP, 3, LYonedot(LYPathLeaf(arg)));
-	HTAddParam(&buffer, FMT_ZIP, 4, LYPathLeaf(arg));
-	HTEndParam(&buffer, FMT_ZIP, 4);
+	if ((program = HTGetProgramPath(ppZIP)) != NULL) {
+	    dirname = DirectoryOf(arg);
+	    HTAddParam(&buffer, FMT_ZIP, 1, dirname);
+	    HTAddParam(&buffer, FMT_ZIP, 2, program);
+	    HTAddParam(&buffer, FMT_ZIP, 3, LYonedot(LYPathLeaf(arg)));
+	    HTAddParam(&buffer, FMT_ZIP, 4, LYPathLeaf(arg));
+	    HTEndParam(&buffer, FMT_ZIP, 4);
+	}
 	return buffer;
     }
-#if !defined(ARCHIVE_ONLY) && defined(UNZIP_PATH)
+#if !defined(ARCHIVE_ONLY)
     if ((arg = match_op("UNZIP", line)) != 0) {
 #define FMT_UNZIP "cd %s; %s -q %s"
-	dirname = DirectoryOf(arg);
-	HTAddParam(&buffer, FMT_UNZIP, 1, dirname);
-	HTAddParam(&buffer, FMT_UNZIP, 2, UNZIP_PATH);
-	HTAddParam(&buffer, FMT_UNZIP, 3, arg);
-	HTEndParam(&buffer, FMT_UNZIP, 3);
+	if ((program = HTGetProgramPath(ppUNZIP)) != NULL) {
+	    dirname = DirectoryOf(arg);
+	    HTAddParam(&buffer, FMT_UNZIP, 1, dirname);
+	    HTAddParam(&buffer, FMT_UNZIP, 2, program);
+	    HTAddParam(&buffer, FMT_UNZIP, 3, arg);
+	    HTEndParam(&buffer, FMT_UNZIP, 3);
+	}
 	return buffer;
     }
 # endif /* !ARCHIVE_ONLY */
 #endif /* OK_ZIP */
 
-#ifdef COMPRESS_PATH
     if ((arg = match_op("COMPRESS", line)) != 0) {
 #define FMT_COMPRESS "%s %s"
-	HTAddParam(&buffer, FMT_COMPRESS, 1, COMPRESS_PATH);
-	HTAddParam(&buffer, FMT_COMPRESS, 2, arg);
-	HTEndParam(&buffer, FMT_COMPRESS, 2);
+	if ((program = HTGetProgramPath(ppCOMPRESS)) != NULL) {
+	    HTAddParam(&buffer, FMT_COMPRESS, 1, program);
+	    HTAddParam(&buffer, FMT_COMPRESS, 2, arg);
+	    HTEndParam(&buffer, FMT_COMPRESS, 2);
+	}
 	return buffer;
     }
-#endif /* COMPRESS_PATH */
 
     return NULL;
 }
@@ -2185,6 +2210,12 @@ PUBLIC BOOLEAN local_install ARGS3(
     int count = 0;
     int n = 0;		/* indices into 'args[]' */
     static int src = -1;
+    CONST char *program;
+
+    if ((program = HTGetProgramPath(ppINSTALL)) == NULL) {
+	HTAlert(gettext("Install in the selected directory not permitted."));
+	return 0;
+    }
 
     /*
      *	Determine the status of the selected item.
@@ -2291,7 +2322,7 @@ PUBLIC BOOLEAN local_install ARGS3(
 	}
 	args[src] = savepath;
 	HTSprintf0(&tmpbuf, "install %s in %s", savepath, destpath);
-	if (LYExecv(INSTALL_PATH, args, tmpbuf) <= 0) {
+	if (LYExecv(program, args, tmpbuf) <= 0) {
 	    FREE(tmpbuf);
 	    FREE(tmpdest);
 	    return (-1);
@@ -2318,7 +2349,7 @@ PUBLIC BOOLEAN local_install ARGS3(
 		FREE(args[src]);
 		continue;	/* skip this source file */
 	    }
-	    err = (LYExecv(INSTALL_PATH, args, tmpbuf) <= 0);
+	    err = (LYExecv(program, args, tmpbuf) <= 0);
 	    FREE(args[src]);
 	    if (err) {
 		FREE(tmpbuf);
diff --git a/src/LYMail.c b/src/LYMail.c
index 5a0f3eac..7e8731cb 100644
--- a/src/LYMail.c
+++ b/src/LYMail.c
@@ -15,8 +15,6 @@
 #include <LYLeaks.h>
 
 #define MAX_SUBJECT 70
-#define EMPTY(s) ((s) == 0 || *(s) == 0)
-#define NIL_OK(s) (((s) != 0) ? (s) : "<nil>")
 
 BOOLEAN term_letter;	/* Global variable for async i/o. */
 
@@ -76,7 +74,7 @@ PRIVATE void comma_append ARGS2(
 	while (*src == ',' || isspace(UCH(*src)))
 	    src++;
 	if (*src) {
-	    if (EMPTY(*dst)) {
+	    if (isEmpty(*dst)) {
 		StrAllocCopy(*dst, src);
 	    } else {
 		StrAllocCat(*dst, ",");
@@ -113,7 +111,7 @@ PRIVATE void extract_field ARGS3(
 	}
 	cp++;
     }
-    CTRACE((tfp, "extract_field(%s) = '%s'\n", keyword, NIL_OK(*dst)));
+    CTRACE((tfp, "extract_field(%s) = '%s'\n", keyword, NONNULL(*dst)));
 }
 
 /*
@@ -149,7 +147,7 @@ PRIVATE void extract_subject ARGS2(
 	    cp1 = NULL;
 	}
     }
-    CTRACE((tfp, "extract_subject(%s) = '%s'\n", keyword, NIL_OK(dst)));
+    CTRACE((tfp, "extract_subject(%s) = '%s'\n", keyword, NONNULL(dst)));
 }
 
 /*
@@ -219,7 +217,7 @@ PRIVATE void extract_body ARGS2(
 	}
 	cp++;
     }
-    CTRACE((tfp, "extract_body(%s) = '%s'\n", keyword, NIL_OK(*dst)));
+    CTRACE((tfp, "extract_body(%s) = '%s'\n", keyword, NONNULL(*dst)));
 }
 
 /*
@@ -376,10 +374,10 @@ PRIVATE char *blat_cmd(
     fprintf(fp, "-t\n%s\n", address);
     if (subject)
 	fprintf(fp, "-s\n%s\n", subject);
-    if (!EMPTY(mail_addr)) {
+    if (!isEmpty(mail_addr)) {
 	fprintf(fp, "-f\n%s\n", mail_addr);
     }
-    if (!EMPTY(ccaddr)) {
+    if (!isEmpty(ccaddr)) {
 	fprintf(fp, "-c\n%s\n", ccaddr);
     }
     LYCloseOutput(fp);
@@ -570,10 +568,10 @@ PUBLIC void mailform ARGS4(
 #endif
 
     CTRACE((tfp, "mailform(\"%s\", \"%s\", \"%s\", \"%s\")\n",
-	NIL_OK(mailto_address),
-	NIL_OK(mailto_subject),
-	NIL_OK(mailto_content),
-	NIL_OK(mailto_type)));
+	NONNULL(mailto_address),
+	NONNULL(mailto_subject),
+	NONNULL(mailto_content),
+	NONNULL(mailto_type)));
 
     if (!mailto_address || !mailto_content) {
 	HTAlert(BAD_FORM_MAILTO);
@@ -650,8 +648,8 @@ PUBLIC void mailform ARGS4(
     /*
      *	Allow user to edit the default Subject - FM
      */
-    if (EMPTY(subject)) {
-	if (!EMPTY(mailto_subject)) {
+    if (isEmpty(subject)) {
+	if (!isEmpty(mailto_subject)) {
 	    LYstrncpy(subject, mailto_subject, MAX_SUBJECT);
 	} else {
 	    sprintf(subject, "mailto:%.63s", address);
@@ -672,7 +670,7 @@ PUBLIC void mailform ARGS4(
      */
     if (!LYNoCc) {
 	sprintf(self, "%.*s", MAX_SUBJECT,
-		EMPTY(personal_mail_address) ? "" : personal_mail_address);
+		isEmpty(personal_mail_address) ? "" : personal_mail_address);
 	_statusline("Cc: ");
 	if ((ch = LYgetstr(self, VISIBLE, MAX_SUBJECT, NORECALL)) < 0) {
 	    /*
@@ -696,17 +694,17 @@ PUBLIC void mailform ARGS4(
 	goto cleanup;
     }
 
-    if (!EMPTY(mailto_type)) {
+    if (!isEmpty(mailto_type)) {
 	fprintf(fd, "Mime-Version: 1.0\n");
 	fprintf(fd, "Content-Type: %s\n", mailto_type);
     }
     fprintf(fd, "To: %s\n", address);
-    if (!EMPTY(personal_mail_address))
+    if (!isEmpty(personal_mail_address))
 	fprintf(fd, "From: %s\n", personal_mail_address);
-    if (!EMPTY(ccaddr))
+    if (!isEmpty(ccaddr))
 	fprintf(fd, "Cc: %s\n", ccaddr);
     fprintf(fd, "Subject: %s\n\n", subject);
-    if (!EMPTY(keywords))
+    if (!isEmpty(keywords))
 	fprintf(fd, "Keywords: %s\n", keywords);
     _statusline(SENDING_FORM_CONTENT);
 #else	/* e.g., VMS, DOS */
@@ -722,17 +720,17 @@ PUBLIC void mailform ARGS4(
 	    LYCloseTempFP(fd);
 	    goto cleanup;
 	}
-	if (!EMPTY(mailto_type)) {
+	if (!isEmpty(mailto_type)) {
 	    fprintf(hfd, "Mime-Version: 1.0\n");
 	    fprintf(hfd, "Content-Type: %s\n", mailto_type);
-	    if (!EMPTY(personal_mail_address))
+	    if (!isEmpty(personal_mail_address))
 		fprintf(hfd, "From: %s\n", personal_mail_address);
 	}
 	/*
 	 *  For PMDF, put any keywords and the subject
 	 *  in the header file and close it. - FM
 	 */
-	if (!EMPTY(keywords)) {
+	if (!isEmpty(keywords)) {
 	    fprintf(hfd, "Keywords: %s\n", keywords);
 	}
 	fprintf(hfd, "Subject: %s\n\n", subject);
@@ -754,12 +752,12 @@ PUBLIC void mailform ARGS4(
     } else
 #endif
     {
-	if (!EMPTY(mailto_type)) {
+	if (!isEmpty(mailto_type)) {
 	    fprintf(fd, "Mime-Version: 1.0\n");
 	    fprintf(fd, "Content-Type: %s\n", mailto_type);
 	}
 	fprintf(fd,"To: %s\n", address);
-	if (!EMPTY(personal_mail_address))
+	if (!isEmpty(personal_mail_address))
 	    fprintf(fd,"From: %s\n", personal_mail_address);
 	fprintf(fd,"Subject: %.70s\n\n", subject);
     }
@@ -835,7 +833,7 @@ PUBLIC void mailform ARGS4(
     StrAllocCopy(command, cmd);
 
     vms_append_addrs(&command, address, "");
-    if (!EMPTY(ccaddr)) {
+    if (!isEmpty(ccaddr)) {
 	vms_append_addrs(&command, ccaddr, "/CC");
     }
 
@@ -894,9 +892,9 @@ PUBLIC void mailmsg ARGS4(
     char *command = NULL;
 
     CTRACE((tfp, "mailmsg(%d, \"%s\", \"%s\", \"%s\")\n", cur,
-	NIL_OK(owner_address),
-	NIL_OK(filename),
-	NIL_OK(linkname)));
+	NONNULL(owner_address),
+	NONNULL(filename),
+	NONNULL(linkname)));
 
 #endif /* VMS */
 
@@ -975,7 +973,7 @@ PUBLIC void mailmsg ARGS4(
 
     fprintf(fd, "To: %s\n", address);
     fprintf(fd, "Subject: Lynx Error in %s\n", filename);
-    if (!EMPTY(personal_mail_address)) {
+    if (!isEmpty(personal_mail_address)) {
 	fprintf(fd, "Cc: %s\n", personal_mail_address);
     }
     fprintf(fd, "X-URL: %s\n", filename);
@@ -997,7 +995,7 @@ PUBLIC void mailmsg ARGS4(
 	    return;
 	}
 
-	if (!EMPTY(personal_mail_address)) {
+	if (!isEmpty(personal_mail_address)) {
 	    fprintf(fd, "Cc: %s\n", personal_mail_address);
 	}
 	fprintf(fd, "X-URL: %s\n", filename);
@@ -1122,9 +1120,9 @@ PUBLIC void reply_by_mail ARGS4(
     int i;
     int c = 0;	/* user input */
     char my_tmpfile[LY_MAXPATH];
-    char *command = NULL;
     char default_subject[MAX_SUBJECT + 10];
 #if USE_VMS_MAILER
+    char *command = NULL;
     BOOLEAN isPMDF = LYMailPMDF();
     char hdrfile[LY_MAXPATH];
     FILE *hfd = 0;
@@ -1138,14 +1136,14 @@ PUBLIC void reply_by_mail ARGS4(
 #endif /* USE_VMS_MAILER */
 
     CTRACE((tfp, "reply_by_mail(\"%s\", \"%s\", \"%s\", \"%s\")\n",
-	NIL_OK(mail_address),
-	NIL_OK(filename),
-	NIL_OK(title),
-	NIL_OK(refid)));
+	NONNULL(mail_address),
+	NONNULL(filename),
+	NONNULL(title),
+	NONNULL(refid)));
 
     term_letter = FALSE;
 
-    if (EMPTY(mail_address)) {
+    if (isEmpty(mail_address)) {
 	HTAlert(NO_ADDRESS_IN_MAILTO_URL);
 	return;
     }
@@ -1234,7 +1232,7 @@ PUBLIC void reply_by_mail ARGS4(
     /*
      *	Set the default subject. - FM
      */
-    if (EMPTY(default_subject) && !EMPTY(title)) {
+    if (isEmpty(default_subject) && !isEmpty(title)) {
 	strncpy(default_subject, title, MAX_SUBJECT);
 	default_subject[MAX_SUBJECT] = '\0';
     }
@@ -1253,8 +1251,8 @@ PUBLIC void reply_by_mail ARGS4(
 	 */
 	fprintf((isPMDF ? hfd : fd),
 		"X-URL: %s%s\n",
-		EMPTY(filename) ? STR_MAILTO_URL : filename,
-		EMPTY(filename) ? to_address : "");
+		isEmpty(filename) ? STR_MAILTO_URL : filename,
+		isEmpty(filename) ? to_address : "");
 	fprintf((isPMDF ? hfd : fd),
 		"X-Mailer: %s, Version %s\n", LYNX_NAME, LYNX_VERSION);
 #ifdef NO_ANONYMOUS_EMAIL
@@ -1297,14 +1295,14 @@ PUBLIC void reply_by_mail ARGS4(
     /*
      *	Put the X-URL and X-Mailer lines in the header.
      */
-    if (!EMPTY(filename)) {
+    if (!isEmpty(filename)) {
 	HTSprintf(&header, "X-URL: %s\n", filename);
     } else {
 	HTSprintf(&header, "X-URL: mailto:%s\n", to_address);
     }
     HTSprintf(&header, "X-Mailer: %s, Version %s\n", LYNX_NAME, LYNX_VERSION);
 
-    if (!EMPTY(refid)) {
+    if (!isEmpty(refid)) {
 	HTSprintf(&header, "In-Reply-To: <%s>\n", refid);
     }
 #endif /* VMS */
@@ -1405,7 +1403,7 @@ PUBLIC void reply_by_mail ARGS4(
     label = "Subject";
     if (*default_subject) {
 	StrAllocCopy(the_subject, default_subject);
-    } else if (!EMPTY(filename)) {
+    } else if (!isEmpty(filename)) {
 	HTSprintf(&the_subject, "%s", filename);
     } else {
 	HTSprintf(&the_subject, "mailto:%s", to_address);
@@ -1439,14 +1437,14 @@ PUBLIC void reply_by_mail ARGS4(
     /*
     **	Add the Cc: header. - FM
     */
-    if (!EMPTY(ccaddr)) {
+    if (!isEmpty(ccaddr)) {
 	HTSprintf(&header, "Cc: %s\n", ccaddr);
     }
 
     /*
     **	Add the Keywords: header. - FM
     */
-    if (!EMPTY(keywords)) {
+    if (!isEmpty(keywords)) {
 	HTSprintf(&header, "Keywords: %s\n", keywords);
     }
 
@@ -1457,7 +1455,7 @@ PUBLIC void reply_by_mail ARGS4(
     CTRACE((tfp,"**header==\n%s",header));
 #endif /* !VMS */
 
-    if (!no_editor && !EMPTY(editor)) {
+    if (!no_editor && !isEmpty(editor)) {
 
 	if (body) {
 	    cp1 = body;
@@ -1609,7 +1607,7 @@ PUBLIC void reply_by_mail ARGS4(
 	 *  For PMDF, put any keywords and the subject
 	 *  in the header file and close it. - FM
 	 */
-	if (!EMPTY(keywords)) {
+	if (!isEmpty(keywords)) {
 	    fprintf(hfd, "Keywords: %s\n", keywords);
 	}
 	fprintf(hfd, "Subject: %s\n\n", the_subject);
@@ -1638,7 +1636,7 @@ PUBLIC void reply_by_mail ARGS4(
     }
 
     vms_append_addrs(&command, to_address, "");
-    if (!EMPTY(ccaddr)) {
+    if (!isEmpty(ccaddr)) {
 	vms_append_addrs(&command, ccaddr, "/CC");
     }
 
@@ -1658,7 +1656,6 @@ PUBLIC void reply_by_mail ARGS4(
     if ((fp = LYPipeToMailer()) == 0) {
 	HTInfoMsg(CANCELLED);
     }
-    FREE(command);
 #else
     if ((fp = LYOpenTemp(tmpfile2, ".txt", "w")) == NULL) {
 	HTAlert(MAILTO_URL_TEMPOPEN_FAILED);
@@ -1713,7 +1710,6 @@ cleanup:
     term_letter = FALSE;
 
 #if USE_VMS_MAILER
-    FREE(command);
     while (LYRemoveTemp(my_tmpfile) == 0)
 	;		 /* Delete the tmpfile(s). */
     if (isPMDF) {
diff --git a/src/LYMain.c b/src/LYMain.c
index 5dfa4cb3..d59787ed 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -96,10 +96,6 @@ PUBLIC char *syslog_txt = NULL;		/* syslog arb text for session */
 #endif /* SYSLOG_REQUESTED_URLS */
 #endif /* !VMS */
 
-#ifdef VMS
-PUBLIC char *LYCSwingPath = NULL;
-#endif /* VMS */
-
 #ifdef DIRED_SUPPORT
 PUBLIC BOOLEAN lynx_edit_mode = FALSE;
 PUBLIC BOOLEAN no_dired_support = FALSE;
@@ -530,8 +526,7 @@ PUBLIC int LYNoZapKey = 0; /* 0: off (do z checking), 1: full, 2: initially */
 #endif
 
 #ifndef DISABLE_NEWS
-extern int HTNewsChunkSize; /* Number of news articles per chunk (HTNews.c) */
-extern int HTNewsMaxChunk;  /* Max news articles before chunking (HTNews.c) */
+#include <HTNews.h>
 #endif
 
 PUBLIC BOOLEAN FileInitAlreadyDone = FALSE;
@@ -633,8 +628,10 @@ PRIVATE void free_lynx_globals NOARGS
 
 #ifdef VMS
     Define_VMSLogical("LYNX_VERSION", "");
-    FREE(LYCSwingPath);
 #endif /* VMS */
+#ifndef VMS
+    FREE(lynx_version_putenv_command);
+#endif
 
 #if USE_VMS_MAILER
     FREE(mail_adrs);
@@ -1013,7 +1010,7 @@ PUBLIC int main ARGS2(
     /* Set the text message domain.  */
 #if defined(HAVE_LIBINTL_H) || defined(HAVE_LIBGETTEXT_H)
 #ifndef __DJGPP__
-    if ((cp = LYGetEnv("LYNX_LOCALDIR")) == 0)
+    if ((cp = LYGetEnv("LYNX_LOCALEDIR")) == 0)
 	cp = LOCALEDIR;
     bindtextdomain ("lynx", cp);
 #endif /* !__DJGPP__ */
@@ -1169,12 +1166,6 @@ PUBLIC int main ARGS2(
 	exit_immediately(EXIT_FAILURE);
     }
 
-#ifdef VMS
-#ifdef CSWING_PATH
-    StrAllocCopy(LYCSwingPath, CSWING_PATH);
-#endif /* CSWING_PATH */
-#endif /* VMS */
-
 #if USE_VMS_MAILER
 #ifndef MAIL_ADRS
 #define MAIL_ADRS "\"IN%%\"\"%s\"\"\""
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index 6e75a691..95054600 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -158,6 +158,9 @@ PRIVATE int str_n_cmp(const char *p, const char *q, int n)
 #include <LYexit.h>
 #include <LYLeaks.h>
 
+/* two constants: */
+PUBLIC HTLinkType * HTInternalLink = 0;
+PUBLIC HTAtom * WWW_SOURCE = 0;
 
 #ifndef DONT_TRACK_INTERNAL_LINKS
 #define NO_INTERNAL_OR_DIFFERENT(c,n) TRUE
@@ -471,13 +474,22 @@ PRIVATE void move_address ARGS2(
 /*
  * This is for traversal call from within partial mode in LYUtils.c
  * and HTFormat.c  It simply calls HText_pageDisplay() but utilizes
- * LYMainLoop.c PRIVATE variables.
- * Perhaps, this could adhere more logic from mainloop(), in the future.
+ * LYMainLoop.c PRIVATE variables to manage proper newline position
+ * in case of #fragment
  */
-PUBLIC void LYMainLoop_pageDisplay ARGS1(
+PUBLIC BOOL LYMainLoop_pageDisplay ARGS1(
 	int,		line_num)
 {
 #ifdef DISP_PARTIAL
+    CONST char * pound;
+    int prev_newline = Newline;
+
+    /*
+     *  Override Newline with a new value if user
+     *  scrolled the document while loading (in LYUtils.c).
+     */
+    Newline = line_num;
+
 #ifdef SOURCE_CACHE
     /*
      * reparse_document() acts on 'curdoc' which always on top of the
@@ -487,29 +499,30 @@ PUBLIC void LYMainLoop_pageDisplay ARGS1(
      */
     if (!from_source_cache)
 #endif
-    /*
-     * Disable display_partial if requested URL has #fragment and we are not
-     * popped from the history stack so can't calculate correct newline
-     * position for fragment.  Otherwise user got the new document from the
-     * first page and was moved to #fragment later after download completed,
-     * but only if s/he did not mess screen up by scrolling before...  So fall
-     * down to old behavior here ... until we rewrite HTFindPoundSelector()
-     */
-    if (display_partial
-     && newdoc.line == 1
-     && findPoundSelector(newdoc.address)) {
-	display_partial = FALSE; /* restrict for this document */
-	return;			/* no repaint */
-    }
-
-    /*
-     *  Override Newline with a new value if user
-     *  scrolled the document while loading (in LYUtils.c).
-     */
+	/*
+	 * If the requested URL has the #fragment, and we are not popped
+	 * from the history stack, and have not scrolled the document yet -
+	 * we should calculate correct newline position for the fragment.
+	 * (This is a bit suboptimal since HTFindPoundSelector() traverse
+	 * anchors list each time, so we have a quadratic complexity
+	 * and may load CPU in a worst case).
+	 */
+	if (display_partial
+	    && newdoc.line == 1 && line_num == 1 && prev_newline == 1
+	    && (pound = findPoundSelector(newdoc.address))
+	    && *pound && *(pound+1)) {
+	    if (HTFindPoundSelector(pound+1)) {
+		/* HTFindPoundSelector will initialize www_search_result */
+		Newline = www_search_result;
+	    } else {
+		Newline = prev_newline; /* restore ??? */
+		return NO;	/* no repaint */
+	    }
+	}
 #endif /* DISP_PARTIAL */
-    Newline = line_num;
 
     HText_pageDisplay(Newline, prev_target);
+    return YES;
 }
 
 
@@ -1848,18 +1861,19 @@ PRIVATE void handle_LYK_DIRED_MENU ARGS3(
 {
 #ifdef VMS
     char *cp, *temp = 0;
+    char *test = HTGetProgramPath(ppCSWING);
 
     /*
      *	Check if the CSwing Directory/File Manager is available.
-     *	Will be disabled if LYCSwingPath is NULL, zero-length,
+     *	Will be disabled if CSWING path is NULL, zero-length,
      *	or "none" (case insensitive), if no_file_url was set via
      *	the file_url restriction, if no_goto_file was set for
      *	the anonymous account, or if HTDirAccess was set to
      *	HT_DIR_FORBID or HT_DIR_SELECTIVE via the -nobrowse
      *	or -selective switches. - FM
      */
-    if (!(LYCSwingPath && *LYCSwingPath) ||
-	!strcasecomp(LYCSwingPath, "none") ||
+    if (isEmpty(test) ||
+	!strcasecomp(test, "none") ||
 	no_file_url || no_goto_file ||
 	HTDirAccess == HT_DIR_FORBID ||
 	HTDirAccess == HT_DIR_SELECTIVE) {
@@ -1893,7 +1907,7 @@ PRIVATE void handle_LYK_DIRED_MENU ARGS3(
 	if (HTStat(cp, &stat_info) == -1) {
 	    CTRACE((tfp, "mainloop: Can't stat %s\n", cp));
 	    FREE(cp);
-	    HTSprintf0(&temp, "%s []", LYCSwingPath);
+	    HTSprintf0(&temp, "%s []", HTGetProgramPath(ppCSWING));
 	    *refresh_screen = TRUE;  /* redisplay */
 	} else {
 	    char *VMSdir = NULL;
@@ -1921,7 +1935,7 @@ PRIVATE void handle_LYK_DIRED_MENU ARGS3(
 		    cp == NULL;
 		}
 	    }
-	    HTSprintf0(&temp, "%s %s", LYCSwingPath, VMSdir);
+	    HTSprintf0(&temp, "%s %s", HTGetProgramPath(ppCSWING), VMSdir);
 	    FREE(VMSdir);
 	    /*
 	     *	Uncache the current document in case we
@@ -1944,7 +1958,7 @@ PRIVATE void handle_LYK_DIRED_MENU ARGS3(
 	 *  an argument and don't uncache the current
 	 *  document. - FM
 	 */
-	HTSprintf0(&temp, "%s []", LYCSwingPath);
+	HTSprintf0(&temp, "%s []", HTGetProgramPath(ppCSWING));
 	*refresh_screen = TRUE;	/* redisplay */
     }
     stop_curses();
@@ -5234,6 +5248,16 @@ int mainloop NOARGS
     int i;
     int follow_col = -1, key_count = 0, last_key = 0;
 
+/*  "internal" means "within the same document, with certainty".
+ *  It includes a space so it cannot conflict with any (valid) "TYPE"
+ *  attributes on A elements. [According to which DTD, anyway??] - kw
+ */
+    HTInternalLink = HTAtom_for("internal link");  /* init, used as const */
+
+#ifndef WWW_SOURCE
+    WWW_SOURCE = HTAtom_for("www/source");  /* init, used as const */
+#endif
+
 /*
  *  curdoc.address contains the name of the file that is currently open.
  *  newdoc.address contains the name of the file that will soon be
@@ -6051,10 +6075,17 @@ try_again:
 	    resizeterm(LYlines, LYcols);
 	    wresize(LYwin, LYlines, LYcols);
 #else
+#if 0 /* defined(PDCURSES) && defined(HAVE_XCURSES) */
+	    resize_term(LYlines, LYcols);
+	    if (LYwin != 0)
+		LYwin = resize_window(LYwin, LYlines, LYcols);
+	    refresh();
+#else
 	    stop_curses();
 	    start_curses();
 	    LYclear();
 #endif
+#endif
 	    refresh_screen = TRUE; /* to force a redraw */
 	    if (HTMainText)	/* to REALLY force it... - kw */
 		HText_setStale(HTMainText);
diff --git a/src/LYMainLoop.h b/src/LYMainLoop.h
index 31804315..c74e875a 100644
--- a/src/LYMainLoop.h
+++ b/src/LYMainLoop.h
@@ -10,7 +10,7 @@ extern int LYGetNewline NOPARAMS;
 extern int mainloop NOPARAMS;
 extern void HTAddGotoURL PARAMS((char *url));
 extern void LYCloseTracelog NOPARAMS;
-extern void LYMainLoop_pageDisplay PARAMS((int line_num));
+extern BOOL LYMainLoop_pageDisplay PARAMS((int line_num));
 extern void LYSetNewline PARAMS((int value));
 extern void handle_LYK_TRACE_TOGGLE NOPARAMS;
 extern void handle_LYK_WHEREIS PARAMS((int cmd, BOOLEAN *refresh_screen));
diff --git a/src/LYOptions.c b/src/LYOptions.c
index 90648290..8f763e1b 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -36,7 +36,7 @@ PRIVATE void terminate_options	PARAMS((int sig));
 #endif
 
 #if defined(USE_SLANG) || defined(COLOR_CURSES)
-PRIVATE BOOLEAN can_do_colors = 0;
+PRIVATE BOOLEAN can_do_colors = FALSE;
 #endif
 
 PUBLIC BOOLEAN LYCheckUserAgent NOARGS
@@ -55,7 +55,7 @@ PUBLIC BOOLEAN LYCheckUserAgent NOARGS
 PRIVATE void SetupChosenShowColor NOARGS
 {
 #if defined(USE_SLANG) || defined(COLOR_CURSES)
-    can_do_colors = 1;
+    can_do_colors = TRUE;
 #if defined(COLOR_CURSES)
     if (LYCursesON)	/* could crash if called before initialization */
 	can_do_colors = (BOOL) has_colors();
@@ -1212,7 +1212,7 @@ draw_options:
 						  choices, 4, FALSE, FALSE);
 			}
 #if defined(COLOR_CURSES)
-			again = (BOOL) (chosen == 2 && !has_colors());
+			again = (BOOL) (chosen == SHOW_COLOR_ON && !has_colors());
 			if (again) {
 			    char * terminal = LYGetEnv("TERM");
 			    if (terminal)
@@ -1246,7 +1246,7 @@ draw_options:
 		}
 		CurrentShowColor = LYShowColor;
 #ifdef USE_SLANG
-		SLtt_Use_Ansi_Colors = (LYShowColor > 1 ? 1 : 0);
+		SLtt_Use_Ansi_Colors = (LYShowColor > SHOW_COLOR_OFF ? TRUE : FALSE);
 #endif
 		response = ' ';
 		if (LYSelectPopups && !no_option_save) {
@@ -2086,7 +2086,6 @@ PUBLIC int popup_choice ARGS7(
  */
 #define SELECTED(flag) (flag) ? selected_string : ""
 #define DISABLED(flag) (flag) ? disabled_string : ""
-#define NOTEMPTY(text) (text && text[0]) ? text : ""
 
 typedef struct {
     int value;
@@ -2691,7 +2690,7 @@ PUBLIC int postoptions ARGS1(
 	    }
 	    CurrentShowColor = LYShowColor;
 #ifdef USE_SLANG
-	    SLtt_Use_Ansi_Colors = (LYShowColor > 1 ? 1 : 0);
+	    SLtt_Use_Ansi_Colors = (LYShowColor > SHOW_COLOR_OFF ? TRUE : FALSE);
 #endif
 	}
 #endif /* USE_SLANG || COLOR_CURSES */
@@ -3254,7 +3253,7 @@ PRIVATE int gen_options ARGS1(
 
     /* Editor: INPUT */
     PutLabel(fp0, gettext("Editor"), editor_string);
-    PutTextInput(fp0, editor_string, NOTEMPTY(editor), text_len,
+    PutTextInput(fp0, editor_string, NonNull(editor), text_len,
 		      DISABLED(no_editor || system_editor));
 
     /* Search Type: SELECT */
@@ -3390,7 +3389,7 @@ PRIVATE int gen_options ARGS1(
 
     /* X Display: INPUT */
     PutLabel(fp0, gettext("X Display"),	x_display_string);
-    PutTextInput(fp0, x_display_string, NOTEMPTY(x_display), text_len, "");
+    PutTextInput(fp0, x_display_string, NonNull(x_display), text_len, "");
 
     /*
      * Document Appearance
@@ -3479,23 +3478,23 @@ PRIVATE int gen_options ARGS1(
     /* Mail Address: INPUT */
     PutLabel(fp0, gettext("Personal mail address"), mail_address_string);
     PutTextInput(fp0, mail_address_string,
-		      NOTEMPTY(personal_mail_address), text_len, "");
+		      NonNull(personal_mail_address), text_len, "");
 
     /* Preferred Document Character Set: INPUT */
     PutLabel(fp0, gettext("Preferred document character set"), preferred_doc_char_string);
     PutTextInput(fp0, preferred_doc_char_string,
-		      NOTEMPTY(pref_charset), cset_len+2, "");
+		      NonNull(pref_charset), cset_len+2, "");
 
     /* Preferred Document Language: INPUT */
     PutLabel(fp0, gettext("Preferred document language"), preferred_doc_lang_string);
     PutTextInput(fp0, preferred_doc_lang_string,
-		      NOTEMPTY(language), cset_len+2, "");
+		      NonNull(language), cset_len+2, "");
 
     /* User Agent: INPUT */
     if (!no_useragent) {
 	PutLabel(fp0, gettext("User-Agent header"), user_agent_string);
 	PutTextInput(fp0, user_agent_string,
-			  NOTEMPTY(LYUserAgent), text_len, "");
+			  NonNull(LYUserAgent), text_len, "");
     }
 
     /*
@@ -3583,7 +3582,7 @@ PRIVATE int gen_options ARGS1(
     } else {
 	PutLabel(fp0, gettext("Bookmarks file"), single_bookmark_string);
 	PutTextInput(fp0, single_bookmark_string,
-			 NOTEMPTY(bookmark_page), text_len, "");
+			 NonNull(bookmark_page), text_len, "");
     }
 
     /* Visited Pages: SELECT */
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index fda43d69..0c96100b 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -36,8 +36,7 @@
 #include <LYLeaks.h>
 
 #ifndef DISABLE_NEWS
-extern int HTNewsMaxChunk;  /* Max news articles before chunking (HTNews.c) */
-extern int HTNewsChunkSize; /* Number of news articles per chunk (HTNews.c) */
+#include <HTNews.h>
 #endif
 
 PUBLIC BOOLEAN have_read_cfg = FALSE;
@@ -240,9 +239,14 @@ PUBLIC int match_item_by_name ARGS3(
 int default_fg = DEFAULT_COLOR;
 int default_bg = DEFAULT_COLOR;
 #else
+#ifdef PDCURSES
+int default_fg = 15;
+int default_bg = COLOR_BLACK;
+#else
 int default_fg = COLOR_WHITE;
 int default_bg = COLOR_BLACK;
 #endif
+#endif
 
 PRIVATE CONST char *Color_Strings[16] =
 {
@@ -418,6 +422,7 @@ static Config_Enum tbl_abort_source_cache[] = {
 #define PARSE_INT(n,v)   {n, CONF_INT,         UNION_INT(v), 0}
 #define PARSE_TIM(n,v)   {n, CONF_TIME,        UNION_INT(v), 0}
 #define PARSE_STR(n,v)   {n, CONF_STR,         UNION_STR(v), 0}
+#define PARSE_PRG(n,v)   {n, CONF_PRG,         UNION_DEF(v), 0}
 #define PARSE_Env(n,v)   {n, CONF_ENV,         UNION_ENV(v), 0}
 #define PARSE_ENV(n,v)   {n, CONF_ENV2,        UNION_ENV(v), 0}
 #define PARSE_FUN(n,v)   {n, CONF_FUN,         UNION_FUN(v), 0}
@@ -433,6 +438,7 @@ typedef enum {
     ,CONF_ENUM
     ,CONF_INT
     ,CONF_STR
+    ,CONF_PRG
     ,CONF_ENV			/* from environment variable */
     ,CONF_ENV2			/* from environment VARIABLE */
     ,CONF_INCLUDE		/* include file-- handle special */
@@ -1236,6 +1242,7 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_SET(RC_BOLD_H1,              bold_H1),
      PARSE_SET(RC_BOLD_HEADERS,         bold_headers),
      PARSE_SET(RC_BOLD_NAME_ANCHORS,    bold_name_anchors),
+     PARSE_PRG(RC_BZIP2_PATH,           ppBZIP2),
      PARSE_SET(RC_CASE_SENSITIVE_ALWAYS_ON, case_sensitive),
      PARSE_FUN(RC_CHARACTER_SET,        character_set_fun),
 #ifdef CAN_SWITCH_DISPLAY_CHARSET
@@ -1243,10 +1250,13 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_STR(RC_CHARSETS_DIRECTORY,   charsets_directory),
 #endif
      PARSE_SET(RC_CHECKMAIL,            check_mail),
+     PARSE_PRG(RC_CHMOD_PATH,           ppCHMOD),
      PARSE_SET(RC_COLLAPSE_BR_TAGS,     LYCollapseBRs),
 #ifdef USE_COLOR_TABLE
      PARSE_FUN(RC_COLOR,                color_fun),
 #endif
+     PARSE_PRG(RC_COMPRESS_PATH,        ppCOMPRESS),
+     PARSE_PRG(RC_COPY_PATH,            ppCOPY),
 #ifndef __DJGPP__
      PARSE_INT(RC_CONNECT_TIMEOUT,      connect_timeout),
 #endif
@@ -1263,7 +1273,7 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_STR(RC_COOKIE_STRICT_INVALID_DOMAIN, LYCookieSStrictCheckDomains),
      PARSE_Env(RC_CSO_PROXY, 0 ),
 #ifdef VMS
-     PARSE_STR(RC_CSWING_PATH,          LYCSwingPath),
+     PARSE_PRG(RC_CSWING_PATH,          ppCSWING),
 #endif
      PARSE_FUN(RC_DEFAULT_BOOKMARK_FILE, default_bookmark_file_fun),
      PARSE_FUN(RC_DEFAULT_CACHE_SIZE,   default_cache_size_fun),
@@ -1304,6 +1314,7 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_STR(RC_GLOBAL_MAILCAP,       global_type_map),
      PARSE_Env(RC_GOPHER_PROXY,         0 ),
      PARSE_SET(RC_GOTOBUFFER,           goto_buffer),
+     PARSE_PRG(RC_GZIP_PATH,            ppGZIP),
      PARSE_STR(RC_HELPFILE,             helpfile),
 #ifdef MARK_HIDDEN_LINKS
      PARSE_STR(RC_HIDDEN_LINK_MARKER,   hidden_link_marker),
@@ -1317,6 +1328,7 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_Env(RC_HTTPS_PROXY,          0 ),
      PARSE_REQ(RC_INCLUDE,              0),
      PARSE_TIM(RC_INFOSECS,             InfoSecs),
+     PARSE_PRG(RC_INSTALL_PATH,         ppINSTALL),
      PARSE_STR(RC_JUMP_PROMPT,          jumpprompt),
      PARSE_SET(RC_JUMPBUFFER,           jump_buffer),
      PARSE_FUN(RC_JUMPFILE,             jumpfile_fun),
@@ -1358,7 +1370,9 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_SET(RC_MAKE_PSEUDO_ALTS_FOR_INLINES, pseudo_inline_alts),
      PARSE_TIM(RC_MESSAGESECS,          MessageSecs),
      PARSE_SET(RC_MINIMAL_COMMENTS,     minimal_comments),
+     PARSE_PRG(RC_MKDIR_PATH,           ppMKDIR),
      PARSE_ENU(RC_MULTI_BOOKMARK_SUPPORT, LYMultiBookmarks, tbl_multi_bookmarks),
+     PARSE_PRG(RC_MV_PATH,              ppMV),
      PARSE_SET(RC_NCR_IN_BOOKMARKS,     UCSaveBookmarksInUnicode),
 #ifndef DISABLE_NEWS
      PARSE_FUN(RC_NEWS_CHUNK_SIZE,      news_chunk_size_fun),
@@ -1411,6 +1425,8 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_TIM(RC_REPLAYSECS,           ReplaySecs),
 #endif
      PARSE_SET(RC_REUSE_TEMPFILES,      LYReuseTempfiles),
+     PARSE_PRG(RC_RLOGIN_PATH,          ppRLOGIN),
+     PARSE_PRG(RC_RM_PATH,              ppRM),
 #ifndef NO_RULES
      PARSE_FUN(RC_RULE,                 HTSetConfiguration),
      PARSE_FUN(RC_RULESFILE,            cern_rulesfile_fun),
@@ -1443,19 +1459,25 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_STR(RC_SYSTEM_MAIL,          system_mail),
      PARSE_STR(RC_SYSTEM_MAIL_FLAGS,    system_mail_flags),
      PARSE_FUN(RC_TAGSOUP,              get_tagsoup),
+     PARSE_PRG(RC_TAR_PATH,             ppTAR),
+     PARSE_PRG(RC_TELNET_PATH,          ppTELNET),
 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
      PARSE_SET(RC_TEXTFIELDS_NEED_ACTIVATION, textfields_activation_option),
 #endif
+     PARSE_PRG(RC_TN3270_PATH,          ppTN3270),
 #if defined(_WINDOWS)
      PARSE_INT(RC_TIMEOUT,              lynx_timeout),
 #endif
-     PARSE_SET(RC_TRIM_INPUT_FIELDS,  LYtrimInputFields),
+     PARSE_PRG(RC_TOUCH_PATH,           ppTOUCH),
+     PARSE_SET(RC_TRIM_INPUT_FIELDS,    LYtrimInputFields),
 #ifdef EXEC_LINKS
      PARSE_DEF(RC_TRUSTED_EXEC,         EXEC_PATH),
 #endif
 #ifdef LYNXCGI_LINKS
      PARSE_DEF(RC_TRUSTED_LYNXCGI,      CGI_PATH),
 #endif
+     PARSE_PRG(RC_UNCOMPRESS_PATH,      ppUNCOMPRESS),
+     PARSE_PRG(RC_UNZIP_PATH,           ppUNZIP),
 #ifdef DIRED_SUPPORT
      PARSE_ADD(RC_UPLOADER,             uploaders),
 #endif
@@ -1468,11 +1490,14 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_SET(RC_USE_MOUSE,            LYUseMouse),
 #endif
      PARSE_SET(RC_USE_SELECT_POPUPS,    LYSelectPopups),
+     PARSE_PRG(RC_UUDECODE_PATH,        ppUUDECODE),
      PARSE_SET(RC_VERBOSE_IMAGES,       verbose_img),
      PARSE_SET(RC_VI_KEYS_ALWAYS_ON,    vi_keys),
      PARSE_FUN(RC_VIEWER,               viewer_fun),
      PARSE_Env(RC_WAIS_PROXY,           0 ),
      PARSE_STR(RC_XLOADIMAGE_COMMAND,   XLoadImageCommand),
+     PARSE_PRG(RC_ZCAT_PATH,            ppZCAT),
+     PARSE_PRG(RC_ZIP_PATH,             ppZIP),
 
      PARSE_NIL
 };
@@ -1624,6 +1649,7 @@ PUBLIC void LYSetConfigValue ARGS2(
 {
     Config_Type *tbl = lookup_config(name);
     ParseUnionPtr q = ParseUnionOf(tbl);
+    char *temp;
 
     switch (tbl->type) {
     case CONF_BOOL:
@@ -1692,6 +1718,12 @@ PUBLIC void LYSetConfigValue ARGS2(
 	add_trusted (value, q->def_value);
 	break;
 #endif
+
+    case CONF_PRG:
+	if (StrAllocCopy(temp, value))
+	    HTSetProgramPath(q->def_value, temp);
+	break;
+
     default:
 	break;
     }
@@ -1997,6 +2029,7 @@ PUBLIC void read_cfg ARGS4(
 	int,	nesting_level,
 	FILE *,	fp0)
 {
+    HTInitProgramPaths();
     do_read_cfg(cfg_filename, parent_filename, nesting_level, fp0, NULL);
 }
 
diff --git a/src/LYStrings.c b/src/LYStrings.c
index 1af7339f..02615488 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -41,8 +41,6 @@
 #include <LYShowInfo.h>
 #include <LYLeaks.h>
 
-extern BOOL HTPassHighCtrlRaw;
-
 #if defined(WIN_EX)
 #undef  BUTTON_CTRL
 #define BUTTON_CTRL	0	/* Quick hack */
@@ -328,7 +326,7 @@ PRIVATE void LYAddToCloset ARGS2(RecallType, recall, char*, str)
 	LYRemoveFromCloset(list);
 }
 
-
+#ifdef USE_MOUSE
 PRIVATE int XYdist ARGS5(
     int,	x1,
     int,	y1,
@@ -552,6 +550,7 @@ PRIVATE int set_clicked_link ARGS4(
     }
     return c;
 }
+#endif /* USE_MOUSE */
 
 /*
  *  LYstrncpy() terminates strings with a null byte.
@@ -813,7 +812,7 @@ PRIVATE int sl_read_mouse_event ARGS1(
 	if (button == 0)  /* left */
 	  return set_clicked_link (mouse_x, mouse_y, FOR_PANEL, 1);
 
-        if (button == 1)  /* middle */
+	if (button == 1)  /* middle */
 	  return LYReverseKeymap (LYK_VIEW_BOOKMARK);
 
 	if (button == 2)   /* right */
@@ -5448,9 +5447,9 @@ PUBLIC char * SNACopy ARGS3(
 {
     FREE(*dest);
     if (src) {
-	*dest = typecallocn(char, n + 1);
+	*dest = typeMallocn(char, n + 1);
 	if (*dest == NULL) {
-	    CTRACE((tfp, "Tried to calloc %d bytes\n", n));
+	    CTRACE((tfp, "Tried to malloc %d bytes\n", n));
 	    outofmem(__FILE__, "SNACopy");
 	}
 	strncpy (*dest, src, n);
@@ -5476,7 +5475,7 @@ PUBLIC char * SNACat ARGS3(
 	    strncpy(*dest + length, src, n);
 	    *(*dest + length + n) = '\0'; /* terminate */
 	} else {
-	    *dest = typecallocn(char, n + 1);
+	    *dest = typeMallocn(char, n + 1);
 	    if (*dest == NULL)
 		outofmem(__FILE__, "SNACat");
 	    memcpy(*dest, src, n);
diff --git a/src/LYStrings.h b/src/LYStrings.h
index 45ef8594..3fcb443e 100644
--- a/src/LYStrings.h
+++ b/src/LYStrings.h
@@ -78,7 +78,7 @@ extern char * LYno_attr_mbcs_case_strstr PARAMS((
 	int *		nstartp,
 	int *		nendp));
 
-#define non_empty(s) ((s) != NULL && *(s) != '\0')
+#define non_empty(s) !isEmpty(s)
 
 #define LYno_attr_mb_strstr(chptr, tarptr, utf_flag, count_gcells, nstartp, nendp) \
 	(case_sensitive \
diff --git a/src/LYStructs.h b/src/LYStructs.h
index 4920ce63..def68923 100644
--- a/src/LYStructs.h
+++ b/src/LYStructs.h
@@ -6,14 +6,14 @@
 #endif /* HTANCHOR_H */
 
 typedef struct {
-    int hl_x;
     char *hl_text;
+    short hl_x;
 } HiliteInfo;
 
 typedef struct {
-    int hl_len;		/* number of strings in this struct */
-    HiliteInfo hl_base;
     HiliteInfo *hl_info;
+    HiliteInfo hl_base;
+    short hl_len;              /* number of strings in this struct */
 } HiliteList;
 
 typedef struct {
diff --git a/src/LYUtils.c b/src/LYUtils.c
index 8f3458c5..599577de 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -139,10 +139,9 @@ extern int BSDselect PARAMS((int nfds, fd_set * readfds, fd_set * writefds,
 
 #define COPY_COMMAND "%s %s %s"
 
-extern BOOLEAN LYHaveCJKCharacterSet;
-
 PRIVATE HTList * localhost_aliases = NULL;	/* Hosts to treat as local */
 PRIVATE char *HomeDir = NULL;			/* HOME directory */
+
 PUBLIC	HTList * sug_filenames = NULL;		/* Suggested filenames	 */
 
 /*
@@ -392,7 +391,7 @@ PRIVATE BOOL show_whereis_targets ARGS6(
 					       utf_flag, YES,
 					       &HitOffset,
 					       &LenNeeded)) != NULL)
-	         && (offset + LenNeeded) < LYcols) {
+		 && (offset + LenNeeded) < LYcols) {
 		    Data = cp;
 		    Offset = (offset + HitOffset);
 		} else {
@@ -1356,8 +1355,10 @@ PUBLIC void statusline ARGS1(
 #else
 	/* draw the status bar in the STATUS style */
 	{
-		int a=(strncmp(buffer, ALERT_FORMAT, ALERT_PREFIX_LEN) ||
-		       !hashStyles[s_alert].name) ? s_status : s_alert;
+		int a = (strncmp(buffer, ALERT_FORMAT, ALERT_PREFIX_LEN)
+			|| !hashStyles[s_alert].name)
+			? s_status
+			: s_alert;
 		LynxChangeStyle (a, STACK_ON);
 		LYaddstr(buffer);
 		wbkgdset(LYwin,
@@ -1731,8 +1732,8 @@ PUBLIC int HTCheckForInterrupt NOARGS
 	    } /* end switch */
 	    if (Newline_partial < 1)
 		Newline_partial = 1;
-	    NumOfLines_partial = HText_getNumOfLines();
-	    LYMainLoop_pageDisplay(Newline_partial);
+	    if (LYMainLoop_pageDisplay(Newline_partial))
+		NumOfLines_partial = HText_getNumOfLines();
 	}
 #endif /* DISP_PARTIAL */
 	break;
@@ -3710,7 +3711,7 @@ PUBLIC void LYConvertToURL ARGS2(
 	for(; *cp_url != '\0'; cp_url++)
 	    if (*cp_url == '\\')
 		*cp_url = '/';
-	    cp_url--;
+	cp_url--;
 	if (LYIsDosDrive(*AllocatedString) && *cp_url == ':')
 	    LYAddPathSep(AllocatedString);
     }
@@ -4851,7 +4852,7 @@ PRIVATE char *HomeEnv NOARGS
     }
 #endif
 
-    return result; 
+    return result;
 }
 
 PUBLIC CONST char * Home_Dir NOARGS
@@ -6759,45 +6760,43 @@ PUBLIC int LYCopyFile ARGS2(
 	char *,		dst)
 {
     int code;
+    CONST char *program;
 
-#if !defined(COPY_PATH)
+    if ((program = HTGetProgramPath(ppCOPY)) != NULL) {
+	char *the_command = 0;
 
-#define BUF_SIZE	1024
+	HTAddParam(&the_command, COPY_COMMAND, 1, program);
+	HTAddParam(&the_command, COPY_COMMAND, 2, src);
+	HTAddParam(&the_command, COPY_COMMAND, 3, dst);
+	HTEndParam(&the_command, COPY_COMMAND, 3);
 
-    FILE *fin, *fout;
-    unsigned char buff[BUF_SIZE];
-    int len;
+	CTRACE((tfp, "command: %s\n", the_command));
+	stop_curses();
+	code = LYSystem(the_command);
+	start_curses();
 
-    code = EOF;
-    if ((fin = fopen(src, BIN_R)) != 0) {
-	if ((fout = fopen(dst, BIN_W)) != 0) {
-	    code = 0;
-	    while ((len = fread(buff, 1, BUF_SIZE, fin)) > 0) {
-		fwrite(buff, 1, len, fout);
-		if (ferror(fout)) {
-		    code = EOF;
-		    break;
+	FREE(the_command);
+    } else {
+	FILE *fin, *fout;
+	unsigned char buff[BUFSIZ];
+	int len;
+
+	code = EOF;
+	if ((fin = fopen(src, BIN_R)) != 0) {
+	    if ((fout = fopen(dst, BIN_W)) != 0) {
+		code = 0;
+		while ((len = fread(buff, 1, sizeof(buff), fin)) > 0) {
+		    fwrite(buff, 1, len, fout);
+		    if (ferror(fout)) {
+			code = EOF;
+			break;
+		    }
 		}
+		LYCloseOutput(fout);
 	    }
-	    LYCloseOutput(fout);
+	    LYCloseInput(fin);
 	}
-	LYCloseInput(fin);
     }
-#else
-    char *the_command = 0;
-
-    HTAddParam(&the_command, COPY_COMMAND, 1, COPY_PATH);
-    HTAddParam(&the_command, COPY_COMMAND, 2, src);
-    HTAddParam(&the_command, COPY_COMMAND, 3, dst);
-    HTEndParam(&the_command, COPY_COMMAND, 3);
-
-    CTRACE((tfp, "command: %s\n", the_command));
-    stop_curses();
-    code = LYSystem(the_command);
-    start_curses();
-
-    FREE(the_command);
-#endif
 
     if (code) {
 	HTAlert(CANNOT_WRITE_TO_FILE);
diff --git a/src/LYrcFile.h b/src/LYrcFile.h
index b7144243..590436ce 100644
--- a/src/LYrcFile.h
+++ b/src/LYrcFile.h
@@ -23,14 +23,17 @@
 #define RC_BOLD_HEADERS                 "bold_headers"
 #define RC_BOLD_NAME_ANCHORS            "bold_name_anchors"
 #define RC_BOOKMARK_FILE                "bookmark_file"
+#define RC_BZIP2_PATH                   "bzip2_path"
 #define RC_CASE_SENSITIVE_ALWAYS_ON     "case_sensitive_always_on"
 #define RC_CASE_SENSITIVE_SEARCHING     "case_sensitive_searching"
 #define RC_CHARACTER_SET                "character_set"
 #define RC_CHARSETS_DIRECTORY           "charsets_directory"
 #define RC_CHARSET_SWITCH_RULES         "charset_switch_rules"
 #define RC_CHECKMAIL                    "checkmail"
+#define RC_CHMOD_PATH                   "chmod_path"
 #define RC_COLLAPSE_BR_TAGS             "collapse_br_tags"
 #define RC_COLOR                        "color"
+#define RC_COMPRESS_PATH                "compress_path"
 #define RC_CONNECT_TIMEOUT              "connect_timeout"
 #define RC_COOKIE_ACCEPT_DOMAINS        "cookie_accept_domains"
 #define RC_COOKIE_FILE                  "cookie_file"
@@ -39,6 +42,7 @@
 #define RC_COOKIE_REJECT_DOMAINS        "cookie_reject_domains"
 #define RC_COOKIE_SAVE_FILE             "cookie_save_file"
 #define RC_COOKIE_STRICT_INVALID_DOMAIN "cookie_strict_invalid_domains"
+#define RC_COPY_PATH                    "copy_path"
 #define RC_CSO_PROXY                    "cso_proxy"
 #define RC_CSWING_PATH                  "cswing_path"
 #define RC_DEFAULT_BOOKMARK_FILE        "default_bookmark_file"
@@ -75,6 +79,7 @@
 #define RC_GLOBAL_MAILCAP               "global_mailcap"
 #define RC_GOPHER_PROXY                 "gopher_proxy"
 #define RC_GOTOBUFFER                   "gotobuffer"
+#define RC_GZIP_PATH                    "gzip_path"
 #define RC_HELPFILE                     "helpfile"
 #define RC_HIDDEN_LINK_MARKER           "hidden_link_marker"
 #define RC_HISTORICAL_COMMENTS          "historical_comments"
@@ -84,6 +89,7 @@
 #define RC_HTTP_PROXY                   "http_proxy"
 #define RC_INCLUDE                      "include"
 #define RC_INFOSECS                     "infosecs"
+#define RC_INSTALL_PATH                 "install_path"
 #define RC_JUMPBUFFER                   "jumpbuffer"
 #define RC_JUMPFILE                     "jumpfile"
 #define RC_JUMP_PROMPT                  "jump_prompt"
@@ -112,8 +118,10 @@
 #define RC_MAKE_PSEUDO_ALTS_FOR_INLINES "make_pseudo_alts_for_inlines"
 #define RC_MESSAGESECS                  "messagesecs"
 #define RC_MINIMAL_COMMENTS             "minimal_comments"
+#define RC_MKDIR_PATH                   "mkdir_path"
 #define RC_MULTI_BOOKMARK               "multi_bookmark"
 #define RC_MULTI_BOOKMARK_SUPPORT       "multi_bookmark_support"
+#define RC_MV_PATH                      "mv_path"
 #define RC_NCR_IN_BOOKMARKS             "ncr_in_bookmarks"
 #define RC_NEWSPOST_PROXY               "newspost_proxy"
 #define RC_NEWSREPLY_PROXY              "newsreply_proxy"
@@ -154,6 +162,8 @@
 #define RC_REFERER_WITH_QUERY           "referer_with_query"
 #define RC_REPLAYSECS                   "replaysecs"
 #define RC_REUSE_TEMPFILES              "reuse_tempfiles"
+#define RC_RLOGIN_PATH                  "rlogin_path"
+#define RC_RM_PATH                      "rm_path"
 #define RC_RULE                         "rule"
 #define RC_RULESFILE                    "rulesfile"
 #define RC_RUN_ALL_EXECUTION_LINKS      "run_all_execution_links"
@@ -186,11 +196,17 @@
 #define RC_SYSTEM_MAIL                  "system_mail"
 #define RC_SYSTEM_MAIL_FLAGS            "system_mail_flags"
 #define RC_TAGSOUP                      "tagsoup"
+#define RC_TAR_PATH                     "tar_path"
+#define RC_TELNET_PATH                  "telnet_path"
 #define RC_TEXTFIELDS_NEED_ACTIVATION   "textfields_need_activation"
 #define RC_TIMEOUT                      "timeout"
+#define RC_TN3270_PATH                  "tn3270_path"
+#define RC_TOUCH_PATH                   "touch_path"
 #define RC_TRIM_INPUT_FIELDS            "trim_input_fields"
 #define RC_TRUSTED_EXEC                 "trusted_exec"
 #define RC_TRUSTED_LYNXCGI              "trusted_lynxcgi"
+#define RC_UNCOMPRESS_PATH              "uncompress_path"
+#define RC_UNZIP_PATH                   "unzip_path"
 #define RC_UPLOADER                     "uploader"
 #define RC_URL_DOMAIN_PREFIXES          "url_domain_prefixes"
 #define RC_URL_DOMAIN_SUFFIXES          "url_domain_suffixes"
@@ -199,6 +215,7 @@
 #define RC_USE_FIXED_RECORDS            "use_fixed_records"
 #define RC_USE_MOUSE                    "use_mouse"
 #define RC_USE_SELECT_POPUPS            "use_select_popups"
+#define RC_UUDECODE_PATH                "uudecode_path"
 #define RC_VERBOSE_IMAGES               "verbose_images"
 #define RC_VIEWER                       "viewer"
 #define RC_VISITED_LINKS                "visited_links"
@@ -206,6 +223,8 @@
 #define RC_VI_KEYS_ALWAYS_ON            "vi_keys_always_on"
 #define RC_WAIS_PROXY                   "wais_proxy"
 #define RC_XLOADIMAGE_COMMAND           "xloadimage_command"
+#define RC_ZCAT_PATH                    "zcat_path"
+#define RC_ZIP_PATH                     "zip_path"
 
 extern Config_Enum tbl_DTD_recovery[];
 extern Config_Enum tbl_keypad_mode[];
diff --git a/src/UCdomap.c b/src/UCdomap.c
index 4e97d837..34ee8b35 100644
--- a/src/UCdomap.c
+++ b/src/UCdomap.c
@@ -74,6 +74,11 @@
 int auto_display_charset = -1;
 #endif
 
+CONST char *UC_GNsetMIMEnames[4] =
+	{"iso-8859-1", "x-dec-graphics", "cp437", "x-transparent"};
+
+int UC_GNhandles[4] = {-1, -1, -1, -1};
+
 /*
  *  Some of the code below, and some of the comments, are left in for
  *  historical reasons.  Not all those tables below are currently
@@ -831,6 +836,7 @@ PRIVATE int conv_uni_to_str ARGS4(
 }
 
 PUBLIC int UCInitialized = 0;
+
 /*
  *  [ original comment: - KW ]
  * This is called at sys_setup time, after memory and the console are
diff --git a/src/UCdomap.h b/src/UCdomap.h
index 71cbc696..3a494252 100644
--- a/src/UCdomap.h
+++ b/src/UCdomap.h
@@ -39,11 +39,6 @@ extern void UC_Charset_Setup PARAMS((
 	int			UC_rawuni,
 	int			codepage));
 
-CONST char *UC_GNsetMIMEnames[4] =
-	{"iso-8859-1", "x-dec-graphics", "cp437", "x-transparent"};
-
-int UC_GNhandles[4] = {-1, -1, -1, -1};
-
 struct UC_charset {
 	CONST char *MIMEname;
 	CONST char *LYNXname;
@@ -60,10 +55,10 @@ struct UC_charset {
 };
 
 extern int UCNumCharsets;
+extern int UCInitialized;
 
 extern void UCInit NOARGS;
 
-
 /*
  *  INSTRUCTIONS for adding new character sets which do not have
  *              Unicode tables.