#include <functions.h>
#include <ctype.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <graphics/text.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>

#define FAULT 1
#define ON 1
#define NO_FAULT 0
#define NO_WINDW 1
#define NO_GRAFX 2
#define NO_INTUI 3

#define MAKEDIR_S 0
#define DELETE_S  1
#define DODOS_S   2
#define RENAME_S  3
#define STORE_S   4
#define WRITE_S   5
#define COPY_S    6
#define FLUSH_S   7
#define PURGE_S   8
#define CLEAR_S   9
#define PRINT_S  10
#define ASK_S    11
#define WAIT_S   12
#define IF_S     13
#define ELSE_S   14
#define END_S    15
#define QUIT_S   16
#define AS_S     17
#define EXISTS_S 18
#define MAXCOM 19

#define NO_FLAG     1
#define YES_FLAG    2
#define TRUE_FLAG   4
#define FALSE_FLAG  8
#define OK_FLAG    16
#define FAULT_FLAG 32
#define MAXPRED 6

#define SYMBOL 1
#define STRING 2
#define PREDICATE 3

#define NOT_FOUND -1

struct StoredFile
{
struct StoredFile *sf_NextFile;
int sf_Size;
char sf_Name[80];
};


struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Window *MyWindow;
struct RastPort *rp;

char PrintOutBuffer[80];

struct TextAttr MyAttr =
{
 (STRPTR)"topaz.font",
 8,
 NULL,
 NULL
};


SHORT TextVectors8[] =
{
 0,0, 69,0, 69,10, 0, 10, 0, 0, 69,0, 70,1, 70,11, 1,11
};

struct Border TextBorder8 = { -1,-1, 1,0,JAM2, 9, &TextVectors8[0], NULL };

struct IntuiText NOText =
{ 1, 0, JAM2, 2, 1, &MyAttr, (UBYTE *)"   NO   ", NULL };

struct IntuiText CONTINUEText =
{ 1, 0, JAM2, 2, 1, &MyAttr, (UBYTE *)"CONTINUE", NULL };

struct IntuiText YESText =
{ 1, 0, JAM2, 2, 1, &MyAttr, (UBYTE *)"  YES   ", NULL };

struct IntuiText OutText =
{ 1, 0, JAM2, 0, 0, &MyAttr, (UBYTE *)PrintOutBuffer, NULL };


struct Gadget CONTGadg =
{
 NULL,
 -80, -15,
 68,9,
 GADGHCOMP | GRELRIGHT | GRELBOTTOM,
 GADGIMMEDIATE | RELVERIFY,
 BOOLGADGET,
 (APTR)&TextBorder8,
 NULL,
 &CONTINUEText,
 NULL,
 NULL,
 1,
 NULL
};

struct Gadget NOGadg =
{
 NULL,
 -80, -15,
 68,9,
 GADGHCOMP | GRELRIGHT | GRELBOTTOM,
 GADGIMMEDIATE | RELVERIFY,
 BOOLGADGET,
 (APTR)&TextBorder8,
 NULL,
 &NOText,
 NULL,
 NULL,
 1,
 NULL
};

struct Gadget YESGadg =
{
 &NOGadg,
 12, -15,
 68,9,
 GADGHCOMP | GRELBOTTOM,
 GADGIMMEDIATE | RELVERIFY,
 BOOLGADGET,
 (APTR)&TextBorder8,
 NULL,
 &YESText,
 NULL,
 NULL,
 2,
 NULL
};

struct NewWindow WindowData =
{
 0,0,
 512,128,
 0,1,
 GADGETUP,
 WINDOWDRAG | WINDOWDEPTH | ACTIVATE,
 NULL,
 NULL,
 (UBYTE*)"MultiInstall Version 1.00 by Stefan G. Boldorf in 1991",
 NULL, NULL,
 NULL, NULL,
 NULL, NULL,
 WBENCHSCREEN,
};

struct StoredFile *FirstFile = NULL;
long IF_Level =0, STATE_Flags = 4;
long LineCount, PrintCount, PrintChars, MaxLines, PrintLine;
long WinWidth, WinHeight;
char *LastPos, *Curr;


char Command_List[19][8] =
{
 "MAKEDIR", "DELETE", "DODOS", "RENAME",       /* Normal DOS functions   */
 "STORE", "WRITE", "COPY", "FLUSH",            /* File functions         */
 "PURGE", "CLEAR",
 "PRINT", "ASK", "WAIT",                       /* IO functions           */
 "IF", "ELSE", "END", "QUIT", "AS",            /* Structural functions   */
 "EXISTS"                                      /* Predicate function     */
};


char Predicate_List[6][6] =
{
 "NO", "YES", "TRUE", "FALSE", "OK", "FAULT"
};


char InfoList[10][56] =
{
 "This is MultiInstall Version 1.00 by Stefan G. Boldorf",
 "                                                      ",
 "                            Date of creation 8.8. 1991",
 "                                                      ",
 "MultiInstall is a simple Utility  for installing large",
 "program  packages. It is driven  via an ASCII file and",
 "can be started  from  either  Workbench or  CLI/SHELL.",
 "                                                      ",
 "This  utility is in the  Public  Domain, see the .doc",
 "file for the copying agreement and instructions.      "
};


/* --------------------------- Environment Stuff ----------------------- */



void
CloseInstWindow( how)
int how;
{
 switch (how)
   {
    case NO_FAULT: CloseWindow( MyWindow);
    case NO_WINDW: CloseLibrary( GfxBase);
    case NO_GRAFX: CloseLibrary( IntuitionBase);
    case NO_INTUI: break;
   }
}



int
OpenInstWindow()
{
 int fault;

 fault =0;
 if ( !fault)
   {
    fault = (IntuitionBase = (struct IntuitionBase *)
             OpenLibrary("intuition.library", 0L))? NO_FAULT: NO_INTUI;
   }
 if ( !fault)
   {
    fault = (GfxBase = (struct GfxBase *)
             OpenLibrary("graphics.library", 0L))? NO_FAULT: NO_GRAFX;
   }
 if ( !fault)
   {
    fault = (MyWindow = (struct Window *)
             OpenWindow( &WindowData))? NO_FAULT: NO_WINDW;
   }
 if ( !fault)
   {
    rp = MyWindow->RPort;
    PrintCount =0;
    WinWidth   = 508 - MyWindow->BorderLeft - MyWindow->BorderRight;
    PrintChars = WinWidth >>3;
    WinHeight = MyWindow->Height -MyWindow->BorderTop
                -MyWindow->BorderBottom -20;
    MaxLines = WinHeight / 9;
    PrintLine =0;
   }
 else
   {
    CloseInstWindow( fault);
   }
 return( fault);
}



void
ClearPrint()
{
 SetAPen( rp, 0L);
 RectFill( rp, (long)(MyWindow->BorderLeft), (long)(MyWindow->BorderTop),
               (long)(512 - (int)(MyWindow->BorderRight)),
               (long)(128 - (int)(MyWindow->BorderBottom)));
 SetAPen( rp, 1L);
 PrintCount = (long)(MyWindow->BorderTop) +1;
 PrintLine =0;
}



void
PrintOut( TheText)
char *TheText;
{
 if ( PrintLine >= MaxLines)
   {
    ClipBlit( rp, MyWindow->BorderLeft, MyWindow->BorderTop +9,
              rp, MyWindow->BorderLeft, MyWindow->BorderTop,
                  WinWidth, WinHeight, 0xc0);
    PrintLine = MaxLines -1;
    PrintCount = (int)(MyWindow->BorderTop) +1 +9*MaxLines;
   }
 strncpy( PrintOutBuffer, TheText, PrintChars);
 PrintOutBuffer[PrintChars] =0;
 SetAPen( rp, 0);
 RectFill( rp, (int)(MyWindow->BorderLeft), PrintCount,
                512 - (int)(MyWindow->BorderRight), PrintCount +8);
 PrintIText( rp, &OutText, (int)(MyWindow->BorderLeft), PrintCount);
 PrintCount += 9;
 PrintLine++;
}



void
ClearGadget( Gad, Win)
struct Gadget *Gad;
struct Window *Win;
{
 struct RastPort *wrp;
 int x, y;

 wrp = Win->RPort;
 SetAPen( wrp, 0);
 SetDrMd( wrp, JAM2);
 x = (Gad->Flags & GRELRIGHT) ? Win->Width  +Gad->LeftEdge: Gad->LeftEdge;
 y = (Gad->Flags & GRELBOTTOM)? Win->Height +Gad->TopEdge : Gad->TopEdge;
 RectFill( wrp, x -2, y -2, x +Gad->Width +1, y +Gad->Height +1);
 SetAPen( wrp, 1);
}



void
WaitForUser( TheText)
char *TheText;
{
 struct IntuiMessage *MyMess;
 struct Gadget *MyLoc;
 int MyClass, MyID;

 PrintOut( TheText);
 ModifyIDCMP( MyWindow, GADGETUP);
 AddGadget( MyWindow, &CONTGadg, -1);
 RefreshGadgets( &CONTGadg, MyWindow, NULL);
 MyID = 0;
 while ( MyID != 1)
   {
    Wait( 1<<MyWindow->UserPort->mp_SigBit);
    while( MyMess = (struct IntuiMessage *)GetMsg( MyWindow->UserPort))
      {
       MyClass = MyMess->Class;
       MyLoc = (struct Gadget *)MyMess->IAddress;
       ReplyMsg( MyMess);
      }
    if ( MyClass == GADGETUP)
      {
       MyID = MyLoc->GadgetID;
      }
   }
 ClearGadget( &CONTGadg, MyWindow);
 RemoveGadget( MyWindow, &CONTGadg);
 ModifyIDCMP( MyWindow, NULL);
}



void
ErrorOut( ETxt)
char *ETxt;
{
 char ErTxt[80];

 if (LineCount) sprintf( ErTxt, "Error in line %d: %s", LineCount, ETxt);
 WaitForUser( ErTxt);
}



void
AskAbout( TheText)
char *TheText;
{
 struct IntuiMessage *MyMess;
 struct Gadget *MyLoc;
 int MyClass, MyID;

 PrintOut( TheText);
 ModifyIDCMP( MyWindow, GADGETUP);
 AddGList( MyWindow, &YESGadg, -1, 2, NULL);
 RefreshGList( &YESGadg, MyWindow, NULL, 2);
 MyID = 0;
 while ( MyID == 0)
   {
    Wait( 1<< MyWindow->UserPort->mp_SigBit);
    while( MyMess = (struct IntuiMessage *)GetMsg( MyWindow->UserPort))
      {
       MyClass = MyMess->Class;
       MyLoc = (struct Gadget *)MyMess->IAddress;
       ReplyMsg( MyMess);
      }
    if ( MyClass == GADGETUP)
      {
       MyID = MyLoc->GadgetID;
      }
   }
 ClearGadget( &YESGadg, MyWindow);
 ClearGadget( &NOGadg, MyWindow);
 RemoveGList( MyWindow, &YESGadg, 2);
 ModifyIDCMP( MyWindow, NULL);
 STATE_Flags = (MyID ==1)? (STATE_Flags & ~YES_FLAG)|NO_FLAG:
                           (STATE_Flags & ~NO_FLAG)|YES_FLAG;
}



void
PrintInfo()
{
 int t;

 ClearPrint();
 for( t=0; t < 9; t++)
   {
    PrintOut( InfoList[t]);
   }
 WaitForUser( InfoList[9]);
}



/* ------------------------------ DOS Stuff ---------------------------- */



int
FileSize( Name)
char *Name;
{
 struct FileInfoBlock MyInfo;
 struct FileLock *MyFile;
 int back;

 back =0;
 if ( MyFile = (struct FileLock *) Lock( Name, ACCESS_READ))
   {
    if ( Examine( MyFile, &MyInfo))
      {
       back = MyInfo.fib_Size;
      }
    UnLock( MyFile);
   }
 return( back);
}



int
ReadFile( Name, Loc, Size)
char *Name;
char *Loc;
int Size;
{
 struct FileHandle *fh;
 int back;

 back = FALSE;
 fh = NULL;
 if ( fh = Open( Name, MODE_OLDFILE))
   {
    back = Read( fh, Loc, Size) == Size;
    Close( fh);
   }
 return( back);
}



int
WriteFile( Name, Loc, Size)
char *Name;
char *Loc;
int Size;
{
 struct FileHandle *fh;
 int back;

 back = FALSE;
 fh = NULL;
 if ( fh = Open( Name, MODE_NEWFILE))
   {
    back = Write( fh, Loc, Size) == Size;
    Close( fh);
   }
 return( back);
}



/* --------------------------- List Handling ----------------------- */



int
StoreFile( Name, ID)
char *Name;
char *ID;
{
 struct StoredFile *help, *CurF;
 int DataSize, back;
 char *DataBuffer;

 back = FALSE;
 CurF = NULL;
 if ((DataSize = FileSize( Name)) > 0)
   {
    if (CurF = (struct StoredFile *)
                AllocMem( sizeof( struct StoredFile) +DataSize,
                                  MEMF_PUBLIC|MEMF_CLEAR))
      {
       CurF->sf_Size = DataSize;
       CurF->sf_NextFile = NULL;
       strncpy( &CurF->sf_Name[0], ID, PrintChars);
       CurF->sf_Name[PrintChars] =0;
       DataBuffer = (char *)(CurF) + sizeof( struct StoredFile);
       if ( ReadFile( Name, DataBuffer, DataSize))
         {
          back = TRUE;
          if ( FirstFile == NULL)
            {
             FirstFile = CurF;
            }
          else
            {
             help = FirstFile;
             while( help->sf_NextFile)
               {
                help = help->sf_NextFile;
               }
             help->sf_NextFile = CurF;
            }
         }
       else
         {
          ErrorOut("File is corrupt");
          FreeMem( (char *)CurF, DataSize + sizeof( struct StoredFile));
         }
      }
    else
      {
       ErrorOut("Not enough memory");
      }
   }
 else
   {
    ErrorOut("File not found");
   }
 return( back);
}



struct StoredFile
*FindFile( ID)
char *ID;
{
 struct StoredFile *Back;
 int searching;

 if (Back = FirstFile)
   {
    searching = TRUE;
    while (Back && searching)
      {
       if ( strcmp( ID, Back->sf_Name) == NULL)
         {
          searching = FALSE;
         }
       else
         {
          Back = Back->sf_NextFile;
         }
      }
   }
 return( Back);
}



int
RemoveFile( ID)
char *ID;
{
 struct StoredFile *CurF, *Pred;
 int searching, back = FALSE;

 if (CurF = FindFile( ID))
   {
    if (CurF == FirstFile)
      {
       FirstFile = CurF->sf_NextFile;
      }
    else
      {
       Pred = FirstFile;
       while ( Pred->sf_NextFile != CurF)
         {
          Pred = Pred->sf_NextFile;
         }
       Pred->sf_NextFile = CurF->sf_NextFile;
      }
    FreeMem( CurF, CurF->sf_Size + sizeof( struct StoredFile));
    back = TRUE;
   }
 else
   {
    ErrorOut("File is not stored");
   }
 return( back);
}



int
SaveFile( ID, Name)
char *ID;
char *Name;
{
 struct StoredFile *CurF;
 int back;
 char *DataBuffer;

 back =FALSE;
 if (CurF = FindFile( ID))
   {
    DataBuffer = (char *)(CurF) + sizeof( struct StoredFile);
    if (!(back = WriteFile( Name, DataBuffer, CurF->sf_Size)))
      {
       ErrorOut("Could not write file");
      }
   }
 else
   {
    ErrorOut("File not stored");
   }
 return( back);
}



int
RemoveAllFiles()
{
 struct StoredFile *help;

 while ( FirstFile != NULL)
   {
    help = FirstFile->sf_NextFile;
    FreeMem( FirstFile, FirstFile->sf_Size + sizeof( struct StoredFile));
    FirstFile = help;
   }
 return( TRUE);
}



int
CopyFile( InName, OutName)
char *InName;
char *OutName;
{
 int DataSize, back;
 char *DataBuffer;

 back = FALSE;
 if ((DataSize = FileSize( InName)) > 0)
   {
    if (DataBuffer = (char *) AllocMem( DataSize, MEMF_PUBLIC|MEMF_CLEAR))
      {
       if ( ReadFile( InName, DataBuffer, DataSize))
         {
          if ( WriteFile( OutName, DataBuffer, DataSize))
            {
             back = TRUE;
            }
          else
            {
             ErrorOut("Could not write file");
            }
         }
       else
         {
          ErrorOut("Could not read file");
         }
       FreeMem( DataBuffer, DataSize);
      }
    else
      {
       ErrorOut("Could not allocate memory");
      }
   }
 return( back);
}



int
ExistsFile( Name)
char *Name;
{
 if ( FileSize( Name))
   {
    STATE_Flags |= OK_FLAG;
    STATE_Flags &= ~FAULT_FLAG;
   }
 else
   {
    STATE_Flags &= ~OK_FLAG;
    STATE_Flags |= FAULT_FLAG;
   }
 return( TRUE);
}



/* --------------------------- Search Fuctions ----------------------- */



int
NextCommand()
{
 int searching, t;

 t=0;
 searching = TRUE;
 while (( t < MAXCOM)&&(searching))
   {
    if ( strncmp( Curr, Command_List[t], strlen( Command_List[t])) == 0)
      {
       searching = FALSE;
       Curr += strlen( Command_List[t]);
      }
    else
      {
       t++;
      }
   }
 if ( searching) t = NOT_FOUND;
 return( t);
}



int
NextPredicate()
{
 int searching, t;

 t=0;
 searching = TRUE;
 while (( t < MAXPRED)&&(searching))
   {
    if ( strncmp( Curr, Predicate_List[t], strlen( Predicate_List[t])) == 0)
      {
       searching = FALSE;
       Curr += strlen( Predicate_List[t]);
      }
    else
      {
       t++;
      }
   }
 if ( searching) t = NOT_FOUND;
 return( t);
}



int
NextString( Buffer)
char *Buffer;
{
 int searching, t;

 t =0;
 if ( *Curr == 34)
   {
    Curr++;
    while ((*Curr != 34)&&(Curr < LastPos))
      {
       if ( *Curr == 92) Curr++;
       if ( t < 78)Buffer[t] = *Curr;
       if ( *Curr == 10) LineCount++;
       t++;
       Curr++;
      }
    Curr++;
   }
 if ( t > 78) t = 0;
 Buffer[t] =0;
 return( t);
}



int
NextItem()
{
 int searching, type;

 searching = TRUE;
 type =0;
 while (searching)
   {
    if ( *Curr == 59)
      {
       while ((*Curr != 10)&&( Curr < LastPos))
         {
          Curr++;
         }
       Curr++;
       LineCount++;
      }
    if (isalpha((int)(*Curr)))
      {
       type = SYMBOL;
       searching = FALSE;
      }
    if (*Curr == 34)
      {
       type = STRING;
       searching = FALSE;
      }
    if ( Curr >= LastPos)
      {
       searching = FALSE;
      }
    if ((searching) &&( Curr < LastPos))
      {
       if ( *Curr == 10) LineCount++;
       Curr++;
      }
   }
 return( type);
}



/* --------------------------- Execute Fuctions ----------------------- */



int
Exec_Simple( Com)
int Com;
{
 struct FileLock *MyLock;
 struct FileHandle *nfh;
 char *Help;
 int len, Correct, DosError;
 char SBuffer[80];

 Correct = FALSE;
 if ( NextItem() == STRING)
   {
    if (len = NextString( SBuffer))
      {
       switch (Com)
         {
          case MAKEDIR_S:  if (MyLock = CreateDir( SBuffer))
                             {
                              UnLock( MyLock);
                              Correct = TRUE;
                             }
                           else
                             {
                              ErrorOut("Unable to create directory");
                             }
                           break;
          case DELETE_S:   Correct = DeleteFile( SBuffer);
                           break;
          case DODOS_S:    if (nfh = Open("RAM:mil.tmp", MODE_NEWFILE))
                             {
                              Correct = Execute( SBuffer, nfh, nfh);
                              Close(nfh);
                              DeleteFile("RAM:mil.tmp");
                             }
                           if (DosError = IoErr())
                             {
                              sprintf( SBuffer, "DOS Error No %d", DosError);
                              ErrorOut( SBuffer);
                              Correct = FALSE;
                             }
                           break;
          case FLUSH_S:    Correct = RemoveFile( SBuffer);
                           break;
          case PRINT_S:    PrintOut( SBuffer);
                           Correct = TRUE;
                           break;
          case ASK_S:      AskAbout( SBuffer);
                           Correct = TRUE;
                           break;
          case WAIT_S:     WaitForUser( SBuffer);
                           Correct = TRUE;
                           break;
          case EXISTS_S:   Correct = ExistsFile( SBuffer);
                           break;
         }
      }
    else
      {
       ErrorOut( "Valid string expected!");
       Correct = FALSE;
      }
   }
 else
   {
    ErrorOut( "String value expected!");
    Correct = FALSE;
   }
 return( Correct);
}



int
Exec_Double( Com)
int Com;
{
 int t, searching, Correct, len_A, len_B;
 char *Help;
 char Buffer_A[80], Buffer_B[80];

 Correct = FALSE;
 if ( NextItem() == STRING)
   {
    if (len_A = NextString( Buffer_A))
      {
       if ( NextItem() == SYMBOL)
         {
          if (NextCommand() == AS_S)
            {
             if ( NextItem() == STRING)
               {
                if (len_B = NextString( Buffer_B))
                  {
                   switch( Com)
                     {
                      case RENAME_S: Correct = Rename( Buffer_A, Buffer_B);
                                     break;
                      case STORE_S:  Correct = StoreFile( Buffer_A, Buffer_B);
                                     break;
                      case WRITE_S:  Correct = SaveFile( Buffer_A, Buffer_B);
                                     break;
                      case COPY_S:   Correct = CopyFile( Buffer_A, Buffer_B);
                                     break;
                     }
                  }
               }
            }
         }
      }
   }
 return( Correct);
}



int
Exec_IF()
{
 int found, type, Curr_IF_Level;
 int back = FALSE;
 char DBuf[80];

 Curr_IF_Level = IF_Level;
 if ( NextItem( ) == SYMBOL)
   {
    if ((found = NextPredicate())< MAXPRED)
      {
       if (!(STATE_Flags & (1<<found)))
         {
          found = FALSE;
          while ((! found)&&(Curr < LastPos))
            {
             if ((type = NextItem()) == SYMBOL)
               {
                type = NextCommand();
                if ( type != NOT_FOUND)
                  {
                   if (((type == END_S)||(type == ELSE_S))
                       &&(Curr_IF_Level == IF_Level))
                     {
                      found = TRUE;
                      back = TRUE;
                     }
                   else
                     {
                      if ( type == END_S) Curr_IF_Level--;
                     }
                   if ( type == IF_S)
                     {
                      Curr_IF_Level++;
                      if ( NextItem() == SYMBOL)
                        {
                         if (NextPredicate() == NOT_FOUND)
                           {
                            ErrorOut("No predicate after IF");
                            found = TRUE;
                           }
                        }
                      else
                        {
                         ErrorOut("No predicate symbol after IF");
                         found = TRUE;
                        }
                     }
                  }
                else
                  {
                   ErrorOut("Predicate outside IF");
                   found = TRUE;
                  }
               }
             else
               {
                if (type == STRING) NextString( DBuf);
               }
            }
         }
       else
         {
          back = TRUE;
         }
       IF_Level++;
      }
    else
      {
       ErrorOut("Expected a predictate");
      }
   }
 else
   {
    ErrorOut("Expected a predictate symbol");
   }
 return( back);
}



int
Exec_SkipElse()
{
 int found, type, CurrIFLevel, Com, back = FALSE;
 char DBuf[80];

 found = FALSE;
 CurrIFLevel = IF_Level;
 while ((! found)&&(Curr < LastPos))
   {
    if ((type = NextItem()) == SYMBOL)
      {
       Com = NextCommand();
       if ((Com == END_S)&&(CurrIFLevel == IF_Level))
         {
          found = TRUE;
          back = TRUE;
         }
       else
         {
          if (Com == END_S) CurrIFLevel--;
         }
       if (Com == IF_S)
         {
          CurrIFLevel++;
          if ( NextItem() == SYMBOL)
            {
             if (NextPredicate() == NOT_FOUND)
               {
                ErrorOut("No predicate after IF");
                found = TRUE;
               }
            }
          else
            {
             ErrorOut("No predicate symbol after IF");
             found = TRUE;
            }
         }
      }
    else
      {
       if (type == STRING) NextString( DBuf);
      }
   }
 return( back);
}



void
Exec_Script( Start)
char *Start;
{
 int Correct, done, CommandNr;

 Correct = TRUE;
 done = FALSE;
 Curr = Start;
 LineCount =1;
 while (( Curr < LastPos)&&(Correct)&&(!done))
   {
    if (NextItem() == SYMBOL)
      {
       CommandNr = NextCommand();
       switch( CommandNr)
         {
          case ASK_S:
          case WAIT_S:
          case DODOS_S:
          case FLUSH_S:
          case PRINT_S:
          case DELETE_S:
          case EXISTS_S:
          case MAKEDIR_S: Correct = Exec_Simple( CommandNr);
                          break;
          case STORE_S:
          case WRITE_S:
          case COPY_S:
          case RENAME_S: Correct = Exec_Double( CommandNr);
                         break;
          case PURGE_S:  Correct = RemoveAllFiles();
                         break;
          case CLEAR_S:  ClearPrint();
                         Correct = TRUE;
                         break;
          case IF_S:     Correct = Exec_IF();
                         break;
          case END_S:    IF_Level--;
                         if ( IF_Level < 0)
                           {
                            Correct = FALSE;
                           }
                         else
                           {
                            Correct = TRUE;
                           }
                         break;
          case ELSE_S:   Correct = Exec_SkipElse();
                         break;
          case AS_S:     ErrorOut("Unexpected AS found");
                         Correct = FALSE;
          case QUIT_S:   done = TRUE;
                         Correct = TRUE;
                         break;
          default:       ErrorOut("Unexpected Symbol found!");
                         Correct = FALSE;
                         break;
         }
      }
    else
      {
       if ( Curr < LastPos)
         {
          ErrorOut("Line has to start with a command!");
         }
       else
         {
          WaitForUser("Reached last script line, click [CONTINUE] to leave!");
         }
       Correct = FALSE;
      }
   }
}



/* --------------------------- Open Routine ----------------------- */



void
HandleScript( Name)
char *Name;
{
 int The_Size;
 char *StartPos;

 LineCount =0;
 if (The_Size = FileSize( Name))
   {
    if ( StartPos = (char *)AllocMem( The_Size, MEMF_PUBLIC|MEMF_CLEAR))
      {
       if (ReadFile( Name, StartPos, The_Size))
         {
          LastPos = StartPos +The_Size;
          LineCount =1;
          Exec_Script( StartPos);
          RemoveAllFiles();
         }
       else
         {
          ErrorOut("Mangled script file");
         }
       FreeMem( StartPos, The_Size);
      }
    else
      {
       ErrorOut("Not enought memory");
      }
   }
 else
   {
    ErrorOut("File empty or not there");
   }
}



/* --------------------------- Main Routine ----------------------- */



main( argc, argv)
int argc;
char **argv;
{
 struct WBStartup *WBMess;
 char *ScriptFile;

 if (! OpenInstWindow())
   {
    ClearPrint();
    ScriptFile = NULL;
    if ( argc == 0)
      {
       WBMess = (struct WBStartup *) argv;
       if ( WBMess->sm_NumArgs == 2)
         {
          ScriptFile = WBMess->sm_ArgList[1].wa_Name;
         }
      }
    else
      {
       if ( argc > 1)
         {
          ScriptFile = argv[1];
         }
      }
    if ( ScriptFile)
      {
       HandleScript( ScriptFile);
      }
    else
      {
       PrintInfo();
      }
    CloseInstWindow( NO_FAULT);
   }
 exit( 0);
}



/* ------------------------------ THE END ------------------------------ */

