Blame src/LYMail.c

Packit f574b8
/*
Packit f574b8
 * $LynxId: LYMail.c,v 1.99 2018/03/18 19:16:29 tom Exp $
Packit f574b8
 */
Packit f574b8
#include <HTUtils.h>
Packit f574b8
#include <HTParse.h>
Packit f574b8
#include <LYGlobalDefs.h>
Packit f574b8
#include <HTAlert.h>
Packit f574b8
#include <LYCurses.h>
Packit f574b8
#include <LYSignal.h>
Packit f574b8
#include <LYUtils.h>
Packit f574b8
#include <LYClean.h>
Packit f574b8
#include <LYStrings.h>
Packit f574b8
#include <GridText.h>
Packit f574b8
#include <LYMail.h>
Packit f574b8
#include <LYEdit.h>
Packit f574b8
#include <LYCharSets.h>		/* to get current charset for mail header */
Packit f574b8
Packit f574b8
#include <LYLeaks.h>
Packit f574b8
Packit f574b8
#define MAX_SUBJECT 70
Packit f574b8
Packit f574b8
BOOLEAN term_letter;		/* Global variable for async i/o. */
Packit f574b8
Packit f574b8
static void terminate_letter(int sig GCC_UNUSED)
Packit f574b8
{
Packit f574b8
    term_letter = TRUE;
Packit f574b8
    /* Reassert the AST */
Packit f574b8
    signal(SIGINT, terminate_letter);
Packit f574b8
#if USE_VMS_MAILER || defined(PDCURSES)
Packit f574b8
    /*
Packit f574b8
     * Refresh the screen to get rid of the "interrupt" message.
Packit f574b8
     */
Packit f574b8
    if (!dump_output_immediately) {
Packit f574b8
	lynx_force_repaint();
Packit f574b8
	LYrefresh();
Packit f574b8
    }
Packit f574b8
#endif /* VMS */
Packit f574b8
}
Packit f574b8
Packit f574b8
/* HTUnEscape with control-code nuking */
Packit f574b8
static void SafeHTUnEscape(char *string)
Packit f574b8
{
Packit f574b8
    int i;
Packit f574b8
    int flg = FALSE;
Packit f574b8
Packit f574b8
    HTUnEscape(string);
Packit f574b8
    for (i = 0; string[i] != '\0'; i++) {
Packit f574b8
	/* FIXME: this is no longer explicitly 7-bit ASCII,
Packit f574b8
	   but are there portability problems? */
Packit f574b8
	if ((!LYIsASCII(string[i])) || !isprint(UCH(string[i]))) {
Packit f574b8
	    string[i] = '?';
Packit f574b8
	    flg = TRUE;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    if (flg)
Packit f574b8
	HTAlert(MAILTO_SQUASH_CTL);
Packit f574b8
}
Packit f574b8
Packit f574b8
static void remove_tildes(char *string)
Packit f574b8
{
Packit f574b8
    /*
Packit f574b8
     * Change the first character to a space if it is a '~'.
Packit f574b8
     */
Packit f574b8
    if (*string == '~')
Packit f574b8
	*string = ' ';
Packit f574b8
}
Packit f574b8
Packit f574b8
static void comma_append(char **dst,
Packit f574b8
			 char *src)
Packit f574b8
{
Packit f574b8
    if (*src) {
Packit f574b8
	while (*src == ',' || isspace(UCH(*src)))
Packit f574b8
	    src++;
Packit f574b8
	if (*src) {
Packit f574b8
	    if (isEmpty(*dst)) {
Packit f574b8
		StrAllocCopy(*dst, src);
Packit f574b8
	    } else {
Packit f574b8
		StrAllocCat(*dst, ",");
Packit f574b8
		StrAllocCat(*dst, src);
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
static void extract_field(char **dst,
Packit f574b8
			  char *src,
Packit f574b8
			  const char *keyword)
Packit f574b8
{
Packit f574b8
    int len = (int) strlen(keyword);
Packit f574b8
    char *cp, *cp1;
Packit f574b8
Packit f574b8
    cp = (src + 1);
Packit f574b8
    while (*cp != '\0') {
Packit f574b8
	if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
Packit f574b8
	    !strncasecomp(cp, keyword, len)) {
Packit f574b8
	    cp += len;
Packit f574b8
	    if ((cp1 = StrChr(cp, '&')) != NULL) {
Packit f574b8
		*cp1 = '\0';
Packit f574b8
	    }
Packit f574b8
	    comma_append(dst, cp);
Packit f574b8
	    if (cp1) {
Packit f574b8
		*cp1 = '&';
Packit f574b8
		cp = cp1;
Packit f574b8
		cp1 = NULL;
Packit f574b8
	    } else {
Packit f574b8
		break;
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
	cp++;
Packit f574b8
    }
Packit f574b8
    CTRACE((tfp, "extract_field(%s) = '%s'\n", keyword, *dst));
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Seek and handle a subject=foo.  - FM
Packit f574b8
 */
Packit f574b8
static void extract_subject(char *dst,
Packit f574b8
			    char *src)
Packit f574b8
{
Packit f574b8
    const char *keyword = "subject=";
Packit f574b8
    int len = (int) strlen(keyword);
Packit f574b8
    char *cp, *cp1;
Packit f574b8
Packit f574b8
    cp = (src + 1);
Packit f574b8
    while (*cp != '\0') {
Packit f574b8
	if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
Packit f574b8
	    !strncasecomp(cp, keyword, len))
Packit f574b8
	    break;
Packit f574b8
	cp++;
Packit f574b8
    }
Packit f574b8
    if (*cp) {
Packit f574b8
	cp += len;
Packit f574b8
	if ((cp1 = StrChr(cp, '&')) != NULL) {
Packit f574b8
	    *cp1 = '\0';
Packit f574b8
	}
Packit f574b8
	if (*cp) {
Packit f574b8
	    LYStrNCpy(dst, cp, MAX_SUBJECT);
Packit f574b8
	    SafeHTUnEscape(dst);
Packit f574b8
	}
Packit f574b8
	if (cp1) {
Packit f574b8
	    *cp1 = '&';
Packit f574b8
	    cp1 = NULL;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    CTRACE((tfp, "extract_subject(%s) = '%s'\n", keyword, NONNULL(dst)));
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Seek and handle body=foo fields.  - FM
Packit f574b8
 */
Packit f574b8
static void extract_body(char **dst,
Packit f574b8
			 char *src)
Packit f574b8
{
Packit f574b8
    const char *keyword = "body=";
Packit f574b8
    int len = (int) strlen(keyword);
Packit f574b8
    int i;
Packit f574b8
    char *cp, *cp0, *cp1, *temp = 0;
Packit f574b8
Packit f574b8
    cp = (src + 1);
Packit f574b8
    while (*cp != '\0') {
Packit f574b8
	if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
Packit f574b8
	    !strncasecomp(cp, keyword, len)) {
Packit f574b8
	    cp += len;
Packit f574b8
	    if ((cp1 = StrChr(cp, '&')) != NULL) {
Packit f574b8
		*cp1 = '\0';
Packit f574b8
	    }
Packit f574b8
	    if (*cp) {
Packit f574b8
		/*
Packit f574b8
		 * Break up the value into lines with a maximum length of 78. 
Packit f574b8
		 * - FM
Packit f574b8
		 */
Packit f574b8
		StrAllocCopy(temp, cp);
Packit f574b8
		HTUnEscape(temp);
Packit f574b8
		cp0 = temp;
Packit f574b8
		while ((cp = StrChr(cp0, '\n')) != NULL) {
Packit f574b8
		    *cp = '\0';
Packit f574b8
		    if (cp > cp0) {
Packit f574b8
			if (*(cp - 1) == '\r') {
Packit f574b8
			    *(cp - 1) = '\0';
Packit f574b8
			}
Packit f574b8
		    }
Packit f574b8
		    i = 0;
Packit f574b8
		    len = (int) strlen(cp0);
Packit f574b8
		    while (len > 78) {
Packit f574b8
			HTSprintf(dst, "%.78s\n", &cp0[i]);
Packit f574b8
			i += 78;
Packit f574b8
			len = (int) strlen(&cp0[i]);
Packit f574b8
		    }
Packit f574b8
		    HTSprintf(dst, "%s\n", &cp0[i]);
Packit f574b8
		    cp0 = (cp + 1);
Packit f574b8
		}
Packit f574b8
		i = 0;
Packit f574b8
		len = (int) strlen(cp0);
Packit f574b8
		while (len > 78) {
Packit f574b8
		    HTSprintf(dst, "%.78s\n", &cp0[i]);
Packit f574b8
		    i += 78;
Packit f574b8
		    len = (int) strlen(&cp0[i]);
Packit f574b8
		}
Packit f574b8
		if (len) {
Packit f574b8
		    HTSprintf(dst, "%s\n", &cp0[i]);
Packit f574b8
		}
Packit f574b8
		FREE(temp);
Packit f574b8
	    }
Packit f574b8
	    if (cp1) {
Packit f574b8
		*cp1 = '&';
Packit f574b8
		cp = cp1;
Packit f574b8
		cp1 = NULL;
Packit f574b8
	    } else {
Packit f574b8
		break;
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
	cp++;
Packit f574b8
    }
Packit f574b8
    CTRACE((tfp, "extract_body(%s) = '%s'\n", keyword, NONNULL(*dst)));
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Convert any Explorer semi-colon Internet address separators to commas - FM
Packit f574b8
 */
Packit f574b8
static BOOLEAN trim_comma(char *address)
Packit f574b8
{
Packit f574b8
    if (address[(strlen(address) - 1)] == ',')
Packit f574b8
	address[(strlen(address) - 1)] = '\0';
Packit f574b8
    return (BOOL) (*address == '\0');
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Convert any Explorer semi-colon Internet address separators to commas - FM
Packit f574b8
 */
Packit f574b8
static BOOLEAN convert_explorer(char *address)
Packit f574b8
{
Packit f574b8
    char *cp = address;
Packit f574b8
    char *cp0;
Packit f574b8
    char *cp1;
Packit f574b8
Packit f574b8
    while ((cp1 = StrChr(cp, '@')) != NULL) {
Packit f574b8
	cp1++;
Packit f574b8
	if ((cp0 = StrChr(cp1, ';')) != NULL) {
Packit f574b8
	    *cp0 = ',';
Packit f574b8
	    cp1 = cp0 + 1;
Packit f574b8
	}
Packit f574b8
	cp = cp1;
Packit f574b8
    }
Packit f574b8
    return trim_comma(address);
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * reply_by_mail() prompts line-by-line for header information, allowing
Packit f574b8
 * scrolling of the screen.
Packit f574b8
 */
Packit f574b8
static int header_prompt(const char *label,
Packit f574b8
			 char **result,
Packit f574b8
			 unsigned limit)
Packit f574b8
{
Packit f574b8
    char buffer[LINESIZE];
Packit f574b8
    int ok;
Packit f574b8
Packit f574b8
    if (*result != 0) {
Packit f574b8
	LYaddstr(CTRL_U_TO_ERASE);
Packit f574b8
	LYStrNCpy(buffer, *result, sizeof(buffer) - 1);
Packit f574b8
    } else
Packit f574b8
	*buffer = 0;
Packit f574b8
Packit f574b8
    if (limit > sizeof(buffer))
Packit f574b8
	limit = sizeof(buffer);
Packit f574b8
Packit f574b8
    LYaddstr(gettext(label));
Packit f574b8
    LYaddstr(": ");
Packit f574b8
    ok = (LYGetStr(buffer, FALSE, limit, NORECALL) >= 0
Packit f574b8
	  && !term_letter);
Packit f574b8
    LYaddstr("\n");
Packit f574b8
Packit f574b8
    if (ok) {
Packit f574b8
	remove_tildes(buffer);
Packit f574b8
	StrAllocCopy(*result, buffer);
Packit f574b8
    }
Packit f574b8
    term_letter = FALSE;
Packit f574b8
    return ok;
Packit f574b8
}
Packit f574b8
Packit f574b8
static void show_addresses(char *addresses)
Packit f574b8
{
Packit f574b8
    char *cp = addresses;
Packit f574b8
    char *cp1;
Packit f574b8
Packit f574b8
    while ((cp1 = StrChr(cp, ',')) != NULL) {
Packit f574b8
	*cp1 = '\0';
Packit f574b8
	while (*cp == ' ')
Packit f574b8
	    cp++;
Packit f574b8
	if (*cp) {
Packit f574b8
	    LYaddstr(cp);
Packit f574b8
	    LYaddstr(",\n  ");
Packit f574b8
	}
Packit f574b8
	*cp1 = ',';
Packit f574b8
	cp = (cp1 + 1);
Packit f574b8
    }
Packit f574b8
    if (*cp) {
Packit f574b8
	LYaddstr(cp);
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
#if USE_BLAT_MAILER
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * blat's options-file parser (see makeargv.cpp) treats backslash and double
Packit f574b8
 * quote characters specially.  lynx doesn't.  Do a conversion as we write the
Packit f574b8
 * option.
Packit f574b8
 *
Packit f574b8
 * Other quirks (reading blat 3.06):
Packit f574b8
 * + Whitespace not in quotes terminates a line.
Packit f574b8
 * + Blat allows a comment-character to terminate a line.  By default, that
Packit f574b8
 *   is a semicolon.
Packit f574b8
 *
Packit f574b8
 * Given that, the simplest thing to do is to always quote the string, using
Packit f574b8
 * escaping to handle special cases.
Packit f574b8
 */
Packit f574b8
static void blat_option(FILE *fp, const char *option, const char *value)
Packit f574b8
{
Packit f574b8
    if (non_empty(value)) {
Packit f574b8
	char *result = malloc(strlen(option) + 4 + 4 * strlen(value));
Packit f574b8
	char *working = result;
Packit f574b8
Packit f574b8
	CTRACE((tfp, "blat_option(opt=\"%s\", value=\"%s\")\n", option, value));
Packit f574b8
	sprintf(working, "%s \"", option);
Packit f574b8
	working += strlen(working);
Packit f574b8
Packit f574b8
	while (*value != '\0') {
Packit f574b8
	    unsigned ch = UCH(*value);
Packit f574b8
Packit f574b8
	    switch (ch) {
Packit f574b8
	    case '\\':
Packit f574b8
		*working++ = '\\';
Packit f574b8
		*working++ = '\\';
Packit f574b8
		break;
Packit f574b8
	    case '"':
Packit f574b8
		*working++ = '\\';
Packit f574b8
		*working++ = '"';
Packit f574b8
		break;
Packit f574b8
	    default:
Packit f574b8
		if (ch < ' ' || ch > '~') {
Packit f574b8
		    sprintf(working, "\\%03o", ch);
Packit f574b8
		} else {
Packit f574b8
		    *working++ = ch;
Packit f574b8
		}
Packit f574b8
		break;
Packit f574b8
	    }
Packit f574b8
	    ++value;
Packit f574b8
	}
Packit f574b8
	*working++ = '"';
Packit f574b8
	*working++ = '\n';
Packit f574b8
	*working = 0;
Packit f574b8
Packit f574b8
	CTRACE((tfp, "->%s", result));
Packit f574b8
	fputs(result, fp);
Packit f574b8
	FREE(result);
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
syntax for blat 2.6.2:
Packit f574b8
Blat <filename> -t <recipient> [optional switches (see below)]
Packit f574b8
Packit f574b8
-bodyF <filename> : file with the message body
Packit f574b8
-t <recipient>    : recipient list (comma separated)
Packit f574b8
-s <subj>         : subject line
Packit f574b8
-f <sender>       : overrides the default sender address (must be known to server)
Packit f574b8
-i <addr>         : a 'From:' address, not necessarily known to the SMTP server.
Packit f574b8
-c <recipient>    : carbon copy recipient list (comma separated)
Packit f574b8
-b <recipient>    : blind carbon copy recipient list (comma separated)
Packit f574b8
-help             : displays the help message.
Packit f574b8
-mime             : MIME Quoted-Printable Content-Transfer-Encoding.
Packit f574b8
-q                : supresses *all* output.
Packit f574b8
-server <addr>    : overrides the default SMTP server to be used.
Packit f574b8
Packit f574b8
*/
Packit f574b8
Packit f574b8
static char *blat_cmd(char *filename,
Packit f574b8
		      char *address,
Packit f574b8
		      char *subject,
Packit f574b8
		      char *ccaddr,
Packit f574b8
		      char *mail_addr)
Packit f574b8
{
Packit f574b8
    char *b_cmd = NULL;
Packit f574b8
Packit f574b8
    if (mail_is_altblat) {
Packit f574b8
	const char *format = "%s %s -t %s -s %s %s%s%s";
Packit f574b8
Packit f574b8
	HTAddParam(&b_cmd, format, 1, ALTBLAT_MAIL);
Packit f574b8
	HTAddParam(&b_cmd, format, 2, filename);
Packit f574b8
	HTAddParam(&b_cmd, format, 3, address);
Packit f574b8
	HTAddParam(&b_cmd, format, 4, subject);
Packit f574b8
	HTAddToCmd(&b_cmd, format, 5, ALTBLAT_MAIL_FLAGS);
Packit f574b8
	if (non_empty(ccaddr)) {
Packit f574b8
	    HTAddToCmd(&b_cmd, format, 6, " -c ");
Packit f574b8
	    HTAddParam(&b_cmd, format, 7, NonNull(ccaddr));
Packit f574b8
	}
Packit f574b8
	HTEndParam(&b_cmd, format, 8);
Packit f574b8
Packit f574b8
    } else {
Packit f574b8
Packit f574b8
	const char *format = "%s -of %s";
Packit f574b8
	char bl_cmd_file[LY_MAXPATH];
Packit f574b8
	FILE *fp;
Packit f574b8
Packit f574b8
#ifdef __CYGWIN__
Packit f574b8
	char dosname[LY_MAXPATH];
Packit f574b8
Packit f574b8
#else
Packit f574b8
	char *dosname;
Packit f574b8
#endif
Packit f574b8
Packit f574b8
	bl_cmd_file[0] = '\0';
Packit f574b8
	if ((fp = LYOpenTemp(bl_cmd_file, ".blt", "w")) == NULL) {
Packit f574b8
	    HTAlert(FORM_MAILTO_FAILED);
Packit f574b8
	    return NULL;
Packit f574b8
	}
Packit f574b8
Packit f574b8
	HTAddParam(&b_cmd, format, 1, BLAT_MAIL);
Packit f574b8
Packit f574b8
	ConvertToWin32Path(filename, dosname);
Packit f574b8
	blat_option(fp, "-bodyF", dosname);
Packit f574b8
	blat_option(fp, "-t", address);
Packit f574b8
	blat_option(fp, "-s", subject);
Packit f574b8
	blat_option(fp, "-f", mail_addr);
Packit f574b8
	blat_option(fp, "-c", ccaddr);
Packit f574b8
	LYCloseOutput(fp);
Packit f574b8
Packit f574b8
	ConvertToWin32Path(bl_cmd_file, dosname);
Packit f574b8
Packit f574b8
	HTAddParam(&b_cmd, format, 2, dosname);
Packit f574b8
	HTEndParam(&b_cmd, format, 3);
Packit f574b8
Packit f574b8
    }
Packit f574b8
Packit f574b8
    return b_cmd;
Packit f574b8
}
Packit f574b8
Packit f574b8
#endif /* USE_BLAT_MAILER */
Packit f574b8
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
BOOLEAN LYMailPMDF(void)
Packit f574b8
{
Packit f574b8
    return (system_mail != 0)
Packit f574b8
	? !strncasecomp(system_mail, "PMDF SEND", 9)
Packit f574b8
	: FALSE;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Add all of the people in the address field to the command
Packit f574b8
 */
Packit f574b8
static void vms_append_addrs(char **cmd, char *address, char *option)
Packit f574b8
{
Packit f574b8
    BOOLEAN first = TRUE;
Packit f574b8
    char *cp;
Packit f574b8
    char *address_ptr1;
Packit f574b8
    char *address_ptr2;
Packit f574b8
Packit f574b8
    address_ptr1 = address;
Packit f574b8
    do {
Packit f574b8
	if ((cp = StrChr(address_ptr1, ',')) != NULL) {
Packit f574b8
	    address_ptr2 = (cp + 1);
Packit f574b8
	    *cp = '\0';
Packit f574b8
	} else {
Packit f574b8
	    address_ptr2 = NULL;
Packit f574b8
	}
Packit f574b8
Packit f574b8
	/*
Packit f574b8
	 * 4 letters is arbitrarily the smallest possible mail address, at
Packit f574b8
	 * least for lynx.  That way extra spaces won't confuse the mailer and
Packit f574b8
	 * give a blank address.
Packit f574b8
	 */
Packit f574b8
	if (strlen(address_ptr1) > 3) {
Packit f574b8
	    if (!first) {
Packit f574b8
		StrAllocCat(*cmd, ",");
Packit f574b8
	    }
Packit f574b8
	    HTSprintf(cmd, mail_adrs, address_ptr1);
Packit f574b8
	    if (*option && LYMailPMDF())
Packit f574b8
		StrAllocCat(*cmd, option);
Packit f574b8
	    first = FALSE;
Packit f574b8
	}
Packit f574b8
	address_ptr1 = address_ptr2;
Packit f574b8
    } while (address_ptr1 != NULL);
Packit f574b8
}
Packit f574b8
Packit f574b8
static void remove_quotes(char *string)
Packit f574b8
{
Packit f574b8
    while (*string != 0) {
Packit f574b8
	if (StrChr("\"&|", *string) != 0)
Packit f574b8
	    *string = ' ';
Packit f574b8
	string++;
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
#else
Packit f574b8
#if CAN_PIPE_TO_MAILER
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Open a pipe to the mailer
Packit f574b8
 */
Packit f574b8
FILE *LYPipeToMailer(void)
Packit f574b8
{
Packit f574b8
    char *buffer = NULL;
Packit f574b8
    FILE *fp = NULL;
Packit f574b8
Packit f574b8
    if (LYSystemMail()) {
Packit f574b8
	HTSprintf0(&buffer, "%s %s", system_mail, system_mail_flags);
Packit f574b8
	fp = popen(buffer, "w");
Packit f574b8
	CTRACE((tfp, "popen(%s) %s\n", buffer, fp != 0 ? "OK" : "FAIL"));
Packit f574b8
	FREE(buffer);
Packit f574b8
    }
Packit f574b8
    return fp;
Packit f574b8
}
Packit f574b8
#else /* DOS, Win32, etc. */
Packit f574b8
Packit f574b8
int LYSendMailFile(char *the_address,
Packit f574b8
		   char *the_filename,
Packit f574b8
		   char *the_subject GCC_UNUSED,
Packit f574b8
		   char *the_ccaddr GCC_UNUSED,
Packit f574b8
		   char *message)
Packit f574b8
{
Packit f574b8
    char *cmd = NULL;
Packit f574b8
    int code;
Packit f574b8
Packit f574b8
    if (!LYSystemMail())
Packit f574b8
	return 0;
Packit f574b8
Packit f574b8
#if USE_BLAT_MAILER
Packit f574b8
    if (mail_is_blat) {
Packit f574b8
	cmd = blat_cmd(the_filename,
Packit f574b8
		       the_address,
Packit f574b8
		       the_subject,
Packit f574b8
		       the_ccaddr,
Packit f574b8
		       personal_mail_address);
Packit f574b8
    } else
Packit f574b8
#endif
Packit f574b8
#ifdef __DJGPP__
Packit f574b8
    if (LYGetEnv("SHELL")) {
Packit f574b8
	extern char *shell;
Packit f574b8
	const char *c_option;
Packit f574b8
	const char *format = "%s %s %s -t %s -F %s";
Packit f574b8
Packit f574b8
	if (dj_is_bash) {
Packit f574b8
	    c_option = "-c";
Packit f574b8
	} else {
Packit f574b8
	    c_option = "/c";
Packit f574b8
	}
Packit f574b8
	HTAddParam(&cmd, format, 1, shell);
Packit f574b8
	HTAddParam(&cmd, format, 2, c_option);
Packit f574b8
	HTAddParam(&cmd, format, 3, system_mail);
Packit f574b8
	HTAddParam(&cmd, format, 4, the_address);
Packit f574b8
	HTAddParam(&cmd, format, 5, the_filename);
Packit f574b8
	HTEndParam(&cmd, format, 6);
Packit f574b8
    } else
Packit f574b8
#endif /* __DJGPP__ */
Packit f574b8
    {
Packit f574b8
	const char *format = "%s -t %s -F %s";
Packit f574b8
Packit f574b8
	HTAddParam(&cmd, format, 1, system_mail);
Packit f574b8
	HTAddParam(&cmd, format, 2, the_address);
Packit f574b8
	HTAddParam(&cmd, format, 3, the_filename);
Packit f574b8
	HTEndParam(&cmd, format, 4);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    stop_curses();
Packit f574b8
    SetOutputMode(O_TEXT);
Packit f574b8
    printf("%s\n\n$ %s\n\n%s",
Packit f574b8
	   *message ? message : gettext("Sending"),
Packit f574b8
	   cmd, PLEASE_WAIT);
Packit f574b8
    code = LYSystem(cmd);
Packit f574b8
    LYSleepMsg();
Packit f574b8
    start_curses();
Packit f574b8
    SetOutputMode(O_BINARY);
Packit f574b8
Packit f574b8
    FREE(cmd);
Packit f574b8
Packit f574b8
    return code;
Packit f574b8
}
Packit f574b8
#endif /* CAN_PIPE_TO_FILE */
Packit f574b8
#endif /* USE_VMS_MAILER */
Packit f574b8
Packit f574b8
/*
Packit f574b8
 *  mailform() sends form content to the mailto address(es). - FM
Packit f574b8
 */
Packit f574b8
void mailform(const char *mailto_address,
Packit f574b8
	      const char *mailto_subject,
Packit f574b8
	      const char *mailto_content,
Packit f574b8
	      const char *mailto_type)
Packit f574b8
{
Packit f574b8
    FILE *fd;
Packit f574b8
    char *address = NULL;
Packit f574b8
    char *ccaddr = NULL;
Packit f574b8
    char *keywords = NULL;
Packit f574b8
    char *cp = NULL;
Packit f574b8
    char self[MAX_SUBJECT + 10];
Packit f574b8
    char subject[MAX_SUBJECT + 10];
Packit f574b8
    char *searchpart = NULL;
Packit f574b8
    char buf[512];
Packit f574b8
    int len, i;
Packit f574b8
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    static char *cmd;
Packit f574b8
    char *command = NULL;
Packit f574b8
    BOOLEAN isPMDF = LYMailPMDF();
Packit f574b8
    char hdrfile[LY_MAXPATH];
Packit f574b8
#endif
Packit f574b8
#if !CAN_PIPE_TO_MAILER
Packit f574b8
    char my_tmpfile[LY_MAXPATH];
Packit f574b8
#endif
Packit f574b8
Packit f574b8
    CTRACE((tfp, "mailto_address: \"%s\"\n", NONNULL(mailto_address)));
Packit f574b8
    CTRACE((tfp, "mailto_subject: \"%s\"\n", NONNULL(mailto_subject)));
Packit f574b8
    CTRACE((tfp, "mailto_content: \"%s\"\n", NONNULL(mailto_content)));
Packit f574b8
    CTRACE((tfp, "mailto_type:    \"%s\"\n", NONNULL(mailto_type)));
Packit f574b8
Packit f574b8
    if (!LYSystemMail())
Packit f574b8
	return;
Packit f574b8
Packit f574b8
    if (!mailto_address || !mailto_content) {
Packit f574b8
	HTAlert(BAD_FORM_MAILTO);
Packit f574b8
	return;
Packit f574b8
    }
Packit f574b8
    subject[0] = '\0';
Packit f574b8
    self[0] = '\0';
Packit f574b8
Packit f574b8
    if ((cp = StrChr(mailto_address, '\n')) != NULL)
Packit f574b8
	*cp = '\0';
Packit f574b8
    StrAllocCopy(address, mailto_address);
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Check for a ?searchpart.  - FM
Packit f574b8
     */
Packit f574b8
    if ((cp = StrChr(address, '?')) != NULL) {
Packit f574b8
	StrAllocCopy(searchpart, cp);
Packit f574b8
	*cp = '\0';
Packit f574b8
	cp = (searchpart + 1);
Packit f574b8
	if (*cp != '\0') {
Packit f574b8
	    /*
Packit f574b8
	     * Seek and handle a subject=foo.  - FM
Packit f574b8
	     */
Packit f574b8
	    extract_subject(subject, searchpart);
Packit f574b8
Packit f574b8
	    /*
Packit f574b8
	     * Seek and handle to=address(es) fields.  Appends to address.  -
Packit f574b8
	     * FM
Packit f574b8
	     */
Packit f574b8
	    extract_field(&address, searchpart, "to=");
Packit f574b8
Packit f574b8
	    /*
Packit f574b8
	     * Seek and handle cc=address(es) fields.  Excludes Bcc=address(es)
Packit f574b8
	     * as unsafe.  We may append our own cc (below) as a list for the
Packit f574b8
	     * actual mailing.  - FM
Packit f574b8
	     */
Packit f574b8
	    extract_field(&ccaddr, searchpart, "cc=");
Packit f574b8
Packit f574b8
	    /*
Packit f574b8
	     * Seek and handle keywords=term(s) fields.  - FM
Packit f574b8
	     */
Packit f574b8
	    extract_field(&keywords, searchpart, "keywords=");
Packit f574b8
Packit f574b8
	    if (keywords != NULL) {
Packit f574b8
		if (*keywords != '\0') {
Packit f574b8
		    SafeHTUnEscape(keywords);
Packit f574b8
		} else {
Packit f574b8
		    FREE(keywords);
Packit f574b8
		}
Packit f574b8
	    }
Packit f574b8
Packit f574b8
	    FREE(searchpart);
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if (convert_explorer(address)) {
Packit f574b8
	HTAlert(BAD_FORM_MAILTO);
Packit f574b8
	goto cleanup;
Packit f574b8
    }
Packit f574b8
    if (ccaddr != NULL) {
Packit f574b8
	if (convert_explorer(ccaddr)) {
Packit f574b8
	    FREE(ccaddr);
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Unescape the address and ccaddr fields.  - FM
Packit f574b8
     */
Packit f574b8
    SafeHTUnEscape(address);
Packit f574b8
    if (ccaddr != NULL) {
Packit f574b8
	SafeHTUnEscape(ccaddr);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Allow user to edit the default Subject - FM
Packit f574b8
     */
Packit f574b8
    if (subject[0] == '\0') {
Packit f574b8
	if (non_empty(mailto_subject)) {
Packit f574b8
	    LYStrNCpy(subject, mailto_subject, MAX_SUBJECT);
Packit f574b8
	} else {
Packit f574b8
	    sprintf(subject, "mailto:%.63s", address);
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    _statusline(SUBJECT_PROMPT);
Packit f574b8
    if (LYGetStr(subject, FALSE, MAX_SUBJECT, NORECALL) < 0) {
Packit f574b8
	/*
Packit f574b8
	 * User cancelled via ^G. - FM
Packit f574b8
	 */
Packit f574b8
	HTInfoMsg(FORM_MAILTO_CANCELLED);
Packit f574b8
	goto cleanup;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Allow user to specify a self copy via a CC:  entry, if permitted.  - FM
Packit f574b8
     */
Packit f574b8
    if (!LYNoCc) {
Packit f574b8
	sprintf(self, "%.*s", MAX_SUBJECT,
Packit f574b8
		isEmpty(personal_mail_address) ? "" : personal_mail_address);
Packit f574b8
	_statusline("Cc: ");
Packit f574b8
	if (LYGetStr(self, FALSE, MAX_SUBJECT, NORECALL) < 0) {
Packit f574b8
	    /*
Packit f574b8
	     * User cancelled via ^G. - FM
Packit f574b8
	     */
Packit f574b8
	    HTInfoMsg(FORM_MAILTO_CANCELLED);
Packit f574b8
	    goto cleanup;
Packit f574b8
	}
Packit f574b8
	remove_tildes(self);
Packit f574b8
	if (ccaddr == NULL) {
Packit f574b8
	    StrAllocCopy(ccaddr, self);
Packit f574b8
	} else {
Packit f574b8
	    StrAllocCat(ccaddr, ",");
Packit f574b8
	    StrAllocCat(ccaddr, self);
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
#if CAN_PIPE_TO_MAILER
Packit f574b8
    if ((fd = LYPipeToMailer()) == 0) {
Packit f574b8
	HTAlert(FORM_MAILTO_FAILED);
Packit f574b8
	goto cleanup;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if (non_empty(mailto_type)) {
Packit f574b8
	fprintf(fd, "Mime-Version: 1.0\n");
Packit f574b8
	fprintf(fd, "Content-Type: %s\n", mailto_type);
Packit f574b8
    }
Packit f574b8
    fprintf(fd, "To: %s\n", address);
Packit f574b8
    if (non_empty(personal_mail_address))
Packit f574b8
	fprintf(fd, "From: %s\n", personal_mail_address);
Packit f574b8
    if (non_empty(ccaddr))
Packit f574b8
	fprintf(fd, "Cc: %s\n", ccaddr);
Packit f574b8
    fprintf(fd, "Subject: %s\n\n", subject);
Packit f574b8
    if (non_empty(keywords))
Packit f574b8
	fprintf(fd, "Keywords: %s\n", keywords);
Packit f574b8
    _statusline(SENDING_FORM_CONTENT);
Packit f574b8
#else /* e.g., VMS, DOS */
Packit f574b8
    if ((fd = LYOpenTemp(my_tmpfile, ".txt", "w")) == NULL) {
Packit f574b8
	HTAlert(FORM_MAILTO_FAILED);
Packit f574b8
	goto cleanup;
Packit f574b8
    }
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    if (isPMDF) {
Packit f574b8
	FILE *hfd;
Packit f574b8
Packit f574b8
	if ((hfd = LYOpenTemp(hdrfile, ".txt", "w")) == NULL) {
Packit f574b8
	    HTAlert(FORM_MAILTO_FAILED);
Packit f574b8
	    LYCloseTempFP(fd);
Packit f574b8
	    goto cleanup;
Packit f574b8
	}
Packit f574b8
	if (non_empty(mailto_type)) {
Packit f574b8
	    fprintf(hfd, "Mime-Version: 1.0\n");
Packit f574b8
	    fprintf(hfd, "Content-Type: %s\n", mailto_type);
Packit f574b8
	    if (non_empty(personal_mail_address))
Packit f574b8
		fprintf(hfd, "From: %s\n", personal_mail_address);
Packit f574b8
	}
Packit f574b8
	/*
Packit f574b8
	 * For PMDF, put any keywords and the subject in the header file and
Packit f574b8
	 * close it.  - FM
Packit f574b8
	 */
Packit f574b8
	if (non_empty(keywords)) {
Packit f574b8
	    fprintf(hfd, "Keywords: %s\n", keywords);
Packit f574b8
	}
Packit f574b8
	fprintf(hfd, "Subject: %s\n\n", subject);
Packit f574b8
	LYCloseTempFP(hfd);
Packit f574b8
    } else if (mailto_type &&
Packit f574b8
	       !strncasecomp(mailto_type, "multipart/form-data", 19)) {
Packit f574b8
	/*
Packit f574b8
	 * Ugh!  There's no good way to include headers while we're still using
Packit f574b8
	 * "generic" VMS MAIL, so we'll put this in the body of the message.  -
Packit f574b8
	 * FM
Packit f574b8
	 */
Packit f574b8
	fprintf(fd, "X-Content-Type: %s\n\n", mailto_type);
Packit f574b8
    }
Packit f574b8
#else /* !VMS (DOS) */
Packit f574b8
#if USE_BLAT_MAILER
Packit f574b8
    if (mail_is_blat) {
Packit f574b8
	if (strlen(subject) > MAX_SUBJECT)
Packit f574b8
	    subject[MAX_SUBJECT] = '\0';
Packit f574b8
    } else
Packit f574b8
#endif
Packit f574b8
    {
Packit f574b8
	if (non_empty(mailto_type)) {
Packit f574b8
	    fprintf(fd, "Mime-Version: 1.0\n");
Packit f574b8
	    fprintf(fd, "Content-Type: %s\n", mailto_type);
Packit f574b8
	}
Packit f574b8
	fprintf(fd, "To: %s\n", address);
Packit f574b8
	if (non_empty(personal_mail_address))
Packit f574b8
	    fprintf(fd, "From: %s\n", personal_mail_address);
Packit f574b8
	fprintf(fd, "Subject: %.70s\n\n", subject);
Packit f574b8
    }
Packit f574b8
#endif /* VMS */
Packit f574b8
#endif /* CAN_PIPE_TO_MAILER */
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Break up the content into lines with a maximum length of 78.  If the
Packit f574b8
     * ENCTYPE was text/plain, we have physical newlines and should take them
Packit f574b8
     * into account.  Otherwise, the actual newline characters in the content
Packit f574b8
     * are hex escaped.  - FM
Packit f574b8
     */
Packit f574b8
    while ((cp = StrChr(mailto_content, '\n')) != NULL) {
Packit f574b8
	*cp = '\0';
Packit f574b8
	i = 0;
Packit f574b8
	len = (int) strlen(mailto_content);
Packit f574b8
	while (len > 78) {
Packit f574b8
	    LYStrNCpy(buf, &mailto_content[i], 78);
Packit f574b8
	    fprintf(fd, "%s\n", buf);
Packit f574b8
	    i += 78;
Packit f574b8
	    len = (int) strlen(&mailto_content[i]);
Packit f574b8
	}
Packit f574b8
	fprintf(fd, "%s\n", &mailto_content[i]);
Packit f574b8
	mailto_content = (cp + 1);
Packit f574b8
    }
Packit f574b8
    i = 0;
Packit f574b8
    len = (int) strlen(mailto_content);
Packit f574b8
    while (len > 78) {
Packit f574b8
	LYStrNCpy(buf, &mailto_content[i], 78);
Packit f574b8
	fprintf(fd, "%s\n", buf);
Packit f574b8
	i += 78;
Packit f574b8
	len = (int) strlen(&mailto_content[i]);
Packit f574b8
    }
Packit f574b8
    if (len)
Packit f574b8
	fprintf(fd, "%s\n", &mailto_content[i]);
Packit f574b8
Packit f574b8
#if CAN_PIPE_TO_MAILER
Packit f574b8
    pclose(fd);
Packit f574b8
    LYSleepMsg();
Packit f574b8
#else
Packit f574b8
    LYCloseTempFP(fd);
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    /*
Packit f574b8
     * Set the mail command.  - FM
Packit f574b8
     */
Packit f574b8
    if (isPMDF) {
Packit f574b8
	/*
Packit f574b8
	 * Now set up the command.  - FM
Packit f574b8
	 */
Packit f574b8
	HTSprintf0(&cmd,
Packit f574b8
		   "%s %s %s,%s ",
Packit f574b8
		   system_mail,
Packit f574b8
		   system_mail_flags,
Packit f574b8
		   hdrfile,
Packit f574b8
		   my_tmpfile);
Packit f574b8
    } else {
Packit f574b8
	/*
Packit f574b8
	 * For "generic" VMS MAIL, include the subject in the command, and
Packit f574b8
	 * ignore any keywords to minimize risk of them making the line too
Packit f574b8
	 * long or having problem characters.  - FM
Packit f574b8
	 */
Packit f574b8
	HTSprintf0(&cmd,
Packit f574b8
		   "%s %s%s/subject=\"%s\" %s ",
Packit f574b8
		   system_mail,
Packit f574b8
		   system_mail_flags,
Packit f574b8
		   (strncasecomp(system_mail, "MAIL", 4) ? "" : "/noself"),
Packit f574b8
		   subject,
Packit f574b8
		   my_tmpfile);
Packit f574b8
    }
Packit f574b8
    StrAllocCopy(command, cmd);
Packit f574b8
Packit f574b8
    vms_append_addrs(&command, address, "");
Packit f574b8
    if (non_empty(ccaddr)) {
Packit f574b8
	vms_append_addrs(&command, ccaddr, "/CC");
Packit f574b8
    }
Packit f574b8
Packit f574b8
    stop_curses();
Packit f574b8
    printf("%s\n\n$ %s\n\n%s", SENDING_FORM_CONTENT, command, PLEASE_WAIT);
Packit f574b8
    LYSystem(command);		/* Mail (VMS) */
Packit f574b8
    FREE(command);
Packit f574b8
    LYSleepAlert();
Packit f574b8
    start_curses();
Packit f574b8
    (void) LYRemoveTemp(my_tmpfile);
Packit f574b8
    if (isPMDF)
Packit f574b8
	(void) LYRemoveTemp(hdrfile);
Packit f574b8
#else /* DOS */
Packit f574b8
    LYSendMailFile(address,
Packit f574b8
		   my_tmpfile,
Packit f574b8
		   subject,
Packit f574b8
		   ccaddr,
Packit f574b8
		   SENDING_FORM_CONTENT);
Packit f574b8
    (void) LYRemoveTemp(my_tmpfile);
Packit f574b8
#endif /* USE_VMS_MAILER */
Packit f574b8
#endif /* CAN_PIPE_TO_MAILER */
Packit f574b8
Packit f574b8
  cleanup:
Packit f574b8
    FREE(address);
Packit f574b8
    FREE(ccaddr);
Packit f574b8
    FREE(keywords);
Packit f574b8
    return;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 *  mailmsg() sends a message to the owner of the file, if one is defined,
Packit f574b8
 *  telling of errors (i.e., link not available).
Packit f574b8
 */
Packit f574b8
void mailmsg(int cur,
Packit f574b8
	     char *owner_address,
Packit f574b8
	     char *filename,
Packit f574b8
	     char *linkname)
Packit f574b8
{
Packit f574b8
    FILE *fd, *fp;
Packit f574b8
    char *address = NULL;
Packit f574b8
    char *searchpart = NULL;
Packit f574b8
    char *cmd = NULL, *cp;
Packit f574b8
Packit f574b8
#ifdef ALERTMAIL
Packit f574b8
    BOOLEAN skip_parsing = FALSE;
Packit f574b8
#endif
Packit f574b8
#if !CAN_PIPE_TO_MAILER
Packit f574b8
    char *ccaddr;
Packit f574b8
    char subject[128];
Packit f574b8
    char my_tmpfile[LY_MAXPATH];
Packit f574b8
#endif
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    BOOLEAN isPMDF = LYMailPMDF();
Packit f574b8
    char hdrfile[LY_MAXPATH];
Packit f574b8
    char *command = NULL;
Packit f574b8
Packit f574b8
    CTRACE((tfp, "mailmsg(%d, \"%s\", \"%s\", \"%s\")\n", cur,
Packit f574b8
	    NONNULL(owner_address),
Packit f574b8
	    NONNULL(filename),
Packit f574b8
	    NONNULL(linkname)));
Packit f574b8
Packit f574b8
#endif /* VMS */
Packit f574b8
Packit f574b8
    if (!LYSystemMail())
Packit f574b8
	return;
Packit f574b8
Packit f574b8
#ifdef ALERTMAIL
Packit f574b8
    if (owner_address == NULL) {
Packit f574b8
	owner_address = ALERTMAIL;
Packit f574b8
	skip_parsing = TRUE;
Packit f574b8
    }
Packit f574b8
#endif
Packit f574b8
Packit f574b8
    if (isEmpty(owner_address))
Packit f574b8
	return;
Packit f574b8
    if ((cp = StrChr(owner_address, '\n')) != NULL) {
Packit f574b8
#ifdef ALERTMAIL
Packit f574b8
	if (skip_parsing)
Packit f574b8
	    return;		/* invalidly defined - ignore - kw */
Packit f574b8
#else
Packit f574b8
	*cp = '\0';
Packit f574b8
#endif
Packit f574b8
    }
Packit f574b8
    if (!strncasecomp(owner_address, "lynx-dev@", 9)) {
Packit f574b8
	/*
Packit f574b8
	 * Silently refuse sending bad link messages to lynx-dev.
Packit f574b8
	 */
Packit f574b8
	return;
Packit f574b8
    }
Packit f574b8
    StrAllocCopy(address, owner_address);
Packit f574b8
Packit f574b8
#ifdef ALERTMAIL
Packit f574b8
    /*
Packit f574b8
     * If we are using a fixed address given by ALERTMAIL, it is supposed to
Packit f574b8
     * already be in usable form, without URL-isms like ?-searchpart and
Packit f574b8
     * URL-escaping.  So skip some code.  - kw
Packit f574b8
     */
Packit f574b8
    if (!skip_parsing)
Packit f574b8
#endif
Packit f574b8
    {
Packit f574b8
	/*
Packit f574b8
	 * Check for a ?searchpart.  - FM
Packit f574b8
	 */
Packit f574b8
	if ((cp = StrChr(address, '?')) != NULL) {
Packit f574b8
	    StrAllocCopy(searchpart, cp);
Packit f574b8
	    *cp = '\0';
Packit f574b8
	    cp = (searchpart + 1);
Packit f574b8
	    if (*cp != '\0') {
Packit f574b8
		/*
Packit f574b8
		 * Seek and handle to=address(es) fields.
Packit f574b8
		 * Appends to address.  We ignore any other
Packit f574b8
		 * headers in the ?searchpart.  - FM
Packit f574b8
		 */
Packit f574b8
		extract_field(&address, searchpart, "to=");
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
Packit f574b8
	(void) convert_explorer(address);
Packit f574b8
Packit f574b8
	/*
Packit f574b8
	 * Unescape the address field.  - FM
Packit f574b8
	 */
Packit f574b8
	SafeHTUnEscape(address);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if (trim_comma(address)) {
Packit f574b8
	FREE(address);
Packit f574b8
	CTRACE((tfp, "mailmsg: No address in '%s'.\n", owner_address));
Packit f574b8
	return;
Packit f574b8
    }
Packit f574b8
#if CAN_PIPE_TO_MAILER
Packit f574b8
    if ((fd = LYPipeToMailer()) == 0) {
Packit f574b8
	FREE(address);
Packit f574b8
	CTRACE((tfp, "mailmsg: '%s' failed.\n", cmd));
Packit f574b8
	return;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    fprintf(fd, "To: %s\n", address);
Packit f574b8
    fprintf(fd, "Subject: Lynx Error in %s\n", filename);
Packit f574b8
    if (non_empty(personal_mail_address)) {
Packit f574b8
	fprintf(fd, "Cc: %s\n", personal_mail_address);
Packit f574b8
    }
Packit f574b8
    fprintf(fd, "X-URL: %s\n", filename);
Packit f574b8
    fprintf(fd, "X-Mailer: %s, Version %s\n\n", LYNX_NAME, LYNX_VERSION);
Packit f574b8
#else
Packit f574b8
    if ((fd = LYOpenTemp(my_tmpfile, ".txt", "w")) == NULL) {
Packit f574b8
	CTRACE((tfp, "mailmsg: Could not fopen '%s'.\n", my_tmpfile));
Packit f574b8
	FREE(address);
Packit f574b8
	return;
Packit f574b8
    }
Packit f574b8
    sprintf(subject, "Lynx Error in %.56s", filename);
Packit f574b8
    ccaddr = personal_mail_address;
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    if (isPMDF) {
Packit f574b8
	FILE *hfd;
Packit f574b8
Packit f574b8
	if ((hfd = LYOpenTemp(hdrfile, ".txt", "w")) == NULL) {
Packit f574b8
	    CTRACE((tfp, "mailmsg: Could not fopen '%s'.\n", hdrfile));
Packit f574b8
	    FREE(address);
Packit f574b8
	    return;
Packit f574b8
	}
Packit f574b8
Packit f574b8
	if (non_empty(personal_mail_address)) {
Packit f574b8
	    fprintf(fd, "Cc: %s\n", personal_mail_address);
Packit f574b8
	}
Packit f574b8
	fprintf(fd, "X-URL: %s\n", filename);
Packit f574b8
	fprintf(fd, "X-Mailer: %s, Version %s\n\n", LYNX_NAME, LYNX_VERSION);
Packit f574b8
	/*
Packit f574b8
	 * For PMDF, put the subject in the header file and close it.  - FM
Packit f574b8
	 */
Packit f574b8
	fprintf(hfd, "Subject: Lynx Error in %.56s\n\n", filename);
Packit f574b8
	LYCloseTempFP(hfd);
Packit f574b8
    }
Packit f574b8
#endif /* USE_VMS_MAILER */
Packit f574b8
#endif /* CAN_PIPE_TO_MAILER */
Packit f574b8
Packit f574b8
    fprintf(fd, gettext("The link   %s :?: %s \n"),
Packit f574b8
	    links[cur].lname, links[cur].target);
Packit f574b8
    fprintf(fd, gettext("called \"%s\"\n"), LYGetHiliteStr(cur, 0));
Packit f574b8
    fprintf(fd, gettext("in the file \"%s\" called \"%s\"\n"), filename, linkname);
Packit f574b8
    fprintf(fd, "%s\n\n", gettext("was requested but was not available."));
Packit f574b8
    fprintf(fd, "%s\n\n", gettext("Thought you might want to know."));
Packit f574b8
Packit f574b8
    fprintf(fd, "%s\n", gettext("This message was automatically generated by"));
Packit f574b8
    fprintf(fd, "%s %s", LYNX_NAME, LYNX_VERSION);
Packit f574b8
    if ((LynxSigFile != NULL) &&
Packit f574b8
	(fp = fopen(LynxSigFile, TXT_R)) != NULL) {
Packit f574b8
	fputs("-- \n", fd);
Packit f574b8
	while (LYSafeGets(&cmd, fp) != NULL)
Packit f574b8
	    fputs(cmd, fd);
Packit f574b8
	LYCloseInput(fp);
Packit f574b8
    }
Packit f574b8
#if CAN_PIPE_TO_MAILER
Packit f574b8
    pclose(fd);
Packit f574b8
#else
Packit f574b8
    LYCloseTempFP(fd);
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    if (isPMDF) {
Packit f574b8
	/*
Packit f574b8
	 * Now set up the command.  - FM
Packit f574b8
	 */
Packit f574b8
	HTSprintf0(&command,
Packit f574b8
		   "%s %s %s,%s ",
Packit f574b8
		   system_mail,
Packit f574b8
		   system_mail_flags,
Packit f574b8
		   hdrfile,
Packit f574b8
		   my_tmpfile);
Packit f574b8
    } else {
Packit f574b8
	/*
Packit f574b8
	 * For "generic" VMS MAIL, include the subject in the command.  - FM
Packit f574b8
	 */
Packit f574b8
	HTSprintf0(&command,
Packit f574b8
		   "%s %s/self/subject=\"Lynx Error in %.56s\" %s ",
Packit f574b8
		   system_mail,
Packit f574b8
		   system_mail_flags,
Packit f574b8
		   filename,
Packit f574b8
		   my_tmpfile);
Packit f574b8
    }
Packit f574b8
    vms_append_addrs(&command, address, "");
Packit f574b8
Packit f574b8
    LYSystem(command);		/* VMS */
Packit f574b8
    FREE(command);
Packit f574b8
    FREE(cmd);
Packit f574b8
    (void) LYRemoveTemp(my_tmpfile);
Packit f574b8
    if (isPMDF) {
Packit f574b8
	(void) LYRemoveTemp(hdrfile);
Packit f574b8
    }
Packit f574b8
#else /* DOS */
Packit f574b8
    LYSendMailFile(address,
Packit f574b8
		   my_tmpfile,
Packit f574b8
		   subject,
Packit f574b8
		   ccaddr,
Packit f574b8
		   "");
Packit f574b8
    (void) LYRemoveTemp(my_tmpfile);
Packit f574b8
#endif /* USE_VMS_MAILER */
Packit f574b8
#endif /* CAN_PIPE_TO_MAILER */
Packit f574b8
Packit f574b8
    if (traversal) {
Packit f574b8
	FILE *ofp;
Packit f574b8
Packit f574b8
	if ((ofp = LYAppendToTxtFile(TRAVERSE_ERRORS)) == NULL) {
Packit f574b8
	    if ((ofp = LYNewTxtFile(TRAVERSE_ERRORS)) == NULL) {
Packit f574b8
		perror(NOOPEN_TRAV_ERR_FILE);
Packit f574b8
		exit_immediately(EXIT_FAILURE);
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
Packit f574b8
	fprintf(ofp, "%s\t%s \tin %s\n",
Packit f574b8
		links[cur].lname, links[cur].target, filename);
Packit f574b8
	LYCloseOutput(ofp);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    FREE(address);
Packit f574b8
    return;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 *  reply_by_mail() invokes sendmail on Unix or mail on VMS to send
Packit f574b8
 *  a comment from the users to the owner
Packit f574b8
 */
Packit f574b8
void reply_by_mail(char *mail_address,
Packit f574b8
		   char *filename,
Packit f574b8
		   const char *title,
Packit f574b8
		   const char *refid)
Packit f574b8
{
Packit f574b8
    char user_input[LINESIZE];
Packit f574b8
    FILE *fd, *fp;
Packit f574b8
    const char *label = NULL;
Packit f574b8
    char *from_address = NULL;
Packit f574b8
    char *cc_address = NULL;
Packit f574b8
    char *to_address = NULL;
Packit f574b8
    char *the_subject = NULL;
Packit f574b8
    char *ccaddr = NULL;
Packit f574b8
    char *keywords = NULL;
Packit f574b8
    char *searchpart = NULL;
Packit f574b8
    char *body = NULL;
Packit f574b8
    char *cp = NULL, *cp1 = NULL;
Packit f574b8
    int i;
Packit f574b8
    int c = 0;			/* user input */
Packit f574b8
    char my_tmpfile[LY_MAXPATH];
Packit f574b8
    char default_subject[MAX_SUBJECT + 10];
Packit f574b8
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    char *command = NULL;
Packit f574b8
    BOOLEAN isPMDF = LYMailPMDF();
Packit f574b8
    char hdrfile[LY_MAXPATH];
Packit f574b8
    FILE *hfd = 0;
Packit f574b8
Packit f574b8
#else
Packit f574b8
#if !CAN_PIPE_TO_MAILER
Packit f574b8
    char tmpfile2[LY_MAXPATH];
Packit f574b8
#endif
Packit f574b8
    char buf[4096];		/* 512 */
Packit f574b8
    char *header = NULL;
Packit f574b8
    size_t nbytes;
Packit f574b8
#endif /* USE_VMS_MAILER */
Packit f574b8
Packit f574b8
    CTRACE((tfp, "reply_by_mail(\"%s\", \"%s\", \"%s\", \"%s\")\n",
Packit f574b8
	    NONNULL(mail_address),
Packit f574b8
	    NONNULL(filename),
Packit f574b8
	    NONNULL(title),
Packit f574b8
	    NONNULL(refid)));
Packit f574b8
Packit f574b8
    term_letter = FALSE;
Packit f574b8
Packit f574b8
    if (!LYSystemMail())
Packit f574b8
	return;
Packit f574b8
Packit f574b8
    if (isEmpty(mail_address)) {
Packit f574b8
	HTAlert(NO_ADDRESS_IN_MAILTO_URL);
Packit f574b8
	return;
Packit f574b8
    }
Packit f574b8
    StrAllocCopy(to_address, mail_address);
Packit f574b8
Packit f574b8
    if ((fd = LYOpenTemp(my_tmpfile, ".txt", "w")) == NULL) {
Packit f574b8
	HTAlert(MAILTO_URL_TEMPOPEN_FAILED);
Packit f574b8
	return;
Packit f574b8
    }
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    if (isPMDF) {
Packit f574b8
	if ((hfd = LYOpenTemp(hdrfile, ".txt", "w")) == NULL) {
Packit f574b8
	    HTAlert(MAILTO_URL_TEMPOPEN_FAILED);
Packit f574b8
	    return;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
#endif /* VMS */
Packit f574b8
    default_subject[0] = '\0';
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Check for a ?searchpart.  - FM
Packit f574b8
     */
Packit f574b8
    if ((cp = StrChr(to_address, '?')) != NULL) {
Packit f574b8
	StrAllocCopy(searchpart, cp);
Packit f574b8
	*cp = '\0';
Packit f574b8
	cp = (searchpart + 1);
Packit f574b8
	if (*cp != '\0') {
Packit f574b8
	    /*
Packit f574b8
	     * Seek and handle a subject=foo.  - FM
Packit f574b8
	     */
Packit f574b8
	    extract_subject(default_subject, searchpart);
Packit f574b8
Packit f574b8
	    /*
Packit f574b8
	     * Seek and handle to=address(es) fields.  Appends to address.  -
Packit f574b8
	     * FM
Packit f574b8
	     */
Packit f574b8
	    extract_field(&to_address, searchpart, "to=");
Packit f574b8
Packit f574b8
	    /*
Packit f574b8
	     * Seek and handle cc=address(es) fields.  Excludes Bcc=address(es)
Packit f574b8
	     * as unsafe.  We may append our own cc (below) as a list for the
Packit f574b8
	     * actual mailing.  - FM
Packit f574b8
	     */
Packit f574b8
	    extract_field(&ccaddr, searchpart, "cc=");
Packit f574b8
Packit f574b8
	    /*
Packit f574b8
	     * Seek and handle keywords=term(s) fields.  - FM
Packit f574b8
	     */
Packit f574b8
	    extract_field(&keywords, searchpart, "keywords=");
Packit f574b8
Packit f574b8
	    if (keywords != NULL) {
Packit f574b8
		if (*keywords != '\0') {
Packit f574b8
		    SafeHTUnEscape(keywords);
Packit f574b8
		} else {
Packit f574b8
		    FREE(keywords);
Packit f574b8
		}
Packit f574b8
	    }
Packit f574b8
Packit f574b8
	    /*
Packit f574b8
	     * Seek and handle body=foo fields.  - FM
Packit f574b8
	     */
Packit f574b8
	    extract_body(&body, searchpart);
Packit f574b8
Packit f574b8
	    FREE(searchpart);
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if (convert_explorer(to_address)) {
Packit f574b8
	HTAlert(NO_ADDRESS_IN_MAILTO_URL);
Packit f574b8
	goto cancelled;
Packit f574b8
    }
Packit f574b8
    if (ccaddr != NULL) {
Packit f574b8
	if (convert_explorer(ccaddr)) {
Packit f574b8
	    FREE(ccaddr);
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Unescape the address and ccaddr fields.  - FM
Packit f574b8
     */
Packit f574b8
    SafeHTUnEscape(to_address);
Packit f574b8
    if (ccaddr != NULL) {
Packit f574b8
	SafeHTUnEscape(ccaddr);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Set the default subject.  - FM
Packit f574b8
     */
Packit f574b8
    if ((default_subject[0] == '\0') && non_empty(title)) {
Packit f574b8
	LYStrNCpy(default_subject, title, MAX_SUBJECT);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Use ^G to cancel mailing of comment and don't let SIGINTs exit lynx.
Packit f574b8
     */
Packit f574b8
    signal(SIGINT, terminate_letter);
Packit f574b8
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    if (isPMDF || !body) {
Packit f574b8
	/*
Packit f574b8
	 * Put the X-URL and X-Mailer lines in the hdrfile for PMDF or
Packit f574b8
	 * my_tmpfile for VMS MAIL.  - FM
Packit f574b8
	 */
Packit f574b8
	fprintf((isPMDF ? hfd : fd),
Packit f574b8
		"X-URL: %s%s\n",
Packit f574b8
		isEmpty(filename) ? STR_MAILTO_URL : filename,
Packit f574b8
		isEmpty(filename) ? to_address : "");
Packit f574b8
	fprintf((isPMDF ? hfd : fd),
Packit f574b8
		"X-Mailer: %s, Version %s\n", LYNX_NAME, LYNX_VERSION);
Packit f574b8
#ifdef NO_ANONYMOUS_EMAIL
Packit f574b8
	if (!isPMDF) {
Packit f574b8
	    fprintf(fd, "\n");
Packit f574b8
	}
Packit f574b8
#endif /* NO_ANONYMOUS_EMAIL */
Packit f574b8
    }
Packit f574b8
#else /* Unix/DOS/Windows */
Packit f574b8
    /*
Packit f574b8
     * Put the To:  line in the header.
Packit f574b8
     */
Packit f574b8
#ifndef DOSPATH
Packit f574b8
    HTSprintf(&header, "To: %s\n", to_address);
Packit f574b8
#endif
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Put the Mime-Version, Content-Type and Content-Transfer-Encoding in the
Packit f574b8
     * header.  This assumes that the same character set is used for composing
Packit f574b8
     * the mail which is currently selected as display character set...  Don't
Packit f574b8
     * send a charset if we have a CJK character set selected, since it may not
Packit f574b8
     * be appropriate for mail...  Also don't use an unofficial "x-" charset. 
Packit f574b8
     * Also if the charset would be "us-ascii" (7-bit replacements selected,
Packit f574b8
     * don't send any MIME headers.  - kw
Packit f574b8
     */
Packit f574b8
    if (strncasecomp(LYCharSet_UC[current_char_set].MIMEname,
Packit f574b8
		     "us-ascii", 8) != 0) {
Packit f574b8
	StrAllocCat(header, "Mime-Version: 1.0\n");
Packit f574b8
	if (!LYHaveCJKCharacterSet &&
Packit f574b8
	    strncasecomp(LYCharSet_UC[current_char_set].MIMEname, "x-", 2)
Packit f574b8
	    != 0) {
Packit f574b8
	    HTSprintf(&header, "Content-Type: " STR_PLAINTEXT "; charset=%s\n",
Packit f574b8
		      LYCharSet_UC[current_char_set].MIMEname);
Packit f574b8
	}
Packit f574b8
	StrAllocCat(header, "Content-Transfer-Encoding: 8bit\n");
Packit f574b8
    }
Packit f574b8
    /*
Packit f574b8
     * Put the X-URL and X-Mailer lines in the header.
Packit f574b8
     */
Packit f574b8
    if (non_empty(filename)) {
Packit f574b8
	HTSprintf(&header, "X-URL: %s\n", filename);
Packit f574b8
    } else {
Packit f574b8
	HTSprintf(&header, "X-URL: mailto:%s\n", to_address);
Packit f574b8
    }
Packit f574b8
    HTSprintf(&header, "X-Mailer: %s, Version %s\n", LYNX_NAME, LYNX_VERSION);
Packit f574b8
Packit f574b8
    if (non_empty(refid)) {
Packit f574b8
	HTSprintf(&header, "In-Reply-To: <%s>\n", refid);
Packit f574b8
    }
Packit f574b8
#endif /* VMS */
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Clear the screen and inform the user.
Packit f574b8
     */
Packit f574b8
    LYclear();
Packit f574b8
    LYmove(2, 0);
Packit f574b8
    scrollok(LYwin, TRUE);	/* Enable scrolling. */
Packit f574b8
    if (body)
Packit f574b8
	LYaddstr(SENDING_MESSAGE_WITH_BODY_TO);
Packit f574b8
    else
Packit f574b8
	LYaddstr(SENDING_COMMENT_TO);
Packit f574b8
    show_addresses(to_address);
Packit f574b8
    if (
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
	   (isPMDF == TRUE) &&
Packit f574b8
#endif /* VMS */
Packit f574b8
	   (cp = ccaddr) != NULL) {
Packit f574b8
	if (StrChr(cp, ',') != NULL) {
Packit f574b8
	    LYaddstr(WITH_COPIES_TO);
Packit f574b8
	} else {
Packit f574b8
	    LYaddstr(WITH_COPY_TO);
Packit f574b8
	}
Packit f574b8
	show_addresses(ccaddr);
Packit f574b8
    }
Packit f574b8
    LYaddstr(CTRL_G_TO_CANCEL_SEND);
Packit f574b8
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    if (isPMDF || !body) {
Packit f574b8
#endif /* USE_VMS_MAILER */
Packit f574b8
#ifndef NO_ANONYMOUS_EMAIL
Packit f574b8
	/*
Packit f574b8
	 * Get the user's personal name.
Packit f574b8
	 */
Packit f574b8
	LYaddstr(ENTER_NAME_OR_BLANK);
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
	if (isPMDF) {
Packit f574b8
	    label = "Personal_name";
Packit f574b8
	} else {
Packit f574b8
	    label = "X-Personal_name";
Packit f574b8
	}
Packit f574b8
#else
Packit f574b8
	label = "X-Personal_Name";
Packit f574b8
#endif /* USE_VMS_MAILER */
Packit f574b8
	if (!header_prompt(label, &personal_mail_name, LINESIZE)) {
Packit f574b8
	    goto cancelled;
Packit f574b8
	}
Packit f574b8
	if (*personal_mail_name) {
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
	    fprintf((isPMDF ? hfd : fd), "%s: %s\n", label, personal_mail_name);
Packit f574b8
#else
Packit f574b8
	    HTSprintf(&header, "%s: %s\n", label, personal_mail_name);
Packit f574b8
#endif /* VMS */
Packit f574b8
	}
Packit f574b8
Packit f574b8
	/*
Packit f574b8
	 * Get the user's return address.
Packit f574b8
	 */
Packit f574b8
	LYaddstr(ENTER_MAIL_ADDRESS_OR_OTHER);
Packit f574b8
	LYaddstr(MEANS_TO_CONTACT_FOR_RESPONSE);
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
	if (isPMDF) {
Packit f574b8
	    label = "From";
Packit f574b8
	} else {
Packit f574b8
	    label = "X-From";
Packit f574b8
	}
Packit f574b8
#else
Packit f574b8
	label = "From";
Packit f574b8
#endif /* VMS */
Packit f574b8
	/* Add the personal mail address if there is one. */
Packit f574b8
	if (non_empty(personal_mail_address))
Packit f574b8
	    StrAllocCopy(from_address, personal_mail_address);
Packit f574b8
	if (!header_prompt(label, &from_address, LINESIZE)) {
Packit f574b8
	    goto cancelled;
Packit f574b8
	}
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
	if (*from_address) {
Packit f574b8
	    fprintf(isPMDF ? hfd : fd, "%s: %s\n", label, from_address);
Packit f574b8
	}
Packit f574b8
	if (!isPMDF) {
Packit f574b8
	    fprintf(fd, "\n");
Packit f574b8
	}
Packit f574b8
#else
Packit f574b8
	HTSprintf(&header, "%s: %s\n", label, from_address);
Packit f574b8
#endif /* USE_VMS_MAILER */
Packit f574b8
#endif /* !NO_ANONYMOUS_EMAIL */
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    }
Packit f574b8
#endif /* USE_VMS_MAILER */
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Get the subject line.
Packit f574b8
     */
Packit f574b8
    LYaddstr(ENTER_SUBJECT_LINE);
Packit f574b8
    label = "Subject";
Packit f574b8
    if (*default_subject) {
Packit f574b8
	StrAllocCopy(the_subject, default_subject);
Packit f574b8
    } else if (non_empty(filename)) {
Packit f574b8
	HTSprintf(&the_subject, "%s", filename);
Packit f574b8
    } else {
Packit f574b8
	HTSprintf(&the_subject, "mailto:%s", to_address);
Packit f574b8
    }
Packit f574b8
    if (!header_prompt(label, &the_subject, MAX_SUBJECT)) {
Packit f574b8
	goto cancelled;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Offer a CC line, if permitted.  - FM
Packit f574b8
     */
Packit f574b8
    if (!LYNoCc) {
Packit f574b8
	LYaddstr(ENTER_ADDRESS_FOR_CC);
Packit f574b8
	LYaddstr(BLANK_FOR_NO_COPY);
Packit f574b8
	if (non_empty(personal_mail_address))
Packit f574b8
	    StrAllocCopy(cc_address, personal_mail_address);
Packit f574b8
	if (!header_prompt("Cc", &cc_address, LINESIZE)) {
Packit f574b8
	    goto cancelled;
Packit f574b8
	}
Packit f574b8
	comma_append(&ccaddr, cc_address);
Packit f574b8
    }
Packit f574b8
#if !USE_VMS_MAILER
Packit f574b8
    HTSprintf(&header, "%s: %s\n", label, the_subject);
Packit f574b8
#if !CAN_PIPE_TO_MAILER
Packit f574b8
    if (*to_address) {
Packit f574b8
	HTSprintf(&header, "To: %s\n", to_address);
Packit f574b8
    }
Packit f574b8
#endif
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Add the Cc:  header.  - FM
Packit f574b8
     */
Packit f574b8
    if (non_empty(ccaddr)) {
Packit f574b8
	HTSprintf(&header, "Cc: %s\n", ccaddr);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Add the Keywords:  header.  - FM
Packit f574b8
     */
Packit f574b8
    if (non_empty(keywords)) {
Packit f574b8
	HTSprintf(&header, "Keywords: %s\n", keywords);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Terminate the header.
Packit f574b8
     */
Packit f574b8
    StrAllocCat(header, "\n");
Packit f574b8
    CTRACE((tfp, "**header==\n%s", header));
Packit f574b8
#endif /* !VMS */
Packit f574b8
Packit f574b8
    if (!no_editor && non_empty(editor)) {
Packit f574b8
Packit f574b8
	if (body) {
Packit f574b8
	    cp1 = body;
Packit f574b8
	    while ((cp = StrChr(cp1, '\n')) != NULL) {
Packit f574b8
		*cp++ = '\0';
Packit f574b8
		fprintf(fd, "%s\n", cp1);
Packit f574b8
		cp1 = cp;
Packit f574b8
	    }
Packit f574b8
	} else if (strcmp(HTLoadedDocumentURL(), "")) {
Packit f574b8
	    /*
Packit f574b8
	     * Ask if the user wants to include the original message.
Packit f574b8
	     */
Packit f574b8
	    BOOLEAN is_preparsed = (BOOL) (LYPreparsedSource &&
Packit f574b8
					   HTisDocumentSource());
Packit f574b8
Packit f574b8
	    if (HTConfirm(is_preparsed
Packit f574b8
			  ? INC_PREPARSED_MSG_PROMPT
Packit f574b8
			  : INC_ORIG_MSG_PROMPT) == YES) {
Packit f574b8
		print_wwwfile_to_fd(fd, TRUE, (BOOL) !is_preparsed);
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
	LYCloseTempFP(fd);	/* Close the tmpfile. */
Packit f574b8
	scrollok(LYwin, FALSE);	/* Stop scrolling.    */
Packit f574b8
Packit f574b8
	if (term_letter || LYCharIsINTERRUPT(c))
Packit f574b8
	    goto cleanup;
Packit f574b8
Packit f574b8
	/*
Packit f574b8
	 * Spawn the users editor on the mail file
Packit f574b8
	 */
Packit f574b8
	edit_temporary_file(my_tmpfile, "", SPAWNING_EDITOR_FOR_MAIL);
Packit f574b8
Packit f574b8
    } else if (body) {
Packit f574b8
	/*
Packit f574b8
	 * Let user review the body.  - FM
Packit f574b8
	 */
Packit f574b8
	LYclear();
Packit f574b8
	LYmove(0, 0);
Packit f574b8
	LYaddstr(REVIEW_MESSAGE_BODY);
Packit f574b8
	LYrefresh();
Packit f574b8
	cp1 = body;
Packit f574b8
	i = (LYlines - 5);
Packit f574b8
	while ((cp = StrChr(cp1, '\n')) != NULL) {
Packit f574b8
	    if (i <= 0) {
Packit f574b8
		LYaddstr(RETURN_TO_CONTINUE);
Packit f574b8
		LYrefresh();
Packit f574b8
		c = LYgetch();
Packit f574b8
		LYaddstr("\n");
Packit f574b8
		if (term_letter || LYCharIsINTERRUPT(c)) {
Packit f574b8
		    goto cancelled;
Packit f574b8
		}
Packit f574b8
		i = (LYlines - 2);
Packit f574b8
	    }
Packit f574b8
	    *cp++ = '\0';
Packit f574b8
	    fprintf(fd, "%s\n", cp1);
Packit f574b8
	    LYaddstr(cp1);
Packit f574b8
	    LYaddstr("\n");
Packit f574b8
	    cp1 = cp;
Packit f574b8
	    i--;
Packit f574b8
	}
Packit f574b8
	while (i >= 0) {
Packit f574b8
	    LYaddstr("\n");
Packit f574b8
	    i--;
Packit f574b8
	}
Packit f574b8
	LYrefresh();
Packit f574b8
	LYCloseTempFP(fd);	/* Close the tmpfile.     */
Packit f574b8
	scrollok(LYwin, FALSE);	/* Stop scrolling.        */
Packit f574b8
Packit f574b8
    } else {
Packit f574b8
	/*
Packit f574b8
	 * Use the internal line editor for the message.
Packit f574b8
	 */
Packit f574b8
	LYaddstr(ENTER_MESSAGE_BELOW);
Packit f574b8
	LYaddstr(ENTER_PERIOD_WHEN_DONE_A);
Packit f574b8
	LYaddstr(ENTER_PERIOD_WHEN_DONE_B);
Packit f574b8
	LYaddstr(CTRL_G_TO_CANCEL_SEND);
Packit f574b8
	LYaddstr("\n\n");
Packit f574b8
	LYrefresh();
Packit f574b8
	*user_input = '\0';
Packit f574b8
	if (LYGetStr(user_input, FALSE, sizeof(user_input), NORECALL) < 0 ||
Packit f574b8
	    term_letter || STREQ(user_input, ".")) {
Packit f574b8
	    goto cancelled;
Packit f574b8
	}
Packit f574b8
Packit f574b8
	while (!STREQ(user_input, ".") && !term_letter) {
Packit f574b8
	    LYaddstr("\n");
Packit f574b8
	    remove_tildes(user_input);
Packit f574b8
	    fprintf(fd, "%s\n", user_input);
Packit f574b8
	    *user_input = '\0';
Packit f574b8
	    if (LYGetStr(user_input, FALSE,
Packit f574b8
			 sizeof(user_input), NORECALL) < 0) {
Packit f574b8
		goto cancelled;
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
Packit f574b8
	fprintf(fd, "\n");	/* Terminate the message. */
Packit f574b8
	LYCloseTempFP(fd);	/* Close the tmpfile.     */
Packit f574b8
	scrollok(LYwin, FALSE);	/* Stop scrolling.        */
Packit f574b8
    }
Packit f574b8
Packit f574b8
#if !USE_VMS_MAILER
Packit f574b8
    /*
Packit f574b8
     * Ignore CTRL-C on this last question.
Packit f574b8
     */
Packit f574b8
    signal(SIGINT, SIG_IGN);
Packit f574b8
#endif /* !VMS */
Packit f574b8
    LYStatusLine = (LYlines - 1);
Packit f574b8
    c = HTConfirm(body ? SEND_MESSAGE_PROMPT : SEND_COMMENT_PROMPT);
Packit f574b8
    LYStatusLine = -1;
Packit f574b8
    if (c != YES) {
Packit f574b8
	LYclear();		/* clear the screen */
Packit f574b8
	goto cleanup;
Packit f574b8
    }
Packit f574b8
    if ((body == NULL && non_empty(LynxSigFile)) &&
Packit f574b8
	(fp = fopen(LynxSigFile, TXT_R)) != NULL) {
Packit f574b8
	LYStatusLine = (LYlines - 1);
Packit f574b8
	if (term_letter) {
Packit f574b8
	    _user_message(APPEND_SIG_FILE, LynxSigFile);
Packit f574b8
	    c = 0;
Packit f574b8
	} else {
Packit f574b8
	    char *msg = NULL;
Packit f574b8
Packit f574b8
	    HTSprintf0(&msg, APPEND_SIG_FILE, LynxSigFile);
Packit f574b8
	    c = HTConfirm(msg);
Packit f574b8
	    FREE(msg);
Packit f574b8
	}
Packit f574b8
	LYStatusLine = -1;
Packit f574b8
	if (c == YES) {
Packit f574b8
	    if ((fd = fopen(my_tmpfile, TXT_A)) != NULL) {
Packit f574b8
		char *buffer = NULL;
Packit f574b8
Packit f574b8
		fputs("-- \n", fd);
Packit f574b8
		while (LYSafeGets(&buffer, fp) != NULL) {
Packit f574b8
		    fputs(buffer, fd);
Packit f574b8
		}
Packit f574b8
		LYCloseOutput(fd);
Packit f574b8
		FREE(buffer);
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
	LYCloseInput(fp);
Packit f574b8
    }
Packit f574b8
    LYclear();			/* Clear the screen. */
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Send the message.
Packit f574b8
     */
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    /*
Packit f574b8
     * Set the mail command.  - FM
Packit f574b8
     */
Packit f574b8
    if (isPMDF) {
Packit f574b8
	/*
Packit f574b8
	 * For PMDF, put any keywords and the subject in the header file and
Packit f574b8
	 * close it.  - FM
Packit f574b8
	 */
Packit f574b8
	if (non_empty(keywords)) {
Packit f574b8
	    fprintf(hfd, "Keywords: %s\n", keywords);
Packit f574b8
	}
Packit f574b8
	fprintf(hfd, "Subject: %s\n\n", the_subject);
Packit f574b8
	LYCloseTempFP(hfd);
Packit f574b8
	/*
Packit f574b8
	 * Now set up the command.  - FM
Packit f574b8
	 */
Packit f574b8
	HTSprintf0(&command, "%s %s %s,%s ",
Packit f574b8
		   system_mail,
Packit f574b8
		   system_mail_flags,
Packit f574b8
		   hdrfile,
Packit f574b8
		   my_tmpfile);
Packit f574b8
    } else {
Packit f574b8
	/*
Packit f574b8
	 * For "generic" VMS MAIL, include the subject in the command, and
Packit f574b8
	 * ignore any keywords to minimize risk of them making the line too
Packit f574b8
	 * long or having problem characters.  - FM
Packit f574b8
	 */
Packit f574b8
	HTSprintf0(&command, "%s %s%s/subject=\"%s\" %s ",
Packit f574b8
		   system_mail,
Packit f574b8
		   system_mail_flags,
Packit f574b8
		   (strncasecomp(system_mail, "MAIL", 4) ? "" : "/noself"),
Packit f574b8
		   the_subject,
Packit f574b8
		   my_tmpfile);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    vms_append_addrs(&command, to_address, "");
Packit f574b8
    if (non_empty(ccaddr)) {
Packit f574b8
	vms_append_addrs(&command, ccaddr, "/CC");
Packit f574b8
    }
Packit f574b8
Packit f574b8
    stop_curses();
Packit f574b8
    printf("%s\n\n$ %s\n\n%s", SENDING_COMMENT, command, PLEASE_WAIT);
Packit f574b8
    LYSystem(command);		/* SENDING COMMENT (VMS) */
Packit f574b8
    FREE(command);
Packit f574b8
    LYSleepAlert();
Packit f574b8
    start_curses();
Packit f574b8
#else /* Unix/DOS/Windows */
Packit f574b8
    /*
Packit f574b8
     * Send the tmpfile into sendmail.
Packit f574b8
     */
Packit f574b8
    _statusline(SENDING_YOUR_MSG);
Packit f574b8
#if CAN_PIPE_TO_MAILER
Packit f574b8
    signal(SIGINT, SIG_IGN);
Packit f574b8
    if ((fp = LYPipeToMailer()) == 0) {
Packit f574b8
	HTInfoMsg(CANCELLED);
Packit f574b8
    }
Packit f574b8
#else
Packit f574b8
    if ((fp = LYOpenTemp(tmpfile2, ".txt", "w")) == NULL) {
Packit f574b8
	HTAlert(MAILTO_URL_TEMPOPEN_FAILED);
Packit f574b8
    }
Packit f574b8
#endif /* CAN_PIPE_TO_MAILER */
Packit f574b8
    if (fp != 0) {
Packit f574b8
	fd = fopen(my_tmpfile, TXT_R);
Packit f574b8
	if (fd == NULL) {
Packit f574b8
	    HTInfoMsg(CANCELLED);
Packit f574b8
#if CAN_PIPE_TO_MAILER
Packit f574b8
	    pclose(fp);
Packit f574b8
#else
Packit f574b8
	    LYCloseTempFP(fp);
Packit f574b8
#endif /* CAN_PIPE_TO_MAILER */
Packit f574b8
	} else {
Packit f574b8
#if USE_BLAT_MAILER
Packit f574b8
	    if (!mail_is_blat)
Packit f574b8
		fputs(header, fp);
Packit f574b8
#else
Packit f574b8
	    fputs(header, fp);
Packit f574b8
#endif
Packit f574b8
	    while ((nbytes = fread(buf, (size_t) 1, sizeof(buf), fd)) != 0) {
Packit f574b8
		if (fwrite(buf, (size_t) 1, (size_t) nbytes, fp) < nbytes)
Packit f574b8
		    break;
Packit f574b8
	    }
Packit f574b8
#if CAN_PIPE_TO_MAILER
Packit f574b8
	    pclose(fp);
Packit f574b8
#else
Packit f574b8
	    LYCloseTempFP(fp);	/* Close the tmpfile. */
Packit f574b8
	    LYSendMailFile(to_address,
Packit f574b8
			   tmpfile2,
Packit f574b8
			   the_subject,
Packit f574b8
			   ccaddr,
Packit f574b8
			   SENDING_COMMENT);
Packit f574b8
	    (void) LYRemoveTemp(tmpfile2);	/* Delete the tmpfile. */
Packit f574b8
#endif /* CAN_PIPE_TO_MAILER */
Packit f574b8
	    LYCloseInput(fd);	/* Close the tmpfile. */
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
#endif /* USE_VMS_MAILER */
Packit f574b8
    goto cleanup;
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Come here to cleanup and exit.
Packit f574b8
     */
Packit f574b8
  cancelled:
Packit f574b8
    HTInfoMsg(CANCELLED);
Packit f574b8
    LYCloseTempFP(fd);		/* Close the tmpfile.   */
Packit f574b8
    scrollok(LYwin, FALSE);	/* Stop scrolling.      */
Packit f574b8
  cleanup:
Packit f574b8
    signal(SIGINT, cleanup_sig);
Packit f574b8
    term_letter = FALSE;
Packit f574b8
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
    while (LYRemoveTemp(my_tmpfile) == 0) ;	/* Delete the tmpfile(s). */
Packit f574b8
    if (isPMDF) {
Packit f574b8
	(void) LYRemoveTemp(hdrfile);	/* Delete the hdrfile. */
Packit f574b8
    }
Packit f574b8
#else
Packit f574b8
    FREE(header);
Packit f574b8
    (void) LYRemoveTemp(my_tmpfile);	/* Delete the tmpfile. */
Packit f574b8
#endif /* VMS */
Packit f574b8
Packit f574b8
    FREE(from_address);
Packit f574b8
    FREE(the_subject);
Packit f574b8
    FREE(cc_address);
Packit f574b8
    FREE(to_address);
Packit f574b8
    FREE(ccaddr);
Packit f574b8
    FREE(keywords);
Packit f574b8
    FREE(body);
Packit f574b8
    return;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Check that we have configured values for system mailer.
Packit f574b8
 */
Packit f574b8
BOOLEAN LYSystemMail(void)
Packit f574b8
{
Packit f574b8
    if (isEmpty(system_mail) || !strcmp(system_mail, "unknown")) {
Packit f574b8
	HTAlert(gettext("No system mailer configured"));
Packit f574b8
	return FALSE;
Packit f574b8
    }
Packit f574b8
    return TRUE;
Packit f574b8
}