
/*
 *  SCLI.C
 *
 *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
 *
 *  SHELL SERVER.   THIS REQUIRES MY PIPE DEVICE TO WORK!!!!!!!!!!
 *
 *  Use DSOC on the UNIX end (DSOC 8193)
 *
 *  Only one connection accepted at a time in this baby.
 *  HUGE CLUDGE!!!
 *
 *  DNET_LEVEL must be 9 or higher.
 */

#include <stdio.h>
#include <fcntl.h>
#include "servers.h"

int Enable_Abort;
char Buf[4096];

typedef struct Process PROC;

extern struct MsgPort *DListen();
extern PROC *FindTask();

_main()
{
    struct MsgPort *port;
    PROC    *proc = FindTask(NULL);
    long    chan;
    long    mask, rmask;
    long    len, n;
    char    nl, co;
    int     fd;
    long    namei = (long)proc;
    APTR    oldwptr;
    char    mycis = 0, mycos = 0;

    Enable_Abort = 0;
    if (proc->pr_CLI) {
	Version("SCli", VERSION, SCLI_VERSION);
	_exit(0);
    }


    port = DListen(8196);
    WaitPort(&proc->pr_MsgPort);
    ReplyMsg(GetMsg(&proc->pr_MsgPort));
    if (!port)
	_exit(1);
    mask = SIGBREAKF_CTRL_C|(1 << port->mp_SigBit);
    oldwptr = proc->pr_WindowPtr;
    proc->pr_WindowPtr = (APTR)-1;
    /*proc->pr_ConsoleTask = DeviceProc("dpipe:");
    if (!proc->pr_CIS) {
	mycis = 1;
	proc->pr_CIS = Open("nil:", 1006);
    }
    if (!proc->pr_COS) {
	mycos = 1;
	proc->pr_COS = Open("nil:", 1006);
    }
    */
    for (;;) {
	rmask = Wait(mask);
	if (rmask & SIGBREAKF_CTRL_C)
	    break;
	if (chan = DAccept(port)) {
	    long fh;
	    long mask;
	    long fhmask, smask;
	    short sig;
	    char pname[16];
	    char buf[64];

	    if (GetEnvVal(DNET_LEVEL) < 9) {
		DWrite(chan, "Permission Denied\n", 18);
		DClose(chan);
		continue;
	    }


	    sprintf(pname, "%08lx", namei++);
	    sprintf(buf, "newshell <nil: >nil: dpipe:%s/St FROM s:remote-startup", pname);
	    Execute(buf, NULL, NULL);
	    sig = AllocSignal(-1);
	    fhmask = 1 << sig;
	    smask = 1 << ((struct MsgPort *)chan)->mp_SigBit;
	    sprintf(buf, "dpipe:%s/Mctns%ld", pname, sig);
	    fh = Open(buf, 1006);
	    if (fh) {
		char notdone = 1;
		DWrite(chan, "Amiga CLI   running\n", 20);
		while (notdone) {
		    char buf[256];
		    int n;
		    mask = Wait(fhmask | smask | SIGBREAKF_CTRL_C);
		    while ((n = Read(fh, buf, 256)) > 0) {
			DWrite(chan, buf, n);
		    }
		    if (n < 0)
			notdone = 0;
		    while ((n = DNRead(chan, buf, 256)) > 0) {
			/*
			DWrite(chan, buf, n);
			*/
			Write(fh, buf, n);
		    }
		    if (n == -2) {
			short pv;
			short pa;
			DGetIoctl(chan, &pv, &pa);
		    } else if (n < 0)
			notdone = 0;
		}
		Write(fh, "ENDCLI\n", 7);
		Write(fh, "ENDCLI\n", 7);
		Close(fh);
	    }
	    DClose(chan);
	    FreeSignal(sig);
	    puts("DONE");
	}
    }
    proc->pr_WindowPtr = oldwptr;
    if (mycos) {
	Close(proc->pr_COS);
	proc->pr_COS = NULL;
    }
    if (mycis) {
	Close(proc->pr_CIS);
	proc->pr_CIS = NULL;
    }
    DUnListen(port);
}



