#include <stdlib.h>
#include <string.h>

#include <exec/types.h>

#include <dos/var.h>
#include <dos/dostags.h>

#include <exec/memory.h>

#include <libraries/dos.h>
#include <libraries/dosextens.h>

#include <dlg/dlg.h>
#include <dlg/user.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/dlg.h>

#include <pragmas/dlg.h>

struct PathList {BPTR pl_NextPath;
                 BPTR pl_PathLock;
                };


BPTR LoadSegPath(char *, struct CommandLineInterface *);
BOOL IsScript   (char *);


LONG __saveds __asm LIBTranslateBuffer(register __a0 char *, register __a1 char *, register __d0 ULONG, register __a2 struct USER_DATA *, register __a3 struct Ram_File *, register __d1 char *);


BOOL __saveds __asm LIBChainProgram(register __a0 char *buffer,
                                    register __a1 char *port)

{SetVar(port, buffer, -1, GVF_LOCAL_ONLY);
 return(TRUE);
}


LONG __saveds __asm LIBOverlayProgram(register __a0 char *buffer)

{struct Process              *myproc;
 struct CommandLineInterface *cli;

 char                         myname[256];
 BPTR                         myhdir;
 BPTR                         mymod;

 struct Segment              *cmdseg;
 BPTR                         seglist = NULL;
 int                          rslt    = -1;

 char                        *pname;
 char                        *args;
 char                        *p;
 long                         len;
 long                         stack;

 len = strlen(buffer) + 3;
 if (!(pname = AllocMem(len, MEMF_PUBLIC)))  return(rslt);

 for(args = pname, p = buffer; (*args = *p) && *args != '\n'; args++, p++);
 *args++ = ' ';
 *args++ = '\n';
 *args   =  0;

 for(args = pname; *args != ' '; args++);
 *args++ = 0;

 if (IsScript(pname))
    {strcpy(myname,    "Execute ");
     strcpy(&myname[8], buffer);
     rslt = !Execute(myname, NULL, Output());
    }
  else
    {myproc = (struct Process *)FindTask(0);
     cli    = (struct CommandLineInterface *)BADDR(myproc->pr_CLI);

     GetProgramName(myname, 255);
     myhdir = myproc->pr_HomeDir;
     mymod  = cli->cli_Module;

     p                  = FilePart(pname);
     myproc->pr_HomeDir = NULL;
     cli->cli_Module    = NULL;

     Forbid();
     if (!(cmdseg = FindSegment(p, NULL, FALSE)))
           cmdseg = FindSegment(p, NULL, TRUE);

     if (cmdseg)
        {if (cmdseg->seg_UC <= CMD_DISABLED)
             cmdseg = NULL;
           else
            {if (cmdseg->seg_UC >= 0)  cmdseg->seg_UC++;
             seglist = cmdseg->seg_Seg;
            }
        }
     Permit();

     if (!seglist)  seglist = LoadSegPath(pname, cli);

     if (seglist)
        {SetIoErr(0);
         if (!SetProgramName(pname))  SetProgramName("DLG-Module");

         stack = cli->cli_DefaultStack;
         if (stack < 1000)  stack = 1000;

         cli->cli_Module = seglist;
         rslt            = RunCommand(seglist, stack*4, args, strlen(args));

         if (cmdseg)
            {Forbid();
             if (cmdseg->seg_UC>0)  cmdseg->seg_UC--;
             Permit();
            }
          else
             UnLoadSeg(cli->cli_Module);
        }

     if (myproc->pr_HomeDir)  UnLock(myproc->pr_HomeDir);

     SetProgramName(myname);
     myproc->pr_HomeDir = myhdir;
     cli->cli_Module    = mymod;
    }


 FreeMem(pname, len);
 return(rslt);
}


BOOL __saveds __asm LIBDialogBatch(register __a0 char             *batchfile,
                                   register __a1 struct USER_DATA *User,
                                   register __a2 struct Ram_File  *Ram,
                                   register __a3 char             *Ext)

{BPTR   fh;
 BPTR   fo;

 char  *p;
 char   filename[256];
 char   ibuffer [512];
 char   obuffer[1024];
 struct TagItem st[3] = {SYS_Input, 0, SYS_Output, 0, 0, 0};

 if (!(fh = Open(batchfile, MODE_OLDFILE)))  return(FALSE);

 p = stpcpy(filename, "Execute T:");
 p = stpcpy(p,         Ext);
     strcpy(p,        ".Batch");
 if (!(fo = Open(&filename[8], MODE_NEWFILE)))
      {Close(fh);
       return(FALSE);
      }

 while(FGets(fh, ibuffer, 512))
       Write(fo, obuffer, LIBTranslateBuffer(ibuffer, obuffer, 1024, User, Ram, Ext));
 Close(fh);
 Close(fo);


 st[0].ti_Data = Input();
 st[1].ti_Data = Output();
 System(filename, &st[0]);
 DeleteFile(&filename[8]);

 return(TRUE);
}


BPTR LoadSegPath(char *cmd, struct CommandLineInterface *cli)

{BPTR             seglist;
 struct PathList *pl;
 char            *s;
 char             path[256];

 seglist = LoadSeg(cmd);
 if (seglist)        return(seglist);

 for(s=cmd; *s; s++)
    {if (*s == ':')  return(NULL);
     if (*s == '/')  return(NULL);
    }

 pl = (struct PathList *)BADDR(cli->cli_CommandDir);

 while(pl)
      {if (pl->pl_PathLock)
          {if (NameFromLock(pl->pl_PathLock,path,256))
              {AddPart(path, cmd, 256);
               seglist = LoadSeg(path);
               if (seglist)  return(seglist);
              }
          }

       pl=(struct PathList *)BADDR(pl->pl_NextPath);
      }

 strcpy(path,    "C:");
 strcpy(&path[2], cmd);
 return(LoadSeg(path));
}


BOOL IsScript(char *filename)

{__aligned struct FileInfoBlock fib;
 BPTR             lock;
 BOOL             result = FALSE;

 lock = Lock(filename,ACCESS_READ);
 if (lock)
    {if (Examine(lock, &fib))
         if (fib.fib_Protection&FIBF_SCRIPT)  result = TRUE;

     UnLock(lock);
    }

 return(result);
}
