#include "HTUtils.h"
#include "tcp.h"
#include "HTAlert.h"
#include "LYCurses.h"
#include "LYSignal.h"
#include "LYUtils.h"
#include "LYClean.h"
#include "LYStrings.h"
#include "GridText.h"
#include "LYSystem.h"
#include "LYGlobalDefs.h"
#include "HTParse.h"

#include "LYLeaks.h"

#define FREE(x) if (x) {free(x); x = NULL;}

/*
 * mailform sends form content to the mailto address(es) - FM
 */

PUBLIC void mailform ARGS3(char *,mailto_address, char *,mailto_subject,
			   char *,mailto_content)
{
	FILE *fd;
	char *address = NULL;
	char cmd[256], *cp, *cp0, *cp1;
	int len, i, ch, recall;
	char subject[80];
#ifdef VMS
	char tmpfile[80];
	char *address_ptr1, *address_ptr2;
	BOOLEAN first=TRUE;
#endif /* VMS */

	if (!mailto_address || !mailto_subject || !mailto_content) {
	    HTAlert("Malformed mailto form submission!  Cancelled.");
	    return;
	}

	if((cp = (char *)strchr(mailto_address,'\n')) != NULL)
	    *cp = '\0';
	StrAllocCopy(address, mailto_address);

	/* Check for a ?subject=foo */
	subject[0] = '\0';
	if ((cp=strchr(address, '?')) != NULL &&
	    strcasecomp(cp+1, "subject=")) {
	    *cp = '\0';
	    cp += 9;
	    strncpy(subject, cp, 70);
	    subject[70] = '\0';
	    HTUnEscape(subject);
	}

	/* Unescape any hex escaped pounds. */
	while((cp1=strstr(address, "%23")) != NULL) {
	    *cp1 = '#';
	    cp0 = (cp1 + 1);
	    cp1 = (cp0 + 2);
	    for (i = 0; cp1[i]; i++) {
	        cp0[i] = cp1[i];
	    }
	    cp0[i] = '\0';
	}

	/* Unescape any hex escaped percents. */
	while((cp1=strstr(address, "%25")) != NULL) {
	    cp0 = (cp1 + 1);
	    cp1 = (cp0 + 2);
	    for (i = 0; cp1[i]; i++) {
	        cp0[i] = cp1[i];
	    }
	    cp0[i] = '\0';
	}

	/*
	 * Convert any Explorer semi-colon Internet address
	 * separators to commas.
	 */
	cp = address;
	while ((cp1=strchr(cp, '@')) != NULL) {
	    cp1++;
	    if ((cp0 = strchr(cp1, ';')) != NULL) {
	        *cp0 = ',';
		cp1 = cp0 + 1;
	    }
	    cp = cp1;
	}

        /* Allow user to edit the default Subject */
	if (subject[0] == '\0') {
	    strncpy(subject, mailto_subject, 70);
	    subject[70] = '\0';
	}
	recall = 0;
	_statusline("Subject: ");
	if ((ch=LYgetstr(subject, VISIBLE, 71, recall)) < 0) {
	    /*
	     * User cancelled via ^G. - FM
	     */
	    _statusline("Mailto form submission Cancelled!!!");
	    sleep(InfoSecs);
	    FREE(address);
	    return;
	 }

#ifdef UNIX
#ifdef MMDF
	sprintf(cmd, "%s -mlruxto,cc\\*",system_mail);
#else
	sprintf(cmd, "%s -t -oi", system_mail);
#endif /* MMDF */

	if ((fd = popen(cmd, "w")) == NULL) {
	    HTAlert("Mailto form submission failed!");
	    FREE(address);
	    return;
	}

	fprintf(fd,"To: %s\n", address);
	if (personal_mail_address && *personal_mail_address)
	    fprintf(fd,"From: %s\n", personal_mail_address);
	fprintf(fd,"Subject: %.70s\n\n", subject);
	_statusline("Sending form content....");
#endif /* UNIX */
#ifdef VMS
	sprintf(tmpfile,"%s%s",lynx_temp_space, "temp_mail.");
	if((fd = fopen(tmpfile,"w")) == NULL) {
	    HTAlert("Mailto form submission failed!");
	    FREE(address);
	    return;
	}

#endif /* VMS */

	/*
	 * Break up the content into lines with a maximimum length of 78.
	 * The actual newline characters in the content are hex escaped.
	 */
	i = 0;
	len = strlen(mailto_content);
	while (len > 78) {
	    strncpy(cmd, (char *)&mailto_content[i], 78);
	    cmd[78] = '\0';
	    fprintf(fd, "%s\n", cmd);
	    i += 78;
	    len = strlen((char *)&mailto_content[i]);
	}
	if (len)
	    fprintf(fd, "%s\n", (char *)&mailto_content[i]);

#ifdef UNIX
	pclose(fd);
	sleep(MessageSecs);
#endif /* UNIX */
#ifdef VMS
	fclose(fd);
	sprintf(cmd, "%s /subject=\"%.70s\" %s ",system_mail,
						 subject,tmpfile);


	address_ptr1 = address;
	do {
	    if((cp = strchr(address_ptr1,',')) != NULL) {
	        address_ptr2=cp+1;
	        *cp = '\0';
	    } else
		address_ptr2=NULL;
	
	    if(strlen(address) > 3) {
		if(!first)
		    strcat(cmd, ", ");  /* add a comma and a space */
	        sprintf( &cmd[strlen(cmd)], mail_adrs, address_ptr1);
		first = FALSE;
	    }

	    address_ptr1=address_ptr2;
	} while(address_ptr1!=NULL);

        stop_curses();
	printf("Sending form content:\n\n$ %s\n\nPlease wait...", cmd);
	system(cmd);
	sleep(MessageSecs);
	start_curses();
	remove(tmpfile);
#endif /* VMS */

	FREE(address);
	return;
}

/*
 * mailmsg sends a message to the owner of the
 * file if one is defined telling of errors. (ie link not available)
 */

PUBLIC void mailmsg ARGS4(int,cur, char *,owner_address, 
		char *,filename, char *,linkname)
{
	FILE *fd;
	char *address = NULL;
	char cmd[256], *cp, *cp0, *cp1;
	int i;
#ifdef VMS
	char tmpfile[80];
	char *address_ptr1, *address_ptr2;
	BOOLEAN first=TRUE;
#endif /* VMS */

	if ((cp = (char *)strchr(owner_address,'\n')) != NULL)
		*cp = '\0';
	StrAllocCopy(address, owner_address);

	/* Check for a ?subject=foo and trim it. */
	if ((cp=strchr(address, '?')) != NULL &&
	    strcasecomp(cp+1, "subject="))
	    *cp = '\0';

	/* Unescape any hex escaped pounds. */
	while((cp1=strstr(address, "%23")) != NULL) {
	    *cp1 = '#';
	    cp0 = (cp1 + 1);
	    cp1 = (cp0 + 2);
	    for (i = 0; cp1[i]; i++) {
	        cp0[i] = cp1[i];
	    }
	    cp0[i] = '\0';
	}

	/* Unescape any hex escaped percents. */
	while((cp1=strstr(address, "%25")) != NULL) {
	    cp0 = (cp1 + 1);
	    cp1 = (cp0 + 2);
	    for (i = 0; cp1[i]; i++) {
	        cp0[i] = cp1[i];
	    }
	    cp0[i] = '\0';
	}
	
	/*
	 * Convert any Explorer semi-colon Internet address
	 * separators to commas.
	 */
	cp = address;
	while ((cp1=strchr(cp, '@')) != NULL) {
	    cp1++;
	    if ((cp0 = strchr(cp1, ';')) != NULL) {
	        *cp0 = ',';
		cp1 = cp0 + 1;
	    }
	    cp = cp1;
	}

#ifdef UNIX
#ifdef MMDF
	sprintf(cmd, "%s -mlruxto,cc\\*",system_mail);
#else
	sprintf(cmd, "%s -t -oi", system_mail);
#endif /* MMDF */

	if ((fd = popen(cmd, "w")) == NULL) {
	    FREE(address);
	    return;
	}

	fprintf(fd,"To: %s\n", address);
	fprintf(fd,"Subject: Lynx Error in %s\n\n",filename);
	fprintf(fd,"X-URL: %s\n",filename);
	fprintf(fd,"X-Mailer: Lynx, Version %s\n",LYNX_VERSION);
#endif /* UNIX */
#ifdef VMS
	sprintf(tmpfile,"%s%s",lynx_temp_space, "temp_mail.");
	if((fd = fopen(tmpfile,"w")) == NULL) {
	    FREE(address);
	    return;
	}

#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);
#ifdef UNIX
	pclose(fd);
#endif /* UNIX */
#ifdef VMS
	fclose(fd);
	sprintf(cmd, "%s /subject=\"Lynx Error in %s\" %s ",system_mail,
							filename,tmpfile);


	address_ptr1 = address;
	do {
	    if((cp = strchr(address_ptr1,',')) != NULL) {
	        address_ptr2=cp+1;
	        *cp = '\0';
	    } else
		address_ptr2=NULL;
	
	    if(strlen(address) > 3) {
		if(!first)
		    strcat(cmd, ", ");  /* add a comma and a space */
	        sprintf( &cmd[strlen(cmd)], mail_adrs, address_ptr1);
		first = FALSE;
	    }

	    address_ptr1=address_ptr2;
	} while(address_ptr1!=NULL);

	system(cmd);
	remove(tmpfile);
#endif /* VMS */

	if (traversal) {
	    FILE *ofp;

	    if((ofp = fopen(TRAVERSE_ERRORS,"a+")) == NULL) {
                if((ofp = fopen(TRAVERSE_ERRORS,"w")) == NULL) {
		    perror("unable to open traversal errors output file");
		    exit(-1);
                }
	    }

	    fprintf(ofp,"%s	%s 	in %s\n",links[cur].lname, 
						links[cur].target, filename);
	    fclose(ofp);
	}

	FREE(address);
	return;
}

/*
 * this procedure only works on unix & VMS 
 * reply by mail invokes sendmail or mail on VMS to send a comment 
 * from the users to the owner 
 */

/* global variable for async i/o */
BOOLEAN term_letter;
PRIVATE void terminate_letter  PARAMS((int sig));
PRIVATE void remove_tildes PARAMS((char *string));

PUBLIC void reply_by_mail ARGS3(char *,mail_address,
				char *,filename, char *,title)
{
	char user_input[1000];
	FILE *fd;
	char *address = NULL, *cp, *cp0, *cp1;
	int i;
	int c;  /* user input */
	char tmpfile[100], cmd[256];
	static char * personal_name=NULL;
	char subject[80];
#ifdef VMS
	char *address_ptr1=NULL, *address_ptr2=NULL;
	BOOLEAN first=TRUE;
#else
	char buf[512];
	char *header = NULL;
	FILE *fp;
	int n;
#endif /* VMS */

	term_letter=FALSE;

	clear();
	move(2,0);

	tempname(tmpfile,NEW_FILE);
	if((fd = fopen(tmpfile,"w")) == NULL)
	    return;

	if (mail_address && *mail_address)
	    StrAllocCopy(address, mail_address);
	else
	    StrAllocCopy(address, "");

	/* Check for a ?subject=foo */
	subject[0] = '\0';
	if ((cp=strchr(address, '?')) != NULL &&
	    strcasecomp(cp+1, "subject=")) {
	    *cp = '\0';
	    cp += 9;
	    strncpy(subject, cp, 70);
	    subject[70] = '\0';
	    HTUnEscape(subject);
	}
	if (subject[0] == '\0' && title && *title) {
	    strncpy(subject, title, 70);
	    subject[70] = '\0';
	}

	/* Unescape any hex escaped pounds. */
	while((cp1=strstr(address, "%23")) != NULL) {
	    *cp1 = '#';
	    cp0 = (cp1 + 1);
	    cp1 = (cp0 + 2);
	    for (i = 0; cp1[i]; i++) {
	        cp0[i] = cp1[i];
	    }
	    cp0[i] = '\0';
	}

	/* Unescape any hex escaped percents. */
	while((cp1=strstr(address, "%25")) != NULL) {
	    cp0 = (cp1 + 1);
	    cp1 = (cp0 + 2);
	    for (i = 0; cp1[i]; i++) {
	        cp0[i] = cp1[i];
	    }
	    cp0[i] = '\0';
	}
	
	/*
	 * Convert any Explorer semi-colon Internet address
	 * separators to commas.
	 */
	cp = address;
	while ((cp1=strchr(cp, '@')) != NULL) {
	    cp1++;
	    if ((cp0 = strchr(cp1, ';')) != NULL) {
	        *cp0 = ',';
		cp1 = cp0 + 1;
	    }
	    cp = cp1;
	}

	addstr("You are now sending a comment to:");
	addstr("\n	");
	if(*address != '\0') {
	    addstr(address);
	}
	addstr("\n\nUse Ctrl-G to cancel if you do not want to send a message\n\n");

	/* Use ^G to cancel mailing of comment */
	/* and don't let sigints exit lynx     */
        signal(SIGINT, terminate_letter);

#ifdef UNIX
	/* put the to: line in the temp file */
	sprintf(buf,"To: %s\n", address);
	StrAllocCat(header, buf);
	sprintf(buf,"X-URL: %s%s\n",*filename ? filename : "mailto:",
				    *filename ? "" : address);
	StrAllocCat(header, buf);
	sprintf(buf,"X-Mailer: Lynx, Version %s\n",LYNX_VERSION);
	StrAllocCat(header, buf);
#endif /* UNIX */


#ifdef NO_ANONYMOUS_EMAIL
	addstr(" Please enter a mail address or some other\n");
	addstr(" means to contact you in the message, if you\n");
	addstr(" desire a response.");
#ifdef VMS
	fprintf(fd,"X-Mailer: Lynx, Version %s\n",LYNX_VERSION);
#endif /* VMS */
#else /* !NO_ANONYMOUS_EMAIL */

	addstr(" Please enter your name, or leave it blank if you wish to remain anonymous\n");
	if(personal_name == NULL)
	    *user_input = '\0';
	else {
	    addstr(" Use Control-U to erase the default.\n");
	    strcpy(user_input, personal_name);
	}
#ifdef VMS
	addstr("X_Personal_name: ");
#else
	addstr("Personal Name: ");
#endif /* VMS */
	if (LYgetstr(user_input, VISIBLE,
		     sizeof(user_input), NORECALL) < 0 ||
	    term_letter) {
	    _statusline("Comment request cancelled!!!");
	    fclose(fd);  /* close the temp file */
	    sleep(InfoSecs);
	    goto cleanup;
	}

	remove_tildes(user_input);
	StrAllocCopy(personal_name, user_input);

	term_letter=FALSE;
#ifdef VMS
	fprintf(fd,"X-URL: %s%s\n",*filename ? filename : "mailto:",
				   *filename ? "" : address);
	fprintf(fd,"X-Mailer: Lynx, Version %s\n",LYNX_VERSION);
	if (*user_input)
	    fprintf(fd,"X-Personal_name: %s\n",user_input);
#else
	sprintf(buf,"X-Personal_name: %s\n",user_input);
	StrAllocCat(header, buf);
#endif /* VMS */

	addstr("\n\n Please enter a mail address or some other\n");
	addstr(" means to contact you, if you desire a response.\n");
	if (personal_mail_address)
	    addstr(" Use Control-U to erase the default.\n");
#ifdef VMS
	addstr("X-From: ");
#else
	addstr("From: ");
#endif /* VMS */
	/* 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) {
	    _statusline("Comment request cancelled!!!");
	    sleep(InfoSecs);
	    fclose(fd);  /* close the temp file */
	    goto cleanup;
	}
	remove_tildes(user_input);

#ifdef VMS
	if (*user_input)
	    fprintf(fd,"X-From: %s\n\n",user_input);
	else
	    fprintf(fd, "\n");
#else
	sprintf(buf,"From: %s\n",user_input);
	StrAllocCat(header, buf);
#endif /* VMS */

#endif /* NO_ANONYMOUS_EMAIL */

	addstr("\n\n Please enter a subject line.\n");
	addstr(" Use Control-U to erase the default.\n");
	addstr("Subject: ");
	sprintf(user_input, "%.70s%.63s", (subject[0] != '\0') ?
			       subject : (*filename ? filename : "mailto:"),
			     		  (subject[0] != '\0') ?
				  "" :	(*filename ? "" : address));
	if (LYgetstr(user_input, VISIBLE, 71, NORECALL) < 0 ||
	    term_letter) {
	    _statusline("Comment request cancelled!!!");
	    sleep(InfoSecs);
	    fclose(fd);  /* close the temp file */
	    goto cleanup;
	}
	remove_tildes(user_input);

#ifdef VMS
	sprintf(subject, "%.70s", user_input);
#else
	sprintf(buf,"Subject: %s\n",user_input);
	StrAllocCat(header, buf);
#endif /* VMS */

#ifndef VMS
	addstr("\n\n Enter a mail address for a CC of your\n");
	addstr(" message, if you desire a copy.\n");
	if (personal_mail_address)
	    addstr(" Use Control-U to erase the default.\n");
	addstr(" (Leave blank if you don't want a copy.)\n");
	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) {
	    _statusline("Comment request cancelled!!!");
	    sleep(InfoSecs);
	    fclose(fd);  /* close the temp file */
	    goto cleanup;
	}
	remove_tildes(user_input);

	if (*user_input)
	    sprintf(buf,"Cc: %s\n\n",user_input);
	else
	    sprintf(buf,"\n");  /* terminate header */
	StrAllocCat(header, buf);
#endif /* !VMS */

	if(!no_editor && editor && *editor != '\0' && 
					strcmp(HTLoadedDocumentURL(),"")) {
	    char *editor_arg = "";

            /* ask if the user wants to include the original message */
            _statusline("Do you wish to include the original message? (y/n) ");
            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 */
                print_wwwfile_to_fd(fd,1);
        
	    fclose(fd);

	    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,tmpfile);
	    _statusline("Spawning your selected editor to edit mail message");
	    stop_curses();
	    if(system(user_input)) {
	        start_curses();
		_statusline(
    "Error spawning editor, check your editor definition in the options menu");
	  	sleep(AlertSecs);
	    } else {
	        start_curses();
	    }

	} else {
	
	    addstr("\n\n Please enter your message below.");
	    addstr("\n When you are done, press enter and put a single period (.)");
	    addstr("\n on a line and press enter again.");
	    addstr("\n\n");
	    scrollok(stdscr,TRUE);
	    refresh();
    	    *user_input = '\0';
	    if (LYgetstr(user_input, VISIBLE,
	    		 sizeof(user_input), NORECALL) < 0 ||
	        term_letter) {
	        _statusline("Comment request cancelled!!!");
	        sleep(InfoSecs);
	        fclose(fd);  /* close the temp file */
	        goto cleanup;
	    }


	    while(!STREQ(user_input,".") && !term_letter) { 
	       addch('\n');
	       remove_tildes(user_input);
	       fprintf(fd,"%s\n",user_input);
	       *user_input = '\0';
	       if (LYgetstr(user_input, VISIBLE,
	       		    sizeof(user_input), NORECALL) < 0) {
	          _statusline("Comment request cancelled!!!");
	          sleep(InfoSecs);
	          fclose(fd);  /* close the temp file */
	          goto cleanup;
	       }
	    }

	    fprintf(fd,"\n");

	    fclose(fd);  /* close the temp file */
	    scrollok(stdscr,FALSE);  /* stop scrolling */
	}

	/*
	 *	Ignore CTRL-C on this last question.
	 */
#ifndef VMS
        signal(SIGINT, SIG_IGN);
#endif /* !VMS */

	_statusline("Send this comment? (y/n) ");
	c = 0;
	while(TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
	      !term_letter && c != 7   && c != 3)
	    c = LYgetch();

	clear();  /* clear the screen */

	if(TOUPPER(c) != 'Y') {
	   goto cleanup;
	}

#ifdef VMS
	sprintf( cmd, "%s /subject=\"%s\" %s ",
		  system_mail, subject, tmpfile);

	/* now add all the people in the address field */
	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 posible mail address,
	     * at least for lynx.  That way extra spaces won't
	     * confuse the mailer and give a blank address
	     */
	    if(strlen(address_ptr1) > 3) {	
	        if(!first)
		    strcat(cmd, ", ");  /* add a comma and a space */
	        sprintf( &cmd[strlen(cmd)], mail_adrs, address_ptr1);
		first=FALSE;
	    }

	    address_ptr1=address_ptr2;
	} while(address_ptr1!=NULL);

        stop_curses();
	printf("Sending your comment:\n\n$ %s\n\nPlease wait...", cmd);
	system(cmd);
	sleep(MessageSecs);
	start_curses();
	goto cleandown;
#else
	/* send the tmpfile into sendmail.  
	 */
	_statusline("Sending your message....");
#ifdef MMDF
	sprintf(cmd, "%s -mlruxto,cc\\*",system_mail);
#else
	sprintf(cmd,"%s -t -oi", system_mail);
#endif /* MMDF */

	signal(SIGINT, SIG_IGN);
	fp = popen(cmd, "w");
	if (fp == NULL) {
	    _statusline("Comment request cancelled!!!");
	    sleep(InfoSecs);
	    goto cleanup;
	}
	fd = fopen(tmpfile, "r");
	if (fd == NULL) {
	    _statusline("Comment request cancelled!!!");
	    sleep(InfoSecs);
	    pclose(fp);  /* close the temp file */
	    goto cleanup;
	}
	fputs(header, fp);
	while ((n = fread(buf, 1, sizeof(buf), fd)) != 0)
		fwrite(buf, 1, n, fp);
	pclose(fp);
	fclose(fd);

	if(TRACE)
	    printf("%s\n",cmd);

#endif /* VMS */

	/* come here to cleanup and exit */
cleanup:
	signal(SIGINT, cleanup_sig);
#ifndef VMS
	FREE(header);
#endif /* !VMS */

#ifdef VMS
cleandown:
#endif /* VMS */
	term_letter = FALSE;

	scrollok(stdscr,FALSE);  /* stop scrolling */
#ifdef SCO
	unlink(tmpfile);
#else
	remove(tmpfile);
#endif /* SCO */

	FREE(address);
	return;
}

PRIVATE void terminate_letter ARGS1(int,sig)
{
	term_letter=TRUE;
	/* Reassert the AST */
	signal(SIGINT, terminate_letter);
#ifdef VMS
        /* Refresh the screen to get rid of the "interrupt" message */
	if (!dump_output_immediately) {
	    clearok(curscr, TRUE);
	    refresh();
	}
#endif /* VMS */
}

PRIVATE void remove_tildes ARGS1(char *,string)
{
       /* change the first character to a space if
	* it is a '~'
	*/
    if(*string == '~')
	*string = ' ';
}
