about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GridText.c302
-rw-r--r--src/GridText.h3
-rw-r--r--src/HTAlert.c25
-rw-r--r--src/HTAlert.h1
-rw-r--r--src/LYCgi.c43
-rw-r--r--src/LYCharSets.c2
-rw-r--r--src/LYDownload.c8
-rw-r--r--src/LYKeymap.c3
-rw-r--r--src/LYKeymap.h7
-rw-r--r--src/LYLeaks.c12
-rw-r--r--src/LYMainLoop.c36
-rw-r--r--src/LYReadCFG.c43
-rw-r--r--src/LYUtils.c20
-rw-r--r--src/chrtrans/MAKEW32.BAT3
-rw-r--r--src/chrtrans/makefile.dos1
-rw-r--r--src/structdump.h137
16 files changed, 630 insertions, 16 deletions
diff --git a/src/GridText.c b/src/GridText.c
index 89789f89..50a41e3b 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -8687,3 +8687,305 @@ PUBLIC BOOL HText_AreDifferent ARGS2(
      */
     return(FALSE);
 }
+
+/*
+ *  Transfer the initial contents of a TEXTAREA to a temp file, invoke the
+ *  user's editor on that file, then transfer the contents of the resultant
+ *  edited file back into the TEXTAREA (expanding the size of the area, if
+ *  required).   KED  01/26/99
+ */
+PUBLIC void HText_ExtEditForm ARGS1(
+            struct link *, form_link)
+{
+    struct stat stat_info;
+
+    char       *ed_temp;
+    FILE       *fp;
+
+    TextAnchor *anchor_ptr;
+    TextAnchor *start_anchor = NULL;
+    TextAnchor *end_anchor  = NULL;
+    BOOLEAN	firstanchor = TRUE;
+    int 	orig_cnt    = 0;
+    int 	line_cnt    = 1;
+
+    FormInfo   *form	 = form_link->form;
+    char       *areaname = form->name;
+    int 	form_num = form->number;
+
+    HTLine     *htline;
+
+    TextAnchor *a = 0;
+    FormInfo   *f = 0;
+    HTLine     *l = 0;
+
+    char       *ebuf;
+    char       *tbuf = NULL;
+    char       *line;
+    char       *cp;
+    char       *p;
+    int 	len;
+    int 	i;
+    int 	n;
+    size_t	size;
+
+    ed_temp = (char *)malloc(LY_MAXPATH);
+    if ((fp = LYOpenTemp (ed_temp, "", "w")) == 0) {
+	FREE(ed_temp);
+	return;
+    }
+
+    /*
+     *	Begin at the beginning, to find 1st anchor in the TEXTAREA, then
+     *	write all of its lines (anchors) out to the edit temp file.
+     *
+     *	[Finding the TEXTAREA we're actually *in* with these attributes
+     *	 isn't foolproof.  The form_num isn't unique to a given TEXTAREA,
+     *	 and there *could* be TEXTAREA's with the same "name".	If that
+     *	 should ever be true, we'll actually get the data from the *1st*
+     *	 TEXTAREA in the page that matches.  We should probably assign
+     *	 a unique id to each TEXTAREA in a page, and match on that, to
+     *	 avoid this (potential) problem.
+     *
+     *	 Since the odds of "false matches" *actually* happening in real
+     *	 life seem rather small though, we'll hold off doing this, for a
+     *	 rainy day ...]
+     */
+    anchor_ptr = HTMainText->first_anchor;
+
+    while (anchor_ptr) {
+
+	if ((anchor_ptr->link_type	     == INPUT_ANCHOR)    &&
+	    (anchor_ptr->input_field->type   == F_TEXTAREA_TYPE) &&
+	    (anchor_ptr->input_field->number == form_num)	 &&
+	    !strcmp (anchor_ptr->input_field->name, areaname))   {
+
+	    if (firstanchor) {
+		firstanchor = FALSE;
+		start_anchor = anchor_ptr;
+	    }
+	    orig_cnt++;
+
+	    /*
+	     * Write the anchor's text to the temp edit file.
+	     */
+	    fputs (anchor_ptr->input_field->value, fp);
+	    fputc ('\n', fp);
+
+	 } else {
+
+	    if (!firstanchor)
+		break;
+	 }
+	 anchor_ptr = anchor_ptr->next;
+    }
+    fclose (fp);
+
+    /*
+     *	Go edit the TEXTAREA temp file.
+     */
+    HTSprintf0 (&tbuf, "%s %s", editor, ed_temp);
+
+    LYSystem (tbuf);
+
+#ifdef UNIX
+    /*
+     *  Delete backup file, if that's your style.
+     */
+    HTSprintf0 (&tbuf, "%s~", ed_temp);
+    if (stat (tbuf, &stat_info) == 0)
+       remove (tbuf);
+#endif
+    free (tbuf);
+
+    /*
+     *	Read back the edited temp file, whacking off any trailing whitespace.
+     */
+    if (stat (ed_temp, &stat_info) < 0
+     || !S_ISREG(stat_info.st_mode)
+     || (size = stat_info.st_size) == 0) {
+	size = 0;
+	ebuf = malloc(1);
+    } else {
+	ebuf = (char *) calloc (size + 1, (sizeof(char)));
+
+	fp = fopen (ed_temp, "r");
+	size = fread (ebuf, 1, size, fp);
+	fclose (fp);
+    }
+    if (ebuf == 0)
+	outofmem(__FILE__, "HText_ExtEditForm");
+
+    /*
+     *	Nuke any blank lines from the end of the edited data.
+     */
+    while ((size != 0) && isspace(ebuf[size-1]))
+	ebuf[--size] = '\0';
+
+    /*
+     *	Copy each line from the temp file into the corresponding anchor
+     *	struct, removing any trailing whitespace.  Add new lines to the
+     *	TEXTAREA if needed.  (Always leave the user with a blank line at
+     *	the end of the TEXTAREA.)
+     */
+    if ((line = (char *) malloc (MAX_LINE)) == 0)
+	outofmem(__FILE__, "HText_ExtEditForm");
+
+    anchor_ptr = start_anchor;
+    len = 0;
+    p = ebuf;
+
+    while ((line_cnt <= orig_cnt) || (*p) || ((len != 0) && (*p == '\0'))) {
+
+	if ((cp = strchr (p, '\n')) != 0)
+	   len = cp - p;
+	else
+	   len = strlen (p);
+
+	strncpy(line, "\0", MAX_LINE);
+	strncpy(line, p, len);
+
+	cp = p;
+
+	/*
+	 *  Whack off trailing whitespace from the line.
+	 *
+	 *  [maybe use isspace() here instead, too (portable ?)]
+	 */
+	for (size = MAX_LINE, p = line + size - 1; size != 0; p--, size--) {
+	    if (isspace(*p))
+		*p = '\0';
+	    else
+		break;
+	}
+
+	/*
+	 *  If there are more lines in the edit buffer than were in the
+	 *  original TEXTAREA, we need to add some new lines, continuing
+	 *  until the edit buffer is empty.
+	 *
+	 *  [cloning structs should me moved to a seperate fn(), or three]
+	 */
+	if (line_cnt > orig_cnt) {
+
+	   /*
+	    *  Find line in the text that matches ending anchorline of
+	    *  the TEXTAREA.
+	    */
+	   for (htline = HTMainText->last_line->next, i = 0;
+		i != end_anchor->line_num;
+		htline = htline->next, i++);
+
+	   /*
+	    *  Clone and initialize the structs needed to add a new
+	    *  TEXTAREA anchor.
+	    */
+	   if ((a = (TextAnchor *) calloc (1, sizeof(*a))) == 0
+	    || (f = (FormInfo   *) calloc (1, sizeof(*f))) == 0
+	    || (l = (HTLine     *) calloc (1, LINE_SIZE(MAX_LINE))) == 0)
+		outofmem(__FILE__, "HText_ExtEditForm");
+
+	   /*  Init all the fields in the new anchor.  */
+	   a->next	       = end_anchor->next;
+	   a->number	       = end_anchor->number;
+	   a->start	       = end_anchor->start +
+				 end_anchor->input_field->size + 1;
+	   a->line_pos	       = end_anchor->line_pos;
+	   a->extent	       = end_anchor->extent;
+	   a->line_num	       = end_anchor->line_num + 1;
+	   StrAllocCopy (a->hightext, end_anchor->hightext);
+	   StrAllocCopy (a->hightext2, end_anchor->hightext2);
+	   a->hightext2offset  = end_anchor->hightext2offset;
+	   a->link_type	       = end_anchor->link_type;
+	   a->input_field      = f;
+	   a->show_anchor      = end_anchor->show_anchor;
+	   a->inUnderline      = end_anchor->inUnderline;
+	   a->anchor	       = end_anchor->anchor;
+
+	   /*  Just the (seemingly) relevant fields in the FormInfo.	*/
+	   StrAllocCopy (f->name, end_anchor->input_field->name);
+	   f->number	       = end_anchor->input_field->number;
+	   f->type	       = end_anchor->input_field->type;
+	   StrAllocCopy (f->orig_value, end_anchor->input_field->orig_value);
+	   f->size	       = end_anchor->input_field->size;
+	   f->maxlength        = end_anchor->input_field->maxlength;
+	   f->no_cache         = end_anchor->input_field->no_cache;
+
+	   /*  Init all the fields in the new HTLine (but see the #if).  */
+	   l->next	       = htline->next;
+	   l->prev	       = htline;
+	   l->offset	       = htline->offset;
+	   l->size	       = htline->size;
+	   l->split_after      = htline->split_after;
+	   l->bullet	       = htline->bullet;
+#if defined(USE_COLOR_STYLE)
+	   /* dup styles[] if needed [no need in TEXTAREA (?); leave 0's] */
+	   l->numstyles        = htline->numstyles;
+#endif
+	   for (i = 0; htline->data[i] != '\0'; i++)
+	       l->data[i] = htline->data[i];
+	   l->data[i] = '\0';
+
+	   /*
+	    *  Link in the new TextAnchor and make it current; link in
+	    *  the new HTLine.
+	    */
+	   end_anchor->next = a;
+	   anchor_ptr = a;
+
+	   htline->next->prev = l;
+	   htline->next = l;
+	   htline = l;
+	}
+
+	/*
+	 *  Finally copy the new line from the edit buffer into the anchor.
+	 */
+	StrAllocCopy(anchor_ptr->input_field->value, line);
+
+	/*
+	 *  And do the next line, for the next anchor ...
+	 */
+	p = cp + len;
+	if (*p) p++;
+
+	end_anchor = anchor_ptr;
+	anchor_ptr = anchor_ptr->next;
+
+	line_cnt++;
+    }
+
+
+    /*
+     *	If new anchors were added, we need to ripple the new line numbers
+     *	(and char counts ?) thru the subsequent anchors.  Also update the
+     *	HText counts.
+     *
+     *	[dunno if the char counts really need to be done, or if we're using
+     *	 the proper values ... seems OK though ...]
+     */
+    if ((n = (line_cnt - 1) - orig_cnt) > 0) {
+        i = (end_anchor->input_field->size + 1) * n;
+
+        while (anchor_ptr) {
+	    anchor_ptr->line_num  += n;
+	    anchor_ptr->start	  += i;
+	    anchor_ptr 	           = anchor_ptr->next;
+        }
+        HTMainText->Lines += n;
+        HTMainText->chars += i;
+    }
+
+    /*** MOVE the cursor to some logical place ... 1st/only blank line in
+     ***	  the textarea seems most reasonable; lacking that, the end
+     ***	  line of the textarea; lacking that ... the 1st line of the
+     ***	  textarea; else leave it where it is (as we now do).
+     ***/
+
+    free (line);
+    free (ebuf);
+    LYRemoveTemp (ed_temp);
+    free (ed_temp);
+
+    return;
+}
diff --git a/src/GridText.h b/src/GridText.h
index 679e6fa6..30eb4376 100644
--- a/src/GridText.h
+++ b/src/GridText.h
@@ -248,4 +248,7 @@ extern BOOL HText_AreDifferent PARAMS((
 	HTParentAnchor *	anchor,
 	CONST char *		full_address));
 
+extern void HText_ExtEditForm PARAMS((
+	struct link *	form_link));
+
 #endif /* LYGRIDTEXT_H */
diff --git a/src/HTAlert.c b/src/HTAlert.c
index f47c0251..e36fbf66 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -30,11 +30,34 @@ PUBLIC void HTAlert ARGS1(
 {
     CTRACE(tfp, "\nAlert!: %s\n\n", Msg);
     CTRACE_FLUSH(tfp);
-    _user_message("Alert!: %s", Msg);
+    _user_message(ALERT_FORMAT, Msg);
 
     sleep(AlertSecs);
 }
 
+PUBLIC void HTAlwaysAlert ARGS2(
+	CONST char *,	extra_prefix,
+	CONST char *,	Msg)
+{
+    if (!dump_output_immediately && LYCursesON) {
+	HTAlert(Msg);
+    } else {
+	if (extra_prefix) {
+	    fprintf(((TRACE) ? stdout : stderr),
+		    "%s %s!\n",
+		    extra_prefix, Msg);
+	} else {
+	    fprintf(((TRACE) ? stdout : stderr),
+		    ALERT_FORMAT,
+		    (Msg == 0) ? "" : Msg);
+	}
+	fflush(stdout);
+	sleep(AlertSecs);
+	CTRACE(tfp, "\nAlert!: %s\n\n", Msg);
+	CTRACE_FLUSH(tfp);
+    }
+}
+
 /*	Issue an informational message.			HTInfoMsg()
 **	--------------------------------
 */
diff --git a/src/HTAlert.h b/src/HTAlert.h
index 961ee175..b3e5c8a9 100644
--- a/src/HTAlert.h
+++ b/src/HTAlert.h
@@ -29,6 +29,7 @@ extern char * HTPrompt PARAMS((CONST char * Msg, CONST char * deflt));
 **              The input is a list of parameters for printf.
 */
 extern void HTAlert PARAMS((CONST char * Msg));
+extern void HTAlwaysAlert PARAMS((CONST char * extra_prefix, CONST char * Msg));
 extern void HTInfoMsg PARAMS((CONST char * Msg));
 extern void HTUserMsg PARAMS((CONST char * Msg));
 extern void HTUserMsg2 PARAMS((CONST char * Msg, CONST char * Arg));
diff --git a/src/LYCgi.c b/src/LYCgi.c
index 7cd4a4af..b2864c68 100644
--- a/src/LYCgi.c
+++ b/src/LYCgi.c
@@ -58,11 +58,12 @@ struct _HTStream
 PRIVATE char **env = NULL;  /* Environment variables */
 PRIVATE int envc_size = 0;  /* Slots in environment array */
 PRIVATE int envc = 0;	    /* Slots used so far */
+PRIVATE HTList *alloced = NULL;
 #ifdef LYNXCGI_LINKS
-PRIVATE char *user_agent;
-PRIVATE char *server_software;
-PRIVATE char *accept_language;
-PRIVATE char *post_len;
+PRIVATE char *user_agent = NULL;
+PRIVATE char *server_software = NULL;
+PRIVATE char *accept_language = NULL;
+PRIVATE char *post_len = NULL;
 #endif /* LYNXCGI_LINKS */
 
 PRIVATE void add_environment_value PARAMS((char *env_value));
@@ -80,6 +81,29 @@ PRIVATE char *LYStrerror ARGS1(int, code)
 }
 #endif /* HAVE_STRERROR */
 
+PRIVATE void free_alloced_lynxcgi NOARGS
+{
+    void *ptr;
+    while ((ptr = HTList_removeLastObject(alloced)) != NULL) {
+	FREE(ptr);
+    }
+    FREE(alloced);
+#ifdef LYNXCGI_LINKS
+    FREE(user_agent);
+    FREE(server_software);
+#endif
+}
+
+PRIVATE void remember_alloced ARGS1(
+    void *,		ptr)
+{
+    if (!alloced) {
+	alloced = HTList_new();
+	atexit(free_alloced_lynxcgi);
+    }
+    HTList_addObject(alloced, ptr);
+}
+
 /*
  * Simple routine for expanding the environment array and adding a value to
  * it
@@ -89,13 +113,15 @@ PRIVATE void add_environment_value ARGS1(
 {
     if (envc == envc_size) {   /* Need some more slots */
 	envc_size += 10;
-	if (env)
+	if (env) {
 	    env = (char **)realloc(env,
 				   sizeof(env[0]) * (envc_size + 2));
 						/* + terminator and base 0 */
-	else
+	} else {
 	    env = (char **)malloc(sizeof(env[0]) * (envc_size + 2));
 						/* + terminator and base 0 */
+	    remember_alloced(env);
+	}
 	if (env == NULL) {
 	    outofmem(__FILE__, "LYCgi");
 	}
@@ -127,6 +153,7 @@ PUBLIC void add_lynxcgi_environment ARGS1(
 	strcat(add_value, "=");
 	strcat(add_value, env_value);
 	add_environment_value(add_value);
+	remember_alloced(add_value);
     }
 }
 
@@ -464,10 +491,12 @@ PRIVATE int LYLoadCGI ARGS4(
 		dup2(fd2[1], fileno(stderr));
 		close(fd2[1]);
 
+		if (language && *language) {
 		HTSprintf0(&accept_language, "HTTP_ACCEPT_LANGUAGE=%s", language);
 		add_environment_value(accept_language);
+		}
 
-		if (pref_charset) {
+		if (pref_charset && *pref_charset) {
 		    cp = NULL;
 		    StrAllocCopy(cp, "HTTP_ACCEPT_CHARSET=");
 		    StrAllocCat(cp, pref_charset);
diff --git a/src/LYCharSets.c b/src/LYCharSets.c
index ec25d9c6..a309cb05 100644
--- a/src/LYCharSets.c
+++ b/src/LYCharSets.c
@@ -564,6 +564,8 @@ PUBLIC void Set_HTCJK ARGS2(
 	CONST char *,	inMIMEname,
 	CONST char *,	outMIMEname)
 {
+    /* need not check for synonyms: MIMEname's got from LYCharSet_UC */
+
     if (LYRawMode) {
 	if ((!strcmp(inMIMEname, "euc-jp") ||
 	     !strcmp(inMIMEname, "shift_jis")) &&
diff --git a/src/LYDownload.c b/src/LYDownload.c
index 65b27de4..c446e563 100644
--- a/src/LYDownload.c
+++ b/src/LYDownload.c
@@ -414,9 +414,11 @@ check_recall:
 	     *	It actually is not a bug at all and does as it should,
 	     *	putting both names on the command line.
 	     */
-	    HTAddParam(&the_command, download_command->command, 1, file);
-	    HTAddParam(&the_command, download_command->command, 2, buffer);
-	    HTEndParam(&the_command, download_command->command, 2);
+	    count = 1;
+	    HTAddParam(&the_command, download_command->command, count, file);
+	    if (HTCountCommandArgs(download_command->command) > 1) 
+		HTAddParam(&the_command, download_command->command, ++count, buffer);
+	    HTEndParam(&the_command, download_command->command, count);
 
 	} else {
 	    HTAlert(MISCONF_DOWNLOAD_COMMAND);
diff --git a/src/LYKeymap.c b/src/LYKeymap.c
index 338fb202..14625052 100644
--- a/src/LYKeymap.c
+++ b/src/LYKeymap.c
@@ -607,6 +607,7 @@ PRIVATE struct rmap revmap[] = {
 { "SWITCH_DTD",		"switch between two ways of parsing HTML" },
 { "ELGOTO",		"edit the current link's URL or ACTION and go to it" },
 { "CHANGE_LINK",	"force reset of the current link on the page" },
+{ "EDITTEXTAREA",	"use defined external editor to edit the text area" },
 #ifdef USE_EXTERNALS
 { "EXTERN",		"run external program with url" },
 #endif
@@ -701,10 +702,12 @@ PRIVATE void print_binding ARGS2(HTStream *, target, int, i)
     if (prev_lynx_edit_mode && !no_dired_support &&
         (buf = format_binding(key_override, i)) != 0) {
 	(*target->isa->put_block)(target, buf, strlen(buf));
+	FREE(buf);
     } else
 #endif /* DIRED_SUPPORT && OK_OVERRIDE */
     if ((buf = format_binding(keymap, i)) != 0) {
 	(*target->isa->put_block)(target, buf, strlen(buf));
+	FREE(buf);
     }
 }
 
diff --git a/src/LYKeymap.h b/src/LYKeymap.h
index 492784e3..12736985 100644
--- a/src/LYKeymap.h
+++ b/src/LYKeymap.h
@@ -105,15 +105,16 @@ extern unsigned short key_override[];
 #define       LYK_SWITCH_DTD    72
 #define       LYK_ELGOTO        73
 #define       LYK_CHANGE_LINK   74
+#define	      LYK_EDIT_TEXTAREA 75
 
 #ifdef USE_EXTERNALS
-#define       LYK_EXTERN        75
+#define       LYK_EXTERN        76
 #if defined(VMS) || defined(DIRED_SUPPORT)
-#define       LYK_DIRED_MENU    76
+#define       LYK_DIRED_MENU    77
 #endif /* VMS || DIRED_SUPPORT */
 #else  /* USE_EXTERNALS */
 #if defined(VMS) || defined(DIRED_SUPPORT)
-#define       LYK_DIRED_MENU    75
+#define       LYK_DIRED_MENU    76
 #endif /* VMS || DIRED_SUPPORT */
 #endif /* !defined(USE_EXTERNALS) */
 
diff --git a/src/LYLeaks.c b/src/LYLeaks.c
index 2aae0213..58c4b114 100644
--- a/src/LYLeaks.c
+++ b/src/LYLeaks.c
@@ -465,6 +465,12 @@ PUBLIC char * LYLeakSACopy ARGS4(
 	CONST char *,	cp_File,
 	CONST short,	ssi_Line)
 {
+    if (src != NULL && src == *dest) {
+	CTRACE(tfp,
+	       "LYLeakSACopy: *dest equals src, contains \"%s\"\n",
+	       src);
+	return *dest;
+    }
     if (*dest) {
 	LYLeakFree(*dest, cp_File, ssi_Line);
 	*dest = NULL;
@@ -490,6 +496,12 @@ PUBLIC char * LYLeakSACat ARGS4(
 	CONST short,	ssi_Line)
 {
     if (src && *src) {
+	if (src == *dest) {
+	    CTRACE(tfp,
+		   "LYLeakSACat:  *dest equals src, contains \"%s\"\n",
+		   src);
+	    return *dest;
+	}
 	if (*dest) {
 	    int length = strlen(*dest);
 	    *dest = (char *)LYLeakRealloc(*dest,
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index 71a086e8..cfddb3f6 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -1719,6 +1719,8 @@ new_cmd:  /*
 	   *  back through the getch() loop.
 	   */
 
+	CTRACE_FLUSH(tfp);
+
 	switch(cmd) {
 	case 0: /* unmapped character */
 	default:
@@ -4133,7 +4135,7 @@ if (!LYUseFormsOptions) {
 
 	case LYK_EDIT:	/* edit */
 	    if (no_editor) {
-		if (old_c != real_c)	{
+		if (old_c != real_c) {
 		    old_c = real_c;
 		    HTUserMsg(EDIT_DISABLED);
 		}
@@ -4293,6 +4295,38 @@ if (!LYUseFormsOptions) {
 	    }
 	    break;
 
+	case LYK_EDIT_TEXTAREA: /* use external editor on a TEXTAREA - KED */
+	    if (no_editor) {
+		if (old_c != real_c) {
+		    old_c = real_c;
+		    HTUserMsg(EDIT_DISABLED);
+		}
+		break;
+	    }
+
+		/* is curent link part of a textarea */
+	    if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
+		links[curdoc.link].form->type == F_TEXTAREA_TYPE) {
+
+		/* stop screen */
+		stop_curses();
+
+		HText_ExtEditForm (&links[curdoc.link]);
+
+		/* start screen */
+		start_curses();
+		refresh_screen = TRUE;
+
+		/*
+		cmd = LYK_REFRESH;
+		goto new_cmd;
+		*/
+
+	    } else {
+		HTInfoMsg (NOT_IN_TEXTAREA);
+	    }
+	    break;
+
 	case LYK_PRINT:  /* print the file */
 	    if (LYValidate) {
 		if (old_c != real_c)	{
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index 2143d53d..4eefe938 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -1,4 +1,8 @@
+#ifndef NO_RULES
+#include <HTRules.h>
+#else
 #include <HTUtils.h>
+#endif
 #include <HTFile.h>
 #include <UCMap.h>
 
@@ -708,6 +712,41 @@ static int news_posting_fun ARGS1(
     return 0;
 }
 
+#ifndef NO_RULES
+static int cern_rulesfile_fun ARGS1(
+	char *, 	value)
+{
+    char *rulesfile1 = NULL;
+    char *rulesfile2 = NULL;
+    if (HTLoadRules(value) >= 0) {
+	return 0;
+    }
+    StrAllocCopy(rulesfile1, value);
+    LYTrimLeading(value);
+    LYTrimTrailing(value);
+    if (!strncmp(value, "~/", 2)) {
+	StrAllocCopy(rulesfile2, Home_Dir());
+	StrAllocCat(rulesfile2, value+1);
+    }
+    else {
+	StrAllocCopy(rulesfile2, value);
+    }
+    if (strcmp(rulesfile1, rulesfile2) &&
+	HTLoadRules(rulesfile2) >= 0) {
+	FREE(rulesfile1);
+	FREE(rulesfile2);
+	return 0;
+    }
+    fprintf(stderr,
+	    gettext(
+		"Lynx: cannot start, CERN rules file %s is not available\n"
+		),
+	    (rulesfile2 && *rulesfile2) ? rulesfile2 : gettext("(no name)"));
+    exit_immediately(69);	/* EX_UNAVAILABLE in sysexits.h */
+    return 0;			/* though redundant, for compiler-warnings */
+}
+#endif /* NO_RULES */
+
 static int printer_fun ARGS1(
 	char *, 	value)
 {
@@ -929,6 +968,10 @@ static Config_Type Config_Table [] =
      PARSE_SET("prepend_charset_to_source", CONF_BOOL, LYPrependCharsetToSource),
      PARSE_FUN("printer", CONF_FUN, printer_fun),
      PARSE_SET("quit_default_yes", CONF_BOOL, LYQuitDefaultYes),
+#ifndef NO_RULES
+     PARSE_STR("rule", CONF_FUN, HTSetConfiguration),
+     PARSE_STR("rulesfile", CONF_FUN, cern_rulesfile_fun),
+#endif /* NO_RULES */
      PARSE_STR("save_space", CONF_STR, lynx_save_space),
      PARSE_SET("scan_for_buried_news_refs", CONF_BOOL, scan_for_buried_news_references),
      PARSE_SET("seek_frag_area_in_cur", CONF_BOOL, LYSeekFragAREAinCur),
diff --git a/src/LYUtils.c b/src/LYUtils.c
index ffce1d4b..f68da554 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -5638,11 +5638,15 @@ PUBLIC FILE *LYOpenTemp ARGS3(
 	CONST char *,	mode)
 {
     FILE *fp = 0;
+    BOOL first = TRUE;
     BOOL txt = TRUE;
     BOOL wrt = 'r';
     LY_TEMP *p;
 
     CTRACE(tfp, "LYOpenTemp(,%s,%s)\n", suffix, mode);
+    if (result == 0)
+    	return 0;
+
     while (*mode != '\0') {
 	switch (*mode++) {
 	case 'w':	wrt = 'w';	break;
@@ -5669,6 +5673,22 @@ PUBLIC FILE *LYOpenTemp ARGS3(
 	} else {
 	    fp = LYNewBinFile (result);
 	}
+	/*
+	 * If we get a failure to make a temporary file, double check if the
+	 * directory is writable.
+	 */
+#ifdef W_OK	/* FIXME (need a better test) in fcntl.h or unistd.h */
+	if (first) {
+	    first = FALSE;
+	    if (fp == 0) {
+		*LYPathLeaf(result) = 0;
+		if (*result == 0)
+		    strcpy(result, ".");
+		if (access(result, W_OK) < 0)
+		    return 0;
+	    }
+	}
+#endif
     } while (fp == 0);
 
     if ((p = (LY_TEMP *)calloc(1, sizeof(LY_TEMP))) != 0) {
diff --git a/src/chrtrans/MAKEW32.BAT b/src/chrtrans/MAKEW32.BAT
index a5504bc7..48b26f97 100644
--- a/src/chrtrans/MAKEW32.BAT
+++ b/src/chrtrans/MAKEW32.BAT
@@ -20,7 +20,7 @@ makeuctb cp866_uni.tbl > cp866_uni.h
 makeuctb cp869_uni.tbl > cp869_uni.h
 makeuctb def7_uni.tbl  > def7_uni.h
 makeuctb dmcs_uni.tbl > dmcs_uni.h
-makeuctb hpuni.tbl > hpuni.h
+makeuctb hp_uni.tbl > hp_uni.h 
 makeuctb iso01_uni.tbl > iso01_uni.h
 makeuctb iso02_uni.tbl > iso02_uni.h
 makeuctb iso03_uni.tbl > iso03_uni.h
@@ -31,6 +31,7 @@ makeuctb iso07_uni.tbl > iso07_uni.h
 makeuctb iso08_uni.tbl > iso08_uni.h
 makeuctb iso09_uni.tbl > iso09_uni.h
 makeuctb iso10_uni.tbl > iso10_uni.h
+makeuctb iso15_uni.tbl > iso15_uni.h 
 makeuctb koi8r_uni.tbl > koi8r_uni.h
 makeuctb mac_uni.tbl > mac_uni.h
 makeuctb mnem_suni.tbl > mnem_suni.h
diff --git a/src/chrtrans/makefile.dos b/src/chrtrans/makefile.dos
index 6e335a09..3f99eaa9 100644
--- a/src/chrtrans/makefile.dos
+++ b/src/chrtrans/makefile.dos
@@ -95,6 +95,7 @@ cp866_uni.h:		cp866_uni.tbl		makeuctb.exe
 cp869_uni.h:		cp869_uni.tbl		makeuctb.exe
 def7_uni.h:		def7_uni.tbl		makeuctb.exe
 dmcs_uni.h:		dmcs_uni.tbl		makeuctb.exe
+hp_uni.h:               hp_uni.tbl              makeuctb.exe 
 iso01_uni.h:		iso01_uni.tbl		makeuctb.exe
 iso02_uni.h:		iso02_uni.tbl		makeuctb.exe
 iso03_uni.h:		iso03_uni.tbl		makeuctb.exe
diff --git a/src/structdump.h b/src/structdump.h
new file mode 100644
index 00000000..876d4576
--- /dev/null
+++ b/src/structdump.h
@@ -0,0 +1,137 @@
+/*
+ *
+ * Some macros to dump out formatted struct's via the trace file.  -KED
+ *
+ */
+#ifndef STRUCTDUMP_H
+#define STRUCTDUMP_H
+
+/* usage: DUMPSTRUCT_LINK(link_ptr, "message"); */
+#define   DUMPSTRUCT_LINK(L,X) \
+CTRACE(tfp, "\n" \
+            "KED:     link_ptr=%08x  sizeof=%d  ["X"]\n" \
+            "link       struct {\n" \
+            "           *lname=%08x\n" \
+            "            lname=|%s|\n" \
+            "          *target=%08x\n" \
+            "           target=|%s|\n" \
+            "        *hightext=%08x\n" \
+            "         hightext=|%s|\n" \
+            "       *hightext2=%08x\n" \
+            "        hightext2=|%s|\n" \
+            " hightext2_offset=%d\n"   \
+            "      inUnderline=%1x\n"  \
+            "               lx=%d\n"   \
+            "               ly=%d\n"   \
+            "             type=%d\n"   \
+            "    anchor_number=%d\n"   \
+            "  anchor_line_num=%d\n"   \
+            "            *form=%08x\n" \
+            "}\n", \
+            (L), sizeof(*((L))), \
+            (L)->lname, (L)->lname, (L)->target, (L)->target, \
+            (L)->hightext, (L)->hightext, (L)->hightext2, (L)->hightext2, \
+            (L)->hightext2_offset, (L)->inUnderline, (L)->lx, (L)->ly, \
+            (L)->type, (L)->anchor_number, (L)->anchor_line_num, (L)->form); \
+CTRACE_FLUSH(tfp);
+
+
+/* usage: DUMPSTRUCT_ANCHOR(anchor_ptr, "message"); */
+#define   DUMPSTRUCT_ANCHOR(A,X) \
+CTRACE(tfp, "\n" \
+            "KED:   anchor_ptr=%08x  sizeof=%d  ["X"]\n" \
+            "TextAnchor struct {\n"    \
+            "            *next=%08x\n" \
+            "           number=%d\n"   \
+            "            start=%d\n"   \
+            "         line_pos=%d\n"   \
+            "           extent=%d\n"   \
+            "         line_num=%d\n"   \
+            "        *hightext=%08x\n" \
+            "         hightext=|%s|\n" \
+            "       *hightext2=%08x\n" \
+            "        hightext2=|%s|\n" \
+            "  hightext2offset=%d\n"   \
+            "        link_type=%d\n"   \
+            "     *input_field=%08x\n" \
+            "      input_field=|%s|\n" \
+            "      show_anchor=%1x\n"  \
+            "      inUnderline=%1x\n"  \
+            "          *anchor=%08x\n" \
+            "}\n", \
+            (A), sizeof(*((A))), \
+            (A)->next, (A)->number, (A)->start, (A)->line_pos, \
+            (A)->extent, (A)->line_num, \
+            (A)->hightext, (A)->hightext, (A)->hightext2, (A)->hightext2, \
+            (A)->hightext2offset, (A)->link_type, \
+            (A)->input_field, (A)->input_field, \
+            (A)->show_anchor, (A)->inUnderline, (A)->anchor); \
+CTRACE_FLUSH(tfp);
+
+
+/* usage: DUMPSTRUCT_FORM(forminfo_ptr, "message"); */
+#define   DUMPSTRUCT_FORMINFO(F,X) \
+CTRACE(tfp, "\n" \
+            "KED: forminfo_ptr=%08x  sizeof=%d  ["X"]\n" \
+            "FormInfo   struct {\n"    \
+            "            *name=%08x\n" \
+            "             name=|%s|\n" \
+            "           number=%d\n"   \
+            "             type=%d\n"   \
+            "           *value=%08x\n" \
+            "            value=|%s|\n" \
+            "      *orig_value=%08x\n" \
+            "       orig_value=|%s|\n" \
+            "             size=%d\n"   \
+            "        maxlength=%d\n"   \
+            "            group=%d\n"   \
+            "        num_value=%d\n"   \
+            "           hrange=%d\n"   \
+            "           lrange=%d\n"   \
+            "     *select_list=%08x\n" \
+            "    submit_action=|%s|\n" \
+            "    submit_method=%d\n"   \
+            "   submit_enctype=|%s|\n" \
+            "     submit_title=|%s|\n" \
+            "         no_cache=%1x\n"  \
+            "  cp_submit_value=|%s|\n" \
+            "orig_submit_value=|%s|\n" \
+            "           size_l=%d\n"   \
+            "         disabled=%d\n"   \
+            "          name_cs=%d\n"   \
+            "         value_cs=%d\n"   \
+            "        accept_cs=|%s|\n" \
+            "}\n", \
+            (F), sizeof(*((F))), \
+            (F)->name, (F)->name, (F)->number, (F)->type, \
+            (F)->value, (F)->value, (F)->orig_value, (F)->orig_value, \
+            (F)->size, (F)->maxlength, (F)->group, (F)->num_value, \
+            (F)->hrange, (F)->lrange, (F)->select_list, (F)->submit_action, \
+            (F)->submit_method, (F)->submit_enctype, (F)->submit_title, \
+            (F)->no_cache, (F)->cp_submit_value, (F)->orig_submit_value, \
+            (F)->size_l, (F)->disabled, (F)->name_cs, (F)->value_cs, \
+            (F)->accept_cs); \
+CTRACE_FLUSH(tfp);
+
+
+/* usage: DUMPSTRUCT_LINE(htline_ptr, "message"); */
+#define   DUMPSTRUCT_LINE(L,X) \
+CTRACE(tfp, "\n" \
+            "KED: htline_ptr=%08x  sizeof=%d  ["X"]\n" \
+            "HTLine struct {\n"    \
+            "        *next=%08x\n" \
+            "        *prev=%08x\n" \
+            "       offset=%d\n"   \
+            "         size=%d\n"   \
+            "  split_after=%1x\n"  \
+            "       bullet=%1x\n"  \
+            "nodef U_C_S\n"        \
+            "       data[]=%08x\n" \
+            "         data=|%s|\n" \
+            "}\n", \
+            (L), sizeof(*((L))), \
+            (L)->next, (L)->prev, (L)->offset, (L)->size, (L)->split_after, \
+            (L)->bullet, (L)->data, (L)->data); \
+CTRACE_FLUSH(tfp);
+
+#endif /* STRUCTDUMP_H */