(***************************************************************************

     $RCSfile: ARP.mod $
  Description: Interface to arp.library

   Created by: fjc (Frank Copeland)
    $Revision: 2.5 $
      $Author: fjc $
        $Date: 1994/08/08 16:01:38 $

  Copyright © 1994, Frank Copeland.
  This file is part of the Oberon-A Library.
  See Oberon-A.doc for conditions of use and distribution.

***************************************************************************)

MODULE ARP;

(*
** $C- CaseChk       $I- IndexChk  $L+ LongAdr   $N- NilChk
** $P- PortableCode  $R- RangeChk  $S- StackChk  $T- TypeChk
** $V- OvflChk       $Z- ZeroVars
*)

(*
 ************************************************************************
 *                                                                      *
 * 5/3/89       ARPbase.h       by MKSoft from ARPbase.i by SDB         *
 *                                                                      *
 ************************************************************************
 *                                                                      *
 *      AmigaDOS Resource Project -- Library Include File               *
 *                                   for Lattice C 5.x or Manx C 5.x    *
 *                                                                      *
 ************************************************************************
 *                                                                      *
 *      Copyright (c) 1987/1988/1989 by Scott Ballantyne                *
 *                                                                      *
 *      The arp.library, and related code and files may be freely used  *
 *      by supporters of ARP.  Modules in the arp.library may not be    *
 *      extracted for use in independent code, but you are welcome to   *
 *      provide the arp.library with your work and call on it freely.   *
 *                                                                      *
 *      You are equally welcome to add new functions, improve the ones  *
 *      within, or suggest additions.                                   *
 *                                                                      *
 *      BCPL programs are not welcome to call on the arp.library.       *
 *      The welcome mat is out to all others.                           *
 *                                                                      *
 ************************************************************************
 *                                                                      *
 * N O T E !  You MUST! have IoErr() defined as LONG to use LastTracker *
 *            If your compiler has other defines for this, you may wish *
 *            to remove the prototype for IoErr() from this file.       *
 *                                                                      *
 ************************************************************************
 *)

(*
 ************************************************************************
 *      First we need to include the Amiga Standard Include files...    *
 ************************************************************************
 *)


IMPORT E := Exec, D := Dos, I := Intuition, SYS := SYSTEM;

(* All pointers are declared first for convenience *)

TYPE

  ArpBasePtr *             = CPOINTER TO ArpBase;
  EnvBasePtr *             = CPOINTER TO EnvBase;
  FileRequesterPtr *       = CPOINTER TO FileRequester;
  AnchorPathPtr *          = CPOINTER TO AnchorPath;
  AChainPtr *              = CPOINTER TO AChain;
  DirectoryEntryPtr *      = CPOINTER TO DirectoryEntry;
  TrackedResourcePtr *     = CPOINTER TO TrackedResource;
  TrackerPtr *             = CPOINTER TO Tracker;
  DefaultTrackerPtr *      = CPOINTER TO DefaultTracker;
  GenericTrackerPtr *      = CPOINTER TO GenericTracker;
  WindowTrackerPtr *       = CPOINTER TO WindowTracker;
  ResListPtr *             = CPOINTER TO ResList;
  ZombieMsgPtr *           = CPOINTER TO ZombieMsg;
  ProcessControlBlockPtr * = CPOINTER TO ProcessControlBlock;
  NewShellPtr *            = CPOINTER TO NewShell;
  ResidentProgramNodePtr * = CPOINTER TO ResidentProgramNode;
  ResidentProgramTagPtr *  = CPOINTER TO ResidentProgramTag;
  ProcessMemoryPtr *       = CPOINTER TO ProcessMemory;
  DateTimePtr *            = CPOINTER TO DateTime;


CONST

(*
 ************************************************************************
 *      Standard definitions for arp library information                *
 ************************************************************************
 *)

  name *    = "arp.library";   (* Name of library... *)
  version * = 39;              (* Current version... *)

TYPE

(*
 ************************************************************************
 *      The current ARP library node...                                 *
 ************************************************************************
 *)

  ArpBase * = RECORD (E.Library)
  (*libNode *      : E.Library;     (* Standard library node               *)*)
    dosRootNode *  : D.RootNodePtr; (* Copy of dlRoot                      *)
    abFlags *      : E.BSET;        (* See bitdefs below                   *)
    escChar *      : CHAR;          (* Character to be used for escaping   *)
    arpReserved1 * : LONGINT;       (* ArpLib's use only!!                 *)
    envBase *      : E.LibraryPtr;  (* Dummy library for MANX compatibility*)
    dosBase *      : E.LibraryPtr;  (* Cached DosBase                      *)
    gfxBase *      : E.LibraryPtr;  (* Cached GfxBase                      *)
    intuiBase *    : E.LibraryPtr;  (* Cached IntuitionBase                *)
    resLists *     : E.MinList;     (* Resource trackers                   *)
    residentPrgList * : ResidentProgramNodePtr; (* Resident Programs.        *)
    resPrgProtection * : E.SignalSemaphore; (* protection for above       *)
    segList *      : D.BPTR;        (* Pointer to loaded libcode (a BPTR). *)
  END; (* ArpBase *)

TYPE

(*
 ************************************************************************
 *      The following is here *ONLY* for information and for            *
 *      compatibility with MANX.  DO NOT use in new code!               *
 ************************************************************************
 *)

  EnvBase * = RECORD (E.Library)
  (*libNode *  : E.Library;  (* Standard library node for linkage    *)*)
    envSpace * : E.APTR;     (* Access only when Forbidden!          *)
    envSize *  : E.ULONG;    (* Total allocated mem for EnvSpace     *)
    arpBase *  : ArpBasePtr; (* Added in V32 for Resource Tracking   *)
  END; (* EnvBase *)


CONST

(*
 ************************************************************************
 *      These are used in release 33.4 but not by the library code.     *
 *      Instead, individual programs check for these flags.             *
 ************************************************************************
 *)

  wildWorld * = 0;              (* Mixed BCPL/Normal wildcards. *)
  wildBCPL  * = 1;              (* Pure BCPL wildcards.         *)


CONST

(*
 ************************************************************************
 * The alert object is what you use if you really must return an alert  *
 * to the user. You would normally OR this with another alert number    *
 * from the alerts.h file. Generally, should be NON deadend alerts.     *
 *                                                                      *
 * For example, if you can't open ArpLibrary:                           *
 *      Alert( (AgOpenLib|AoArpLib), 0L);                               *
 ************************************************************************
 *)

  aoArpLib       * = 00008036H;             (* Alert object *)

CONST

(*
 ************************************************************************
 *      Alerts that arp.library may return...                           *
 ************************************************************************
 *)

  anArpLib       * = 03600000H;   (* Alert number                         *)
  anArpNoMem     * = 03610000H;   (* No more memory                       *)
  anArpInputMem  * = 03610002H;   (* No memory for input buffer           *)
  anArpNoMakeEnv * = 83610003H;   (* No memory to make EnvLib             *)

  anArpNoDOS     * = 83630001H;   (* Can't open dos.library               *)
  anArpNoGfx     * = 83630002H;   (* Can't open graphics.library          *)
  anArpNoIntuit  * = 83630003H;   (* Can't open intuition                 *)
  anBadPackBlues * = 83640000H;   (* Bad packet returned to SendPacket()  *)
  anZombie       * = 83600003H;   (* Zombie roaming around system         *)

  anArpScattered * = 83600002H;   (* Scatter loading not allowed for arp  *)


CONST

(*
 ************************************************************************
 *      Return codes you can get from calling ARP Assign()...           *
 ************************************************************************
 *)

  assignOK       * = 0; (* Everything is cool and groovey                *)
  assignNODEV    * = 1; (* "Physical" is not valid for assignment        *)
  assignFATAL    * = 2; (* Something really icky happened                *)
  assignCANCEL   * = 3; (* Tried to cancel something but it won't cancel *)

CONST

(*
 ************************************************************************
 *      Size of buffer you need if you are going to call ReadLine()     *
 ************************************************************************
 *)

  maxInputBuf     * = 256;

TYPE

(*
 ************************************************************************
 *      The ARP file requester data structure...                        *
 ************************************************************************
 *)


  FileRequester * = RECORD
    hail *      : E.STRPTR;        (* Hailing text                 *)
    file *      : E.STRPTR;        (* Filename array (FCHARS + 1)  *)
    dir *       : E.STRPTR;        (* Directory array (DSIZE + 1)  *)
    window *    : I.WindowPtr;     (* Window requesting or NULL    *)
    funcFlags * : E.BSET;          (* Set bitdef's below           *)
    flags2 *    : E.BSET;          (* New flags...                 *)
    function *  : E.PROC;          (* Your function, see bitdef's  *)
    leftEdge *  : INTEGER;         (* To be used later...          *)
    topEdge *   : INTEGER;
  END; (* FileRequester *)


CONST

(*
 ************************************************************************
 * The following are the defines for frFuncFlags.  These bits tell      *
 * FileRequest() what your frUserFunc is expecting, and what            *
 * FileRequest() should call it for.                                    *
 *                                                                      *
 * You are called like so:                                              *
 * frFunction(Mask, Object)                                             *
 * E.ULONG        Mask;                                                 *
 * E.APTR         *Object;                                              *
 *                                                                      *
 * The Mask is a copy of the flag value that caused FileRequest() to    *
 * call your function. You can use this to determine what action you    *
 * need to perform, and exactly what Object is, so you know what to do  *
 * and what to return.                                                  *
 ************************************************************************
 *)

  frDoWildFunc  * = 7; (* Call me with a FIB and a name, ZERO return accepts.       *)
  frDoMsgFunc   * = 6; (* You get all IDCMP messages not for FileRequest()          *)
  frDoColor     * = 5; (* Set this bit for that new and different look              *)
  frNewIDCMP    * = 4; (* Force a new IDCMP (only if frWindow != NULL)             *)
  frNewWindFunc * = 3; (* You get to modify the newwindow structure.                *)
  frAddGadFunc  * = 2; (* You get to add gadgets.                                   *)
  frGEventFunc  * = 1; (* Function to call if one of your gadgets is selected.      *)
  frListFunc    * = 0; (* Not implemented yet.                                      *)


CONST

(*
 ************************************************************************
 * The FR2 bits are for frFlags2 in the file requester structure     *
 ************************************************************************
 *)

  fr2LongPath   * = 0; (* Specify the frDir buffer is 256 bytes long *)


CONST

(*
 ************************************************************************
 *      The sizes of the different buffers...                           *
 ************************************************************************
 *)

  fChars * = 32;     (* Filename size                              *)
  dSize *  = 33;     (* Directory name size if not FR2LongPath     *)

  longDSize * = 254;    (* If FR2LongPath is set, use longDSIZE    *)
  longFSize * = 126;    (* For compatibility with ARPbase.i        *)

  frFirstGadget * = 7680H; (* User gadgetID's must be less than this value *)


TYPE

(*
 ************************************************************************
 * Structure expected by FindFirst()/FindNext()                         *
 *                                                                      *
 * You need to allocate this structure and initialize it as follows:    *
 *                                                                      *
 * Set apBreakBits to the signal bits (CDEF) that you want to take a    *
 * break on, or NULL, if you don't want to convenience the user.        *
 *                                                                      *
 * if you want to have the FULL PATH NAME of the files you found,       *
 * allocate a buffer at the END of this structure, and put the size of  *
 * it into apStrLen.  If you don't want the full path name, make sure   *
 * you set apStrLen to zero.  In this case, the name of the file, and   *
 * stats are available in the apInfo, as per usual.                     *
 *                                                                      *
 * Then call FindFirst() and then afterwards, FindNext() with this      *
 * structure.  You should check the return value each time (see below)  *
 * and take the appropriate action, ultimately calling                  *
 * FreeAnchorChain() when there are no more files and you are done.     *
 * You can tell when you are done by checking for the normal AmigaDOS   *
 * return code errorNoMoreENTRIES.                                      *
 *                                                                      *
 * You will also have to check the DirEntryType variable in the apInfo  *
 * structure to determine what exactly you have received.               *
 ************************************************************************
 *)

  AnchorPath * = RECORD
    base *       : AChainPtr; (* Pointer to first anchor                *)
    last *       : AChainPtr; (* Pointer to last anchor                 *)
    breakBits *  : SET;       (* Bits to break on                       *)
    foundBreak * : SET;       (* Bits we broke on. Also returns errorBREAK*)
    flags *      : E.BSET;    (* New use for the extra word...          *)
    reserved *   : SYS.BYTE;  (* To fill it out...                      *)
    strLen *     : INTEGER;   (* This is what used to be apLength       *)
    info *       : D.FileInfoBlock;
  (*buf *        : ARRAY OF SYS.BYTE; (* Allocate a buffer here, if desired *)*)
  END; (* AnchorPath *)

CONST

(*
 ************************************************************************
 *      Bit definitions for the new apFlags...                         *
 ************************************************************************
 *)

  apDoWild      * = 0;    (* User option ALL                              *)
  apItsWild     * = 1;    (* Set by FindFirst, used by FindNext           *)
  apDoDir       * = 2;    (* Bit is SET if a DIR node should be entered   *)
                          (* Application can RESET this bit to AVOID      *)
                          (* entering a dir.                              *)
  apDidDir      * = 3;    (* Bit is set for an "expired" dir node         *)
  apNoMemErr    * = 4;    (* Set if there was not enough memory           *)
  apDoDot       * = 5;    (* If set, '.' (DOT) will convert to CurrentDir *)


TYPE

(*
 ************************************************************************
 * Structure used by the pattern matching functions, no need to obtain, *
 * diddle or allocate this yourself.                                    *
 *                                                                      *
 * Note:  If you did, you will now break as it has changed...           *
 ************************************************************************
 *)

  AChain = RECORD
    child  : AChainPtr;
    parent : AChainPtr;
    lock   : D.FileLockPtr;
    info   : D.FileInfoBlockPtr;
    flags  : E.BSET;
  (*string : ARRAY OF CHAR;   (* Just as is .i file   *)*)
  END; (* AChain *)             (* ???  Don't use this! *)

CONST

  ddPatternBit  * = 0;
  ddExaminedBit * = 1;
  ddCompleted   * = 2;
  ddAllBit      * = 3;


CONST

(*
 ************************************************************************
 * Constants used by wildcard routines                                  *
 *                                                                      *
 * These are the pre-parsed tokens referred to by pattern match.  It    *
 * is not necessary for you to do anything about these, FindFirst()     *
 * FindNext() handle all these for you.                                 *
 ************************************************************************
 *)

  pAny           * = 80X;   (* Token for '*' | '#?' *)
  pSingle        * = 81X;   (* Token for '?'        *)

CONST

(*
 ************************************************************************
 * No need to muck with these as they may change...                     *
 ************************************************************************
 *)

  pOrStart       * = 82X;   (* Token for '('        *)
  pOrNext        * = 83X;   (* Token for '|'        *)
  pOrEnd         * = 84X;   (* Token for ')'        *)
  pNot           * = 85X;   (* Token for '~'        *)
  pNotClass      * = 87X;   (* Token for '^'        *)
  pClass         * = 88X;   (* Token for '[]'       *)
  pRepBeg        * = 89X;   (* Token for '['        *)
  pRepEnd        * = 8AX;   (* Token for ']'        *)


TYPE

(*
 ************************************************************************
 * Structure used by AddDANode(), AddDADevs(), FreeDAList().            *
 *                                                                      *
 * This structure is used to create lists of names, which normally      *
 * are devices, assigns, volumes, files, or directories.                *
 ************************************************************************
 *)

  DirectoryEntry * = RECORD
    next *  : DirectoryEntryPtr; (* Next in list                      *)
    type *  : SHORTINT;          (* dlxmumble                         *)
    flags * : E.BSET;            (* For future expansion, DO NOT USE! *)
  (*name *  : ARRAY OF CHAR;     (* The name of the thing found       *)*)
  END; (* DirectoryEntry *)

CONST

(*
 ************************************************************************
 * Defines you use to get a list of the devices you want to look at.    *
 * For example, to get a list of all directories and volumes, do:       *
 *                                                                      *
 *      AddDADevs( mydalist, (DlfDIRS | dlfVOLUMES) )                   *
 *                                                                      *
 * After this, you can examine the detype field of the elements added   *
 * to your list (if any) to discover specifics about the objects added. *
 *                                                                      *
 * Note that if you want only devices which are also disks, you must    *
 * (DlfDEVICES | dlfDISKONLY).                                          *
 ************************************************************************
 *)

  dlDevices     * = 0;      (* Return devices                               *)
  dlDiskOnly    * = 1;      (* Modifier for above: Return disk devices only *)
  dlVolumes     * = 2;      (* Return volumes only                          *)
  dlDirs        * = 3;      (* Return assigned devices only                 *)


CONST

(*
 ************************************************************************
 * Legal deType values, check for these after a call to AddDADevs(),    *
 * or use on your own as the ID values in AddDANode().                  *
 ************************************************************************
 *)

  dlxFile        * = 0;      (* AddDADevs() can't determine this     *)
  dlxDir         * = 8;      (* AddDADevs() can't determine this     *)
  dlxDevice      * = 16;     (* It's a resident device               *)
  dlxVolume      * = 24;     (* Device is a volume                   *)
  dlxUnmounted   * = 32;     (* Device is not resident               *)
  dlxAssign      * = 40;     (* Device is a logical assignment       *)

(*
 ************************************************************************
 *      Resource Tracking stuff...                                      *
 ************************************************************************
 *                                                                      *
 * There are a few things in arp.library that are only directly         *
 * acessable from assembler.  The glue routines provided by us for      *
 * all 'C' compilers use the following conventions to make these        *
 * available to C programs.  The glue for other language's should use   *
 * as similar a mechanism as possible, so that no matter what language  *
 * or compiler we speak, when talk about arp, we will know what the     *
 * other guy is saying.                                                 *
 *                                                                      *
 * Here are the cases:                                                  *
 *                                                                      *
 * Tracker calls...                                                     *
 *              These calls return the Tracker pointer as a secondary   *
 *              result in the register A1.  For C, there is no clean    *
 *              way to return more than one result so the tracker       *
 *              pointer is returned in IoErr().  For ease of use,       *
 *              there is a define that typecasts IoErr() to the correct *
 *              pointer type.  This is called LastTracker and should    *
 *              be source compatible with the earlier method of storing *
 *              the secondary result.                                   *
 *                                                                      *
 * GetTracker() -                                                       *
 *              Syntax is a bit different for C than the assembly call  *
 *              The C syntax is GetTracker(ID).  The binding routines   *
 *              will store the ID into the tracker on return.  Also,    *
 *              in an effort to remain consistant, the tracker will     *
 *              also be stored in LastTracker.                          *
 *                                                                      *
 * In cases where you have allocated a tracker before you have obtained *
 * a resource (usually the most efficient method), and the resource has *
 * not been obtained, you will need to clear the tracker id.  The macro *
 * clearID() has been provided for that purpose.  It expects a pointer *
 * to a DefaultTracker sort of struct.                                  *
 ************************************************************************

#define CLEAR_ID(t)     ((SHORT * ) t)[-1]* =NULL

 ************************************************************************
 * You MUST prototype IoErr() to prevent the possible error in defining *
 * IoErr() and thus causing LastTracker to give you trash...            *
 *                                                                      *
 * N O T E !  You MUST! have IoErr() defined as LONG to use LastTracker *
 *            If your compiler has other defines for this, you may wish *
 *            to remove the prototype for IoErr().                      *
 ************************************************************************

#define LastTracker     ((struct DefaultTracker * )IoErr())
*)

TYPE

(*
 ************************************************************************
 * The rlFirstItem list (ResList) is a list of TrackedResource (below)  *
 * It is very important that nothing in this list depend on the task    *
 * existing at resource freeing time (i.e., RemTask(0L) type stuff,     *
 * DeletePort() and the rest).                                          *
 *                                                                      *
 * The tracking functions return a struct Tracker *Tracker to you, this *
 * is a pointer to whatever follows the trID variable.                  *
 * The default case is reflected below, and you get it if you call      *
 * GetTracker() ( see DefaultTracker below).                            *
 *                                                                      *
 * NOTE: The two user variables mentioned in an earlier version don't   *
 * exist, and never did. Sorry about that (SDB).                        *
 *                                                                      *
 * However, you can still use ArpAlloc() to allocate your own tracking  *
 * nodes and they can be any size or shape you like, as long as the     *
 * base structure is preserved. They will be freed automagically just   *
 * like the default trackers.                                           *
 ************************************************************************
 *)

  TrackedResource * = RECORD (E.MinNode)
  (*node *   : E.MinNode;      (* Double linked pointer                *)*)
    flags    : E.BSET;         (* Don't touch                          *)
    lock     : SHORTINT;       (* Don't touch, for Get/FreeAccess()    *)
    id *     : INTEGER;        (* Item's ID                            *)
(*
 ************************************************************************
 * The struct DefaultTracker *Tracker portion of the structure.         *
 * The stuff below this point can conceivably vary, depending           *
 * on user needs, etc.  This reflects the default.                      *
 ************************************************************************
 *)
    object * : E.APTR;
    extra *  : E.APTR;
  END; (* TrackedResource *)


TYPE

(*
 ************************************************************************
 * You get a pointer to a struct of the following type when you call    *
 * GetTracker().  You can change this, and use ArpAlloc() instead of    *
 * GetTracker() to do tracking. Of course, you have to take a wee bit   *
 * more responsibility if you do, as well as if you use trakGeneric     *
 * stuff.                                                               *
 *                                                                      *
 * trakGeneric folks need to set up a task function to be called when   *
 * an item is freed.  Some care is required to set this up properly.    *
 *                                                                      *
 * Some special cases are indicated by the unions below, for            *
 * trakWindow, if you have more than one window opened, and don't       *
 * want the IDCMP closed particularly, you need to set a ptr to the     *
 * other window in dtWindow2.  See CloseWindowSafely() for more info.   *
 * If only one window, set this to NULL.                                *
 ************************************************************************
 *)

  Tracker = RECORD END;

  DefaultTracker * = RECORD (Tracker)
    object * : E.APTR;
    extra *  : E.APTR;
  END; (* DefaultTracker *)

  GenericTracker = RECORD (Tracker) (* The object being tracked      *)
    dtResource * : E.APTR;          (* Whatever                      *)
    tgVerify *   : LONGINT;         (* For use during trakGeneric    *)
  END; (* GenericTracker *)

  WindowTracker = RECORD (Tracker)
    tgFunction * : E.PROC;      (* Function to call for trakGeneric  *)
    dtWindow2 *  : I.WindowPtr; (* For trakWindow                    *)
  END; (* WindowTracker *)


CONST

(*
 ************************************************************************
 *      Items the tracker knows what to do about                        *
 ************************************************************************
 *)

  trakAaMem      * = 0;      (* Default (ArpAlloc) element           *)
  trakLock       * = 1;      (* File lock                            *)
  trakTrFile     * = 2;      (* Opened file                          *)
  trakWindow     * = 3;      (* Window -- see docs                   *)
  trakScreen     * = 4;      (* Screen                               *)
  trakLibrary    * = 5;      (* Opened library                       *)
  trakDaMem      * = 6;      (* Pointer to DosAllocMem block         *)
  trakMemNode    * = 7;      (* AllocEntry() node                    *)
  trakSegList    * = 8;      (* Program segment                      *)
  trakResList    * = 9;      (* ARP (nested) ResList                 *)
  trakMem        * = 10;     (* Memory ptr/length                    *)
  trakGeneric    * = 11;     (* Generic Element, your choice         *)
  trakDaList     * = 12;     (* DAlist ( aka file request )          *)
  trakAnchor     * = 13;     (* Anchor chain (pattern matching)      *)
  trakFReq       * = 14;     (* FileRequest struct                   *)
  trakFont       * = 15;     (* GfxBase CloseFont()                  *)
  trakMax        * = 15;     (* Poof, anything higher is tossed      *)

  trUnlink      * = 7;      (* Free node bit                        *)
  trReloc       * = 6;      (* This may be relocated (not used yet) *)
  trMoved       * = 5;      (* Item moved                           *)


TYPE

(*
 ************************************************************************
 * Note: ResList MUST be a DosAllocMem'ed list!, this is done for       *
 * you when you call CreateTaskResList(), typically, you won't need     *
 * to access/allocate this structure.                                   *
 ************************************************************************
 *)

  ResList * = RECORD (E.MinNode)
  (*node *      : E.MinNode;  (* Used by arplib to link reslists      *)*)
    taskID *    : E.TaskPtr;  (* Owner of this list                   *)
    firstItem * : E.MinList;  (* List of Tracked Resources            *)
    link *      : ResListPtr; (* SyncRun's use - hide list here       *)
  END; (* ResList *)

CONST

(*
 ************************************************************************
 *      Returns from CompareLock()                                      *
 ************************************************************************
 *)

  lckEqual       * = 0;   (* The two locks refer to the same object       *)
  lckVolume      * = 1;   (* Locks are on the same volume                 *)
  lckDifVol1     * = 2;   (* Locks are on different volumes               *)
  lckDifVol2     * = 3;   (* Locks are on different volumes               *)

TYPE

(*
 ************************************************************************
 *      ASyncRun() stuff...                                             *
 ************************************************************************
 * Message sent back on your request by an exiting process.             *
 * You request this by putting the address of your message in           *
 * pcbLastGasp, and initializing the ReplyPort variable of your         *
 * ZombieMsg to the port you wish the message posted to.                *
 ************************************************************************
 *)

  ZombieMsg * = RECORD (E.Message)
  (*execMessage * : E.Message;*)
    taskNum *     : E.ULONG; (* Task ID                      *)
    returnCode *  : LONGINT; (* Process's return code        *)
    result2 *     : E.ULONG; (* System return code           *)
    exitTime *    : D.Date;  (* Date stamp at time of exit   *)
    userInfo *    : E.ULONG; (* For whatever you wish        *)
  END; (* ZombieMsg *)

TYPE

(*
 ************************************************************************
 * Structure required by ASyncRun() -- see docs for more info.          *
 ************************************************************************
 *)

  ProcessControlBlock * = RECORD
    stackSize * : E.ULONG;      (* Stacksize for new process                    *)
    pri *       : SHORTINT;     (* Priority of new task                         *)
    control *   : E.BSET;       (* Control bits, see defines below              *)
    trapCode *  : E.APTR;       (* Optional Trap Code                           *)
    input *     : D.BPTR;
    output *    : D.BPTR;       (* Optional stdin, stdout                       *)
    console *   : LONGINT;
    (* console is a union of:
      splatFile * : D.BPTR;     (* File to use for Open("*")                    *)
      conName *   : E.STRPTR;   (* CON: filename                                *)
    *)
    loadedCode * : E.APTR;      (* If not null, will not load/unload code       *)
    lastGasp *  : ZombieMsgPtr; (* ReplyMsg() to be filled in by exit           *)
    wbProcess * : E.MsgPortPtr; (* Valid only when prNOCLI                    *)
  END; (* ProcessControlBlock *)

CONST

(*
 ************************************************************************
 * Formerly needed to pass NULLCMD to a child.  No longer needed.       *
 * It is being kept here for compatibility only...                      *
 ************************************************************************
 *)

  NoCmd   * = "\n";

CONST

(*
 ************************************************************************
 * The following control bits determine what ASyncRun() does on         *
 * Abnormal Exits and on background process termination.                *
 ************************************************************************
 *)

  prSaveIO      * = 0;    (* Don't free/check file handles on exit        *)
  prCloseSplat  * = 1;    (* Close Splat file, must request explicitly    *)
  prNoCLI       * = 2;    (* Don't create a CLI process                   *)
(*prInteractive * = 3;       This is now obsolete...                      *)
  prCode        * = 4;    (* Dangerous yet enticing                       *)
  prStdIO       * = 5;    (* Do the stdio thing, splat * = CON:Filename   *)


CONST

(*
 ************************************************************************
 *      Error returns from SyncRun() and ASyncRun()                     *
 ************************************************************************
 *)

  prNoFile   * = -1;     (* Could not LoadSeg() the file                 *)
  prNoMem    * = -2;     (* No memory for something                      *)
(*prNoCLI      = -3;       This is now obsolete                          *)
  prNoSlot   * = -4;     (* No room in TaskArray                         *)
  prNoInput  * = -5;     (* Could not open input file                    *)
  prNoOutput * = -6;     (* Could not get output file                    *)
(*prNoLock     = -7;        This is now obsolete                         *)
(*prArgErr     = -8;        This is now obsolete                         *)
(*prNoBCPL     = -9;        This is now obsolete                         *)
(*prBadLib     = -10;       This is now obsolete                         *)
  prNoStdIO  * = -11;    (* Couldn't get stdio handles                   *)

CONST

(*
 ************************************************************************
 *      Added V35 of arp.library                                        *
 ************************************************************************
 *)

  prWantsMessage * = -12; (* Child wants you to report IoErr() to user    *)
                          (* for SyncRun() only...                        *)
  prNoShellProc  * = -13; (* Can't create a shell/cli process             *)
  prNoExec       * = -14; (* 'E' bit is clear                             *)
  prScript       * = -15; (* S and E are set, IoErr() contains directory  *)

TYPE

(*
 ************************************************************************
 * Version 35 ASyncRun() allows you to create an independent            *
 * interactive or background Shell/CLI. You need this variant of the    *
 * pcb structure to do it, and you also have new values for nshControl, *
 * see below.                                                           *
 *                                                                      *
 * Syntax for Interactive shell is:                                     *
 *                                                                      *
 * rc=ASyncRun("Optional Window Name","Optional From File",&NewShell);  *
 *                                                                      *
 * Syntax for a background shell is:                                    *
 *                                                                      *
 * rc=ASyncRun("Command line",0L,&NewShell);                            *
 *                                                                      *
 * Same syntax for an Execute style call, but you have to be on drugs   *
 * if you want to do that.                                              *
 ************************************************************************
 *)

  NewShell * = RECORD
    stackSize * : E.ULONG;  (* stacksize shell will use for children        *)
    pri *       : SHORTINT; (* ignored by interactive shells                *)
    control *   : E.BSET;   (* bits/values: see above                       *)
    logMsg *    : E.APTR;   (* Optional login message, if null, use default *)
    input *     : D.BPTR;   (* ignored by interactive shells, but           *)
    output *    : D.BPTR;   (* used by background and execute options.      *)
    reserved *  : ARRAY 5 OF LONGINT;
  END; (* NewShell *)

CONST

(*
 ************************************************************************
 * Bit Values for nshControl, you should use them as shown below, or    *
 * just use the actual values indicated.                                *
 ************************************************************************
 *)

  prCli         * = 0;      (* Do a CLI, not a shell        *)
  prBackGround  * = 1;      (* Background shell             *)
  prExecute     * = 2;      (* Do as EXECUTE...             *)
  prInteractive * = 3;      (* Run an interactive shell     *)
  prFb          * = 7;      (* Alt function bit...          *)


CONST

(*
 ************************************************************************
 *      Common values for shControl which allow you to do usefull      *
 *      and somewhat "standard" things...                               *
 ************************************************************************
 *)

  interactiveShell * = { prFb, prInteractive };           (* Gimme a newshell!            *)
  interactiveCLI   * = { prFb, prInteractive, prCli };    (* Gimme that ol newcli!        *)
  backgroundShell  * = { prFb, prBackGround };            (* gimme a background shell     *)
  executeMe        * = { prFb, prBackGround, prExecute }; (* aptly named, doncha think?   *)

CONST

(*
 ************************************************************************
 *      Additional IoErr() returns added by ARP...                      *
 ************************************************************************
 *)

  errorBufferOverflow   * = 303;    (* User or internal buffer overflow     *)
  errorBreak            * = 304;    (* A break character was received       *)
  errorNotExecutable    * = 305;    (* A file has E bit cleared             *)
  errorNotCLI           * = 400;    (* Program/function neeeds to be cli    *)

TYPE

(*
 ************************************************************************
 *      Resident Program Support                                        *
 ************************************************************************
 * This is the kind of node allocated for you when you AddResidentPrg() *
 * a code segment.  They are stored as a single linked list with the    *
 * root in ArpBase.  If you absolutely *must* wander through this list  *
 * instead of using the supplied functions, then you must first obtain  *
 * the semaphore which protects this list, and then release it          *
 * afterwards.  Do not use Forbid() and Permit() to gain exclusive      *
 * access!  Note that the supplied functions handle this locking        *
 * protocol for you.                                                    *
 ************************************************************************
 *)

  ResidentProgramNode * = RECORD
    next *      : ResidentProgramNodePtr; (* next or NULL        *)
    usage *     : LONGINT;       (* Number of current users      *)
    accessCnt * : E.UWORD;       (* Total times used...          *)
    checkSum *  : E.ULONG;       (* Checksum of code             *)
    segment *   : D.BPTR;        (* Actual segment               *)
    flags *     : E.WSET;        (* See definitions below...     *)
  (*name *      : ARRAY OF CHAR; (* Allocated as needed          *)*)
  END; (* ResidentProgramNode *)

CONST

(*
 ************************************************************************
 *      Bit definitions for rpnFlags....                                *
 ************************************************************************
 *)

  rpnNoCheck * = 0;      (* Set in rpnFlags for no checksumming...      *)
  rpnCache *   = 1;      (* Private usage in v1.3...                    *)


TYPE

(*
 ************************************************************************
 * If your program starts with this structure, ASyncRun() and SyncRun() *
 * will override a users stack request with the value in rptStackSize.  *
 * Furthermore, if you are actually attached to the resident list, a    *
 * memory block of size rptDataSize will be allocated for you, and      *
 * a pointer to this data passed to you in register A4.  You may use    *
 * this block to clone the data segment of programs, thus resulting in  *
 * one copy of text, but multiple copies of data/bss for each process   *
 * invocation.  If you are resident, your program will start at         *
 * rptInstruction, otherwise, it will be launched from the initial      *
 * branch.                                                              *
 ************************************************************************
 *)

  ResidentProgramTag * = RECORD
    nextSeg *   : D.BPTR;    (* Provided by DOS at LoadSeg time      *)
(*
 ************************************************************************
 * The initial branch destination and rptInstruction do not have to be *
 * the same.  This allows different actions to be taken if you are      *
 * diskloaded or resident.  DataSize memory will be allocated only if   *
 * you are resident, but StackSize will override all user stack         *
 * requests.                                                            *
 ************************************************************************
 *)
    bra *       : E.UWORD; (* Short branch to executable           *)
    magic *     : E.UWORD; (* Resident majik value                 *)
    stackSize * : E.ULONG; (* min stack for this process           *)
    dataSize *  : E.ULONG; (* Data size to allocate if resident    *)
    (*      instruction;        Start here if resident          *)
  END; (* ResidentProgramTag *)

TYPE

(*
 ************************************************************************
 * The form of the ARP allocated node in your tasks memlist when        *
 * launched as a resident program. Note that the data portion of the    *
 * node will only exist if you have specified a nonzero value for       *
 * rptDataSize. Note also that this structure is READ ONLY, modify     *
 * values in this at your own risk.  The stack stuff is for tracking,   *
 * if you need actual addresses or stack size, check the normal places  *
 * for it in your process/task struct.                                  *
 ************************************************************************
 *)

  ProcessMemory * = RECORD (E.Node)
  (*node *      : E.Node;*)
    num *       : E.UWORD; (* This is 1 if no data, two if data    *)
    stack *     : E.APTR;
    stackSize * : E.ULONG;
    data *      : E.APTR;  (* Only here if pmNum == 2              *)
    dataSize *  : E.ULONG;
  END; (* ProcessMemory *)

CONST

(*
 ************************************************************************
 * To find the above on your memlist, search for the following name.    *
 * We guarantee this will be the only arp.library allocated node on     *
 * your memlist with this name.                                         *
 * i.e. FindName(task->tcbMemEntry, pmemNAME);                        *
 ************************************************************************
 *)

  pMemName       * = "ARP_MEM";

  residentMagic  * = 4AFCH;          (* same as rtcMATCHWORD (trapf) *)

TYPE

(*
 ************************************************************************
 *      Date String/Data structures                                     *
 ************************************************************************
 *)

  DateTime * = RECORD
    stamp *   : D.Date;    (* DOS Datestamp                        *)
    format *  : E.UBYTE;   (* controls appearance ot datStrDate    *)
    flags *   : E.BSET;    (* See BITDEF's below                   *)
    strDay *  : E.STRPTR;  (* day of the week string               *)
    strDate * : E.STRPTR;  (* date string                          *)
    strTime * : E.STRPTR;  (* time string                          *)
  END; (* DateTime *)

CONST

(*
 ************************************************************************
 *      Size of buffer you need for each DateTime strings:              *
 ************************************************************************
 *)

  lenDatString   * = 10;

CONST

(*
 ************************************************************************
 *      For datFlags                                                   *
 ************************************************************************
 *)

  dtSubst  * = 0; (* Substitute "Today" "Tomorrow" where appropriate      *)
  dtFuture * = 1; (* Day of the week is in future                         *)


CONST

(*
 ************************************************************************
 *      For datFormat                                                  *
 ************************************************************************
 *)

  formatDos * = 0;         (* dd-mmm-yy AmigaDOS's own, unique style               *)
  formatInt * = 1;         (* yy-mm-dd International format                        *)
  formatUSA * = 2;         (* mm-dd-yy The good'ol'USA.                            *)
  formatCDN * = 3;         (* dd-mm-yy Our brothers and sisters to the north       *)
  formatMAX * = formatCDN; (* Larger than this? Defaults to AmigaDOS               *)


(* --- Library Base variable -------------------------------------------- *)


VAR

  base *  : ArpBasePtr;


(* --- Library Functions ------------------------------------------------ *)

TYPE

  ArgArrayPtr = POINTER TO ArgArray;
  ArgArray = ARRAY 7 OF LONGINT;


(*
 ************************************************************************
 *  These duplicate the calls in dos.library                            *
 *  Only include if you can use arp.library without dos.library         *
 ************************************************************************
 *)


LIBCALL (base : ArpBasePtr) Open*
  ( name       [1] : ARRAY OF CHAR;
    accessMode [2] : LONGINT)
  : D.FileHandlePtr;
  -30;
LIBCALL (base : ArpBasePtr) Close*
  ( file [1] : D.FileHandlePtr );
  -36;
LIBCALL (base : ArpBasePtr) Read*
  ( file       [1] : D.FileHandlePtr;
    VAR buffer [2] : ARRAY OF SYS.BYTE;
    length     [3] : LONGINT)
  : LONGINT;
  -42;
LIBCALL (base : ArpBasePtr) Write*
  ( file   [1] : D.FileHandlePtr;
    buffer [2] : ARRAY OF SYS.BYTE;
    length [3] : LONGINT)
  : LONGINT;
  -48;
LIBCALL (base : ArpBasePtr) Input* ()
  : D.FileHandlePtr;
  -54;
LIBCALL (base : ArpBasePtr) Output* ()
  : D.FileHandlePtr;
  -60;
LIBCALL (base : ArpBasePtr) Seek*
  ( file     [1] : D.FileHandlePtr;
    position [2] : LONGINT;
    offset   [3] : LONGINT)
  : LONGINT;
  -66;
LIBCALL (base : ArpBasePtr) DeleteFile*
  ( name [1] : ARRAY OF CHAR )
  : BOOLEAN;
  -72;
LIBCALL (base : ArpBasePtr) Rename*
  ( oldName [1] : ARRAY OF CHAR;
    newName [2] : ARRAY OF CHAR )
  : BOOLEAN;
  -78;
LIBCALL (base : ArpBasePtr) Lock*
  ( name [1] : ARRAY OF CHAR;
    type [2] : LONGINT)
  : D.FileLockPtr;
  -84;
LIBCALL (base : ArpBasePtr) UnLock*
  ( lock [1] : D.FileLockPtr );
  -90;
LIBCALL (base : ArpBasePtr) DupLock*
  ( lock [1] : D.FileLockPtr )
  : D.FileLockPtr;
  -96;
LIBCALL (base : ArpBasePtr) Examine*
  ( lock          [1] : D.FileLockPtr;
    fileInfoBlock [2] : D.FileInfoBlockPtr )
  : BOOLEAN;
  -102;
LIBCALL (base : ArpBasePtr) ExNext*
  ( lock          [1] : D.FileLockPtr;
    fileInfoBlock [2] : D.FileInfoBlockPtr )
  : BOOLEAN;
  -108;
LIBCALL (base : ArpBasePtr) Info*
  ( lock           [1] : D.FileLockPtr;
    parameterBlock [2] : D.InfoDataPtr )
  : BOOLEAN;
  -114;
LIBCALL (base : ArpBasePtr) CreateDir*
  ( name [1] : ARRAY OF CHAR )
  : D.FileLockPtr;
  -120;
LIBCALL (base : ArpBasePtr) CurrentDir*
  ( lock [1] : D.FileLockPtr )
  : D.FileLockPtr;
  -126;
LIBCALL (base : ArpBasePtr) IoErr* ()
  : LONGINT;
  -132;
LIBCALL (base : ArpBasePtr) CreateProc*
  ( name      [1] : ARRAY OF CHAR;
    pri       [2] : LONGINT;
    segList   [3] : D.BPTR;
    stackSize [4] : LONGINT)
  : E.MsgPortPtr;
  -138;
LIBCALL (base : ArpBasePtr) Exit*
  ( returnCode [1] : LONGINT);
  -144;
LIBCALL (base : ArpBasePtr) LoadSeg*
  ( name [1] : ARRAY OF CHAR )
  : D.BPTR;
  -150;
LIBCALL (base : ArpBasePtr) UnLoadSeg*
  ( seglist [1] : D.BPTR );
  -156;
LIBCALL (base : ArpBasePtr) DeviceProc*
  ( name [1] : ARRAY OF CHAR )
  : E.MsgPortPtr;
  -174;
LIBCALL (base : ArpBasePtr) SetComment*
  ( name    [1] : ARRAY OF CHAR;
    comment [2] : ARRAY OF CHAR )
  : BOOLEAN;
  -180;
LIBCALL (base : ArpBasePtr) SetProtection*
  ( name    [1] : ARRAY OF CHAR;
    protect [2] : SET)
  : BOOLEAN;
  -186;
LIBCALL (base : ArpBasePtr) DateStamp*
  ( VAR date [1] : D.Date );
  -192;
LIBCALL (base : ArpBasePtr) Delay*
  ( timeout [1] : E.ULONG);
  -198;
LIBCALL (base : ArpBasePtr) WaitForChar*
  ( file    [1] : D.FileHandlePtr;
    timeout [2] : LONGINT)
  : BOOLEAN;
  -204;
LIBCALL (base : ArpBasePtr) ParentDir*
  ( lock [1] : D.FileLockPtr )
  : D.FileLockPtr;
  -210;
LIBCALL (base : ArpBasePtr) IsInteractive*
  ( file [1] : D.FileHandlePtr )
  : BOOLEAN;
  -216;
LIBCALL (base : ArpBasePtr) Execute*
  ( string [1] : ARRAY OF CHAR;
    file   [2] : D.FileHandlePtr;
    file2  [3] : D.FileHandlePtr )
  : LONGINT;
  -222;


(*
 ************************************************************************
 * Now for the stuff that only exists in arp.library...                 *
 ************************************************************************
 *)

(*
LIBCALL (base : ArpBasePtr) Printf *
  ( string [} : ARRAY OF CHAR;
    args   [] : ARRAY OF LONGINT )
  : LONGINT;
  -228;
LIBCALL (base : ArpBasePtr) FPrintf *
  ( file   [] : D.FileHandlePtr;
    string [] : ARRAY OF CHAR;
    args   [] : ARRAY OF LONGINT )
  : LONGINT;
  -234;
*)
LIBCALL (base : ArpBasePtr) Puts *
  ( string [9] : ARRAY OF CHAR )
  : LONGINT;
  -240;
LIBCALL (base : ArpBasePtr) ReadLine *
  ( VAR string [8] : ARRAY OF CHAR )
  : LONGINT;
  -246;
LIBCALL (base : ArpBasePtr) GADS *
  ( line      [8] : ARRAY OF CHAR;
    len       [0] : LONGINT;
    help      [9] : E.STRPTR;
    VAR args [10] : ARRAY OF SYS.LONGWORD;
    temp     [11] : ARRAY OF CHAR )
  : LONGINT;
  -252;
LIBCALL (base : ArpBasePtr) Atol *
  ( string [8] : ARRAY OF CHAR )
  : LONGINT;
  -258;
LIBCALL (base : ArpBasePtr) EscapeString *
  ( string [8] : ARRAY OF CHAR )
  : E.ULONG;
  -264;
LIBCALL (base : ArpBasePtr) CheckAbort *
  ( func [9] : E.PROC )
  : LONGINT;
  -270;
LIBCALL (base : ArpBasePtr) CheckBreak *
  ( mask [1] : SET;
    func [9] : E.PROC )
  : LONGINT;
  -276;
LIBCALL (base : ArpBasePtr) Getenv *
  ( string     [8] : ARRAY OF CHAR;
    VAR buffer [9] : ARRAY OF CHAR;
    size       [0] : LONGINT )
  : E.STRPTR;
  -282;
LIBCALL (base : ArpBasePtr) Setenv *
  ( varName [8] : ARRAY OF CHAR;
    value   [9] : ARRAY OF CHAR )
  : BOOLEAN;
  -288;
LIBCALL (base : ArpBasePtr) FileRequest *
  ( VAR fileRequester [8] : FileRequester )
  : E.STRPTR;
  -294;
LIBCALL (base : ArpBasePtr) CloseWindowSafely *
  ( window      [8] : I.WindowPtr;
    moreWindows [9] : I.WindowPtr );
  -300;
LIBCALL (base : ArpBasePtr) CreatePort *
  ( name [8] : ARRAY OF CHAR;
    pri  [0] : LONGINT )
  : E.MsgPortPtr;
  -306;
LIBCALL (base : ArpBasePtr) DeletePort *
  ( port [9] : E.MsgPortPtr );
  -312;
LIBCALL (base : ArpBasePtr) SendPacket *
  ( action  [0] : LONGINT;
    args    [8] : ArgArrayPtr;
    handler [9] : E.MsgPortPtr )
  : LONGINT;
  -318;
LIBCALL (base : ArpBasePtr) InitStdPacket *
  ( action     [0] : LONGINT;
    args       [8] : ArgArrayPtr;
    packet     [9] : D.DosPacketPtr;
    replyPort [10] : E.MsgPortPtr );
  -324;
LIBCALL (base : ArpBasePtr) PathName *
  ( lock           [0] : D.FileLockPtr;
    VAR buffer     [8] : ARRAY OF CHAR;
    componentCount [1] : LONGINT )
  : E.ULONG;
  -330;
LIBCALL (base : ArpBasePtr) Assign *
  ( logical  [8] : ARRAY OF CHAR;
    physical [9] : ARRAY OF CHAR )
  : E.ULONG;
  -336;
LIBCALL (base : ArpBasePtr) DosAllocMem *
  ( size [0] : LONGINT )
  : E.APTR;
  -342;
LIBCALL (base : ArpBasePtr) DosFreeMem *
  ( block [9] : E.APTR );
  -348;
LIBCALL (base : ArpBasePtr) BtoCStr *
  ( VAR cstr  [8] : ARRAY OF CHAR;
    bstr      [0] : D.BSTR;
    maxLength [1] : LONGINT )
  : E.ULONG;
  -354;
LIBCALL (base : ArpBasePtr) CtoBStr *
  ( cstr      [8] : ARRAY OF CHAR;
    VAR bstr  [0] : D.BSTR;
    maxLength [1] : LONGINT )
  : E.ULONG;
  -360;
LIBCALL (base : ArpBasePtr) GetDevInfo *
  ( devNode [10] : D.DeviceListPtr )
  : D.DeviceListPtr;
  -366;
LIBCALL (base : ArpBasePtr) FreeTaskResList * ()
  : BOOLEAN;
  -372;
LIBCALL (base : ArpBasePtr) ArpExit *
  ( rc    [0] : LONGINT;
    fault [2] : LONGINT );
  -378;
(*
LIBCALL (base : ArpBasePtr) ArpAlloc *
  ( size [] : LONGINT )
  : E.APTR;
  -384;
LIBCALL (base : ArpBasePtr) ArpAllocMem *
  ( size         [] : LONGINT;
    requirements [] : SET )
  : E.APTR;
  -390;
LIBCALL (base : ArpBasePtr) ArpOpen *
  ( name [] : ARRAY OF CHAR;
    mode [] : LONGINT )
  : D.FileHandlePtr;
  -396;
LIBCALL (base : ArpBasePtr) ArpDupLock *
  ( lock [] : D.FileLockPtr )
  : D.FileLockPtr;
  -402;
LIBCALL (base : ArpBasePtr) ArpLock *
  ( name [] : ARRAY OF CHAR;
    mode [] : LONGINT )
  : D.FileLockPtr;
  -408;
LIBCALL (base : ArpBasePtr) RListAlloc *
  ( VAR resList [] : ResList;
    size        [] : LONGINT )
  : E.APTR;
  -414;
*)
LIBCALL (base : ArpBasePtr) FindCLI *
  ( cliNum [0] : LONGINT )
  : E.APTR;
  -420;
LIBCALL (base : ArpBasePtr) QSort *
  ( data  [8] : E.APTR;
    rSize [0] : LONGINT;
    bSize [1] : LONGINT;
    comp  [9] : E.PROC )
  : BOOLEAN;
  -426;
LIBCALL (base : ArpBasePtr) PatternMatch *
  ( pattern [8] : ARRAY OF CHAR;
    string  [9] : ARRAY OF CHAR )
  : BOOLEAN;
  -432;
LIBCALL (base : ArpBasePtr) FindFirst *
  ( pattern  [0] : ARRAY OF CHAR;
    VAR path [8] : AnchorPath )
  : LONGINT;
  -438;
LIBCALL (base : ArpBasePtr) FindNext *
  ( VAR path [8] : AnchorPath )
  : LONGINT;
  -444;
LIBCALL (base : ArpBasePtr) FreeAnchorChain *
  ( VAR path [8] : AnchorPath );
  -450;
LIBCALL (base : ArpBasePtr) CompareLock *
  ( lock1 [0] : D.FileLockPtr;
    lock2 [1] : D.FileLockPtr )
  : E.ULONG;
  -456;
LIBCALL (base : ArpBasePtr) FindTaskResList * ()
  : ResListPtr;
  -462;
LIBCALL (base : ArpBasePtr) CreateTaskResList * ()
  : ResListPtr;
  -468;
LIBCALL (base : ArpBasePtr) FreeResList *
  ( freeList [9] : ResListPtr );
  -474;
LIBCALL (base : ArpBasePtr) FreeTrackedItem *
  ( item [9] : TrackerPtr );
  -480;
(*
LIBCALL (base : ArpBasePtr) GetTracker *
  ( size [] : LONGINT )
  : TrackerPtr;
  -486;
*)
LIBCALL (base : ArpBasePtr) GetAccess *
  ( tracker [9] : TrackerPtr )
  : E.APTR;
  -492;
LIBCALL (base : ArpBasePtr) FreeAccess *
  ( tracker [9] : TrackerPtr );
  -498;
LIBCALL (base : ArpBasePtr) FreeDAList *
  ( VAR node [9] : DirectoryEntry );
  -504;
LIBCALL (base : ArpBasePtr) AddDANode *
  ( data       [8] : ARRAY OF CHAR;
    VAR daList [9] : DirectoryEntry;
    length     [0] : LONGINT;
    id         [1] : LONGINT )
  : DirectoryEntryPtr;
  -510;
LIBCALL (base : ArpBasePtr) AddDADevs *
  ( VAR daList [8] : DirectoryEntry;
    select     [0] : SET )
  : E.ULONG;
  -516;
LIBCALL (base : ArpBasePtr) Strcmp *
  ( s1 [8] : ARRAY OF CHAR;
    s2 [9] : ARRAY OF CHAR )
  : LONGINT;
  -522;
LIBCALL (base : ArpBasePtr) Strncmp *
  ( s1     [8] : ARRAY OF CHAR;
    s2     [9] : ARRAY OF CHAR;
    length [0] : LONGINT )
  : LONGINT;
  -528;
(*
LIBCALL (base : ArpBasePtr) Toupper *
  ( char [] : LONGINT )
  : CHAR;
  -534;
*)
LIBCALL (base : ArpBasePtr) SyncRun *
  ( name    [8] : ARRAY OF CHAR;
    command [9] : E.STRPTR;
    input   [0] : D.FileHandlePtr;
    output  [1] : D.FileHandlePtr )
  : LONGINT;
  -540;

(*
 ************************************************************************
 *  Added V32 of arp.library                                            *
 ************************************************************************
 *)

LIBCALL (base : ArpBasePtr) ASyncRun *
  ( name     [8] : ARRAY OF CHAR;
    command  [9] : E.STRPTR;
    VAR pcb [10] : ProcessControlBlock )
  : LONGINT;
  -546;
LIBCALL (base : ArpBasePtr) SpawnShell *
  ( name       [8] : ARRAY OF CHAR;
    command    [9] : E.STRPTR;
    VAR shell [10] : NewShell )
  : LONGINT;
  -546;
LIBCALL (base : ArpBasePtr) LoadPrg *
  ( name [1] : ARRAY OF CHAR )
  : D.BPTR;
  -552;
LIBCALL (base : ArpBasePtr) PreParse *
  ( source   [8] : ARRAY OF CHAR;
    VAR dest [9] : ARRAY OF CHAR )
  : BOOLEAN;
  -558;

(*
 ************************************************************************
 * Added V33 of arp.library                                             *
 ************************************************************************
 *)

LIBCALL (base : ArpBasePtr) StamptoStr *
  ( VAR dateTime [8] : DateTime )
  : BOOLEAN;
  -564;
LIBCALL (base : ArpBasePtr) StrtoStamp *
  ( VAR dateTime [8] : DateTime )
  : BOOLEAN;
  -570;
LIBCALL (base : ArpBasePtr) ObtainResidentPrg *
  ( name [8] : ARRAY OF CHAR )
  : ResidentProgramNodePtr;
  -576;
LIBCALL (base : ArpBasePtr) AddResidentPrg *
  ( segment [1] : D.BPTR;
    name    [8] : ARRAY OF CHAR )
  : ResidentProgramNodePtr;
  -582;
LIBCALL (base : ArpBasePtr) RemResidentPrg *
  ( name [8] : ARRAY OF CHAR )
  : LONGINT;
  -588;
LIBCALL (base : ArpBasePtr) UnLoadPrg *
  ( segment [1] : D.BPTR );
  -594;
LIBCALL (base : ArpBasePtr) LMult *
  ( a [0] : LONGINT;
    b [1] : LONGINT )
  : LONGINT;
  -600;
LIBCALL (base : ArpBasePtr) LDiv *
  ( a [0] : LONGINT;
    b [1] : LONGINT )
  : LONGINT;
  -606;
LIBCALL (base : ArpBasePtr) LMod *
  ( a [0] : LONGINT;
    b [1] : LONGINT )
  : LONGINT;
  -612;
LIBCALL (base : ArpBasePtr) CheckSumPrg *
  ( VAR node [0] : ResidentProgramNode )
  : E.ULONG;
  -618;
LIBCALL (base : ArpBasePtr) TackOn *
  ( VAR pathname [8] : ARRAY OF CHAR;
    filename     [9] : ARRAY OF CHAR );
  -624;
LIBCALL (base : ArpBasePtr) BaseName *
  ( name [8] : ARRAY OF CHAR )
  : E.STRPTR;
  -630;
LIBCALL (base : ArpBasePtr) ReleaseResidentPrg *
  ( segment [1] : D.BPTR )
  : ResidentProgramNodePtr;
  -636;

(*
 ************************************************************************
 * Added V36 of arp.library                                             *
 ************************************************************************
 *)

(*
LIBCALL (base : ArpBasePtr) SPrintf *
  ( VAR buffer [] : ARRAY OF CHAR;
    string     [] : ARRAY OF CHAR;
    stream     [] : ARRAY OF LONGINT )
  : LONGINT;
  -642;
LIBCALL (base : ArpBasePtr) GetKeywordIndex *
  ( key      [] : ARRAY OF CHAR;
    template [] : ARRAY OF CHAR )
  : LONGINT;
  -648;
LIBCALL (base : ArpBasePtr) ArpOpenLibrary *
  ( name    [] : ARRAY OF CHAR;
    version [] : LONGINT )
  : E.LibraryPtr;
  -654;
LIBCALL (base : ArpBasePtr) ArpAllocFreq * ()
  : FileRequesterPtr;
  -660;
*)


(* --- C Macros defined as procedures ----------------------------------- *)
(* $L+ Absolute long addressing for globals *)


(* --- Library Base variable -------------------------------------------- *)
(* $L- Address globals through A4 *)


(*------------------------------------*)
PROCEDURE* CloseLib ();

BEGIN (* CloseLib *)
  IF base # NIL THEN E.base.CloseLibrary (base) END
END CloseLib;

(*------------------------------------*)
PROCEDURE OpenLib * (mustOpen : BOOLEAN);

BEGIN (* OpenLib *)
  IF base = NIL THEN
    base :=
      SYS.VAL
        ( ArpBasePtr,
          E.base.OpenLibrary (name, version) );
    IF base # NIL THEN SYS.SETCLEANUP (CloseLib)
    ELSIF mustOpen THEN HALT (100)
    END;
  END
END OpenLib;

BEGIN (* ARP *)
  base := NIL
END ARP.
