/*	Spawn:	various DOS access commands
		for MicroEMACS
*/

#include        <stdio.h>
#include	"estruct.h"
#include        "edef.h"


/*
 * Create a subjob with a copy of the command intrepreter in it. When the
 * command interpreter exits, mark the screen as garbage so that you do a full
 * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
 * Under some (unknown) condition, you don't get one free when DCL starts up.
 */

spawncli(f, n)
{

	int err_type ;

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());
        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
        TTflush();
	TTkclose();
	err_type = spawnlp(0,"G:COMMAND.COM","cls",NULL) ;
	if (err_type != 0) return (FALSE);
	TTkopen();
        sgarbf = TRUE;
        return(TRUE);
}

/*
 * Run a one-liner in a subjob. When the command returns, wait for a single
 * character to be typed, then mark the screen as garbage so a full repaint is
 * done. Bound to "C-X !".
 */

spawn(f, n)
{
        int	s, err_type ;
        char	line[NLINE];

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());
        if ((s=mlreply("!", line, NLINE)) != TRUE)
                return(s);
	movecursor(term.t_nrow - 1, 0);
	TTkclose();
        err_type = system(line);

	TTkopen();

	/* if we are interactive, pause here */

	if (clexec == FALSE) {
	        mlputs("\r\n\n[End]");
        	tgetc();
        }
        sgarbf = TRUE;
        return (TRUE);
}

/*
 * Run an external program with arguments. When it returns, wait for a single
 * character to be typed, then mark the screen as garbage so a full repaint is
 * done. Bound to "C-X $".
 */

execprg(f, n)

{
        int    s, err_type ;
        char            line[NLINE];

	/* don't allow this command if restricted */

	if (restflag)
		return(resterr());

        if ((s=mlreply("$", line, NLINE)) != TRUE)
                return(s);

	movecursor(term.t_nrow - 1, 0);
	TTkclose();
        err_type = system(line);
	TTkopen();

	/* if we are interactive, pause here */

	if (clexec == FALSE) {
	        mlputs("\r\n\n[End]");
        	tgetc();
        }

        sgarbf = TRUE;
        return (TRUE);
}

/*
 * Pipe a one line command into a window
 * Bound to ^X @
 */

pipecmd(f, n)
{
         int    s, err_type;	/* return status from CLI */
	 WINDOW *wp;		/* pointer to new window */
	 BUFFER *bp;		/* pointer to buffer to zot */
        char	line[NLINE];	/* command line send to shell */
	static char bname[] = "command";

	static char filnam[NSTRING] = "command";


	char *tmp;
	FILE *fp;
	FILE *fopen();

	/* don't allow this command if restricted */

	if (restflag)
		return(resterr());

	if ((tmp = getenv("TMP")) == NULL)
		strcpy(filnam, "command");
	else {
		strcpy(filnam, tmp);
                strcat(filnam,"\\command");
        }

	/* get the command to pipe in */

        if ((s=mlreply("@", line, NLINE)) != TRUE)
                return(s);

	/* get rid of the command output buffer if it exists */

        if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
		/* try to make sure we are off screen */
		wp = wheadp;
		while (wp != NULL) {
			if (wp->w_bufp == bp) {
				onlywind(FALSE, 1);
				break;
			}
			wp = wp->w_wndp;
		}
		if (zotbuf(bp) != TRUE)
			return(FALSE);
	}


	strcat(line," >>");
	strcat(line,filnam);
	movecursor(term.t_nrow - 1, 0);
	TTkclose();

        err_type = system(line);

	TTkopen();
        sgarbf = TRUE;
	if ((fp = fopen(filnam, "r")) == NULL) {
		s = FALSE;
	} else {
		fclose(fp);
		s = TRUE;
	}


	if (s != TRUE)
		return(s);
	/* split the current window to make room for the command output */
	if (splitwind(FALSE, 1) == FALSE)
			return(FALSE);
	/* and read the stuff in */
	if (getfile(filnam, FALSE) == FALSE)
		return(FALSE);
	/* make this window in VIEW mode, update all mode lines */
	curwp->w_bufp->b_mode |= MDVIEW;
	wp = wheadp;
	while (wp != NULL) {
		wp->w_flag |= WFMODE;
		wp = wp->w_wndp;
	}
	/* and get rid of the temporary file */
	unlink(filnam);
	return(TRUE);
}

/*
 * filter a buffer through an external DOS program
 * Bound to ^X #
 */

filter(f, n)
{
	int    s, err_type ;	/* return status from CLI */
	BUFFER *bp;		/* pointer to buffer to zot */
        char line[NLINE];	/* command line send to shell */
	char tmpnam[NFILEN];	/* place to store real file name */
	static char bname1[] = "fltinp";

	static char filnam1[] = "fltinp";
	static char filnam2[] = "fltout";

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());
	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
		return(rdonly());	/* we are in read only mode	*/


	/* get the filter name an d its args */
        if ((s=mlreply("#", line, NLINE)) != TRUE)
                return(s);
	/* setup the proper file names */
	bp = curbp;
	strcpy(tmpnam, bp->b_fname);	/* save the original name */
	strcpy(bp->b_fname, bname1);	/* set it to our new one */
	/* write it out, checking for errors */
	if (writeout(filnam1) != TRUE) {
		mlwrite("[Cannot write filter file]");
		strcpy(bp->b_fname, tmpnam);
		return(FALSE);
	}


	strcat(line," <fltinp >fltout");
	movecursor(term.t_nrow - 1, 0);
	TTkclose();

        err_type = system(line);

	TTkopen();
        sgarbf = TRUE;
	s = TRUE;


	/* on failure, escape gracefully */
	if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
		mlwrite("[Execution failed]");
		strcpy(bp->b_fname, tmpnam);
		unlink(filnam1);
		unlink(filnam2);
		return(s);
	}
	/* reset file name */
	strcpy(bp->b_fname, tmpnam);	/* restore name */
	bp->b_flag |= BFCHG;		/* flag it as changed */
	/* and get rid of the temporary file */
	unlink(filnam1);
	unlink(filnam2);
	return(TRUE);
}
