/* spool.c - action for menu item type 'S'
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif				/* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include "hook.h"
#include "terminal.h"
#include "viewfile.h"
#include "viewmenu.h"


extern int menuview_rescan_now;


/* Spool "e" to a temporary file and read it.
 */
void menuview_spooled(menudata_t data, menuentry_t * e)
{
	struct LDB d;
	char *file;
	pid_t c, r;
	int fd, s;
	time_t t;

	if (!e->filename)
		return;

	if (bbs_hook(HOOK_VET_COMMAND, e->filename, data))
		return;

	file = (char *) malloc(strlen(P_tmpdir) + 32);
	if (!file)
		return;
	strcpy(file, P_tmpdir);
	strcat(file, "/mviewXXXXXX");
	fd = mkstemp(file);
	if (fd < 0) {
		remove(file);
		free(file);
		return;
	}

	if (!(e->status & MENU_STATUS_BARLOG))
		bbs_hook(HOOK_LOG_RUN, e, data);

	c = fork();
	if (c == 0) {
		setenv("SPOOL_FILE", file, 1);	/* make filename available */
		dup2(fd, 1);
		dup2(fd, 2);
		close(fd);
		strcpy(data->buf, data->file);
		file = strrchr(data->buf, '/');	/* set CWD */
		if (file)
			*file = 0;
		bbs_hook(HOOK_SET_ACTION, "Spooling", 0);
		bbs_hook(HOOK_SET_KEYPATH, 0, 0);
		menuview_system(e->filename, data->buf);
		exit(0);
	}

	close(fd);

	if (c < 0) {
		remove(file);
		free(file);
		return;
	}

	bbs_hook(HOOK_SET_ACTION, "Run ",
		 (e->status & MENU_STATUS_HIDETITLE) ? "" : e->title);
	bbs_hook(HOOK_SET_KEYPATH, data->buf, 0);

	if ((e->param < 1) || (e->param == '!')) {

		do {

			alarm(10);	    /* update status every 10 seconds */
			r = KEY_NONE;
			bbs_hook(HOOK_KEY_PRESSED, &c, &r);

			r = waitpid(c, &s, 0);

		} while ((r != c) || (!WIFEXITED(s)));

	} else {
		t = time(0) + e->param;
		t_bored(0);
		do {
			sleep(1);
			t_bored(1);
			r = KEY_NONE;
			bbs_hook(HOOK_KEY_PRESSED, &c, &r);
			r = waitpid(c, &s, WNOHANG);
		} while (((r != c) || (!WIFEXITED(s))) && (time(0) < t));
		kill(c, SIGKILL);
		t_bored(0);
	}

	ldb_read(0, file, &d);
	strcpy(d.realname, file);
	do_read_file(&d, e->title, e->status | MENU_STATUS_NOLAST, 0);

	remove(file);
	free(file);

	if (e->param == '!')
		menuview_rescan_now = 1;
}

/* EOF */
