home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff376.lzh / AztecArp / Sources.LZH / _main.c < prev    next >
C/C++ Source or Header  |  1990-08-01  |  7KB  |  308 lines

  1. /* Created 11/08/87 by -=+SDB+=- from file _main.c provided by Manx */
  2. /* Copyright (C) 1987 by Scott Ballantyne */
  3. /* May be freely used by ARP users/supporters */
  4. /* Memory is allocated for the MANX device buffers, etc., but the
  5.  * ARP tracking functions are used.
  6.  * tweeked for v39
  7.  * further tweeked to handle v1.4 workbench startup
  8.  */
  9.  
  10. extern long _savsp, _stkbase;
  11.  
  12. extern int errno, Enable_Abort;
  13.  
  14. extern int _argc;
  15. extern char **_argv;
  16. extern struct WBStartup *WBenchMsg;
  17.  
  18. extern struct _dev *_devtab;
  19. extern short _numdev;
  20.  
  21. extern struct ArpBase *ArpBase;
  22. extern void *IntuitionBase, *GfxBase, *DOSBase;
  23.  
  24. extern struct ExecBase *SysBase;
  25.  
  26. /* !!! alot of things here depend on receiving WBenchMsg before opening arp.library */
  27.  
  28. #ifdef DETACH
  29. static long _alen = 0;
  30. #ifdef PARENT
  31. struct Process *_parent_proc = NULL;
  32. #endif /* PARENT */
  33. #endif /* DETACH */
  34.  
  35. _main(alen, aptr)
  36. long alen;
  37. char *aptr;
  38. {
  39.     register struct Process *pp;
  40.  
  41.     pp = (struct Process *)SysBase -> ThisTask;
  42.  
  43.     if (!pp->pr_CLI
  44. #ifdef DETACH
  45.         && !_alen        /* !!! alen is here because pr_CLI is NULL for bg task, but _alen (hopefully) isn't */
  46. #endif
  47.     )
  48.     {
  49.         WaitPort(&pp -> pr_MsgPort);
  50.         WBenchMsg = (struct WBStartup *)GetMsg(&pp -> pr_MsgPort);
  51.     }
  52.  
  53.     if(!(ArpBase = (struct ArpBase *)OpenLibrary (ArpName,ArpVersion)))
  54.     {
  55.         complain();
  56.         Forbid();
  57.  
  58.         if(WBenchMsg)
  59.             ReplyMsg((struct Message *)WBenchMsg);
  60.  
  61.         return(RETURN_FAIL);
  62.     }
  63.  
  64.     if(!DOSBase)
  65.         DOSBase = ArpBase -> DosBase;
  66.  
  67.     GfxBase        = ArpBase -> GfxBase;
  68.     IntuitionBase    = ArpBase -> IntuiBase;
  69.  
  70. #ifdef DETACH
  71. #ifdef STICKY
  72.     if ((*aptr != 'S' && *aptr != 's') ||
  73.             (*(aptr + 1) != 'T' && *(aptr + 1) != 't') ||
  74.             (*(aptr + 2) != 'I' && *(aptr + 2) != 'i') ||
  75.             (*(aptr + 3) != 'C' && *(aptr + 3) != 'c') ||
  76.             (*(aptr + 4) != 'K' && *(aptr + 4) != 'k') ||
  77.             (*(aptr + 5) != 'Y' && *(aptr + 5) != 'y')) {
  78. #endif /* STICKY */
  79.     {
  80.         void do_detach();
  81.  
  82.         if (!WBenchMsg) do_detach(&alen, &aptr);
  83.     }
  84. #ifdef STICKY
  85.     }
  86. #endif /* STICKY */
  87. #endif /* DETACH */
  88.  
  89.     if(!(_devtab = ArpAlloc(_numdev * sizeof(struct _dev))))
  90.     {
  91.         Alert(AG_NoMemory,NULL);
  92.         ArpExit(RETURN_FAIL,ERROR_NO_FREE_STORE);
  93.     }
  94.  
  95.     _devtab[0] . mode = O_RDONLY;
  96.     _devtab[1] . mode = _devtab[2] . mode = O_WRONLY;
  97.  
  98.     _stkbase = _savsp - *((long *)_savsp+1) + 8;
  99.  
  100.     /* Olsen asks: Does ANYBODY know what the MANX ID in the
  101.      *             following command line is good for?
  102.      */
  103.  
  104.     *(long *)_stkbase = 0x4D414E58;
  105.  
  106.     if(!WBenchMsg)
  107.     {
  108. #ifdef STICKY
  109.         if ((*aptr == 'S' || *aptr == 's') &&
  110.                 (*(aptr + 1) == 'T' || *(aptr + 1) == 't') &&
  111.                 (*(aptr + 2) == 'I' || *(aptr + 2) == 'i') &&
  112.                 (*(aptr + 3) == 'C' || *(aptr + 3) == 'c') &&
  113.                 (*(aptr + 4) == 'K' || *(aptr + 4) == 'k') &&
  114.                 (*(aptr + 5) == 'Y' || *(aptr + 5) == 'y')) {
  115.             _devtab[0].mode |= O_STDIO;    /* shouldn't close if STICKY */
  116.             _devtab[1].mode |= O_STDIO;
  117.             alen -= 6;    /* remove STICKY command line argument */
  118.             aptr += 6;
  119.         }
  120. #endif /* STICKY */
  121.         _cli_parse(pp, alen, aptr);
  122.         Enable_Abort = 1;
  123. #ifndef DETACH
  124.         _devtab[0] . mode |= O_STDIO;        /* shouldn't close if CLI */
  125.         _devtab[1] . mode |= O_STDIO;
  126. #endif /* DETACH */
  127.           /* !!! wb 1.4 tweek */
  128.  
  129.         _devtab[0] . fd = (struct FileHandle *)Input();
  130.  
  131.         if(_devtab[1] . fd = (struct FileHandle *)Output())
  132.             _devtab[2] . fd = (struct FileHandle *)Open("*", MODE_OLDFILE);
  133.  
  134.           /* !!! wb 1.4 tweek */
  135.     }
  136.     else
  137.     {
  138.           /* !!! wb 1.4 tweek */
  139.         _devtab[0] . mode |= O_STDIO;        /* shouldn't close if WB opened something for us */
  140.         _devtab[1] . mode |= O_STDIO;
  141.         _devtab[2] . mode |= O_STDIO;
  142.           /* !!! wb 1.4 tweek */
  143.  
  144.         if(WBenchMsg -> sm_ArgList)
  145.             CurrentDir((BPTR)WBenchMsg -> sm_ArgList -> wa_Lock);
  146.  
  147.         _wb_parse(pp, WBenchMsg);
  148.         _argv = (char **)WBenchMsg;
  149.  
  150.           /* !!! wb 1.4 tweek */
  151.         _devtab[0] . fd = (struct FileHandle *)Input();
  152.         _devtab[1] . fd = _devtab[2] . fd = (struct FileHandle *)Output();
  153.           /* !!! wb 1.4 tweek */
  154.     }
  155.  
  156.     exit(main(_argc, _argv));    /* Need to also close files, etc. */
  157. }
  158.  
  159. static
  160. complain()
  161. {
  162.     BPTR output;
  163.     static char complaint1[] = "You need arp.library V39+";
  164.     static char complaint2[] = "\n";
  165.     static struct IntuiText comptext = { AUTOFRONTPEN, 0, JAM1, 30, 15, NULL, (void *)complaint1 };
  166.     static struct IntuiText oktext = { AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, AUTOLEFTEDGE, AUTOTOPEDGE, NULL, (void *)"Ok" };
  167.     struct Process *pp;
  168.  
  169.     pp = (struct Process *)SysBase -> ThisTask;
  170.  
  171.     if(pp -> pr_CLI && (DOSBase = OpenLibrary ("dos.library",33L)) && (output = Output()))
  172.     {
  173.         Write (output, complaint1, (long)sizeof complaint1-1);
  174.         Write (output, complaint2, (long)sizeof complaint2-1);
  175.     }
  176.     else
  177.     {
  178.         if (IntuitionBase = OpenLibrary ("intuition.library",33L))
  179.         {
  180.             AutoRequest (NULL,&comptext,NULL,&oktext,0L,0L,320L,72L);
  181.             CloseLibrary ((struct Library *)IntuitionBase);
  182.         }
  183.         else
  184.             Alert (AG_OpenLib | AO_ArpLib, 0L);
  185.     }
  186.  
  187.     if (DOSBase)
  188.     {
  189.         CloseLibrary ((struct Library *)DOSBase);
  190.         DOSBase = NULL;
  191.     }
  192. }
  193.  
  194. #ifdef DETACH
  195. extern long _stack, _priority, _BackGroundIO;
  196. extern char *_procname;
  197. BPTR _Backstdout = 0;
  198. extern BPTR _detach_curdir;
  199. extern char *_detach_name;
  200. static char *_aptr = 0;
  201.  
  202. static void
  203. do_detach(alen, aptr)
  204. long *alen;
  205. char **aptr;
  206. {
  207.     struct Process *pp = (struct Process *)SysBase -> ThisTask;
  208.  
  209.     if(pp -> pr_CLI)                       /* first time through!! */
  210.     {
  211.         register char *cp;
  212.         register struct CommandLineInterface *cli;
  213.  
  214. #ifdef PARENT
  215.         _parent_proc = pp;
  216. #endif /* PARENT */
  217.  
  218.         CurrentDir(_detach_curdir = CurrentDir(NULL));
  219.         _detach_curdir = DupLock(_detach_curdir);
  220.  
  221.         cli = (struct CommandLineInterface *)BADDR(pp -> pr_CLI);
  222.  
  223.         if (!_stack)
  224.             _stack = cli -> cli_DefaultStack * 4;
  225.  
  226.         if (_BackGroundIO)
  227.             _Backstdout = (BPTR)Open("*", MODE_OLDFILE);
  228.  
  229.         _alen = *alen;
  230.  
  231.         if(!(_aptr = DosAllocMem(_alen)))
  232.             goto clean;
  233.  
  234.         CopyMem(*aptr, _aptr, _alen);
  235.  
  236.         cp = (char *)BADDR(cli -> cli_CommandName);
  237.  
  238.         if(!(_detach_name = DosAllocMem(cp[0] + 1)))
  239.             goto clean;
  240.  
  241.         CopyMem(cp,_detach_name,cp[0] + 1);
  242.  
  243.         if(CreateProc(_procname,_priority,cli -> cli_Module,_stack))
  244.         {
  245.             cli -> cli_Module = 0;
  246.             ArpExit(0,0);
  247.         }
  248.  
  249. clean:        if (_aptr)
  250.             DosFreeMem(_aptr);
  251.  
  252.         if (_detach_name)
  253.             DosFreeMem(_detach_name);
  254.  
  255.         ArpExit (20,ERROR_NO_FREE_STORE);
  256.     }
  257.  
  258.         /* !!! why is this strcmp() here???
  259.          *
  260.          * Olsen says: This strcmp succeeds if the detach
  261.          * startup code has successfully created the background
  262.          * process with the name given in '_procname'.
  263.          *
  264.          * There is a nasty pitfall; say '_procname = "foo";' 
  265.          * the resulting program is called 'foo', too, and is
  266.          * called from Workbench. What happens? Bang!
  267.          * pp->pr_CLI is zero and the strcmp succeeds.
  268.          * If 'foo' hasn't crashed yet it will crash on exit.
  269.          *
  270.          * Note that the Arp _main() routine fixes this bug
  271.          * by taking a look on WBenchMsg before calling do_detach.
  272.          */
  273.  
  274.     else
  275.     {
  276.             /* second time */
  277.  
  278.         if(!strcmp(pp -> pr_Task . tc_Node . ln_Name, _procname))
  279.         {
  280.             register long *lp;
  281.             register struct DefaultTracker *tr;
  282.  
  283.             if(tr = GetTracker(TRAK_SEGLIST))
  284.             {
  285.                 lp = (long *)BADDR(pp -> pr_SegList);
  286.                 tr -> dt_Object . dt_Resource = (CPTR)lp[3];
  287.             }
  288.  
  289.             if(tr = GetTracker(TRAK_DAMEM))
  290.                 tr -> dt_Object . dt_Resource = (CPTR)_aptr;
  291.  
  292.             if(tr = GetTracker(TRAK_DAMEM))
  293.                 tr -> dt_Object . dt_Resource = (CPTR)_detach_name;
  294.  
  295.             if(tr = GetTracker(TRAK_LOCK))
  296.                 tr -> dt_Object . dt_Resource = (CPTR)_detach_curdir;
  297.  
  298.             CurrentDir(_detach_curdir);
  299.  
  300.             pp -> pr_COS = _Backstdout;
  301.  
  302.             *alen = _alen;
  303.             *aptr = _aptr;
  304.         }
  305.     }
  306. }
  307. #endif /* DETACH */
  308.