sprintf (ed_offset, "%d", ((entry_line - start_line) + 1));  edit_temporary_file(ed_temp, ed_offset, NULL);  CTRACE((tfp, "GridText: returned from editor (%s)\n", editor));
PUBLIC int HText_ExtEditForm ARGS1(	   struct link *,  form_link){    struct stat stat_info;    size_t	size;    char       *ed_temp;    FILE       *fp;    TextAnchor *anchor_ptr;    TextAnchor *start_anchor  = NULL;    TextAnchor *end_anchor    = NULL;    BOOLEAN	firstanchor   = TRUE;    char	ed_offset[10];    int		start_line    = 0;    int		entry_line    = form_link->anchor_line_num;    int		exit_line     = 0;    int		orig_cnt      = 0;    int		line_cnt      = 1;    FormInfo   *form	 = form_link->form;    char       *areaname = form->name;    int		form_num = form->number;    HTLine     *htline	 = NULL;    char       *ebuf;    char       *tbuf = NULL;    char       *line;    char       *lp;    char       *cp;    int         match_tag = 0;    int		newlines  = 0;    int		len;    CTRACE(tfp, "GridText: entered HText_ExtEditForm()\n");    ed_temp = (char *) malloc (LY_MAXPATH);    if ((fp = LYOpenTemp (ed_temp, "", "w")) == 0) {	FREE(ed_temp);	return (0);    }    /*     *	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;		start_line   = anchor_ptr->line_num;	    }	    orig_cnt++;	    /*	     *  Write the anchors' 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;    }    LYCloseTempFP (fp);    CTRACE(tfp, "GridText: TEXTAREA name=|%s| dumped to tempfile\n", areaname);    CTRACE(tfp, "GridText: invoking editor (%s) on tempfile\n", editor);    /*     *	Go edit the TEXTAREA temp file, with the initial editor line     *  corresponding to the TEXTAREA line the cursor is on (if such     *  positioning is supported by the editor [as lynx knows it]).     */    ed_offset[0] = 0; /* pre-ANSI compilers don't initialize aggregates - TD */    if (((entry_line - start_line) > 0) && editor_can_position())#ifdef VMS	sprintf (ed_offset, "-%d", ((entry_line - start_line) + 1));    HTSprintf0 (&tbuf, "%s %s %s", editor, ed_temp, ed_offset);#else	sprintf (ed_offset, "+%d", ((entry_line - start_line) + 1));    HTSprintf0 (&tbuf, "%s %s %s", editor, ed_offset, ed_temp);#endif    LYSystem (tbuf);   /* finally the editor is called */#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);    CTRACE(tfp, "GridText: returned from editor (%s)\n", editor);    /*     *	Read back the edited temp file into our buffer.     */    if ((stat (ed_temp, &stat_info) < 0)   ||	!S_ISREG(stat_info.st_mode)        ||	((size = stat_info.st_size) == 0)) {	size = 0;	ebuf = (char *) calloc (1, 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-1] == '\0')))	ebuf[--size] = '\0';    /*     *	Copy each line from the temp file into the corresponding anchor     *  struct.  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;    lp  = ebuf;    while ((line_cnt <= orig_cnt) || (*lp) || ((len != 0) && (*lp == '\0'))) {	if ((cp = strchr (lp, '\n')) != 0)	   len = cp - lp;	else	   len = strlen (lp);	strncpy (line, lp, len);	*(line + len) = '\0';	cleanup_line_for_textarea (line, len);	/*	 *  If there are more lines in the edit buffer than were in the	 *  original TEXTAREA, we need to add a new line/anchor, continuing	 *  on until the edit buffer is empty.	 */	if (line_cnt > orig_cnt) {	    insert_new_textarea_anchor (&end_anchor, &htline);	    anchor_ptr = end_anchor;   /* make the new anchor current */	    newlines++;	}	/*	 *  Finally copy the new line from the edit buffer into the anchor.	 */	StrAllocCopy(anchor_ptr->input_field->value, line);	/*	 *  Keep track of 1st blank line in any trailing blank lines, for	 *  later cursor repositioning.	 */	if (len > 0)	    exit_line = 0;	else if (exit_line == 0)	    exit_line = anchor_ptr->line_num;	/*	 *  And do the next line of edited text, for the next anchor ...	 */	lp += len;	if (*lp) lp++;	end_anchor = anchor_ptr;	anchor_ptr = anchor_ptr->next;	if (anchor_ptr)	    match_tag = anchor_ptr->number;	line_cnt++;    }    CTRACE(tfp, "GridText: edited text inserted into lynx struct's\n");    /*     *	If we've added any new lines/anchors, we need to adjust various     *  things in all anchor-bearing lines following the last newly added     *  line/anchor.  The fun stuff starts here ...     */    if (newlines > 0)	update_subsequent_anchors (newlines, end_anchor, htline, match_tag);    /*     *  Cleanup time.     */    FREE(line);    FREE(ebuf);    LYRemoveTemp (ed_temp);    FREE(ed_temp);    CTRACE(tfp, "GridText: exiting HText_ExtEditForm()\n");    /*     *  Return the offset needed to move the cursor from its current     *  (on entry) line number, to the 1st blank line of the trailing     *  (group of) blank line(s), which is where we want to be.  Let     *  the caller deal with moving us there, however ... :-) ...     */    return (exit_line - entry_line);}