/*************************

Have you ever wanted CLI on a custom screen with 25 lines of 80 characters? 
Here it is!  By Paul Kienitz, first version 11/27/88.  When compiling with Aztec
C, DO NOT use the +M (3.6) or -BD (5.0) stack checking option.  There are some
provisions for compiling it without Aztec, but they are UNTESTED AND INCOMPLETE.
Last revision date:  12/1/91.

Use the +A flag on the Aztec linker!

Improvements needed, maybe:
   o Add full public screen support.
   o Option to select an arbitrary font.
   o Option to set RGB colors?
   o -Mn option to set overscanmargin?
   o hot key to bring to front and activate?  Make your own, I don't need one.
   o Invisible screen gadgets?  Nah, too difficult to make text show through.

**************************/


/* note to myself: GMC shortcoming with ^C interrupt inside Execute(), or with
Run ... If you Run a program in a GMC window that writes to the window, ^C will
not interrupt it, though it does with some (not all) other console handlers.
This means commands run with the DO option cannot be ^C'ed in a GMC window.
Other incompatibilities of GMC 9.6 with the 2.0 CON: handler are: no support for
simple-refresh windows, and hence no support of text-cut-with-mouse, so that the
-S or SMARTREFRESH option must be used; no support for /WINDOW or /SCREEN or /
AUTO or /BORDERLESS or /BACKDROP, etc... also the filename completer only works
in the curent directory, under V36 kickstart.  The E option, to make it use a
different font, also does not work with GMC. */

#include <exec/exec.h>
#include <exec/execbase.h>
#include <intuition/intuition.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <libraries/dosextens.h>
#include <string.h>
#include <Paul.h>


#define SEMNAME "CLImax gate"


#define BOLD "\2331m"
#define NORMAL "\2330m"


#define GREENISHNESS	{0x484, 0x000, 0x0b0, 0xcc0}
#define DEFAULTISHNESS	{0x05a, 0xfff, 0x002, 0xf80}

#define SCLI struct CommandLineInterface


#define WDHANDLER "CON"
#define WDLEFT    234
#define WDTOP     123
#define WDWIDTH   345
#define WDHEIGHT  69
#define WDTITLE   "unendurable pleasure indefinitely prolonged"
#define WDCMPLEN  30

struct {
    str handler;
    short left, top, width, height;
    str title;
    adr windowptr;
} WFargs = { WDHANDLER, WDLEFT, WDTOP, WDWIDTH, WDHEIGHT, WDTITLE, null };

char chand[300];


typedef struct {
    adr ibase, gbase, dosbase;
    struct TextFont *fawnt;
    struct Screen *scr;
    struct Window *win;
    BPTR wandle, ceedee;
    struct NewWindow *wdef;
    adr oldOpenWindow, wfargs;
    long waitret;
    bool onecmd, dos2;
} stuffy;


adr IntuitionBase, DOSBase, IconBase, DiskfontBase;
struct GfxBase *GfxBase;
struct ExecBase *SysBase;

struct WBStartup *WBenchMsg;
struct Process *me;
struct Preferences *prufs;

#define PREFSIZE (long) ( (str) &prufs->color3 + 2 - (str) prufs)

SCLI *fakli = null;
str prompt, setname;

ustr command, processname;
BPTR oriout, fakeseglist;

bool lace = false, greenify = false, prod = false, frum = false,
	newfont = false, closeori = false, conman = false, behind = false,
	twocolor = false, smartness = false;

char argspot = 0;


str fontname = "topaz.font";		/* no other choices for now */
long fontsize = 11;

stuffy *stuff;


struct NewScreen scrdef = {
	0, 0, 640, 204,	/* Width and Height will be set later */
	2,		/*  4 colors  */
	0, 0,		/*  detail pen = background so no white stripe at top */
	HIRES,		/* inventor of root beer */
	CUSTOMSCREEN,
	null, null,	/* title (won't actually show) filled in later */
	null, null
};


#ifdef PUBLICITY

long screenerror;

#endif


struct NewWindow windef = {
	0, 4, 640, 200,		/* TopEdge and Height will be set later */
	0, 1,
	0,			/* no idcmp */
	ACTIVATE | BACKDROP | BORDERLESS,
	null, null, null,	/* no special gadget or checkmark, no title */
	null,			/* screen pointer; will get set later */
	null,			/* no custom bitmap */
	0, 0, 0, 0,		/* ignored */
	CUSTOMSCREEN
};


/* these are all in bud.a */
extern void beginning(), ending(), CloseStuff(), RDF_MoveByte();
extern short StuffOffs, CommandOffs, NameOffs, FakeOffs, WedgeOffs;

adr WedgeFunc;


void exit();


void spew(s) str s;
{
    register long l = strlen(s);
    if (!oriout && !closeori) {
	closeori = true;
	oriout = OOpen("CON:60/40/450/80/ CLImax error: ");
    }
    if (oriout) Write(oriout, s, l);
}



void cheaprintf(format, arg1 /* , ... */ ) str format; int arg1;
{
    char buffer[512];
    RawDoFmt(format, (adr) &arg1, RDF_MoveByte, buffer);
    spew(buffer);
}



void Die()
{
    BPTR *p, *pp;
    UnLoadSeg(fakeseglist);
    if (stuff->ceedee)
	UnLock(stuff->ceedee);
    if (fakli && fakli->cli_CommandDir) {
	p = gbip(fakli->cli_CommandDir);
	while (p) {
	    UnLock(p[1]);
	    pp = gbip(*p);
	    FreeMem(p, 8);
	    p = pp;
	}
    }
    CloseStuff(stuff);
    exit(10);
}



void OpenStuff()
{   ushort *wbcolor, tallth;
    static ushort lacecolor[4] = GREENISHNESS,
		  unlacecolor[4] = DEFAULTISHNESS;
    long collor;	/* that's how Joan spelled it once */
    struct ViewPort *vp;
    short margin = (lace ? GfxBase->DefaultFont->tf_YSize + 3 : 4);

    tallth = (GfxBase->NormalDisplayRows << lace) - margin;
    if (tallth < (200 << lace))
	tallth = 200 << lace;
    else if (tallth > (246 << lace) && tallth < (256 << lace))
	tallth = 256 << lace;
    if (lace)
	scrdef.ViewModes = HIRES | LACE;
    if (stuff->dos2 && !smartness) {
	windef.Flags |= SIMPLE_REFRESH;		/* so text cut w/ mouse works */
#ifdef PUBLICITY
	scrdef.Type = PUBLICSCREEN;
#endif
    }
    if (behind) {
	scrdef.Type |= SCREENBEHIND;
	windef.Flags &= ~ACTIVATE;
    }
    if (twocolor) scrdef.Depth = 1;
    windef.TopEdge = margin;
    windef.Height = prod ? 480 - margin : tallth;
    scrdef.Height = prod ? 480 : tallth + margin;
    scrdef.Width = windef.Width = prod ? 640 : GfxBase->NormalDisplayColumns;
    if (prod) scrdef.LeftEdge = GfxBase->NormalDisplayColumns - 640;
    scrdef.DefaultTitle = processname;
    if (stuff->dos2)
	stuff->scr = OpenScreenTags(&scrdef,
#ifdef PUBLICITY
					SA_PubName, processname,
					SA_ErrorCode, &screenerror,
#endif
					(prod ? SA_DisplayID : TAG_DONE),
					VGAPRODUCT_KEY, TAG_DONE);
    else
	stuff->scr = OpenScreen(&scrdef);
    if (!stuff->scr) {
#ifdef PUBLICITY
	if (stuff->dos2) switch (screenerror) {
	    case OSERR_NOMEM:
		spew("\nCLImax: insufficient memory to open screen.\n");
		break;
	    case OSERR_NOCHIPMEM:
		spew("\nCLImax: insufficient chip memory to open screen.\n");
		break;
	    case OSERR_PUBNOTUNIQUE:
		spew("\nCLImax: there's already a public screen called \"");
		spew(processname);
		spew("\".\n");
		break;
	    default:
		spew("\nCLImax: can't open screen, reason unknown.\n");
	} else
#endif
	    spew("\nCLImax: can't open screen.\n");
	Die();
    }
    windef.Screen = stuff->scr;
    stuff->wdef = &windef;
    if (!(stuff->win = OpenWindow(&windef))) {
	spew("\nCLImax: can't open backdrop window.\n");
	Die();
    }
    ShowTitle(stuff->scr, FALSE);
    vp = &stuff->scr->ViewPort;
    prufs = null;
    if (greenify) wbcolor = lacecolor;
    else if (prufs = Alloc(PREFSIZE)) {
	GetPrefs(prufs, PREFSIZE);
	wbcolor = &prufs->color0;
    } else wbcolor = unlacecolor;
    for (collor = 0; collor <= 3; collor++, wbcolor++)
	SetRGB4(vp, collor, (*wbcolor >> 8) & 15L,
		    (*wbcolor >> 4) & 15L,
		    *wbcolor & 15L);
    if (prufs) FreeMem(prufs, PREFSIZE);
}



BPTR CopyPath(tass) str tass;
{
    struct Process *wb = (adr) FindTask(tass);
    SCLI *wbclap;
    BPTR *wext, *mext, *lastmext, newpath = 0;
    lastmext = &newpath;
    if (!wb) return 0;
    if (!(wbclap = gbip(wb->pr_CLI))) return 0;
    for (wext = gbip(wbclap->cli_CommandDir); wext; wext = gbip(*wext)) {
	if (!(mext = AllocP(2 * sizeof(BPTR))))
	    break;
	*lastmext = (long) mext >> 2;
	lastmext = mext;
	mext[1] = DupLock(wext[1]);
	mext[0] = 0;
    }
    return (newpath);
}



void bcpy(dest, src, limit) ubyte *dest, *src; short limit;
{
    register ushort l = *(src++);
    if (l >= limit) l = limit - 1;
    *(dest++) = l;
    while (l > 0) {
	*(dest++) = *(src++);
	l--;
    }
}



void FakeCLI()
{
    if (me->pr_CLI) {
	SCLI *mec = gbip(me->pr_CLI);
	fakli->cli_DefaultStack = mec->cli_DefaultStack;  /* NewCLI does this */
	bcpy(prompt, gbip(mec->cli_Prompt), 64);
	bcpy(setname, gbip(mec->cli_SetName), 88);
	/* I just happen to know that the 1.3 CLI allocates 64 bytes for the
	    prompt and 88 bytes for the setname.  On its stack. */
	fakli->cli_CommandDir = CopyPath(null);
    } else {
	register BPTR p;
	fakli->cli_DefaultStack = 1000L;
	if (!(p = CopyPath("Workbench")))
	    if (!(p = CopyPath("Initial CLI")))
		if (!(p = CopyPath("AmigaShell")))
		    if (!(p = CopyPath("New CLI")))
			p = CopyPath("Background CLI");
	fakli->cli_CommandDir = p;
	/* Why, you ask, am I including code that assumes the CLImax process
	   has been launched neither from a CLI nor from Workbench?
	   well, I use MyMenu.  and sometimes the path will get set
	   elsewhere after workbench is already under way so it doesn't know
	   it.  besides, I just had this lying around in FixCLI. */
    }
    fakli->cli_Prompt = (long) prompt >> 2;
    fakli->cli_SetName = (long) setname >> 2;
/*  if (!stuff->ceedee) stuff->ceedee = RLock("SYS:");  */
}



void DooFont()
{
    struct TextAttr f;
    f.ta_Name = (adr) fontname;
    f.ta_YSize = fontsize;
    f.ta_Style = f.ta_Flags = 0;
    stuff->fawnt = OpenFont(&f);
    if (stuff->fawnt && fontsize != stuff->fawnt->tf_YSize) {
	CloseFont(stuff->fawnt);
	stuff->fawnt = null;
    }
    if (!stuff->fawnt)
	if (DiskfontBase = (adr) OpenLibrary("diskfont.library", 0L)) {
	    stuff->fawnt = OpenDiskFont(&f);
	    CloseLibrary(DiskfontBase);
	}
    if (stuff->fawnt)
	SetFont(stuff->win->RPort, stuff->fawnt);
}



bool wasw = false;

bool Scorch(o) char o;
{
    if (o >= '0' && o <= '9' && wasw) {			/* this is way lame */
	stuff->waitret = 10 * stuff->waitret + o - '0';
	return true;
    } else switch (o) {
	case 'g': greenify = true; break;
	case 'i': lace = true; break;
	case 'e': newfont = true; break;
	case 'b': behind = true; break;
#ifdef OLD_SHIT
	case 'm': conman = true; break;
#endif
	case 'p': prod = true; break;
	case '1': twocolor = true; break;
	case 's': smartness = true; break;
	case 'w': stuff->waitret = 0; break;
	default: wasw = false; return false;
    }
    wasw = o == 'w';
    return true;
}



void Wargz()
{
    struct DiskObject *bob;
    str toop;
    register str s;

    if (!(IconBase = OpenLibrary("icon.library", 0L))) return;
    CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);
    if (bob = GetDiskObject((ustr) WBenchMsg->sm_ArgList->wa_Name)) {
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "OPTION")) {
	    register char c;
	    for (c = *toop; c; c = *++toop)
		Scorch(tolower(c));
	}
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "INTERLACE"))
	    lace = true;
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "GREEN"))
	    greenify = true;
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "TOPAZ11"))
	    newfont = true;
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "INACTIVE"))
	    behind = true;
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "PRODUCTIVITY"))
	    prod = true;
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "TWOCOLOR"))
	    twocolor = true;
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "SMARTREFRESH"))
	    smartness = true;
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "WAITRETURN"))
	    stuff->waitret = atol(toop);
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "ARGINSERT")) {
	    while (*toop && *toop <= ' ') toop++;
	    if ((argspot = (char) *toop) && WBenchMsg->sm_NumArgs > 1)
		stuff->ceedee = DupLock(WBenchMsg->sm_ArgList[1].wa_Lock);
	}
	if (!argspot && (toop = FindToolType((ustr *) bob->do_ToolTypes, "CD"))) {
	    while (*toop && *toop <= ' ') toop++;
	    if (stuff->ceedee = RLock(toop)) {
		register int l = strlen(toop);
		if (l >= 88) l = 87;
		*setname = l;
		strncpy(setname + 1, toop, l);
	    }
	}
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "FROM")) {
	    while (*toop && *toop <= ' ') toop++;
	    if (*toop) {
		strcpy(command, "Execute ");
		strcpy(command + 8, toop);
	    } else *command = 0;
	    frum = true;
	}
	if ((toop = FindToolType((ustr *) bob->do_ToolTypes, "COMMAND"))
		    || (toop = FindToolType((ustr *) bob->do_ToolTypes, "DO"))) {
	    s = command;
	    while (*toop && *toop <= ' ') toop++;
	    while (*toop)
		if (*toop == argspot) {
		    register str ss;
		    if (WBenchMsg->sm_NumArgs > 1)
			ss = WBenchMsg->sm_ArgList[1].wa_Name;
		    else ss = "";
		    while (*ss) *(s++) = *(ss++);
		    toop++;
		} else *(s++) = *(toop++);
	    if (!stuff->dos2) strcpy(s, "\nEndCLI >NIL:");
	    else *s = 0;
	    frum = true;
	    stuff->onecmd = -1;
	}
	if (toop = FindToolType((ustr *) bob->do_ToolTypes, "HANDLER")) {
	    WFargs.handler = chand;
	    strcpy(chand, toop);
	    for (s = chand; *s; s++)
		if (*s == ':') *(s--) = 0;
	}
	FreeDiskObject(bob);
    }
    CurrentDir(stuff->ceedee);
    CloseLibrary(IconBase);
    IconBase = null;
}



/* okay, I know perfectly well that this command line parser is really really
lame ... but, the program used to have a really simple syntax that called for a
really simple parser ... and it just sorta grew ... */

int word, chair, ac;
ustr *av;

ubyte nerg()
{
    if (word > ac) return 0;
    else if (av[word][chair]) return tolower(av[word][chair++]);
    else if (++word <= ac) return tolower(av[word][chair = 0]);
    else return 0;
}



void handle(argc, argv) int argc; str argv[];
{
    ubyte c;
    bool kelp = false, stord = true, opto = false, nul = false;
    char weird[300];
    short wc = 0;

    ac = argc; av = (adr) argv; word = 1; chair = 0;
    for (c = nerg(); !nul; c = nerg()) {
	if (stord && c == '-') {
	    opto = true;
	    c = nerg();
	}
	if (c > ' ' && c != ':') {
	    stord = false;
	    if (opto) {
		if (!Scorch(c))
		    cheaprintf("Unknown option \"-%lc\".\n", (long) c);
	    } else weird[wc++] = c;
	} else {
	    opto = false;
	    stord = true;
	    weird[wc] = 0;
	    if (wc) {
		wc = 0;
		if (c == ':') {
		    strcpy(chand, weird);
		    WFargs.handler = &chand[0];
		} else if (weird[0] == '?' || weird[0] == 'h')
		    kelp = true;
		else if (!strcmp(weird, "from") || !strcmp(weird, "do")) {
		    frum = true;
		    stuff->onecmd = - (long) (weird[0] == 'd');
		    for (c = nerg(); c && c <= ' '; c = nerg()) ;
		    if (!c)
			*command = 0;
		    else {
			register ustr cc;
			if (!stuff->onecmd) {
			    cc = command + 8;
			    strcpy(command, "Execute ");
			} else
			    cc = command;
			while (c) {
			    *(cc++) = (ubyte) c;
			    c = nerg();
			}
			if (stuff->onecmd && !stuff->dos2)
			    strcpy(cc, "\nEndCLI >NIL:");
		    }
		} else {
		    cheaprintf("Unrecognized option: \"%s\".  Usage:  " BOLD
				"%s ?" NORMAL " or\n" BOLD "%s" NORMAL
				" { -options } [ handler: ] [ " BOLD "FROM"
				NORMAL " [ scriptfile ] | " BOLD "DO" NORMAL
				" command ]\n\n", weird, argv[0], argv[0]);
		    Die();
		}
	    }
	}
	nul = !c;
    }
    if (kelp) {
	spew(
"\nCLImax by Paul Kienitz -- in the public domain -- usage:\n\n"
"   CLIMAX  { -options }  [ handler: ] [ FROM [ scriptfile ] | DO command ]\n\n"
" -" BOLD "I" NORMAL " = use an interlace screen.       -"
BOLD "E" NORMAL  " = use the Topaz 11 font.\n"
" -" BOLD "P" NORMAL " = use productivity mode.         -"
BOLD "G" NORMAL " = use black-on-green (less flicker).\n"
" -" BOLD "S" NORMAL " = use SMART_REFRESH window.      -"
BOLD "1" NORMAL " = use one bitplane (two colors).\n"
" -" BOLD "B" NORMAL " = open with an inactive window behind other screens.\n"
" -" BOLD "W" NORMAL
	" = wait for Return before exiting after running DO command.  Under 2.0:\n"
" -" BOLD "W" NORMAL "n (e.g. " BOLD "-W10" NORMAL
	") = wait for Return if DO command fails; n is fail level.\n"
" " BOLD "handler:" NORMAL
	" is a console handler, e.g. NEWCON: or GMC: -- default is CON:.\n"
" " BOLD "FROM [scriptfile]" NORMAL
	" means execute the named file before the first prompt.\n"
"     Must be the last option in the command.  Default is S:Shell-Startup if\n"
"     FROM is not used; use FROM with nothing after it to use no script.\n"
" " BOLD "DO command" NORMAL
	" means run just this CLI command and then exit.  May be\n"
"     continued onto multiple lines with a + at the end of each line.\n"
"Use " BOLD "climax ?" NORMAL " or " BOLD "climax H" NORMAL " to show this message.\n"
"See documentation for Workbench tooltypes equivalent to the above options.\n");
	Die();
    }
    stuff->ceedee = DupLock(me->pr_CurrentDir);
}



void Bud()	/* grow a "bud" which can detach as a child process */
{
    long tize = (long) (((str) &ending - (str) &beginning) + 11) & ~3;
    register str taskspace = AllocP(tize);
    if (!taskspace || !IntuitionBase || !GfxBase) {
	spew("\nGaaah!  Not enough memory for CLImax!\n");
	exit(20);
    }
    CopyMemQuick((str) &beginning, taskspace + 8, tize - 8);
    *((long *) taskspace) = tize;
    ((long *) taskspace)[1] = 0;		/* fakeseglist next bptr */
    fakeseglist = (((long) taskspace) >> 2) + 1;
    taskspace += 8;
    command = (adr) (taskspace + CommandOffs);
    processname = (adr) (taskspace + NameOffs);
    WedgeFunc = taskspace + WedgeOffs;
    if (FindTask(processname))			/* create unique name for */
	processname[6] = '0';			/* task, public screen,   */
    while (FindTask(processname))		/* and screen title       */
	processname[6]++;
    fakli = (adr) (taskspace + FakeOffs);
    prompt = (str) fakli + sizeof(SCLI);
    setname = prompt + 64;
    stuff = (adr) (taskspace + StuffOffs);
    stuff->wandle = stuff->ceedee = 0;
    stuff->scr = (adr) stuff->win = stuff->fawnt = null;
    stuff->ibase = IntuitionBase;
    stuff->gbase = GfxBase;
    stuff->dosbase = DOSBase;
    stuff->onecmd = 0;
    stuff->waitret = -1;
}



void WedgeTheWindowOpen(conspec) str conspec;
{
    struct SignalSemaphore gate, *g;
    char gatename[50];

    Forbid();
    if (!(g = FindSemaphore(SEMNAME))) {
	g = &gate;
	gate.ss_Link.ln_Name = &gatename[0];
	strcpy(gatename, SEMNAME);
	gate.ss_Link.ln_Pri = -20;
	/* AddSemaphore */
	InitSemaphore(&gate);
	Enqueue(&SysBase->SemaphoreList, (adr) &gate);
    }
    ObtainSemaphore(g);
    Permit();

    /* this is the operation that must not happen in two CLImax processes at the
	same time -- we open the CON spec while the OpenWindow function is
	wedged, so that our console handler process gets back a different window
	from the one it asked for. */
    stuff->oldOpenWindow = (adr) SetFunction(IntuitionBase, -204, WedgeFunc);
    stuff->wandle = OOpen(conspec);
    SetFunction(IntuitionBase, -204, stuff->oldOpenWindow);

    if (g == &gate) RemSemaphore(g);
    ReleaseSemaphore(g);
    /* at this point, another CLImax process JUST MIGHT POSSIBLY have obtained
	our semaphore at the moment we released it.  We have to wait for it to
	release, before we deallocate it.  So: */
    if (g == &gate) {
	ObtainSemaphore(g);
	ReleaseSemaphore(g);
    }
    /* Since Obtains are processed in first-in-first-out order, there cannot be
	any obtains waiting after this last one, which was made after gate was
	removed from the public list. */
}



void main(argc, argv) int argc; str *argv;
{
    ubyte boof[150];
    BPTR L, Seg = 1;
    APTR mywptr;

    oriout = Output();
#ifndef AZTEC_C
    me = ThisProcess();
    === !do something to get WBenchMsg ===
#endif
    IntuitionBase = (adr) OpenLibrary ("intuition.library", 0L);
    GfxBase = (adr) OpenLibrary ("graphics.library", 0L);
    Bud();
    stuff->dos2 = ((struct Library *) GfxBase)->lib_Version >= 36;
    if (WBenchMsg)
	Wargz();
    else
	handle(argc, argv);
    if (prod) lace = true;
    OpenStuff();

    mywptr = me->pr_WindowPtr;
    me->pr_WindowPtr = (APTR) -1L;
    if (!frum)
	if (L = RLock("S:Shell-Startup")) {
	    strcpy(command, "Execute S:Shell-Startup");
	    UnLock(L);
	} else *command = 0;
    me->pr_WindowPtr = mywptr;
    FakeCLI();
    if (newfont) DooFont();
    WFargs.windowptr = stuff->win;
    stuff->wfargs = &WFargs;
    RawDoFmt("%s:%d/%d/%d/%d/%s/WINDOW 0x%lx", &WFargs, RDF_MoveByte, boof);
    if (stuff->dos2) CacheClearU();

    WedgeTheWindowOpen(boof);
    if (stuff->wandle) {
	if (stuff->onecmd)
	    fakli->cli_FailLevel = maxint;		/* doesn't work */
	else {
	    Write(stuff->wandle, "CLImax by Paul Kienitz maximizes your CLI.\n", 43L);
	    stuff->waitret = -1;
	}
	CreateProc(processname, 0L, fakeseglist, 2000L);
    } else {
	cheaprintf("\nCLImax can't open the %s: handler for the window.\n",
			WFargs.handler);
	Die();
    }
}



/* reduce size by a few K: */

#ifdef AZTEC_C

char arg[256], prame[256];
str argp[3];


void _main(alen, aptr) long alen; str aptr;  /* simplified startup code */
{
    int al = alen;
    ustr poik;

    me = ThisProcess();
    poik = bip(char, bip(struct CommandLineInterface,
			      me->pr_CLI)->cli_CommandName);
    if (me->pr_CLI) {
	strncpy(prame, (str) poik + 1, (size_t) *poik);
	prame[*poik] = 0;
	strupr(prame);
	if (al > 255) al = 255;
	argp[0] = prame;		/* do by hand so purify.a works **/
	argp[1] = arg;
	argp[2] = null;
	strncpy(arg, aptr, al);
	arg[al - 1] = 0;
	WBenchMsg = null;
    } else {
	WaitPort(&me->pr_MsgPort);
	WBenchMsg = (adr) GetMsg(&me->pr_MsgPort);
    }
    main(1, argp);	/* pack all args into argv[1] */
    exit(0);
}



void exit(code) int code;
{
    char c;
    if (oriout && closeori) {
	spew("\n  -- press return:  ");
	Read(oriout, &c, 1L);
	Close(oriout);
    }
    if (WBenchMsg) {
	Forbid();
	ReplyMsg((struct Message *) WBenchMsg);
    }
    Exit((long) code);
}

#endif
