/* Created 11/08/87 by -=+SDB+=- from file _main.c provided by Manx */ /* Copyright (C) 1987 by Scott Ballantyne */ /* May be freely used by ARP users/supporters */ /* Memory is allocated for the MANX device buffers, etc., but the * ARP tracking functions are used. * tweeked for v39 * further tweeked to handle v1.4 workbench startup */ extern long _savsp, _stkbase; extern int errno, Enable_Abort; extern int _argc; extern char **_argv; extern struct WBStartup *WBenchMsg; extern struct _dev *_devtab; extern short _numdev; extern struct ArpBase *ArpBase; extern void *IntuitionBase, *GfxBase, *DOSBase; extern struct ExecBase *SysBase; /* !!! alot of things here depend on receiving WBenchMsg before opening arp.library */ #ifdef DETACH static long _alen = 0; #endif _main(alen, aptr) long alen; char *aptr; { register struct Process *pp; pp = (struct Process *)SysBase -> ThisTask; if (!pp->pr_CLI #ifdef DETACH && !_alen /* !!! alen is here because pr_CLI is NULL for bg task, but _alen (hopefully) isn't */ #endif ) { WaitPort(&pp->pr_MsgPort); WBenchMsg = (struct WBStartup *)GetMsg(&pp->pr_MsgPort); } if (!(ArpBase = (struct ArpBase *)OpenLibrary (ArpName,ArpVersion))) { complain(); Forbid(); if (WBenchMsg) ReplyMsg ((struct Message *)WBenchMsg); return(20); } if(!DOSBase) DOSBase = ArpBase->DosBase; GfxBase = ArpBase->GfxBase; IntuitionBase = ArpBase->IntuiBase; #ifdef DETACH { void do_detach(); if (!WBenchMsg) do_detach(&alen, &aptr); } #endif if ( (_devtab = ArpAlloc( _numdev*(long)sizeof(struct _dev))) == 0) { Alert(AG_NoMemory, 0L); ArpExit(20L, ERROR_NO_FREE_STORE ); } _devtab[0].mode = O_RDONLY; _devtab[1].mode = _devtab[2].mode = O_WRONLY; _stkbase = _savsp - *((long *)_savsp+1) + 8; *(long *)_stkbase = 0x4d414e58L; if (!WBenchMsg) { _cli_parse(pp, alen, aptr); Enable_Abort = 1; #ifndef DETACH _devtab[0].mode |= O_STDIO; /* shouldn't close if CLI */ _devtab[1].mode |= O_STDIO; #endif /* !!! wb 1.4 tweek */ _devtab[0].fd = (struct FileHandle *)Input(); if (_devtab[1].fd = (struct FileHandle *)Output()) _devtab[2].fd = (struct FileHandle *)Open("*", MODE_OLDFILE); /* !!! wb 1.4 tweek */ } else { /* !!! wb 1.4 tweek */ _devtab[0].mode |= O_STDIO; /* shouldn't close if WB opened something for us */ _devtab[1].mode |= O_STDIO; _devtab[2].mode |= O_STDIO; /* !!! wb 1.4 tweek */ if (WBenchMsg->sm_ArgList) CurrentDir((BPTR)WBenchMsg->sm_ArgList->wa_Lock); _wb_parse(pp, WBenchMsg); _argv = (char **)WBenchMsg; /* !!! wb 1.4 tweek */ _devtab[0].fd = (struct FileHandle *)Input(); _devtab[1].fd = _devtab[2].fd = (struct FileHandle *)Output(); /* !!! wb 1.4 tweek */ } main(_argc, _argv); exit(0); /* Need to also close files, etc. */ } /*#if (int)ArpVersion != 39*/ /* !!! this needs fixing!*/ /*#endif*/ static complain() { long output; static char complaint1[] = "You need arp.library V39+"; static char complaint2[] = "\n"; static struct IntuiText comptext = { AUTOFRONTPEN, 0, JAM1, 30, 15, NULL, (void *)complaint1 }; static struct IntuiText oktext = { AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, AUTOLEFTEDGE, AUTOTOPEDGE, NULL, (void *)"Ok" }; struct Process *pp; pp = (struct Process *)SysBase -> ThisTask; if (pp->pr_CLI && (DOSBase = OpenLibrary ("dos.library",33L)) && (output = (long)Output())) { Write (output, complaint1, (long)sizeof complaint1-1); Write (output, complaint2, (long)sizeof complaint2-1); } else if (IntuitionBase = OpenLibrary ("intuition.library",33L)) { AutoRequest (NULL,&comptext,NULL,&oktext,0L,0L,320L,72L); CloseLibrary ((struct Library *)IntuitionBase); } else { Alert (AG_OpenLib | AO_ArpLib, 0L); } if (DOSBase) { CloseLibrary ((struct Library *)DOSBase); DOSBase = NULL; } } #ifdef DETACH extern long _stack, _priority, _BackGroundIO; extern char *_procname; BPTR _Backstdout = 0; extern BPTR _detach_curdir; extern char *_detach_name; static char *_aptr = 0; static void do_detach(alen, aptr) long *alen; char **aptr; { struct Process *pp; /* long l; */ /* struct MemList *mm; */ /* register unsigned short c; */ pp = (struct Process *)SysBase -> ThisTask; if (pp->pr_CLI) { /* first time through!! */ register char *cp; register struct CommandLineInterface *cli; CurrentDir(_detach_curdir = CurrentDir(NULL)); _detach_curdir = DupLock(_detach_curdir); cli = (struct CommandLineInterface *) ((long)pp->pr_CLI << 2); #if 0 l = cli->cli_Module; if ((sav = OpenLibrary(DOSNAME, 33L)) == 0) { lp = (long *)*((long *)*((long *)*((long *)*((long *) _savsp+2)+1)-3)-3)+107; if (*lp != cli->cli_Module) exit(20); } else { CloseLibrary((struct Library *)sav); lp = 0; } if (lp) *lp = 0; #endif if (_stack == 0) _stack = cli->cli_DefaultStack * 4; if (_BackGroundIO) _Backstdout = (BPTR)Open("*", MODE_OLDFILE); _alen = *alen; if (!(_aptr = DosAllocMem(_alen))) goto clean; CopyMem(*aptr, _aptr, _alen); cp = (char *)((long)cli->cli_CommandName << 2); if (!(_detach_name = DosAllocMem((long)cp[0]+1))) goto clean; CopyMem(cp, _detach_name, (long)cp[0]+1); if (CreateProc(_procname, _priority, cli->cli_Module, _stack)) { cli->cli_Module = 0; ArpExit (0L,0L); } clean: if (_aptr) DosFreeMem (_aptr); if (_detach_name) DosFreeMem (_detach_name); ArpExit (20L,ERROR_NO_FREE_STORE); } /* !!! why is this strcmp() here??? * * Olsen says: This strcmp succeeds if the detach * startup code has successfully created the background * process with the name given in '_procname'. * * There is a nasty pitfall; say '_procname = "foo";' * the resulting program is called 'foo', too, and is * called from Workbench. What happens? Bang! * pp->pr_CLI is zero and the strcmp succeeds. * If 'foo' hasn't crashed yet it will crash on exit. * * Note that the Arp _main() routine fixes this bug * by taking a look on WBenchMsg before calling do_detach. */ else if (strcmp(pp->pr_Task.tc_Node.ln_Name, _procname) == 0) { /* second time */ register long *lp; register struct DefaultTracker *tr; if (tr = GetTracker (TRAK_SEGLIST)) { lp = (long *)((long)pp->pr_SegList << 2); tr->dt_Object.dt_Resource = (CPTR)lp[3]; } if (tr = GetTracker (TRAK_DAMEM)) tr->dt_Object.dt_Resource = (CPTR)_aptr; if (tr = GetTracker (TRAK_DAMEM)) tr->dt_Object.dt_Resource = (CPTR)_detach_name; if (tr = GetTracker (TRAK_LOCK)) tr->dt_Object.dt_Resource = (CPTR)_detach_curdir; CurrentDir(_detach_curdir); pp->pr_COS = _Backstdout; *alen = _alen; *aptr = _aptr; } } #endif