/* mail.c - mail current file to self
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif				/* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include "mstring.h"
#include "terminal.h"
#include "viewfile.h"
#include "hook.h"

extern int menuview_abort;


/* Open a file stream as a pipe to sendmail. This is not re-entrant. If
 * "data" is 0, closes the stream instead.
 *
 * Returns 0 on error when opening.
 */
FILE *rf_popen(rf_data_t data)
{
	static pid_t child;
	static int p[2];
	static FILE *fptr = 0;
	pid_t result;
	int status;

	if (data) {			    /* open pipe */
		if (pipe(p))
			return (0);
		child = fork();
		if (child == 0) {
			bbs_hook(HOOK_DROP_PRIVS, SENDMAIL_PATH, 0);
			dup2(p[0], STDIN_FILENO);
			close(p[1]);
			execlp(SENDMAIL_PATH, "sendmail", "-it", 0);
			exit(1);
		} else if (child < 0) {
			close(p[0]);
			close(p[1]);
			return (0);
		}
		close(p[0]);
		fptr = fdopen(p[1], "w");
		return (fptr);
	}

	fclose(fptr);			    /* close pipe */
	close(p[1]);

	do {
		alarm(10);		    /* update status every 10 seconds */
		result = KEY_NONE;
		bbs_hook(HOOK_KEY_PRESSED, 0, &result);

		result = waitpid(child, &status, 0);
		if ((result <= 0)
		    && ((errno == EAGAIN) || (errno == EINTR)))
			result = 1;

	} while (result > 0);

	return (0);
}


/* [M] - Mail file to self.
 */
void rf_mail_file(rf_data_t data)
{
	FILE *fptr;
	char *a;
	long n, e, i;
	int c;

	if (data->flags & MENU_STATUS_BARMAIL)
		return;

	rf_redraw = 1;

	if (bbs_hook(HOOK_CHECK_BAN, "M", 0)) {
		t_goto(0, t_rows - 1);
		t_clrtoeol();
		t_centre
		    ("\035R  *** You are banned from mailing files ***  \035r");
		sleep(2);
		return;
	}

	do {
		if (rf_redraw) {
			rf_wipe_footer(data);
			t_goto(0, t_rows - 1);
			t_centre("[\035BSPACE\035b]:Mail file  "
				 "[\035BE\035b]:Mail entry  "
				 "[\035BQ\035b]:Quit");
			rf_redraw = 0;
		}
		c = toupper(t_getchar(1));
		if (menuview_abort)
			c = 'Q';
		if (c == 12)
			rf_redraw = 1;
	} while ((c != ' ') && (c != 'Q') && (c != 'E'));

	rf_wipe_footer(data);

	if (c == 'E') {			    /* ask user which entry to mail */
		n = data->ldb_entry->current_line;
		c = rf_scan_entries(data, &n,
				    "[\035BSPACE\035b]:Mail  [\035BQ\035b]:Quit",
				    " ", 0, current_user);
		rf_wipe_footer(data);
		if (c != 'Q')
			c = 'E';
	}

	if (c == 'Q') {
		rf_footer(data);
		return;
	}

	if (c == 'E') {			    /* find end of selected entry */
		for (e = n + 1; (e < data->num_lines)
		     && (data->line_pos[e].type != MFILE_LINE_DATESTAMP);
		     e++);
	} else {
		n = 0;
		e = data->num_lines;
	}

	a = current_user;

	if (!bbs_hook(HOOK_LOOKUP_EMAIL, &a, 0)) {

		fptr = rf_popen(data);
		if (!fptr) {
			rf_footer(data);
			return;
		}

		t_goto(0, t_rows - 1);
		t_centre("\035R *** Mailing *** \035r");

		strncpy(data->linebuf, data->title, sizeof(data->linebuf));
		mstripattr(data->linebuf);

		fprintf(fptr, "To: %s\n", a);

		fprintf(fptr, "Subject: %s%s\n\n",
			(c == 'E') ? "Part of " : "", data->linebuf);

		t_bored(0);

		for (i = n; i < e; i++) {
			rf_read_line(data, i);
			mtagexpand(data->linebuf, sizeof(data->linebuf),
				   79,
				   (data->
				    flags & MENU_STATUS_ANONYMOUS) ? 1 : 0,
				   0);
			mstripattr(data->linebuf);
			a = strchr(data->linebuf, '\n');
			if (a)
				*a = 0;
			fprintf(fptr, "%s\n", data->linebuf);
			t_bored(1);
		}

		rf_popen(0);

		if (!(data->flags & MENU_STATUS_BARLOG))
			bbs_hook(HOOK_LOG_MAIL, data, 0);
	}

	t_bored(0);
	rf_wipe_footer(data);
	rf_footer(data);
}

/* EOF */
