home *** CD-ROM | disk | FTP | other *** search
/ MACD 4 / MACD4.iso / Emulatory / AROS / c / shell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1978-03-06  |  7.4 KB  |  409 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: shell.c,v 1.10 1996/10/15 15:42:11 digulla Exp $
  4.     $Log: shell.c,v $
  5.     Revision 1.10  1996/10/15 15:42:11  digulla
  6.     Fixed a bug in the code to extract the names of the redirection files
  7.     Added ">>" (append) redirection.
  8.     Better exit-code
  9.  
  10.     Revision 1.9  1996/10/04 14:35:14  digulla
  11.     Search C: without path C: add
  12.  
  13.     Revision 1.8  1996/09/17 16:43:01  digulla
  14.     Use general startup code
  15.  
  16.     Revision 1.7  1996/09/17 16:09:34  digulla
  17.     Another failure to make SIGALRM work :(
  18.  
  19.     Revision 1.6  1996/09/13 17:52:11  digulla
  20.     Use IPTR
  21.  
  22.     Revision 1.5  1996/09/12 14:47:55  digulla
  23.     More stack
  24.  
  25.     Revision 1.4  1996/08/30 17:02:03  digulla
  26.     Fixed a bug which caused the shell to exit if the timer sent a signal. This
  27.     fix is a very bad hack :(
  28.  
  29.     Revision 1.3  1996/08/23 17:05:58  digulla
  30.     Increased the stack.
  31.  
  32.     Revision 1.2  1996/08/01 17:40:46  digulla
  33.     Added standard header for all files
  34.  
  35.     Desc:
  36.     Lang:
  37. */
  38. #include <exec/memory.h>
  39. #include <exec/libraries.h>
  40. #include <clib/exec_protos.h>
  41. #include <dos/dosextens.h>
  42. #include <dos/rdargs.h>
  43. #include <clib/dos_protos.h>
  44. #include <utility/tagitem.h>
  45. #include <ctype.h>
  46. #include <stdio.h>
  47. #include <aros/debug.h>
  48.  
  49. BPTR cLock;
  50.  
  51. static void printpath(void)
  52. {
  53.     BPTR dir;
  54.     STRPTR buf;
  55.     ULONG i;
  56.     dir=CurrentDir(0);
  57.     for(i=256;;i+=256)
  58.     {
  59.     buf=AllocVec(i,MEMF_ANY);
  60.     if(buf==NULL)
  61.         break;
  62.     if(NameFromLock(dir,buf,i))
  63.     {
  64.         FPuts(Output(),buf);
  65.         FreeVec(buf);
  66.         break;
  67.     }
  68.     FreeVec(buf);
  69.     }
  70.     CurrentDir(dir);
  71. }
  72.  
  73. static void prompt(void)
  74. {
  75.     printpath();
  76.     FPuts(Output(),"> ");
  77.     Flush(Output());
  78. }
  79.  
  80. struct linebuf
  81. {
  82.     BPTR file;
  83.     UBYTE *buf;
  84.     ULONG size;
  85.     ULONG bend;
  86.     ULONG lend;
  87.     LONG eof;
  88. };
  89.  
  90. static LONG readline(struct linebuf *lb)
  91. {
  92.     if(lb->bend)
  93.     {
  94.     UBYTE *src=lb->buf+lb->lend, *dst=lb->buf;
  95.     ULONG i=lb->bend-lb->lend;
  96.     if(i)
  97.         do
  98.         *dst++=*src++;
  99.         while(--i);
  100.     lb->bend-=lb->lend;
  101.     }
  102.     lb->lend=0;
  103.     for(;;)
  104.     {
  105.     LONG subsize;
  106.     for(;lb->lend<lb->bend;)
  107.         if(lb->buf[lb->lend++]=='\n')
  108.         {
  109.         lb->buf[lb->lend-1]='\0';
  110.         return 0;
  111.         }
  112.     if(lb->eof)
  113.     {
  114.         FreeVec(lb->buf);
  115.         lb->buf=NULL;
  116.         lb->eof=0;
  117.         return 0;
  118.     }
  119.     if(lb->bend>=lb->size)
  120.     {
  121.         UBYTE *newbuf;
  122.         newbuf=AllocVec(lb->size+256,MEMF_ANY);
  123.         if(newbuf==NULL)
  124.         {
  125.         FreeVec(lb->buf);
  126.         lb->buf=NULL;
  127.         return ERROR_NO_FREE_STORE;
  128.         }
  129.         CopyMem(lb->buf,newbuf,lb->bend);
  130.         FreeVec(lb->buf);
  131.         lb->buf=newbuf;
  132.         lb->size+=256;
  133.     }
  134.     subsize=Read(lb->file,lb->buf+lb->bend,lb->size-lb->bend);
  135.     if(subsize==0)
  136.     {
  137.         if(lb->bend)
  138.         lb->buf[lb->bend++]='\n';
  139.         lb->eof=1;
  140.     }else if(subsize<0)
  141.     {
  142.         /*ada 30.8.96 This is a REALLY BAD hack !! */
  143.         if (IoErr() != -1 && IoErr() != 0)
  144.         {
  145.         ULONG error = IoErr();
  146.  
  147.         VPrintf ("Shell:Read %ld\n", &error);
  148.         PrintFault(IoErr(), "Shell:Read");
  149.         FreeVec(lb->buf);
  150.         lb->buf=NULL;
  151.         return IoErr();
  152.         }
  153.     }else
  154.         lb->bend+=subsize;
  155.     }
  156. }
  157.  
  158. BPTR loadseg(STRPTR name)
  159. {
  160.     BPTR old, *cur, seg;
  161.     STRPTR s;
  162.     seg=LoadSeg(name);
  163.     if(seg)
  164.     return seg;
  165.     s=name;
  166.     while(*s)
  167.     {
  168.     if(*s==':'||*s=='/')
  169.         return 0;
  170.     s++;
  171.     }
  172.     old=CurrentDir(0);
  173.     cur=(BPTR *)BADDR(Cli()->cli_CommandDir);
  174.     while(cur!=NULL)
  175.     {
  176.     (void)CurrentDir(cur[1]);
  177.     seg=LoadSeg(name);
  178.     if(seg)
  179.         break;
  180.     cur=(BPTR *)BADDR(cur[0]);
  181.     }
  182.     if (!seg)
  183.     {
  184.     (void)CurrentDir(cLock);
  185.     seg=LoadSeg(name);
  186.     }
  187.     CurrentDir(old);
  188.     return seg;
  189. }
  190.  
  191. LONG execute(STRPTR com)
  192. {
  193.     STRPTR s1=NULL, s2=NULL;
  194.     STRPTR args, rest, command=NULL, infile=NULL, outfile=NULL, appfile=NULL;
  195.     STRPTR last;
  196.     BPTR in=0, out=0;
  197.     BPTR seglist, lock;
  198.     struct FileInfoBlock *fib;
  199.     LONG res, size, error=0;
  200.     struct CSource cs;
  201.  
  202.     last=com;
  203.     while(*last++)
  204.     ;
  205.     args=s1=(STRPTR)AllocVec(last-com+1,MEMF_ANY);
  206.     rest=s2=(STRPTR)AllocVec(last-com+1,MEMF_ANY);
  207.     if(args==NULL||rest==NULL)
  208.     {
  209.     error=ERROR_NO_FREE_STORE;
  210.     goto end;
  211.     }
  212.  
  213.     cs.CS_Buffer=com;
  214.     cs.CS_Length=last-com-1;
  215.     cs.CS_CurChr=0;
  216.  
  217.     for(;;)
  218.     {
  219.     while(com[cs.CS_CurChr]==' '||com[cs.CS_CurChr]=='\t')
  220.         *rest++=com[cs.CS_CurChr++];
  221.     if(com[cs.CS_CurChr]==';')
  222.         break;
  223.     if(command==NULL)
  224.         command=args;
  225.     else if(com[cs.CS_CurChr]=='<')
  226.     {
  227.         cs.CS_CurChr ++; /* Skip redirection character */
  228.         infile=args;
  229.     }
  230.     else if(com[cs.CS_CurChr]=='>')
  231.     {
  232.         cs.CS_CurChr ++; /* Skip redirection character */
  233.  
  234.         if(com[cs.CS_CurChr]=='>')
  235.         {
  236.         cs.CS_CurChr ++; /* Skip redirection character */
  237.         appfile=args;
  238.         }
  239.         else
  240.         outfile=args;
  241.     }
  242.     else
  243.     {
  244.         size=cs.CS_CurChr;
  245.         res=ReadItem(args,~0ul/2,&cs);
  246.         while(size<cs.CS_CurChr)
  247.         *rest++=com[size++];
  248.         if(res==ITEM_NOTHING||res==ITEM_ERROR)
  249.         {
  250.         *rest++=0;
  251.         break;
  252.         }
  253.         continue;
  254.     }
  255.     res=ReadItem(args,~0ul/2,&cs);
  256.     if(res!=ITEM_QUOTED&&res!=ITEM_UNQUOTED)
  257.         break;
  258.     while(*args++)
  259.         ;
  260.     }
  261.     if(command==NULL||!*command)
  262.     goto end;
  263.     if(infile!=NULL)
  264.     {
  265.     in=Open(infile,MODE_OLDFILE);
  266.     if(!in)
  267.     {
  268.         infile=NULL;
  269.         error=IoErr();
  270.         goto end;
  271.     }
  272.     in=SelectInput(in);
  273.     }
  274.     if(outfile!=NULL)
  275.     {
  276.     out=Open(outfile,MODE_NEWFILE);
  277.     if(!out)
  278.     {
  279.         outfile=NULL;
  280.         error=IoErr();
  281.         goto end;
  282.     }
  283.     out=SelectOutput(out);
  284.     }
  285.     if(out==NULL && appfile!=NULL)
  286.     {
  287.     out=Open(appfile,MODE_OLDFILE);
  288.     if(!out)
  289.     {
  290.         outfile=NULL;
  291.         error=IoErr();
  292.         goto end;
  293.     }
  294.     Seek (out,0,OFFSET_END);
  295.     out=SelectOutput(out);
  296.     }
  297.     seglist=loadseg(command);
  298.     if(seglist)
  299.     {
  300.     last=s2;
  301.     while(*last++)
  302.         ;
  303.     RunCommand(seglist,100000,s2,last-s2-1);
  304.     UnLoadSeg(seglist);
  305.     }else if(infile==NULL&&outfile==NULL)
  306.     {
  307.     lock=Lock(command,SHARED_LOCK);
  308.     if(lock)
  309.     {
  310.         fib=AllocDosObject(DOS_FIB,NULL);
  311.         if(fib!=NULL)
  312.         {
  313.         if(Examine(lock,fib))
  314.         {
  315.             if(fib->fib_DirEntryType>0)
  316.             lock=CurrentDir(lock);
  317.             else
  318.             SetIoErr(error=ERROR_OBJECT_WRONG_TYPE);
  319.         }
  320.         FreeDosObject(DOS_FIB,fib);
  321.         }
  322.         UnLock(lock);
  323.     }
  324.     else
  325.         error = IoErr ();
  326.     }
  327.  
  328. end:
  329.     if(in)
  330.     Close(SelectInput(in));
  331.     if(out)
  332.     Close(SelectOutput(out));
  333.     FreeVec(s1);
  334.     FreeVec(s2);
  335.     if(error)
  336.     PrintFault(error,"Couldn't run command");
  337.     Flush(Output());
  338.     return 0;
  339. }
  340.  
  341. int executefile(STRPTR name)
  342. {
  343.     struct linebuf lb = { 0, NULL, 0, 0, 0, 0 };
  344.     LONG error=0;
  345.  
  346.     lb.file=Open(name,MODE_OLDFILE);
  347.     if(lb.file)
  348.     {
  349.     for(;;)
  350.     {
  351.         error=readline(&lb);
  352.         if(error||lb.buf==NULL)
  353.         break;
  354.         error = execute(lb.buf);
  355.         if (error != 0)
  356.         PrintFault (error, "execute:");
  357.     }
  358.     Close(lb.file);
  359.     }else
  360.     error=IoErr();
  361.     return error;
  362. }
  363.  
  364. int main (int argc, char ** argv)
  365. {
  366.     struct RDArgs *rda;
  367.     STRPTR args[2]={ "S:Shell-Startup", NULL };
  368.     struct linebuf lb = { 0, NULL, 0, 0, 0, 0 };
  369.     LONG error=0;
  370.  
  371.     lb.file=Input();
  372.  
  373.     cLock = Lock("C:", SHARED_LOCK);
  374.     if (!cLock)
  375.     {
  376.     PrintFault (IoErr(), "Shell");
  377.     return RETURN_ERROR;
  378.     }
  379.  
  380.     rda=ReadArgs("FROM,COMMAND/K/F",(IPTR *)args,NULL);
  381.     if(rda!=NULL)
  382.     {
  383.     if(args[1])
  384.         execute((STRPTR)args[1]);
  385.     else
  386.     {
  387.         ULONG num=((struct Process *)FindTask(NULL))->pr_TaskNum;
  388.         VPrintf("New Shell process %ld\n",&num);
  389.         Flush(Output());
  390.         executefile((STRPTR)args[0]);
  391.         for(;;)
  392.         {
  393.         prompt();
  394.         error=readline(&lb);
  395.         if(error||lb.buf==NULL)
  396.             break;
  397.         execute(lb.buf);
  398.         }
  399.         VPrintf("Process %ld ending\n",&num);
  400.         Flush(Output());
  401.     }
  402.     FreeArgs(rda);
  403.     }
  404.  
  405.     UnLock (cLock);
  406.  
  407.     return 0;
  408. }
  409.