/*
* This file checked for sprintf() buffer overruns on 1998/05/06 by Bela
* Lubkin <filbo@armory.com>. Please don't introduce any new ones...
*
* See comments marked "- BL" for two still-possible overruns in the VMS
* code.
*
* Not yet checked for any other sort of buffer overrun.
*/
#include <HTUtils.h>
#include <HTParse.h>
#include <LYGlobalDefs.h>
#include <HTAlert.h>
#include <LYCurses.h>
#include <LYSignal.h>
#include <LYUtils.h>
#include <LYClean.h>
#include <LYStrings.h>
#include <GridText.h>
#include <LYMail.h>
#include <LYCharSets.h> /* to get current charset for mail header */
#include <LYLeaks.h>
BOOLEAN term_letter; /* Global variable for async i/o. */
PRIVATE void terminate_letter PARAMS((int sig));
PRIVATE void remove_tildes PARAMS((char *string));
/* HTUnEscape with control-code nuking */
PRIVATE void SafeHTUnEscape ARGS1(
char *, string)
{
int i;
int flg = FALSE;
HTUnEscape(string);
for (i=0; string[i] != '\0'; i++)
{
/* FIXME: this is explicitly 7-bit ASCII */
if (string[i] < ' ' || string[i] >= 127)
{
string[i] = '?';
flg = TRUE;
}
}
if (flg)
HTAlert(MAILTO_SQUASH_CTL);
}
/*
** mailform() sends form content to the mailto address(es). - FM
*/
PUBLIC void mailform ARGS4(
CONST char *, mailto_address,
CONST char *, mailto_subject,
CONST char *, mailto_content,
CONST char *, mailto_type)
{
FILE *fd;
char *address = NULL;
char *ccaddr = NULL;
char *keywords = NULL;
char *searchpart = NULL;
char *cp = NULL, *cp0 = NULL, *cp1 = NULL;
char subject[80];
char self[80];
char cmd[512];
int len, i, ch;
#if defined(VMS) || defined(DOSPATH)
char my_tmpfile[256];
char *address_ptr1, *address_ptr2;
char *command = NULL;
BOOLEAN first = TRUE;
BOOLEAN isPMDF = FALSE;
char hdrfile[256];
FILE *hfd;
if (!strncasecomp(system_mail, "PMDF SEND", 9)) {
isPMDF = TRUE;
}
#endif /* VMS */
if (!mailto_address || !mailto_content) {
HTAlert(BAD_FORM_MAILTO);
return;
}
subject[0] = '\0';
self[0] = '\0';
if ((cp = (char *)strchr(mailto_address,'\n')) != NULL)
*cp = '\0';
StrAllocCopy(address, mailto_address);
/*
* Check for a ?searchpart. - FM
*/
if ((cp = strchr(address, '?')) != NULL) {
StrAllocCopy(searchpart, cp);
*cp = '\0';
cp = (searchpart + 1);
if (*cp != '\0') {
/*
* Seek and handle a subject=foo. - FM
*/
while (*cp != '\0') {
if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
!strncasecomp(cp, "subject=", 8))
break;
cp++;
}
if (*cp) {
cp += 8;
if ((cp1 = strchr(cp, '&')) != NULL) {
*cp1 = '\0';
}
if (*cp) {
SafeHTUnEscape(subject);
LYstrncpy(subject, cp, 70);
}
if (cp1) {
*cp1 = '&';
cp1 = NULL;
}
}
/*
* Seek and handle to=address(es) fields.
* Appends to address. - FM
*/
cp = (searchpart + 1);
while (*cp != '\0') {
if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
!strncasecomp(cp, "to=", 3)) {
cp += 3;
if ((cp1 = strchr(cp, '&')) != NULL) {
*cp1 = '\0';
}
while (*cp == ',' || isspace((unsigned char)*cp))
cp++;
if (*cp) {
if (*address) {
StrAllocCat(address, ",");
}
StrAllocCat(address, cp);
}
if (cp1) {
*cp1 = '&';
cp = cp1;
cp1 = NULL;
} else {
break;
}
}
cp++;
}
/*
* Seek and handle cc=address(es) fields. Excludes
* Bcc=address(es) as unsafe. We may append our own
* cc (below) as a list for the actual mailing. - FM
*/
cp = (searchpart + 1);
while (*cp != '\0') {
if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
!strncasecomp(cp, "cc=", 3)) {
cp += 3;
if ((cp1 = strchr(cp, '&')) != NULL) {
*cp1 = '\0';
}
while (*cp == ',' || isspace((unsigned char)*cp))
cp++;
if (*cp) {
if (ccaddr == NULL) {
StrAllocCopy(ccaddr, cp);
} else {
StrAllocCat(ccaddr, ",");
StrAllocCat(ccaddr, cp);
}
}
if (cp1) {
*cp1 = '&';
cp = cp1;
cp1 = NULL;
} else {
break;
}
}
cp++;
}
/*
* Seek and handle keywords=term(s) fields. - FM
*/
cp = (searchpart + 1);
while (*cp != '\0') {
if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
!strncasecomp(cp, "keywords=", 9)) {
cp += 9;
if ((cp1 = strchr(cp, '&')) != NULL) {
*cp1 = '\0';
}
while (*cp == ',' || isspace((unsigned char)*cp))
cp++;
if (*cp) {
if (keywords == NULL) {
StrAllocCopy(keywords, cp);
} else {
StrAllocCat(keywords, cp);
StrAllocCat(keywords, ", ");
}
}
if (cp1) {
*cp1 = '&';
cp = cp1;
cp1 = NULL;
} else {
break;
}
}
cp++;
}
if (keywords != NULL) {
if (*keywords != '\0') {
SafeHTUnEscape(keywords);
} else {
FREE(keywords);
}
}
FREE(searchpart);
}
}
/*
* Convert any Explorer semi-colon Internet address
* separators to commas. - FM
*/
cp = address;
while ((cp1 = strchr(cp, '@')) != NULL) {
cp1++;
if ((cp0 = strchr(cp1, ';')) != NULL) {
*cp0 = ',';
cp1 = cp0 + 1;
}
cp = cp1;
}
if (address[(strlen(address) - 1)] == ',')
address[(strlen(address) - 1)] = '\0';
if (*address == '\0') {
FREE(address);
FREE(ccaddr);
FREE(keywords);
HTAlert(BAD_FORM_MAILTO);
return;
}
if (ccaddr != NULL) {
cp = ccaddr;
while ((cp1 = strchr(cp, '@')) != NULL) {
cp1++;
if ((cp0 = strchr(cp1, ';')) != NULL) {
*cp0 = ',';
cp1 = cp0 + 1;
}
cp = cp1;
}
if (ccaddr[(strlen(ccaddr) - 1)] == ',') {
ccaddr[(strlen(ccaddr) - 1)] = '\0';
}
if (*ccaddr == '\0') {
FREE(ccaddr);
}
}
/*
* Unescape the address and ccaddr fields. - FM
*/
SafeHTUnEscape(address);
if (ccaddr != NULL) {
SafeHTUnEscape(ccaddr);
}
/*
* Allow user to edit the default Subject - FM
*/
if (subject[0] == '\0') {
if (mailto_subject && *mailto_subject) {
LYstrncpy(subject, mailto_subject, 70);
} else {
strcpy(subject, "mailto:");
LYstrncpy((char*)&subject[7], address, 63);
}
}
_statusline(SUBJECT_PROMPT);
if ((ch = LYgetstr(subject, VISIBLE, 71, NORECALL)) < 0) {
/*
* User cancelled via ^G. - FM
*/
HTInfoMsg(FORM_MAILTO_CANCELLED);
FREE(address);
FREE(ccaddr);
FREE(keywords);
return;
}
/*
* Allow user to specify a self copy via a CC:
* entry, if permitted. - FM
*/
if (!LYNoCc) {
sprintf(self, "%.79s", (personal_mail_address ?
personal_mail_address : ""));
self[79] = '\0';
_statusline("Cc: ");
if ((ch = LYgetstr(self, VISIBLE, sizeof(self), NORECALL)) < 0) {
/*
* User cancelled via ^G. - FM
*/
HTInfoMsg(FORM_MAILTO_CANCELLED);
FREE(address);
FREE(ccaddr);
FREE(keywords);
return;
}
remove_tildes(self);
if (ccaddr == NULL) {
StrAllocCopy(ccaddr, self);
} else {
StrAllocCat(ccaddr, ",");
StrAllocCat(ccaddr, self);
}
}
#if defined(VMS) || defined(DOSPATH)
if ((fd = LYOpenTemp(my_tmpfile, ".txt", "w")) == NULL) {
HTAlert(FORM_MAILTO_FAILED);
FREE(address);
FREE(ccaddr);
FREE(keywords);
return;
}
if (isPMDF) {
if ((hfd = LYOpenTemp(hdrfile, ".txt", "w")) == NULL) {
HTAlert(FORM_MAILTO_FAILED);
LYCloseTempFP(fd);
FREE(address);
FREE(ccaddr);
FREE(keywords);
return;
}
}
#ifdef VMS
if (isPMDF) {
if (mailto_type && *mailto_type) {
fprintf(hfd, "Mime-Version: 1.0\n");
fprintf(hfd, "Content-Type: %s\n", mailto_type);
if (personal_mail_address && *personal_mail_address)
fprintf(hfd, "From: %s\n", personal_mail_address);
}
} else if (mailto_type &&
!strncasecomp(mailto_type, "multipart/form-data", 19)) {
/*
* Ugh! There's no good way to include headers while
* we're still using "generic" VMS MAIL, so we'll put
* this in the body of the message. - FM
*/
fprintf(fd, "X-Content-Type: %s\n\n", mailto_type);
}
#else
if (mailto_type && *mailto_type) {
fprintf(fd, "Mime-Version: 1.0\n");
fprintf(fd, "Content-Type: %s\n", mailto_type);
}
fprintf(fd,"To: %s\n", address);
if (personal_mail_address && *personal_mail_address)
fprintf(fd,"From: %s\n", personal_mail_address);
remove_tildes(self);
fprintf(fd,"Subject: %.70s\n\n", subject);
#endif
#else
sprintf(cmd, "%s %s", system_mail, system_mail_flags);
if ((fd = popen(cmd, "w")) == NULL) {
HTAlert(FORM_MAILTO_FAILED);
FREE(address);
FREE(ccaddr);
FREE(keywords);
return;
}
if (mailto_type && *mailto_type) {
fprintf(fd, "Mime-Version: 1.0\n");
fprintf(fd, "Content-Type: %s\n", mailto_type);
}
fprintf(fd, "To: %s\n", address);
if (personal_mail_address && *personal_mail_address)
fprintf(fd, "From: %s\n", personal_mail_address);
if (ccaddr != NULL && *ccaddr != '\0')
fprintf(fd, "Cc: %s\n", ccaddr);
fprintf(fd, "Subject: %s\n\n", subject);
if (keywords != NULL && *keywords != '\0')
fprintf(fd, "Keywords: %s\n", keywords);
_statusline(SENDING_FORM_CONTENT);
#endif /* VMS */
/*
* Break up the content into lines with a maximum length of 78.
* If the ENCTYPE was text/plain, we have physical newlines and
* should take them into account. Otherwise, the actual newline
* characters in the content are hex escaped. - FM
*/
while((cp = strchr(mailto_content, '\n')) != NULL) {
*cp = '\0';
i = 0;
len = strlen(mailto_content);
while (len > 78) {
strncpy(cmd, &mailto_content[i], 78);
cmd[78] = '\0';
fprintf(fd, "%s\n", cmd);
i += 78;
len = strlen(&mailto_content[i]);
}
fprintf(fd, "%s\n", &mailto_content[i]);
mailto_content = (cp+1);
}
i = 0;
len = strlen(mailto_content);
while (len > 78) {
strncpy(cmd, &mailto_content[i], 78);
cmd[78] = '\0';
fprintf(fd, "%s\n", cmd);
i += 78;
len = strlen(&mailto_content[i]);
}
if (len)
fprintf(fd, "%s\n", &mailto_content[i]);
#ifdef UNIX
pclose(fd);
sleep(MessageSecs);
#endif /* UNIX */
#if defined(VMS) || defined(DOSPATH)
LYCloseTempFP(fd);
#ifdef VMS
/*
* Set the mail command. - FM
*/
if (isPMDF) {
/*
* For PMDF, put any keywords and the subject
* in the header file and close it. - FM
*/
if (keywords != NULL && *keywords != '\0') {
fprintf(hfd, "Keywords: %s\n", keywords);
}
fprintf(hfd, "Subject: %s\n\n", subject);
LYCloseTempFP(hfd);
/*
* Now set up the command. - FM
*/
sprintf(cmd,
"%s %s %s,%s ",
system_mail,
system_mail_flags,
hdrfile,
my_tmpfile);
} else {
/*
* For "generic" VMS MAIL, include the subject in the
* command, and ignore any keywords to minimize risk
* of them making the line too long or having problem
* characters. - FM
*
* Possibly still a problem if user supplies long subject. - BL
*/
sprintf(cmd,
"%s %s%s/subject=\"%s\" %s ",
system_mail,
system_mail_flags,
(strncasecomp(system_mail, "MAIL", 4) ? "" : "/noself"),
subject,
my_tmpfile);
}
StrAllocCopy(command, cmd);
/*
* Now add all the people in the address field. - FM
*/
address_ptr1 = address;
do {
if ((cp = strchr(address_ptr1, ',')) != NULL) {
address_ptr2 = (cp+1);
*cp = '\0';
} else {
address_ptr2 = NULL;
}
/*
* 4 letters is arbitrarily the smallest possible mail
* address, at least for lynx. That way extra spaces
* won't confuse the mailer and give a blank address.
*
* ignore addresses so long that they would overflow the
* temporary buffer (i.e. about 500 chars). - BL
*/
if (strlen(address_ptr1) > 3 &&
strlen(address_ptr1) + strlen(mail_adrs) < sizeof(cmd)) {
if (!first) {
StrAllocCat(command, ",");
}
sprintf(cmd, mail_adrs, address_ptr1);
StrAllocCat(command, cmd);
first = FALSE;
}
address_ptr1 = address_ptr2;
} while (address_ptr1 != NULL);
/*
* Now add all the people in the CC field. - FM
*/
if (ccaddr != NULL && *ccaddr != '\0') {
address_ptr1 = ccaddr;
do {
if ((cp = strchr(address_ptr1, ',')) != NULL) {
address_ptr2 = (cp+1);
*cp = '\0';
} else {
address_ptr2 = NULL;
}
/*
* 4 letters is arbitrarily the smallest possible mail
* address, at least for lynx. That way extra spaces
* won't confuse the mailer and give a blank address.
*
* ignore addresses so long that they would overflow the
* temporary buffer (i.e. about 500 chars). - BL
*/
if (strlen(address_ptr1) > 3 &&
strlen(address_ptr1) + strlen(mail_adrs) < sizeof(cmd)) {
StrAllocCat(command, ",");
sprintf(cmd, mail_adrs, address_ptr1);
if (isPMDF) {
strcat(cmd, "/CC");
}
StrAllocCat(command, cmd);
}
address_ptr1 = address_ptr2;
} while (address_ptr1 != NULL);
}
stop_curses();
printf("Sending form content:\n\n$ %s\n\nPlease wait...", command);
LYSystem(command);
FREE(command);
sleep(AlertSecs);
start_curses();
LYRemoveTemp(my_tmpfile);
LYRemoveTemp(hdrfile);
#else /* DOSPATH */
StrAllocCopy(command, system_mail);
StrAllocCat(command, " -t \"");
StrAllocCat(command, address);
StrAllocCat(command, "\" -F ");
StrAllocCat(command, my_tmpfile);
stop_curses();
printf("Sending form content:\n\n$ %s\n\nPlease wait...", command);
LYSystem(command);
FREE(command);
sleep(MessageSecs);
start_curses();
LYRemoveTemp(my_tmpfile);
#endif
#endif /* VMS */
FREE(address);
FREE(ccaddr);
FREE(keywords);
return;
}
/*
** mailmsg() sends a message to the owner of the file, if one is defined,
** telling of errors (i.e., link not available).
*/
PUBLIC void mailmsg ARGS4(
int, cur,
char *, owner_address,
char *, filename,
char *, linkname)
{
FILE *fd, *fp;
char *address = NULL;
char *searchpart = NULL;
char cmd[512], *cp, *cp0, *cp1;
#if defined(VMS) || defined(DOSPATH)
char my_tmpfile[256];
char *address_ptr1, *address_ptr2;
char *command = NULL;
BOOLEAN first = TRUE;
BOOLEAN isPMDF = FALSE;
char hdrfile[256];
FILE *hfd;
CTRACE(tfp, "mailmsg(%d, \"%s\", \"%s\", \"%s\")\n",cur,
cur, owner_address?owner_address:"<nil>",
filename?filename:"<nil>",
linkname?linkname:"<nil>");
if (!strncasecomp(system_mail, "PMDF SEND", 9)) {
isPMDF = TRUE;
}
#endif /* VMS */
if (owner_address == NULL || *owner_address == '\0') {
return;
}
if ((cp = (char *)strchr(owner_address,'\n')) != NULL)
*cp = '\0';
StrAllocCopy(address, owner_address);
/*
* Check for a ?searchpart. - FM
*/
if ((cp = strchr(address, '?')) != NULL) {
StrAllocCopy(searchpart, cp);
*cp = '\0';
cp = (searchpart + 1);
if (*cp != '\0') {
/*
* Seek and handle to=address(es) fields.
* Appends to address. We ignore any other
* headers in the ?searchpart. - FM
*/
cp = (searchpart + 1);
while (*cp != '\0') {
if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
!strncasecomp(cp, "to=", 3)) {
cp += 3;
if ((cp1 = strchr(cp, '&')) != NULL) {
*cp1 = '\0';
}
while (*cp == ',' || isspace((unsigned char)*cp))
cp++;
if (*cp) {
if (*address) {
StrAllocCat(address, ",");
}
StrAllocCat(address, cp);
}
if (cp1) {
*cp1 = '&';
cp = cp1;
cp1 = NULL;
} else {
break;
}
}
cp++;
}
}
}
/*
* Convert any Explorer semi-colon Internet address
* separators to commas. - FM
*/
cp = address;
while ((cp1 = strchr(cp, '@')) != NULL) {
cp1++;
if ((cp0 = strchr(cp1, ';')) != NULL) {
*cp0 = ',';
cp1 = cp0 + 1;
}
cp = cp1;
}
/*
* Unescape the address field. - FM
*/
SafeHTUnEscape(address);
if (address[(strlen(address) - 1)] == ',')
address[(strlen(address) - 1)] = '\0';
if (*address == '\0') {
FREE(address);
CTRACE(tfp, "mailmsg: No address in '%s'.\n",
owner_address);
return;
}
#ifdef UNIX
sprintf(cmd, "%s %s", system_mail, system_mail_flags);
if ((fd = popen(cmd, "w")) == NULL) {
FREE(address);
CTRACE(tfp, "mailmsg: '%s' failed.\n",
cmd);
return;
}
fprintf(fd, "To: %s\n", address);
fprintf(fd, "Subject: Lynx Error in %s\n", filename);
if (personal_mail_address != NULL && *personal_mail_address != '\0') {
fprintf(fd, "Cc: %s\n", personal_mail_address);
}
fprintf(fd, "X-URL: %s\n", filename);
fprintf(fd, "X-Mailer: Lynx, Version %s\n\n", LYNX_VERSION);
#endif /* UNIX */
#if defined(VMS) || defined(DOSPATH)
if ((fd = LYOpenTemp(my_tmpfile, ".txt", "w")) == NULL) {
CTRACE(tfp, "mailmsg: Could not fopen '%s'.\n",
my_tmpfile);
FREE(address);
return;
}
if (isPMDF) {
if ((hfd = LYOpenTemp(hdrfile, ".txt", "w")) == NULL) {
CTRACE(tfp, "mailmsg: Could not fopen '%s'.\n",
hdrfile);
FREE(address);
return;
}
if (personal_mail_address != NULL && *personal_mail_address != '\0') {
fprintf(fd, "Cc: %s\n", personal_mail_address);
}
fprintf(fd, "X-URL: %s\n", filename);
fprintf(fd, "X-Mailer: Lynx, Version %s\n\n", LYNX_VERSION);
}
#endif /* VMS */
fprintf(fd, "The link %s :?: %s \n",
links[cur].lname, links[cur].target);
fprintf(fd, "called \"%s\"\n", links[cur].hightext);
fprintf(fd, "in the file \"%s\" called \"%s\"", filename, linkname);
fputs("\nwas requested but was not available.", fd);
fputs("\n\nThought you might want to know.", fd);
fputs("\n\nThis message was automatically generated by\n", fd);
fprintf(fd, "Lynx ver. %s", LYNX_VERSION);
if ((LynxSigFile != NULL) &&
(fp = fopen(LynxSigFile, "r")) != NULL) {
fputs("-- \n", fd);
while (fgets(cmd, sizeof(cmd), fp) != NULL)
fputs(cmd, fd);
fclose(fp);
}
#ifdef UNIX
pclose(fd);
#endif /* UNIX */
#if defined(VMS) || defined(DOSPATH)
LYCloseTempFP(fd);
#ifdef VMS
if (isPMDF) {
/*
* For PMDF, put the subject in the
* header file and close it. - FM
*/
fprintf(hfd, "Subject: Lynx Error in %.56s\n\n", filename);
LYCloseTempFP(hfd);
/*
* Now set up the command. - FM
*/
sprintf(cmd,
"%s %s %s,%s ",
system_mail,
system_mail_flags,
hdrfile,
my_tmpfile);
} else {
/*
* For "generic" VMS MAIL, include the
* subject in the command. - FM
*/
sprintf(cmd,
"%s %s/self/subject=\"Lynx Error in %.56s\" %s ",
system_mail,
system_mail_flags,
filename,
my_tmpfile);
}
StrAllocCopy(command, cmd);
address_ptr1 = address;
do {
if ((cp = strchr(address_ptr1, ',')) != NULL) {
address_ptr2 = (cp+1);
*cp = '\0';
} else
address_ptr2 = NULL;
/*
* 4 letters is arbitrarily the smallest possible mail
* address, at least for lynx. That way extra spaces
* won't confuse the mailer and give a blank address.
*
* ignore addresses so long that they would overflow the
* temporary buffer (i.e. about 500 chars). - BL
*/
if (strlen(address) > 3 &&
strlen(address) + strlen(mail_adrs) < sizeof(cmd)) {
if (!first) {
StrAllocCat(command, ",");
}
sprintf(cmd, mail_adrs, address_ptr1);
StrAllocCat(command, cmd);
first = FALSE;
}
address_ptr1 = address_ptr2;
} while (address_ptr1 != NULL);
LYSystem(command);
FREE(command);
LYRemoveTemp(my_tmpfile);
if (isPMDF) {
LYRemoveTemp(hdrfile);
}
#else /* DOSPATH */
StrAllocCopy(command, system_mail);
StrAllocCat(command, " -t \"");
StrAllocCat(command, address);
StrAllocCat(command, "\" -F ");
StrAllocCat(command, my_tmpfile);
LYSystem(command);
FREE(command);
LYRemoveTemp(my_tmpfile);
#endif
#endif /* VMS */
if (traversal) {
FILE *ofp;
if ((ofp = LYAppendToTxtFile(TRAVERSE_ERRORS)) == NULL) {
if ((ofp = LYNewTxtFile(TRAVERSE_ERRORS)) == NULL) {
perror(NOOPEN_TRAV_ERR_FILE);
#ifndef NOSIGHUP
(void) signal(SIGHUP, SIG_DFL);
#endif /* NOSIGHUP */
(void) signal(SIGTERM, SIG_DFL);
#ifndef VMS
(void) signal(SIGINT, SIG_DFL);
#endif /* !VMS */
#ifdef SIGTSTP
if (no_suspend)
(void) signal(SIGTSTP,SIG_DFL);
#endif /* SIGTSTP */
exit(-1);
}
}
fprintf(ofp, "%s\t%s \tin %s\n",
links[cur].lname, links[cur].target, filename);
fclose(ofp);
}
FREE(address);
return;
}
/*
** reply_by_mail() invokes sendmail on Unix or mail on VMS to send
** a comment from the users to the owner
*/
PUBLIC void reply_by_mail ARGS3(
char *, mail_address,
char *, filename,
CONST char *, title)
{
char user_input[1000];
FILE *fd, *fp;
char *address = NULL;
char *ccaddr = NULL;
char *keywords = NULL;
char *searchpart = NULL;
char *body = NULL;
char *cp = NULL, *cp0 = NULL, *cp1 = NULL;
char *temp = NULL;
int i, len;
int c = 0; /* user input */
char my_tmpfile[256], cmd[512];
#ifdef DOSPATH
char tmpfile2[256];
#endif
#if defined(DOSPATH) || defined(VMS)
char *command = NULL;
#endif
static char *personal_name = NULL;
char subject[80];
#ifdef VMS
char *address_ptr1 = NULL, *address_ptr2 = NULL;
BOOLEAN first = TRUE;
BOOLEAN isPMDF = FALSE;
char hdrfile[256];
FILE *hfd;
CTRACE(tfp, "reply_by_mail(\"%s\", \"%s\", \"%s\")\n",
mail_address?mail_address:"<nil>",
filename?filename:"<nil>",
title?title:"<nil>");
if (!strncasecomp(system_mail, "PMDF SEND", 9)) {
isPMDF = TRUE;
}
#else
char buf[512];
char *header = NULL;
int n;
#endif /* VMS */
term_letter = FALSE;
if (mail_address && *mail_address) {
StrAllocCopy(address, mail_address);
} else {
HTAlert(NO_ADDRESS_IN_MAILTO_URL);
return;
}
if ((fd = LYOpenTemp(my_tmpfile, ".txt", "w")) == NULL) {
HTAlert(MAILTO_URL_TEMPOPEN_FAILED);
return;
}
#ifdef VMS
if (isPMDF) {
if ((hfd = LYOpenTemp(hdrfile, ".txt", "w")) == NULL) {
HTAlert(MAILTO_URL_TEMPOPEN_FAILED);
return;
}
}
#endif /* VMS */
subject[0] = '\0';
/*
* Check for a ?searchpart. - FM
*/
if ((cp = strchr(address, '?')) != NULL) {
StrAllocCopy(searchpart, cp);
*cp = '\0';
cp = (searchpart + 1);
if (*cp != '\0') {
/*
* Seek and handle a subject=foo. - FM
*/
while (*cp != '\0') {
if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
!strncasecomp(cp, "subject=", 8))
break;
cp++;
}
if (*cp) {
cp += 8;
if ((cp1 = strchr(cp, '&')) != NULL) {
*cp1 = '\0';
}
if (*cp) {
strncpy(subject, cp, 70);
subject[70] = '\0';
SafeHTUnEscape(subject);
}
if (cp1) {
*cp1 = '&';
cp1 = NULL;
}
}
/*
* Seek and handle to=address(es) fields.
* Appends to address. - FM
*/
cp = (searchpart + 1);
while (*cp != '\0') {
if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
!strncasecomp(cp, "to=", 3)) {
cp += 3;
if ((cp1 = strchr(cp, '&')) != NULL) {
*cp1 = '\0';
}
while (*cp == ',' || isspace((unsigned char)*cp))
cp++;
if (*cp) {
if (*address) {
StrAllocCat(address, ",");
}
StrAllocCat(address, cp);
}
if (cp1) {
*cp1 = '&';
cp = cp1;
cp1 = NULL;
} else {
break;
}
}
cp++;
}
/*
* Seek and handle cc=address(es) fields. Excludes
* Bcc=address(es) as unsafe. We may append our own
* cc (below) as a list for the actual mailing. - FM
*/
cp = (searchpart + 1);
while (*cp != '\0') {
if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
!strncasecomp(cp, "cc=", 3)) {
cp += 3;
if ((cp1 = strchr(cp, '&')) != NULL) {
*cp1 = '\0';
}
while (*cp == ',' || isspace((unsigned char)*cp))
cp++;
if (*cp) {
if (ccaddr == NULL) {
StrAllocCopy(ccaddr, cp);
} else {
StrAllocCat(ccaddr, ",");
StrAllocCat(ccaddr, cp);
}
}
if (cp1) {
*cp1 = '&';
cp = cp1;
cp1 = NULL;
} else {
break;
}
}
cp++;
}
/*
* Seek and handle keywords=term(s) fields. - FM
*/
cp = (searchpart + 1);
while (*cp != '\0') {
if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
!strncasecomp(cp, "keywords=", 9)) {
cp += 9;
if ((cp1 = strchr(cp, '&')) != NULL) {
*cp1 = '\0';
}
while (*cp == ',' || isspace((unsigned char)*cp))
cp++;
if (*cp) {
if (keywords == NULL) {
StrAllocCopy(keywords, cp);
} else {
StrAllocCat(keywords, cp);
StrAllocCat(keywords, ", ");
}
StrAllocCat(keywords, cp);
}
if (cp1) {
*cp1 = '&';
cp = cp1;
cp1 = NULL;
} else {
break;
}
}
cp++;
}
if (keywords != NULL) {
if (*keywords != '\0') {
SafeHTUnEscape(keywords);
} else {
FREE(keywords);
}
}
/*
* Seek and handle body=foo fields. - FM
*/
cp = (searchpart + 1);
while (*cp != '\0') {
if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
!strncasecomp(cp, "body=", 5)) {
cp += 5;
if ((cp1 = strchr(cp, '&')) != NULL) {
*cp1 = '\0';
}
if (*cp) {
/*
* Break up the value into lines with
* a maximum length of 78. - FM
*/
StrAllocCopy(temp, cp);
HTUnEscape(temp);
cp0 = temp;
while((cp = strchr(cp0, '\n')) != NULL) {
*cp = '\0';
if (cp > cp0) {
if (*(cp - 1) == '\r') {
*(cp - 1) = '\0';
}
}
i = 0;
len = strlen(cp0);
while (len > 78) {
strncpy(cmd, (char *)&cp0[i], 78);
cmd[78] = '\0';
strcat(cmd, "\n");
StrAllocCat(body, cmd);
i += 78;
len = strlen((char *)&cp0[i]);
}
sprintf(cmd, "%s\n", (char *)&cp0[i]);
StrAllocCat(body, cmd);
cp0 = (cp + 1);
}
i = 0;
len = strlen(cp0);
while (len > 78) {
strncpy(cmd, (char *)&cp0[i], 78);
cmd[78] = '\0';
strcat(cmd, "\n");
StrAllocCat(body, cmd);
i += 78;
len = strlen((char *)&cp0[i]);
}
if (len) {
sprintf(cmd, "%s\n", (char *)&cp0[i]);
StrAllocCat(body, cmd);
}
FREE(temp);
}
if (cp1) {
*cp1 = '&';
cp = cp1;
cp1 = NULL;
} else {
break;
}
}
cp++;
}
FREE(searchpart);
}
}
/*
* Convert any Explorer semi-colon Internet address
* separators to commas. - FM
*/
cp = address;
while ((cp1 = strchr(cp, '@')) != NULL) {
cp1++;
if ((cp0 = strchr(cp1, ';')) != NULL) {
*cp0 = ',';
cp1 = cp0 + 1;
}
cp = cp1;
}
if (address[(strlen(address) - 1)] == ',')
address[(strlen(address) - 1)] = '\0';
if (*address == '\0') {
FREE(address);
FREE(ccaddr);
FREE(keywords);
FREE(body);
LYCloseTempFP(fd); /* Close the tmpfile. */
LYRemoveTemp(my_tmpfile); /* Delete the tmpfile. */
HTAlert(NO_ADDRESS_IN_MAILTO_URL);
return;
}
if (ccaddr != NULL) {
cp = ccaddr;
while ((cp1 = strchr(cp, '@')) != NULL) {
cp1++;
if ((cp0 = strchr(cp1, ';')) != NULL) {
*cp0 = ',';
cp1 = cp0 + 1;
}
cp = cp1;
}
if (ccaddr[(strlen(ccaddr) - 1)] == ',') {
ccaddr[(strlen(ccaddr) - 1)] = '\0';
}
if (*ccaddr == '\0') {
FREE(ccaddr);
}
}
/*
* Unescape the address and ccaddr fields. - FM
*/
SafeHTUnEscape(address);
if (ccaddr != NULL) {
SafeHTUnEscape(ccaddr);
}
/*
* Set the default subject. - FM
*/
if (subject[0] == '\0' && title && *title) {
strncpy(subject, title, 70);
subject[70] = '\0';
}
/*
* Use ^G to cancel mailing of comment
* and don't let SIGINTs exit lynx.
*/
signal(SIGINT, terminate_letter);
#ifdef VMS
if (isPMDF || !body) {
/*
* Put the X-URL and X-Mailer lines in the hdrfile
* for PMDF or my_tmpfile for VMS MAIL. - FM
*/
fprintf((isPMDF ? hfd : fd),
"X-URL: %s%s\n",
(filename && *filename) ? filename : "mailto:",
(filename && *filename) ? "" : address);
fprintf((isPMDF ? hfd : fd),
"X-Mailer: Lynx, Version %s\n",LYNX_VERSION);
#ifdef NO_ANONYMOUS_MAIL
if (!isPMDF) {
fprintf(fd, "\n");
}
#endif /* NO_ANONYMOUS_MAIL */
}
#else /* Unix: */
/*
* Put the To: line in the header.
*/
#ifndef DOSPATH
StrAllocCopy(header, "To: ");
StrAllocCat(header, address);
StrAllocCat(header, "\n");
#endif
/*
* Put the Mime-Version, Content-Type and
* Content-Transfer-Encoding in the header.
* This assumes that the same character set is used
* for composing the mail which is currently selected
* as display character set...
* Don't send a charset if we have a CJK character set
* selected, since it may not be appropriate for mail...
* Also don't use an unofficial "x-" charset.
* Also if the charset would be "us-ascii" (7-bit replacements
* selected, don't send any MIME headers. - kw
*/
if (strncasecomp(LYCharSet_UC[current_char_set].MIMEname,
"us-ascii", 8) != 0) {
StrAllocCat(header, "Mime-Version: 1.0\n");
if (!LYHaveCJKCharacterSet &&
strncasecomp(LYCharSet_UC[current_char_set].MIMEname, "x-", 2)
!= 0) {
sprintf(buf,"Content-Type: text/plain; charset=%s\n",
LYCharSet_UC[current_char_set].MIMEname);
StrAllocCat(header, buf);
}
StrAllocCat(header, "Content-Transfer-Encoding: 8bit\n");
}
/*
* Put the X-URL and X-Mailer lines in the header.
*/
StrAllocCat(header, "X-URL: ");
if (filename && *filename) {
StrAllocCat(header, filename);
}
else {
StrAllocCat(header, "mailto:");
StrAllocCat(header, address);
}
StrAllocCat(header, "\n");
sprintf(buf, "X-Mailer: Lynx, Version %s\n", LYNX_VERSION);
StrAllocCat(header, buf);
#endif /* VMS */
/*
* Clear the screen and inform the user.
*/
clear();
move(2,0);
scrollok(stdscr, TRUE); /* Enable scrolling. */
if (body)
addstr(SENDING_MESSAGE_WITH_BODY_TO);
else
addstr(SENDING_COMMENT_TO);
cp = address;
while ((cp1 = strchr(cp, ',')) != NULL) {
*cp1 = '\0';
while (*cp == ' ')
cp++;
if (*cp) {
addstr(cp);
addstr(",\n ");
}
*cp1 = ',';
cp = (cp1 + 1);
}
if (*cp) {
addstr(cp);
}
#ifdef VMS
if ((isPMDF == TRUE) &&
(cp = ccaddr) != NULL)
#else
if ((cp = ccaddr) != NULL)
#endif /* VMS */
{
if (strchr(cp, ',') != NULL) {
addstr(WITH_COPIES_TO);
} else {
addstr(WITH_COPY_TO);
}
while ((cp1 = strchr(cp, ',')) != NULL) {
*cp1 = '\0';
while (*cp == ' ')
cp++;
if (*cp) {
addstr(cp);
addstr(",\n ");
}
*cp1 = ',';
cp = (cp1 + 1);
}
if (*cp) {
addstr(cp);
}
}
addstr(CTRL_G_TO_CANCEL_SEND);
#ifdef VMS
if (isPMDF || !body) {
#endif /* VMS */
#ifndef NO_ANONYMOUS_EMAIL
/*
* Get the user's personal name.
*/
addstr(ENTER_NAME_OR_BLANK);
if (personal_name == NULL)
*user_input = '\0';
else {
addstr(CTRL_U_TO_ERASE);
strcpy(user_input, personal_name);
}
#ifdef VMS
if (isPMDF) {
addstr("Personal_name: ");
} else {
addstr("X_Personal_name: ");
}
#else
addstr("Personal Name: ");
#endif /* VMS */
if (LYgetstr(user_input, VISIBLE, sizeof(user_input), NORECALL) < 0 ||
term_letter) {
addstr("\n");
HTInfoMsg(COMMENT_REQUEST_CANCELLED);
LYCloseTempFP(fd); /* Close the tmpfile. */
scrollok(stdscr,FALSE); /* Stop scrolling. */
goto cleanup;
}
addstr("\n");
remove_tildes(user_input);
StrAllocCopy(personal_name, user_input);
term_letter = FALSE;
if (*user_input) {
#ifdef VMS
fprintf((isPMDF ? hfd : fd),
"X-Personal_name: %s\n",user_input);
#else
StrAllocCat(header, "X-Personal_name: ");
StrAllocCat(header, user_input);
StrAllocCat(header, "\n");
#endif /* VMS */
}
/*
* Get the user's return address.
*/
addstr(ENTER_MAIL_ADDRESS_OR_OTHER);
addstr(MEANS_TO_CONTACT_FOR_RESPONSE);
if (personal_mail_address)
addstr(CTRL_U_TO_ERASE);
#ifdef VMS
if (isPMDF) {
addstr("From: ");
} else {
addstr("X-From: ");
}
#else
addstr("From: ");
#endif /* VMS */
/* Add the personal mail address if there is one. */
sprintf(user_input, "%s", (personal_mail_address ?
personal_mail_address : ""));
if (LYgetstr(user_input, VISIBLE, sizeof(user_input), NORECALL) < 0 ||
term_letter) {
addstr("\n");
HTInfoMsg(COMMENT_REQUEST_CANCELLED);
LYCloseTempFP(fd); /* Close the tmpfile. */
scrollok(stdscr,FALSE); /* Stop scrolling. */
goto cleanup;
}
addstr("\n");
remove_tildes(user_input);
#ifdef VMS
if (*user_input) {
if (isPMDF) {
fprintf(hfd, "From: %s\n", user_input);
} else {
fprintf(fd, "X-From: %s\n\n", user_input);
}
} else if (!isPMDF) {
fprintf(fd, "\n");
}
#else
StrAllocCat(header, "From: ");
StrAllocCat(header, user_input);
StrAllocCat(header, "\n");
#endif /* VMS */
#endif /* !NO_ANONYMOUS_EMAIL */
#ifdef VMS
}
#endif /* VMS */
/*
* Get the subject line.
*/
addstr(ENTER_SUBJECT_LINE);
addstr(CTRL_U_TO_ERASE);
addstr("Subject: ");
/* Add the default subject. */
sprintf(user_input, "%.70s%.63s",
(subject[0] != '\0') ?
subject :
((filename && *filename) ?
filename : "mailto:"),
(subject[0] != '\0') ?
"" :
((filename && *filename) ?
"" : address));
if (LYgetstr(user_input, VISIBLE, 71, NORECALL) < 0 ||
term_letter) {
addstr("\n");
HTInfoMsg(COMMENT_REQUEST_CANCELLED);
LYCloseTempFP(fd); /* Close the tmpfile. */
scrollok(stdscr,FALSE); /* Stop scrolling. */
goto cleanup;
}
addstr("\n");
remove_tildes(user_input);
#ifdef VMS
sprintf(subject, "%.70s", user_input);
#else
StrAllocCat(header, "Subject: ");
StrAllocCat(header, user_input);
StrAllocCat(header, "\n");
#endif /* VMS */
/*
* Offer a CC line, if permitted. - FM
*/
user_input[0] = '\0';
if (!LYNoCc) {
addstr(ENTER_ADDRESS_FOR_CC);
if (personal_mail_address)
addstr(CTRL_U_TO_ERASE);
addstr(BLANK_FOR_NO_COPY);
addstr("Cc: ");
/*
* Add the mail address if there is one.
*/
sprintf(user_input, "%s", (personal_mail_address ?
personal_mail_address : ""));
if (LYgetstr(user_input, VISIBLE, sizeof(user_input), NORECALL) < 0 ||
term_letter) {
addstr("\n");
HTInfoMsg(COMMENT_REQUEST_CANCELLED);
LYCloseTempFP(fd); /* Close the tmpfile. */
scrollok(stdscr, FALSE); /* Stop scrolling. */
goto cleanup;
}
addstr("\n");
}
remove_tildes(user_input);
if (*user_input) {
cp = user_input;
while (*cp == ',' || isspace((unsigned char)*cp))
cp++;
if (*cp) {
if (ccaddr == NULL) {
StrAllocCopy(ccaddr, cp);
} else {
StrAllocCat(ccaddr, ",");
StrAllocCat(ccaddr, cp);
}
}
}
#ifdef DOSPATH
if (*address) {
StrAllocCat(header, "To: ");
StrAllocCat(header, address);
StrAllocCat(header, "\n");
}
#endif
#ifndef VMS
/*
** Add the Cc: header. - FM
*/
if (ccaddr != NULL && *ccaddr != '\0') {
StrAllocCat(header, "Cc: ");
StrAllocCat(header, ccaddr);
StrAllocCat(header, "\n");
}
/*
** Add the Keywords: header. - FM
*/
if (keywords != NULL && *keywords != '\0') {
StrAllocCat(header, "Keywords: ");
StrAllocCat(header, keywords);
StrAllocCat(header, "\n");
}
/*
* Terminate the header.
*/
sprintf(buf, "\n");
StrAllocCat(header, buf);
CTRACE(tfp,"**header==\n%s",header);
#endif /* !VMS */
if (!no_editor && editor && *editor != '\0') {
/*
* Use an external editor for the message.
*/
char *editor_arg = "";
if (body) {
cp1 = body;
while((cp = strchr(cp1, '\n')) != NULL) {
*cp++ = '\0';
fprintf(fd, "%s\n", cp1);
cp1 = cp;
}
} else if (strcmp(HTLoadedDocumentURL(), "")) {
/*
* Ask if the user wants to include the original message.
*/
BOOLEAN is_preparsed = (LYPreparsedSource &&
HTisDocumentSource());
if (is_preparsed)
_statusline(INC_PREPARSED_MSG_PROMPT);
else
_statusline(INC_ORIG_MSG_PROMPT);
c = 0;
while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
!term_letter && c != 7 && c != 3)
c = LYgetch();
if (TOUPPER(c) == 'Y') {
/*
* The 1 will add the reply "> " in front of every line.
*/
if (is_preparsed)
print_wwwfile_to_fd(fd, 0);
else
print_wwwfile_to_fd(fd, 1);
}
}
LYCloseTempFP(fd); /* Close the tmpfile. */
scrollok(stdscr,FALSE); /* Stop scrolling. */
if (term_letter || c == 7 || c == 3)
goto cleanup;
/*
* Spawn the users editor on the mail file
*/
if (strstr(editor, "pico")) {
editor_arg = " -t"; /* No prompt for filename to use */
}
sprintf(user_input, "%s%s %s", editor, editor_arg, my_tmpfile);
_statusline(SPAWNING_EDITOR_FOR_MAIL);
stop_curses();
if (LYSystem(user_input)) {
start_curses();
HTAlert(ERROR_SPAWNING_EDITOR);
} else {
start_curses();
}
} else if (body) {
/*
* Let user review the body. - FM
*/
clear();
move(0,0);
addstr(REVIEW_MESSAGE_BODY);
refresh();
cp1 = body;
i = (LYlines - 5);
while((cp = strchr(cp1, '\n')) != NULL) {
if (i <= 0) {
addstr(RETURN_TO_CONTINUE);
refresh();
c = LYgetch();
addstr("\n");
if (term_letter || c == 7 || c == 3) {
addstr(CANCELLED);
sleep(InfoSecs);
LYCloseTempFP(fd); /* Close the tmpfile. */
scrollok(stdscr, FALSE); /* Stop scrolling. */
goto cleanup;
}
i = (LYlines - 2);
}
*cp++ = '\0';
fprintf(fd, "%s\n", cp1);
addstr(cp1);
addstr("\n");
cp1 = cp;
i--;
}
while (i >= 0) {
addstr("\n");
i--;
}
refresh();
LYCloseTempFP(fd); /* Close the tmpfile. */
scrollok(stdscr,FALSE); /* Stop scrolling. */
} else {
/*
* Use the internal line editor for the message.
*/
addstr(ENTER_MESSAGE_BELOW);
addstr(ENTER_PERIOD_WHEN_DONE_A);
addstr(ENTER_PERIOD_WHEN_DONE_B);
addstr("\n\n");
refresh();
*user_input = '\0';
if (LYgetstr(user_input, VISIBLE, sizeof(user_input), NORECALL) < 0 ||
term_letter || STREQ(user_input, ".")) {
HTInfoMsg(COMMENT_REQUEST_CANCELLED);
LYCloseTempFP(fd); /* Close the tmpfile. */
scrollok(stdscr,FALSE); /* Stop scrolling. */
goto cleanup;
}
while (!STREQ(user_input, ".") && !term_letter) {
addstr("\n");
remove_tildes(user_input);
fprintf(fd, "%s\n", user_input);
*user_input = '\0';
if (LYgetstr(user_input, VISIBLE,
sizeof(user_input), NORECALL) < 0) {
HTInfoMsg(COMMENT_REQUEST_CANCELLED);
LYCloseTempFP(fd); /* Close the tmpfile. */
scrollok(stdscr,FALSE); /* Stop scrolling. */
goto cleanup;
}
}
fprintf(fd, "\n"); /* Terminate the message. */
LYCloseTempFP(fd); /* Close the tmpfile. */
scrollok(stdscr,FALSE); /* Stop scrolling. */
}
#ifndef VMS
/*
* Ignore CTRL-C on this last question.
*/
signal(SIGINT, SIG_IGN);
#endif /* !VMS */
LYStatusLine = (LYlines - 1);
if (body)
_statusline(SEND_MESSAGE_PROMPT);
else
_statusline(SEND_COMMENT_PROMPT);
LYStatusLine = -1;
c = 0;
while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
!term_letter && c != 7 && c != 3)
c = LYgetch();
if (TOUPPER(c) != 'Y') {
clear(); /* clear the screen */
goto cleanup;
}
if ((body == NULL && LynxSigFile != NULL) &&
(fp = fopen(LynxSigFile, "r")) != NULL) {
LYStatusLine = (LYlines - 1);
_user_message(APPEND_SIG_FILE, LynxSigFile);
c = 0;
LYStatusLine = -1;
while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
!term_letter && c != 7 && c != 3)
c = LYgetch();
if (TOUPPER(c) == 'Y') {
if ((fd = fopen(my_tmpfile, "a")) != NULL) {
fputs("-- \n", fd);
while (fgets(user_input, sizeof(user_input), fp) != NULL) {
fputs(user_input, fd);
}
fclose(fd);
}
}
fclose(fp);
}
clear(); /* Clear the screen. */
/*
* Send the message.
*/
#ifdef VMS
/*
* Set the mail command. - FM
*/
if (isPMDF) {
/*
* For PMDF, put any keywords and the subject
* in the header file and close it. - FM
*/
if (keywords != NULL && *keywords != '\0') {
fprintf(hfd, "Keywords: %s\n", keywords);
}
fprintf(hfd, "Subject: %s\n\n", subject);
LYCloseTempFP(hfd);
/*
* Now set up the command. - FM
*/
sprintf(cmd,
"%s %s %s,%s ",
system_mail,
system_mail_flags,
hdrfile,
my_tmpfile);
} else {
/*
* For "generic" VMS MAIL, include the subject in the
* command, and ignore any keywords to minimize risk
* of them making the line too long or having problem
* characters. - FM
*
* Possibly still a problem if user supplies long subject. - BL
*/
sprintf(cmd,
"%s %s%s/subject=\"%s\" %s ",
system_mail,
system_mail_flags,
(strncasecomp(system_mail, "MAIL", 4) ? "" : "/noself"),
subject,
my_tmpfile);
}
StrAllocCopy(command, cmd);
/*
* Now add all the people in the address field. - FM
*/
address_ptr1 = address;
do {
if ((cp = strchr(address_ptr1, ',')) != NULL) {
address_ptr2 = (cp+1);
*cp = '\0';
} else {
address_ptr2 = NULL;
}
/*
* 4 letters is arbitrarily the smallest possible mail
* address, at least for lynx. That way extra spaces
* won't confuse the mailer and give a blank address.
*
* ignore addresses so long that they would overflow the
* temporary buffer (i.e. about 500 chars). - BL
*/
if (strlen(address_ptr1) > 3 &&
strlen(address_ptr1) + strlen(mail_adrs) < sizeof(cmd)) {
if (!first) {
StrAllocCat(command, ",");
}
sprintf(cmd, mail_adrs, address_ptr1);
StrAllocCat(command, cmd);
first = FALSE;
}
address_ptr1 = address_ptr2;
} while (address_ptr1 != NULL);
/*
* Now add all the people in the CC field. - FM
*/
if (ccaddr != NULL && *ccaddr != '\0') {
address_ptr1 = ccaddr;
do {
if ((cp = strchr(address_ptr1, ',')) != NULL) {
address_ptr2 = (cp+1);
*cp = '\0';
} else {
address_ptr2 = NULL;
}
/*
* 4 letters is arbitrarily the smallest possible mail
* address, at least for lynx. That way extra spaces
* won't confuse the mailer and give a blank address.
*
* ignore addresses so long that they would overflow the
* temporary buffer (i.e. about 500 chars). - BL
*/
if (strlen(address_ptr1) > 3 &&
strlen(address_ptr1) + strlen(mail_adrs) < sizeof(cmd)) {
StrAllocCat(command, ",");
sprintf(cmd, mail_adrs, address_ptr1);
if (isPMDF) {
strcat(cmd, "/CC");
}
StrAllocCat(command, cmd);
}
address_ptr1 = address_ptr2;
} while (address_ptr1 != NULL);
}
stop_curses();
printf("Sending your comment:\n\n$ %s\n\nPlease wait...", command);
LYSystem(command);
FREE(command);
sleep(AlertSecs);
start_curses();
goto cleandown;
#else /* Unix: */
/*
* Send the tmpfile into sendmail.
*/
_statusline(SENDING_YOUR_MSG);
sprintf(cmd, "%s %s", system_mail, system_mail_flags);
#ifdef DOSPATH
if ((fp = LYOpenTemp(tmpfile2, ".txt", "w")) == NULL) {
HTAlert(MAILTO_URL_TEMPOPEN_FAILED);
return;
}
#else
signal(SIGINT, SIG_IGN);
fp = popen(cmd, "w");
if (fp == NULL) {
HTInfoMsg(COMMENT_REQUEST_CANCELLED);
goto cleanup;
}
#endif /* DOSPATH */
fd = fopen(my_tmpfile, "r");
if (fd == NULL) {
HTInfoMsg(COMMENT_REQUEST_CANCELLED);
pclose(fp);
goto cleanup;
}
fputs(header, fp);
while ((n = fread(buf, 1, sizeof(buf), fd)) != 0)
fwrite(buf, 1, n, fp);
#ifdef DOSPATH
StrAllocCopy(command, system_mail);
StrAllocCat(command, " -t \"");
StrAllocCat(command, address);
StrAllocCat(command, "\" -F ");
StrAllocCat(command, tmpfile2);
LYCloseTempFP(fp); /* Close the tmpfile. */
stop_curses();
printf("Sending your comment:\n\n$ %s\n\nPlease wait...", command);
LYSystem(command);
FREE(command);
sleep(MessageSecs);
start_curses();
LYRemoveTemp(tmpfile2); /* Delete the tmpfile. */
#else
pclose(fp);
#endif
LYCloseTempFP(fd); /* Close the tmpfile. */
CTRACE(tfp, "%s\n", cmd);
#endif /* VMS */
/*
* Come here to cleanup and exit.
*/
cleanup:
signal(SIGINT, cleanup_sig);
#if !defined(VMS) && !defined(DOSPATH)
FREE(header);
#endif /* !VMS */
#if defined(VMS) || defined(DOSPATH)
cleandown:
#endif /* VMS */
term_letter = FALSE;
#ifdef VMS
FREE(command);
if (isPMDF) {
LYRemoveTemp(hdrfile);
}
#endif /* VMS */
LYRemoveTemp(my_tmpfile);
FREE(address);
FREE(ccaddr);
FREE(keywords);
FREE(body);
return;
}
PRIVATE void terminate_letter ARGS1(int,sig GCC_UNUSED)
{
term_letter = TRUE;
/* Reassert the AST */
signal(SIGINT, terminate_letter);
#if defined(VMS) || defined(DOSPATH)
/*
* Refresh the screen to get rid of the "interrupt" message.
*/
if (!dump_output_immediately) {
lynx_force_repaint();
refresh();
}
#endif /* VMS */
}
PRIVATE void remove_tildes ARGS1(char *,string)
{
/*
* Change the first character to
* a space if it is a '~'.
*/
if (*string == '~')
*string = ' ';
}