home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 160.lha / BCPL / mynewcli.c < prev    next >
C/C++ Source or Header  |  1988-04-27  |  9KB  |  248 lines

  1. /* Mynewcli.c - a C language replacement for NEWCLI
  2. Compile and link with Manx 3.4:
  3.   cc mynewcli
  4.   ln mynewcli.o bcpllib.o -lc
  5. By Bill Kinnersley - Dec 18, 1987
  6. Mail:   Physics Dept.
  7.         Montana State University
  8.         Bozeman, MT 59717
  9. BITNET: iphwk@mtsunix1
  10. INTERNET: iphwk%mtsunix1.bitnet@cunyvm.cuny.edu
  11. UUCP: ...psuvax1!mtsunix1.bitnet!iphwk
  12. */
  13. #include <stdio.h>
  14. #include <libraries/dosextens.h>
  15. #include <functions.h>
  16. #include <exec/memory.h>
  17. #include "BCPL.h"
  18. long *gv;
  19. struct rsdnt {
  20.         BPTR    next;
  21.         long    count;
  22.         BPTR    seg;
  23.         char    length;
  24.         char    name[1];
  25. };
  26. struct pathlist {
  27.         BPTR next;
  28.         BPTR lock;
  29. };
  30. long cli_init();
  31. struct pathlist *copypath();
  32. main(argc, argv) char *argv[]; {
  33.         struct RootNode *root;
  34.         struct DosLibrary *doslib;
  35.         struct DosInfo *dosinfo;
  36.         struct rsdnt *list;
  37.         struct pathlist *sub;
  38.         struct MsgPort *fst;
  39.         struct Process *myproc, *newproc;
  40.         struct CommandLineInterface *cli;
  41.         struct DosPacket *pkt;
  42.         struct FileLock *lock;
  43.         long clitask, *tskarr, taskno;
  44.         long stsz, sz, *oldseglist, *newseglist, res;
  45.         BPTR cd=0, procname=0;
  46.         char *wdwname;
  47.         short i, len;
  48.         BCPLInit();
  49.         myproc = (struct Process *)FindTask(0L);
  50.         stsz = myproc->pr_StackSize;
  51.         cli = (struct CommandLineInterface *)BADDR(myproc->pr_CLI);
  52.         gv = (long *)myproc->pr_GlobVec;
  53.         oldseglist = (long *)BADDR(myproc->pr_SegList);
  54.         newseglist = (long *)AllocMem(24L, MEMF_CLEAR);
  55.         *newseglist = 24;
  56.         newseglist++;
  57.         for (i=0; i<4; i++) newseglist[i] = oldseglist[i];
  58.         doslib = (struct DosLibrary *)OpenLibrary("dos.library", 0L);
  59.         root = (struct RootNode *)doslib->dl_Root;
  60.         tskarr = (long *)BADDR(root->rn_TaskArray);
  61.         dosinfo = (struct DosInfo *)BADDR(root->rn_Info);
  62.         for (list = (struct rsdnt *)BADDR(dosinfo->di_NetHand);
  63.                 list; list = (struct rsdnt *)BADDR(list->next))
  64.                 if (strcmp("CLI", list->name)==0) {
  65.                         newseglist[4] = list->seg;
  66.                         if (list->count != -1) list->count++;
  67.                         break;
  68.                 }
  69.         wdwname = (argc>1) ? argv[1] : "CON:0/0/640/100/MyNewCLI";
  70.         Forbid();
  71.         sz = tskarr[0];
  72.         for (taskno=1; taskno<=sz; taskno++) if (!tskarr[taskno]) break;
  73.         if (taskno>sz) {
  74.                 Permit();
  75.                 FreeMem(--newseglist, 24L);
  76.                 printf("Too many tasks\n");
  77.                 goto failure;
  78.         }
  79.         stsz = 3000;
  80.         procname = MakeBSTR("MyNewCLI");
  81.         if (!(clitask = BCPL(CREATEPROCB, bptr(newseglist), stsz>>2, 0L,
  82.                 procname, bptr(gv)))) {
  83.                 Permit();
  84.                 FreeMem(--newseglist, 24L);
  85.                 printf("Unable to create new process\n");
  86.                 goto failure;
  87.         }
  88.         tskarr[taskno] = (long)clitask;
  89.         newproc =(struct Process *)((long)clitask-(long)sizeof(struct Task));
  90.         newproc->pr_TaskNum = taskno;
  91.         Permit();
  92.         cd = DupLock(myproc->pr_CurrentDir);
  93.         if (sub = copypath(cli->cli_CommandDir)) {
  94.                 lock = (struct FileLock *)BADDR(sub->lock);
  95.                 fst = lock->fl_Task;
  96.         }
  97.         else fst = (struct MsgPort *)myproc->pr_FileSystemTask;
  98.         if (BCPL(SENDPKT, 0L, clitask, cli_init, -1L, 0L, cd,
  99.                 wdwname, bptr(sub), bptr(cli), fst))
  100.                 {FreeBSTR(procname); BCPLQuit(); exit(0);}
  101.         printf("Unable to Open Window\n");
  102. failure:
  103.         printf("MyNewCLI Failed\n");
  104.         if (cd) UnLock(cd);
  105.         if (taskno) tskarr[taskno] = 0;
  106.         if (list) if (list->count != -1) list->count--;
  107.         if (procname) FreeBSTR(procname);
  108.         BCPLQuit();
  109.         exit(20);
  110. }
  111. struct pathlist *copypath(arg) BPTR arg; {
  112. /* The PATH is stored in cli_CommandDir as a linked list of Locks */
  113. /* Each newly created CLI must inherit the PATH of its creator */
  114.         struct pathlist *oldlist, *newlist, *link, *lastlink;
  115.         long *mem;
  116.         newlist = NULL;
  117.         lastlink = (struct pathlist *)&newlist;
  118.         oldlist = (struct pathlist *)BADDR(arg);
  119.         while (oldlist) {
  120.                 if (!(mem = (long *)AllocMem(12L, 1L))) break;
  121.                 mem[0] = 12L;
  122.                 link = (struct pathlist *)&mem[1];
  123.                 link->next = NULL;
  124.                 link->lock = DupLock(oldlist->lock);
  125.                 lastlink->next = bptr(link);
  126.                 lastlink = link;
  127.                 oldlist = (struct pathlist *)BADDR(oldlist->next);
  128.         }
  129.         return (struct pathlist *)(BADDR(newlist));
  130. }
  131. struct clistartup {
  132.         long notused[5];
  133.         BPTR curdir, window, path, oldCLI;
  134.         APTR FSTask;
  135. };
  136. extern long a0[3];
  137. long retval;
  138. long cli_init(arg) BPTR arg; {
  139.         struct clistartup *pkt; /* this MUST be the first local */
  140.         struct Process *mytask;
  141.         struct CommandLineInterface *oldcli, *mycli;
  142.         struct FileHandle *fh;
  143.         BPTR input, output;
  144.         long saveres, *array, max, i, putpkt, remtask;
  145.         char *bstr, *prompt, *newprompt, *curdir, *newcurdir;
  146. #asm
  147.         movem.l a1/a3,-(a7)
  148.         asl.l   #2,d1
  149.         move.l  d1,-4(a5)       ;this initializes pkt */
  150. #endasm
  151.         geta4();
  152.         remtask = gv[34];
  153.         putpkt = gv[42];
  154.         oldcli = (struct CommandLineInterface *)BADDR(pkt->oldCLI);
  155.         prompt = (char *)BADDR(oldcli->cli_Prompt);
  156.         curdir = (char *)BADDR(oldcli->cli_SetName);
  157.         mytask = (struct Process *)FindTask(0L);
  158.         mycli = (struct CommandLineInterface *)BADDR(mytask->pr_CLI);
  159.         newprompt = (char *)BADDR(mycli->cli_Prompt);
  160.         newcurdir = (char *)BADDR(mycli->cli_SetName);
  161.         mytask->pr_CurrentDir = pkt->curdir;
  162.         mytask->pr_FileSystemTask = pkt->FSTask;
  163.         mytask->pr_WindowPtr = 0L;
  164.         if (!(input = Open(pkt->window, MODE_OLDFILE))) {
  165.                 saveres = mytask->pr_Result2;
  166.                 returnpkt(pkt, 0L, saveres);
  167.                 mytask->pr_Result2 = saveres;
  168.                 retval = remtask;
  169.                 goto ret;
  170.         }
  171.         if (!IsInteractive(input)) {
  172.                 Close(input);
  173.                 mytask->pr_Result2 = 206;
  174.                 input = 0L;
  175.         }
  176.         mycli->cli_StandardInput = input;
  177.         mytask->pr_CIS = input;
  178.         fh = (struct FileHandle *)BADDR(input);
  179.         mytask->pr_ConsoleTask = (APTR)fh->fh_Type;
  180.         if (!(output = Open("*", MODE_NEWFILE))) {
  181.                 Close(input);
  182.                 saveres = mytask->pr_Result2;
  183.                 returnpkt(pkt, 0L, saveres);
  184.                 mytask->pr_Result2 = saveres;
  185.                 retval = remtask;
  186.                 goto ret;
  187.         }
  188.         mycli->cli_StandardOutput = output;
  189.         mytask->pr_COS = output;
  190.         mycli->cli_CurrentInput = mycli->cli_StandardInput;
  191.         mycli->cli_CurrentOutput = mycli->cli_StandardOutput;
  192.         mycli->cli_Background = 0;
  193.         mycli->cli_CommandDir = pkt->path;
  194.         mycli->cli_ReturnCode = 0;
  195.         mycli->cli_FailLevel = oldcli->cli_FailLevel;
  196.         mycli->cli_Result2 = 0;
  197.         bstr = (char *)BADDR(mycli->cli_CommandFile);
  198.         bstr[0] = 0;
  199.         mycli->cli_DefaultStack = oldcli->cli_DefaultStack;
  200.         mycli->cli_Module = 0;
  201.         max = prompt[0];
  202.         for (i=0; i<=max; i++) newprompt[i] = prompt[i];
  203.         max = curdir[0];
  204.         for (i=0; i<=max; i++) newcurdir[i] = curdir[i];
  205.         printf("New CLI Task %ld\n", mytask->pr_TaskNum);
  206.         array = (long *)BADDR(mytask->pr_SegList);
  207.         array[3] = 0;
  208.         mytask->pr_Result2 = bptr(pkt);
  209.         retval = putpkt;
  210. /* After we return, the new CLI will call retval with argument pr_Result2 */
  211. ret:    ;
  212. #asm
  213.         dseg
  214.         public  _a0
  215.         cseg
  216.         lea     _retval,a1
  217.         move.l  (a1),d1
  218.         lea     _a0,a0
  219.         move.l  0(a0),a2
  220.         move.l  8(a0),a6
  221.         suba.l  a0,a0
  222.         movem.l (a7)+,a1/a3
  223.         unlk    a5
  224.         jmp     (a6)
  225. #endasm
  226. }
  227. returnpkt(pkt, res1, res2) struct DosPacket *pkt; long res1, res2; {
  228.         struct Message *msg;
  229.         struct MsgPort *port;
  230.         port = pkt->dp_Port;
  231.         msg = pkt->dp_Link;
  232.         msg->mn_Node.ln_Name = (char *)pkt;
  233.         msg->mn_Node.ln_Succ = msg->mn_Node.ln_Pred = 0L;
  234.         pkt->dp_Res1 = res1;
  235.         pkt->dp_Res2 = res2;
  236.         PutMsg(port, msg);
  237. }
  238. /*struct DosPacket *taskwait() {
  239.         struct Process *mytask;
  240.         struct MsgPort *myport;
  241.         struct Message *msg;
  242.         mytask = (struct Process *)FindTask(0L);
  243.         myport = &mytask->pr_MsgPort;
  244.         WaitPort(myport);
  245.         msg = GetMsg(myport);
  246.         return((struct DosPacket *)msg->mn_Node.ln_Name);
  247. }*/
  248.