
/*
 *  COMMAND.C
 *
 */

#include "defs.h"
#include <exec/libraries.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>

#define BTOC(bptr,ctype)    ((ctype *)((long)bptr << 2))
#define CTOB(ptr)           ((long)(ptr) >> 2)

typedef struct CommandLineInterface	CLI;
typedef struct Process			Process;

extern struct Library *SysBase;

ExecuteCmdList(list)
MLIST *list;
{
    register NODE *node;
    static __aligned char LBuf[1024];	  /*  offset 1 for BCPL presert   */

    if (XDebug)
	printf("ExecuteCmdList\n");
    if (list) {
	for (node = GetHead(list); node; node = GetSucc(node)) {
	    strcpy(LBuf + 1, node->ln_Name);
	    MacroReplace(1, LBuf + 1, strlen(LBuf + 1));
	    fprintf(stderr, "%s\n", LBuf + 1);
	    if (!ListOnly) {
		if (Execute_Command(LBuf + 1))     /*  error!  */
		    xexit(1);
		if (SetSignal(0,0) & SIGBREAKF_CTRL_C) {
		    puts("^C");
		    xexit(1);
		}
	    }
	}
    }
    if (XDebug)
	puts("ExecuteCmdList END");
}

/*
 *  cmd[-1] is valid space
 */

Execute_Command(cmd)
register char *cmd;
{
    register char *ptr;
    short Ignore = 0;

    while (*cmd == ' ' || *cmd == '\t')
	++cmd;
    if (*cmd == '-') {
	++cmd;
	Ignore = 1;
    }
    for (ptr = cmd; *ptr && *ptr != ' ' && *ptr != '\t'; ++ptr);
    if (ptr - cmd == 2 && (cmd[0]|0x20) == 'c' && (cmd[1]|0x20) == 'd') {
	long lock;

	while (*ptr == ' ' || *ptr == '\t')
	    ++ptr;
	if (*ptr)
	    lock = Lock(ptr, SHARED_LOCK);
	else
	    lock = DupLock(SaveLock);
	if (lock)
	    UnLock(CurrentDir(lock));
	else
	    printf("Unable to cd %s\n", ptr);
	return(0);
    }

    {
	register short i;
	register short c;
	register short err = 0;

	for (i = 0; cmd[i] && cmd[i] != ' ' && cmd[i] != 9; ++i);
	c = cmd[i];
	cmd[i] = 0;

#if INCLUDE_VERSION >= 36
	if (SysBase->lib_Version >= 36) {
	    long seg;
	    long lock;
	    Process *proc = FindTask(NULL);
	    CLI *cli = BTOC(proc->pr_CLI, CLI);
	    long oldCommandName;

	    if (cli) {
		oldCommandName = (long)cli->cli_CommandName;
		cmd[-1] = i;
		cli->cli_CommandName = CTOB(cmd - 1);
	    }

	    if (seg = FindSegment(cmd, 0L, 0)) {
		err = RunCommand(((long *)seg)[2], 8192, cmd + i + 1, strlen(cmd + i + 1));
	    } else if ((lock = _SearchPath(cmd)) && seg = LoadSegLock(lock)) {
		err = RunCommand(seg, 8192, cmd + i + 1, strlen(cmd + i + 1));
		UnLoadSeg(seg);
	    } else {
		cmd[i] = c;
		err = System(cmd, NULL);
	    }
	    if (cli)
		cli->cli_CommandName = (BSTR)oldCommandName;
	} else
#endif
	{
	    cmd[i] = c;
	    Execute(cmd, NULL, NULL);
	    err = 0;
	}
	if (err)
	    printf("Error code %d %s\n", err, (Ignore) ? "(Ignored)":"");
	if (Ignore)
	    return(0);
	return(err);
    }
}

LoadSegLock(lock)
long lock;
{
    long oldLock;
    long seg;

    oldLock = CurrentDir(lock);
    seg = LoadSeg("");
    CurrentDir(oldLock);
    return(seg);
}


