(* Name : ARP.DEF Version: 1.0 Author : Sascha Wildner Date : 07-Dec-90 Description: DEFINITION MODULE for Modula-2 interface to ARP 1.3 -== UPDATE HISTORY ==- Date Version Author Comments -------------------------------------------------------------------------- 07-Dec-90 1.0 Sascha Wildner First implementation *) DEFINITION MODULE ARP; FROM SYSTEM IMPORT ADDRESS, BYTE; FROM AmigaDOS IMPORT BPTR, DateStampRecord, FileHandle, FileInfoBlock, FileInfoBlockPtr, FileLock, InfoData, ProtectionSet; FROM AmigaDOSExt IMPORT DeviceListPtr, FileLockPtr, RootNodePtr; FROM AmigaDOSProcess IMPORT ProcessID, ProcessPtr, StandardPacketPtr; FROM Intuition IMPORT WindowPtr; FROM Libraries IMPORT Library, LibraryPtr; FROM Lists IMPORT MinList; FROM Memory IMPORT MemReqSet; FROM Nodes IMPORT MinNode, Node; FROM Ports IMPORT Message, MsgPortPtr; FROM Semaphores IMPORT SignalSemaphore; FROM Tasks IMPORT SignalSet, TaskPtr; (* Standard definitions for arp.library information *) CONST ARPName = "arp.library"; ARPVersion = 39; (* RPN flag defintions *) TYPE RPNFlags = (NoCheck, (* No checksumming *) Cache, (* Private usage *) RPNF2, RPNF3, RPNF4, RPNF5, RPNF6, RPNF7, RPNF8); RPNFlagsSet = SET OF RPNFlags; (* Resident Program Support [defined here because of the ResidentPrgList *) (* entry in the ARPBase structure] *) (* *) (* 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. *) TYPE ResidentProgramNodePtr = POINTER TO ResidentProgramNode; ResidentProgramNode = RECORD rpnNext : ResidentProgramNodePtr; (* Next or NIL *) rpnUsage : LONGINT; (* Number of current users *) rpnAccessCnt: CARDINAL; (* Total times used *) rpnCheckSum : LONGCARD; (* Checksum of code *) rpnSegment : BPTR; (* Actual segment *) rpnFlags : RPNFlagsSet; (* See flag definitions above *) rpnName : BYTE; (* Allocated as needed *) END; (* These are used in release 33.4 but not by the library code. *) (* Instead, individual programs check for these flags. *) TYPE ARPFlags = (WildWorld, (* Mixed BCPL/Normal wildcards *) WildBCPL); (* Pure BCPL wildcards *) ARPFlagsSet = SET OF ARPFlags; (* The current ARP library node... *) TYPE ARPBasePtr = POINTER TO ARPBaseRecord; ARPBaseRecord = RECORD LibNode : Library; (* Standard library node *) DosRootNode : RootNodePtr; (* Copy of dlRoot *) Flags : ARPFlagsSet; (* See flag definitions above *) ESCChar : CHAR; (* Character to be used for escaping *) ArpReserved1 : LONGINT; (* ArpLib's use only!! *) EnvBase : LibraryPtr; (* Dummy library *) DosBase : LibraryPtr; (* Cached DosBase *) GfxBase : LibraryPtr; (* Cached GfxBase *) IntuiBase : LibraryPtr; (* Cached IntuitionBase *) ResLists : MinList; (* Resource trackers *) ResidentPrgList : ResidentProgramNodePtr; (* Resident programs *) ResPrgProtection: SignalSemaphore; (* Protection for above *) SegList : BPTR; (* Pointer to loaded libcode *) END; (* You use this when opening the library *) VAR ARPBase: LibraryPtr; (* 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 MODULE. Generally, should be NON deadend alerts. *) CONST AOArpLib = 00008036D; (* Alert object *) (* Alerts that arp.library may return... *) ANArpLib = 03600000D; (* Alert number *) ANArpNoMem = 03610000D; (* No more memory *) ANArpInputMem = 03610002D; (* No memory for input buffer *) ANArpNoMakeEnv = 83610003D; (* No memory to make EnvLib *) ANArpNoDOS = 83630001D; (* Can't open dos.library *) ANArpNoGfx = 83630002D; (* Can't open graphics.library *) ANArpNoIntuit = 83630003D; (* Can't open intuition *) ANBadPackBlues = 83640000D; (* Bad packet returned to SendPacket() *) ANZombie = 83600003D; (* Zombie roaming around system *) ANArpScattered = 83600002D; (* Scatter loading not allowed for ARP *) (* Return codes you can get from calling ARP Assign()... *) CONST AssignOK = 0D; (* Everything is cool and groovy *) AssignNoDev = 1D; (* "Physical" is not valid for assignment *) AssignFatal = 2D; (* Something really icky happened *) AssignCancel = 3D; (* Tried to cancel something but it won't cancel *) (* Size of buffer you need if you are going to call ReadLine() *) CONST MaxInputBuf = 256D; (* 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: LONGCARD; Object: ADDRESS) *) (* *) (* The Mask is a copy of the flag value that caused FileRequest() *) (* 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. *) TYPE FileRequesterFlags = (ListFunc, (* Not implemented yet *) GEventFunc, (* Function to call if one of your gadgets is selected *) AddGadFunc, (* You get to add gadgets *) NewWindFunc, (* You get to modify the NewWindow structure *) NewIDCMP, (* Force a new IDCMP (only if frWindow#NIL) *) DoColor, (* Set this bit for that new and different look *) DoMsgFunc, (* You get all IDCMP messages not for FileRequest() *) DoWildFunc); (* Call me with a FIB and a name, ZERO return accepts *) FileRequesterFlagsSet = SET OF FileRequesterFlags; (* These bits are for frFlags2 in the file requester structure *) TYPE FileRequesterFlags2 = (LongPath); (* Specify the frDir buffer is 256 bytes long *) FileRequesterFlags2Set = SET OF FileRequesterFlags2; (* The ARP file requester data structure... *) TYPE FileRequesterPtr = POINTER TO FileRequester; FileRequester = RECORD frHail : ADDRESS; (* Hailing text *) frFile : ADDRESS; (* Filename array *) frDir : ADDRESS; (* Directory array *) frWindow : WindowPtr; (* Window requesting or NIL *) frFuncFlags: FileRequesterFlagsSet; (* See flag definitions above *) frFlags2 : FileRequesterFlags2Set; (* New flags *) frFunction : PROCEDURE(FileRequesterFlagsSet, ADDRESS): INTEGER; (* Your function *) frLeftEdge : INTEGER; (* To be used later *) frTopEdge : INTEGER; END; (* The sizes of the different buffers... *) CONST FChars = 32D; (* Filename size *) DSize = 33D; (* Directory name if not LongPath *) LongDSize = 254D; (* If LongPath is set, use LongDSize *) LongFSize = 126D; (* For compatibility with ArpBase.i *) (* User GadgetIDs must be less than this value *) CONST FRFirstGadget = 7680H; (* AChain flag definitions *) TYPE AChainFlags = (PatternBit,ExaminedBit,Completed,AllBit); AChainFlagsSet = SET OF AChainFlags; (* 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... *) TYPE AChainPtr = POINTER TO AChain; AChain = RECORD anChild : AChainPtr; anParent: AChainPtr; anLock : FileLockPtr; anInfo : FileInfoBlockPtr; anFlags : AChainFlagsSet; anString: CHAR; END; (* Bit definitions for the new apFlags... *) TYPE AnchorFlags = (DoWild, (* User option ALL *) ItsWild, (* Set by FindFirst, used by FindNext *) DoDir, (* Bit is set if a dir node should be entered *) DidDir, (* Bit is set for an "expired" dir node *) NoMemErr, (* Set if there was not enough memory *) DoDot); (* If set, '.' will convert to CurrentDir *) AnchorFlagsSet = SET OF AnchorFlags; (* Structure expected by FindFirst()/FindNext() *) (* *) (* You need to allocate this structure and initialize it as follows: *) (* *) (* Set apBreakBits to the signal bits that you want to take a break *) (* on, or 0, 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 the 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. *) TYPE AnchorPathPtr = POINTER TO AnchorPath; AnchorPath = RECORD apBase : AChainPtr; (* Pointer to first anchor *) apLast : AChainPtr; (* Pointer to last anchor *) apBreakBits : LONGINT; (* Bits to break on *) apFoundBreak: LONGINT; (* Bits we broke on *) apFlags : AnchorFlagsSet; (* New use for the extra word *) apReserved : BYTE; (* To fill it out *) apStrLen : INTEGER; (* This is what used to be apLength *) apInfo : FileInfoBlock; apBuf : BYTE; (* Allocate a buffer here, if desired *) END; (* 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() *) (* and FindNext() handle all these for you. *) CONST PAny = 80H; (* Token for '*' + '#?' *) PSingle = 81H; (* Token for '?' *) (* No need to muck with these as they may change... *) POrStart = 82H; (* Token for '(' *) POrNext = 83H; (* Token for '|' *) POrEnd = 84H; (* Token for ')' *) PNot = 85H; (* Token for '~' *) PNotClass = 87H; (* Token for '^' *) PClass = 88H; (* Token for '[]' *) PRepBeg = 89H; (* Token for '[' *) PRepEnd = 8AH; (* Token for ']' *) (* 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,DeviceListFlagsSet{Dirs,Volumes}) *) (* *) (* 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 *) (* DeviceListFlagsSet{Devices,DiskOnly}. *) TYPE DeviceListFlags = (Devices, (* Return devices *) DiskOnly, (* Modifier for above: Return disk devices only *) Volumes, (* Return volumes only *) Dirs); (* Return assigned devices only *) DeviceListFlagsSet = SET OF DeviceListFlags; (* Legal deType values, check for these after a call to AddDADevs(), *) (* or use on your own as the ID values in AddDANode(). *) CONST DLXFile = BYTE(0); (* AddDADevs() can't determine this *) DLXDir = BYTE(8); (* AddDADevs() can't determine this *) DLXDevice = BYTE(16); (* It's a resident device *) DLXVolume = BYTE(24); (* Device is a volume *) DLXUnmounted = BYTE(32); (* Device is not resident *) DLXAssign = BYTE(40); (* Device is a logical assignment *) (* Structure used by AddDANode, AddDADevs, FreeDAList. *) (* *) (* This structure is used to create lists of names, which normally *) (* are devices, assigns, volumes, files, or directories. *) TYPE DirectoryEntryPtr = POINTER TO DirectoryEntry; DirectoryEntry = RECORD deNext : DirectoryEntryPtr; (* Next in list *) deType : BYTE; (* DLXMumble *) deFlags: BYTE; (* For future expansion *) deName : BYTE; (* The name of the thing found *) END; (* 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(NIL) type stuff, *) (* DeletePort() and the rest). *) (* *) (* The tracking functions return a TrackerPtr 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). *) (* *) (* 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. *) TYPE TrackedResourcePtr = POINTER TO TrackedResource; TrackedResource = RECORD trNode : MinNode; (* Double linked pointer *) trFlags: BYTE; (* Don't touch *) trLock : BYTE; (* Don't touch, for Get/FreeAccess() *) trID : INTEGER; (* Item's ID *) (* The DefaultTracker portion of the structure. The stuff below this point *) (* can conceivably vary, depending on user needs, etc. This reflects the *) (* default. *) CASE trObject: BOOLEAN OF (* The thing being tracked *) FALSE: trResource: ADDRESS| (* Whatever *) TRUE : tgVerify : LONGINT (* For use during TrakGeneric *) END; CASE trExtra : BOOLEAN OF (* Only needed sometimes *) FALSE: tgFunction: POINTER TO PROCEDURE()| (* Function to call for TrakGeneric *) TRUE : trWindow2 : WindowPtr (* For TrakWindow *) END; END; (* You get a pointer to a structure 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 so, 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, 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 NIL. *) TYPE DefaultTrackerPtr = POINTER TO DefaultTracker; DefaultTracker = RECORD CASE dtObject: BOOLEAN OF (* The object being tracked *) FALSE: dtResource: ADDRESS| (* Whatever *) TRUE : tgVerify : LONGINT (* For use during TrakGeneric *) END; CASE dtExtra : BOOLEAN OF FALSE: tgFunction: POINTER TO PROCEDURE()| (* Function to call for TrakGeneric *) TRUE : dtWindow2 : WindowPtr (* For TrakWindow *) END; END; (* Items the tracker knows what to do about *) CONST TrakAAMem = 0D; (* Default (ArpAlloc) element *) TrakLock = 1D; (* File lock *) TrakFile = 2D; (* Opened file *) TrakWindow = 3D; (* Window -- see docs *) TrakScreen = 4D; (* Screen *) TrakLibrary = 5D; (* Opened library *) TrakDAMem = 6D; (* Pointer to DosAllocMem block *) TrakMemNode = 7D; (* AllocEntry() node *) TrakSegList = 8D; (* Program segment *) TrakResList = 9D; (* ARP (nested) ResList *) TrakMem = 10D; (* Memory ptr/length *) TrakGeneric = 11D; (* Generic element, your choice *) TrakDAList = 12D; (* DAList (aka file request *) TrakAnchor = 13D; (* Anchor chain (pattern matching) *) TrakFReq = 14D; (* FileRequest structure *) TrakFont = 15D; (* GfxBase CloseFont() *) TrakMax = 15D; (* Poof, anything higher is tossed *) (* Tracker flag definitions *) TYPE TrackerFlags = (TF0, TF1, TF2, TF3, TF4, Moved, (* Item moved *) Reloc, (* This may be relocated (not used yet) *) Unlink); (* Free node bit *) TrackerFlagsSet = SET OF TrackerFlags; (* 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. *) TYPE ResListPtr = POINTER TO ResList; ResList = RECORD rlNode : MinNode; (* Used by ArpLib to link ResLists *) rlTaskID : TaskPtr; (* Owner of this list *) rlFirstItem: MinList; (* List of tracked resources *) rlLink : ResListPtr; (* SyncRun's use - hide list here *) END; (* Returns from CompareLock() *) CONST LCKEqual = 0D; (* The two locks refer to the same object *) LCKVolume = 1D; (* Locks are on the same volumes *) LCKDifVol1 = 2D; (* Locks are on different volumes *) LCKDifVol2 = 3D; (* Locks are on different volumes *) (* 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. *) TYPE ZombieMsgPtr = POINTER TO ZombieMsg; ZombieMsg = RECORD zmExecMessage: Message; zmTaskNum : LONGCARD; (* Task ID *) zmReturnCode : LONGINT; (* Process's return code *) zmResult2 : LONGCARD; (* System return code *) zmExitTime : DateStampRecord; (* Date stamp at the time of exit *) zmUserInfo : LONGCARD; (* For whatever you wish *) END; (* The following control bits determine what ASyncRun does on *) (* abnormal exits and on background process termination. *) TYPE PCBFlags = (SaveIO, (* Don't free/check file handles on exit *) CloseSplat, (* Close splat file, must request explicitly *) NoCli, (* Don't create a CLI process *) Interactive, (* This is now obsolete... *) Code, (* Dangerous yet enticing *) StdIO); (* Do the StdIO thing, splat = CON:Filename *) PCBFlagsSet = SET OF PCBFlags; (* Structure required by ASyncRun() -- see docs for more info. *) TYPE ProcessControlBlockPtr = POINTER TO ProcessControlBlock; ProcessControlBlock = RECORD pcbStackSize : LONGCARD; (* Stacksize for new process *) pcbPri : BYTE; (* Priority of new task *); pcbControl : PCBFlagsSet; (* Control bits, see defines above *) pcbTrapCode : ADDRESS; (* Optional TrapCode *) pcbInput : BPTR; pcbOutput : BPTR; (* Optional StdIn, StdOut *) CASE pcbConsole: BOOLEAN OF FALSE: pcbSplatFile: BPTR| (* File to use for Open("*") *) TRUE : pcbConName : ADDRESS (* CON: filename *) END; pcbLoadedCode: ADDRESS; (* If not NIL, will not load/unload code *) pcbLastGasp : ZombieMsgPtr; (* ReplyMsg() to be filled in by exit *) pcbWBProcess : MsgPortPtr; (* Valid only when NoCli *) END; (* Formerly needed to pass NULLCMD to a child. No longer needed. *) (* It is being kept here for compatibility only... *) CONST NoCmd = "\n"; (* Error returns from SyncRun() and ASyncRun() *) CONST PRNoFile = -1D; (* Could not LoadSeg() the file *) PRNoMem = -2D; (* No memory for something *) (* PRNoCLI = -3D; This is now obsolete *) PRNoSlot = -4D; (* No room in TaskArray *) PRNoInput = -5D; (* Could not open input file *) PRNoOutput = -6D; (* Could not get output file *) (* PRNoLock = -7D; This is now obsolete *) (* PRArgErr = -8D; This is now obsolete *) (* PRNoBCPL = -9D; This is now obsolete *) (* PRBadLib = -10D; This is now obsolete *) PRNoStdIO = -11D; (* Couldn't get StdIO handles *) (* Added V35 of arp.library *) PRWantsMessage = -12D; (* Child wants you to report IoErr() to user *) PRNoShellProc = -13D; (* Can't create a Shell/CLI process *) PRNoExec = -14D; (* 'E' bit is clear *) PRScript = -15D; (* S and E are set, IoErr() contains directory *) (* Bit values for nshControl, you should use them as shown below, or *) (* just use the actual values indicated. *) TYPE NSHFlags = (CLI, (* Do a CLI, not a Shell *) Background, (* Background Shell *) execute, (* Do as EXECUTE *) InterActive, (* Run an interactive shell *) NSHF4, NSHF5, NSHF6, FB); (* Alt function bit *) NSHFlagsSet = SET OF NSHFlags; (* Common values for nshControl which allow you to do useful *) (* and somewhat "standard" things... *) CONST InteractiveShell = NSHFlagsSet{FB,InterActive}; (* Gimme a newshell! *) InteractiveCLI = NSHFlagsSet{FB,InterActive,CLI}; (* Gimme that ol' newcli *) BackgroundShell = NSHFlagsSet{FB,Background}; (* Gimme a background Shell *) ExecuteMe = NSHFlagsSet{FB,Background,execute}; (* Aptly named, doncha think? *) (* 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(ADR("Optional Window Name"),ADR("Optional From File"), *) (* NewShell); *) (* *) (* Syntax for a background shell is: *) (* *) (* rc:=ASyncRun(ADR("Command line"),NIL,NewShell); *) (* *) (* Same syntax for an execute style call, but you have to be on drugs *) (* if you want to do that. *) TYPE NewShellPtr = POINTER TO NewShell; NewShell = RECORD nshStackSize: LONGCARD; (* Stacksize Shell will use for children *) nshPri : BYTE; (* Ignored by interactive Shells *) nshControl : NSHFlagsSet; (* See above *) nshLogMsg : ADDRESS; (* Optional login message, if NIL, use default *) nshInput : BPTR; (* Ignored by interactive Shells, but *) nshOutput : BPTR; (* used by background and execute options *) nshReserved : ARRAY [0..4] OF LONGINT; END; (* Additional IoErr() returns added by ARP... *) CONST ErrorBufferOverflow = 303D; (* User or internal buffer overflow *) ErrorBreak = 304D; (* A break character was received *) ErrorNotExecutable = 305D; (* A file has E bit cleared *) ErrorNotCLI = 400D; (* Program/function needs to be CLI *) (* 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 the 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. *) TYPE ResidentProgramTagPtr = POINTER TO ResidentProgramTag; ResidentProgramTag = RECORD rptNextSeg : 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. *) rptBRA : CARDINAL; (* Short branch to executable *) rptMagic : CARDINAL; (* Resident majik value *) rptStackSize: LONGCARD; (* Min stack for this process *) rptDataSize : LONGCARD; (* Data size to allocate if resident *) (* rptInstruction Start here if resident *) END; (* 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 structure. *) TYPE ProcessMemoryPtr = POINTER TO ProcessMemory; ProcessMemory = RECORD pmNode : Node; pmNum : CARDINAL; (* This is 1 if no data, 2 if data *) pmStack : ADDRESS; pmStackSize: LONGCARD; pmData : ADDRESS; (* Only here if pmNum=2 *) pmDataSize : LONGCARD; END; (* 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(ADR(task^.tcbMemEntry),PMemName); *) CONST PMemName = "ARP_MEM"; ResidentMagic = 4AFCH; (* Same as RTCMatchWord (trapf) *) (* For datFlags *) TYPE DateTimeFlags = (Subst, (* Substitute "Today" & "Tomorrow" where appropriate *) Future); (* Day of the week is in future *) DateTimeFlagsSet = SET OF DateTimeFlags; (* Date string/data structures *) TYPE DateTimePtr = POINTER TO DateTime; DateTime = RECORD datStamp : DateStampRecord; (* DOS DateStamp *) datFormat : BYTE; (* Controls appearance on datStrDate *) datFlags : DateTimeFlagsSet; (* See above *) datStrDay : ADDRESS; (* Day of the week string *) datStrDate: ADDRESS; (* Date string *) datStrTime: ADDRESS; (* Time string *) END; (* Size of buffer you need for each DateTime strings: *) CONST LenDatString = 10D; (* For datFormat *) CONST FormatDOS = BYTE(0); (* dd-mmm-yy AmigaDOS's own, unique style *) FormatINT = BYTE(1); (* yy-mm-dd International format *) FormatUSA = BYTE(2); (* mm-dd-yy The good ol' USA *) FormatCDN = BYTE(3); (* dd-mm-yy Out brothers and sisters to the north *) FormatMAX = FormatCDN; (* Larger than this? Defaults to AmigaDOS *) (* These duplicate the calls in dos.library *) TYPE ProcPtr = POINTER TO PROCEDURE(); PROCEDURE Open(name: ADDRESS; accessMode: LONGINT): FileHandle; (* Open a file for input or output. name - a null terminated string accessMode - ModeOldFile or ModeNewFile result - file handle *) PROCEDURE Close(file: FileHandle); (* Close an open file. file - file handle *) PROCEDURE Read(file: FileHandle; buffer: ADDRESS; length: LONGINT): LONGINT; (* Read n bytes of data from a file. file - file handle buffer - pointer to a buffer length - number of bytes to read result - actual number of bytes read or -1 if an error occured *) PROCEDURE Write(file: FileHandle; buffer: ADDRESS; length: LONGINT): LONGINT; (* Write n bytes of data to a file. file - file handle buffer - pointer to a buffer length - number of bytes to write result - actual number of bytes written or -1 if an error occured *) PROCEDURE Input(): FileHandle; (* Return the initial input file handle assigned to the program. result - file handle *) PROCEDURE Output(): FileHandle; (* Return the initial output file handle assigned to the program. result - file handle *) PROCEDURE Seek(file: FileHandle; position: LONGINT; mode: LONGINT): LONGINT; (* Move to a logical file position. file - file handle position - an offset to move file position ptr to, positive or negative mode - OffsetBeginning or OffsetCurrent or OffsetEnd result - old file position or -1 if an error occured *) PROCEDURE DeleteFile(name: ADDRESS): BOOLEAN; (* Delete a file or directory. name - null terminated string result - success(TRUE) or failure(FALSE) *) PROCEDURE Rename(oldName, newName: ADDRESS): BOOLEAN; (* Rename directory or file. oldName - null terminated string newName - null terminated string result - success(TRUE) or failure(FALSE) *) PROCEDURE Lock(name: ADDRESS; accessMode: LONGINT): FileLock; (* Lock a directory or file. name - a null terminated string accessMode - SharedLock or ExclusiveLock result - BCPL pointer to a lock *) PROCEDURE UnLock(lock: FileLock); (* Unlock a directory or file. lock - BCPL pointer to a lock *) PROCEDURE DupLock(lock: FileLock): FileLock; (* Duplicate a lock. lock - BCPL pointer to a lock result - BCPL pointer to a lock *) PROCEDURE Examine(lock: FileLock; VAR infoBlock: FileInfoBlock): BOOLEAN; (* Examine a directory or file associated with a lock. lock - BCPL pointer to a lock infoBlock - pointer to a file info block to be filled in result - success(TRUE) or failure(FALSE) *) PROCEDURE ExNext(lock: FileLock; VAR infoBlock: FileInfoBlock): BOOLEAN; (* Examine the next entry in a directory. lock - BCPL pointer to a lock infoBlock - pointer to a file info block to be filled in result - success(TRUE) or failure(FALSE) *) PROCEDURE Info(lock: FileLock; VAR infoData: InfoData): BOOLEAN; (* Return information about a disk. lock - BCPL pointer to a lock infoData - pointer to a InfoData structure to be filled in result - success(TRUE) or failure(FALSE) *) PROCEDURE CreateDir(name: ADDRESS): FileLock; (* Create a new directory. name - null terminated string result - BCPL pointer to a lock *) PROCEDURE CurrentDir(lock: FileLock): FileLock; (* Make a directory associated with a lock the current working directory. lock - BCPL pointer to a lock result - BCPL pointer to a lock *) PROCEDURE CreateProc(name: ADDRESS; pri: LONGINT; segment: ADDRESS; stackSize: LONGINT): ProcessID; (* Create a new process. name - null terminated string pri - priority to be given to process segment - pointer to segment list, as returned by LoadSeg() stackSize - size of root stack in bytes result - the ProcessID or 0 if an error occured *) PROCEDURE Exit(returnCode: LONGINT); (* Exit from a process. returnCode - if the process is running under the CLI this will be the return code returned to the CLI. If the program is running as a distinct process, Exit deletes the process and releases the space associated with the stack, segment list, and process structure *) PROCEDURE LoadSeg(name: ADDRESS): BPTR; (* Load a load module into memory. name - null terminated string result - pointer to a segment or 0 if the load failed *) PROCEDURE UnLoadSeg(segment: BPTR); (* Unload a segment previously loaded by LoadSeg. segment - pointer to a segment originally returned by LoadSeg *) PROCEDURE DeviceProc(name: ADDRESS): ProcessID; (* Return the process identifier of the process handling that I/O. name - null terminated string result - process identifier of the device handler or 0 if not found. If the name refers to a file on a mounted device then a pointer to a directory lock is returned by IOErr() *) PROCEDURE SetComment(name, comment: ADDRESS): BOOLEAN; (* Set a comment on file or directory. name - null terminated string comment - null terminated string of up to 80 characters in length result - success(TRUE) or failure(FALSE) *) PROCEDURE SetProtection(name: ADDRESS; mask: ProtectionSet): BOOLEAN; (* Set file or directory protection. name - null terminated string mask - protection mask to be set result - success(TRUE) or failure(FALSE) *) PROCEDURE DateStamp(VAR v: DateStampRecord); (* Obtain the current date and time in internal format. v - pointer to a DateStamp structure (3 long words) *) PROCEDURE Delay(ticks: LONGINT); (* Delay a process for a specified amount of time. ticks - number of ticks to wait (50 ticks/second) *) PROCEDURE WaitForChar(file: FileHandle; timeout: LONGINT): BOOLEAN; (* Indicates whether characters arrive within a time limit or not. file - file handle timeout - amount of time to wait in micro seconds result - if character arrived before timeout returns TRUE, else FALSE *) PROCEDURE ParentDir(lock: FileLock): FileLock; (* Obtain the parent of a directory or file. lock - BCPL pointer to a lock result - BCPL pointer to a lock *) PROCEDURE IsInteractive(file: FileHandle): BOOLEAN; (* Test if a file is connected to a virtual terminal or not. file - file handle result - TRUE = interactive, FALSE = non-interactive *) PROCEDURE Execute(cmdString: ADDRESS; input, output: FileHandle): BOOLEAN; (* Execute a CLI command. cmdString - null terminated string input - file handle output - file handle result - success(TRUE) or failure(FALSE) *) (* Now for the stuff that only exists in arp.library *) PROCEDURE Printf(string: ADDRESS; args: ADDRESS): LONGINT; (* Print formatted data on current output. string - null terminated string args - null terminated string result - if all goes well, the total count of characters actually written, else -1 *) PROCEDURE FPrintf(file: FileHandle; string: ADDRESS; args: ADDRESS): LONGINT; (* Print formatted data on file. file - file handle string - null terminated string args - null terminated string result - if all goes well, the total count of characters actually written, else -1 or 0 (if a NIL FileHandle was passed) *) PROCEDURE Puts(string: ADDRESS): LONGINT; (* Print string with newline on stdout. string - a null terminated string result - if all goes well, the total count of characters actually written, else -1 *) PROCEDURE ReadLine(buffer: ADDRESS): LONGINT; (* Get a line from current input. buffer - pointer to a 256 byte buffer to store the input string in result - the actual count of the characters returned *) PROCEDURE GADS(line: ADDRESS; len: LONGINT; help: ADDRESS; args: ADDRESS; temp: ADDRESS): LONGINT; (* Do standard AmigaDOS command line parsing. line - pointer to the command line len - length of command line help - pointer to optional extra help string (displayed when question mark typed after command) args - pointer to an array of longwords which will receive the results of the argoment parse. The must ALWAYS be at least one element in this array temp - pointer to AmigaDOS style template result - number of arguments found or -1 if there was an error in the command line *) PROCEDURE Atol(string: ADDRESS): LONGINT; (* Convert ASCII string to LONGINT. string - null terminated string result - the binary value of the string *) PROCEDURE EscapeString(string: ADDRESS): LONGCARD; (* Convert escape characters in string. string - null terminated string result - new length of the string *) PROCEDURE CheckAbort(func: ProcPtr): LONGINT; (* Check for CTRL-C. func - function to call if signal was received (optional, may be NIL) result - either 0 (if signal not received), return value of user function (if func#NIL and signal was received) or signal flag (if func=NIL) *) PROCEDURE CheckBreak(mask: SignalSet; func: ProcPtr): LONGINT; (* Check for CTRL-C/D/E/F. mask - signal set containing the SigBreakCtrlC/D/E/F bits to check for func - (optional) function to call if BREAK occured result - either 0 (if none of the signals specified were received), return value of user function (if func#NIL) or passed signal set *) PROCEDURE GetEnv(string: ADDRESS; buffer: ADDRESS; size: LONGINT): ADDRESS; (* Get the value of an environment variable. string - pointer to environment variable name buffer - user allocated area to store the value associated with the environment variable size - size of buffer in bytes result - if found, pointer to the start of the value string for that variable *) PROCEDURE SetEnv(varName: ADDRESS; value: ADDRESS): BOOLEAN; (* Set the value of an environment variable. varName - pointer to an environment variable name value - buffer which contains the values to be associated with this environment variable result - success(TRUE) or failure(FALSE) *) PROCEDURE FileRequest(fileRequester: FileRequesterPtr): ADDRESS; (* Get filename from user. fileRequester - pointer to an initialized FileRequester structure result - pointer to the file buffer in your FileRequester structure (if user pressed OK) or NIL (if user pressed CANCEL) *) PROCEDURE CloseWindowSafely(window: WindowPtr; moreWindows: ADDRESS); (* Close a window without GURUing. window - pointer to window to be closed moreWindows - if NIL, the MsgPort for this window will be released *) PROCEDURE CreatePort(name: ADDRESS; pri: LONGINT): MsgPortPtr; (* Create a message port. name - pointer to null terminated string (if MsgPort is to be attached to system MsgPort list) or NIL (if MsgPort is to be private to the caller) pri - priority of this MsgPort result - pointer to an initialized MsgPort or NIL (if port could not be allocated) *) PROCEDURE DeletePort(port: MsgPortPtr); (* Deletes a message port. port - pointer to a message port *) PROCEDURE SendPacket(action: LONGINT; args: ADDRESS; handler: MsgPortPtr): LONGINT; (* Send a packet to DOS. action - the action you wish this packet to cause args - pointer to an array of seven long words specifying the arguments to send with the packet. May be NIL (arguments will be set to zero) handler - address of MsgPort of the handler you wish to receive this packet result - dpRes1 field of returned packet *) PROCEDURE InitStdPacket(action: LONGINT; args: ADDRESS; packet: StandardPacketPtr; replyPort: MsgPortPtr); (* Initialize a standard packet structure. action - the type (action) of packet you need args - pointer to an array of seven long words representing the argument values you wish to send to AmigaDOS. May be NIL (packet arguments will be cleared) packet - pointer to the StandardPacket you wish initialized replyPort - reply port for this packet *) PROCEDURE PathName(lock: FileLock; buffer: ADDRESS; componentCount: LONGINT): LONGCARD; (* Find complete pathname of file/directory. lock - lock in the file or directory buffer - area of memory to place the filename in componentCount - number of names that can be placed in the destination area result - 0 (problem: either buffer overflow or disk error) or length of pathname in characters *) PROCEDURE Assign(logical: ADDRESS; physical: ADDRESS): LONGCARD; (* Assigns a logical device name. logical - pointer to name to give to physical device physical - pointer to name of file or device to assign logical or NIL (existing assignment will be removed) result - AssignOk (DeviceInfo has been created) or error (see above) *) PROCEDURE DosAllocMem(size: LONGINT): ADDRESS; (* AmigaDOS compatible memory allocator. size - size of the desired block in bytes result - pointer to allocated memory block (will be longword aligned) or NIL (if the allocation failed) *) PROCEDURE DosFreeMem(block: ADDRESS); (* AmigaDOS compatible memory freer. block - pointer to a memory block returned by DosAllocMem() *) PROCEDURE BtoCstr(cstr: ADDRESS; bstr: BPTR; maxLength: LONGINT): LONGCARD; (* Copy a BSTR to a null terminated string. cstr - pointer to a buffer area for the resulting string (should be maxLength+1 in size) bstr - BPTR to the BSTR to convert maxLength - maximum number of characters in buffer (not including null terminator) result - actual number of characters copied *) PROCEDURE CtoBstr(cstr: ADDRESS; bstr: BPTR; maxLength: LONGINT): LONGCARD; (* Copy a null terminated string to a BSTR. cstr - pointer to the string to convert bstr - BPTR to the destination string (must be maxLength+1 bytes in size) maxLength - number of characters available in BSTR (not including initial count byte) result - actual number of characters transferred *) PROCEDURE GetDevInfo(devNode: DeviceListPtr): DeviceListPtr; (* Traverse through DevInfo device list. devNode - current position in list (or NIL for head) result - next node in list or NIL (if at end of list) *) PROCEDURE FreeTaskResList(): BOOLEAN; (* Free tracked resources for this task. result - success(TRUE) or failure(FALSE) *) PROCEDURE ArpExit(rc: LONGINT; fault: LONGINT); (* Exit immediately, closing ARP, freeing resources. rc - the value you wish to return (0 means a normal exit) fault - if rc#0, this value is the AmigaDOS error code which is used with the "Why" program (ignored if rc=0) *) PROCEDURE ArpAlloc(size: LONGINT): ADDRESS; (* Allocate memory and track. size - amount of memory required result - pointer to a memory block with MemReqSet(MemPuclic,MemClear) or NIL (if an error occurred) *) PROCEDURE ArpAllocMem(size: LONGINT; requirements: MemReqSet): ADDRESS; (* Allocate and track memory. size - amount of memory required requirements - type of memory required result - pointer to a memory block of type and size requested or NIL (if an error occurred) *) PROCEDURE ArpOpen(name: ADDRESS; mode: LONGINT): FileHandle; (* Open a file and track it. name - pointer to a null terminated string mode - valid AmigaDOS access mode result - file handle or NIL *) PROCEDURE ArpDupLock(lock: FileLock): FileLock; (* Duplicate a lock and track it. lock - pointer to a lock result - pointer to a lock or NIL *) PROCEDURE ArpLock(name: ADDRESS; mode: LONGINT): FileLock; (* Get a lock and track it. name - pointer to a null terminated string mode - valid AmigaDOS access value result - a lock or NIL *) PROCEDURE RListAlloc(resList: ResListPtr; size: LONGINT): ADDRESS; (* Allocate and track memory on specific ResList. resList - the ResList the allocation will be chained onto size - the size of the memory request result - pointer to a block of memory of the requested size or NIL *) PROCEDURE FindCLI(cliNum: LONGINT): ProcessPtr; (* Get process structure for CLI number. cliNum - the CLI task number for the process or 0 (which returns the total number of process slots) result - a process structure, NIL or total number of allowable CLI processes (see above) *) PROCEDURE QSort(base: ADDRESS; rSize: LONGINT; bSize: LONGINT; comp: ADDRESS): BOOLEAN; (* Quickly sort whatever you want. base - pointer to the start of a memory region to be sorted rSize - size of region to be sorted bSize - size of a single element in bytes comp - function to be provided by caller, which compares two elements from the set to be sorted. result - success(TRUE) or failure(FALSE) *) PROCEDURE PatternMatch(pattern: ADDRESS; string: ADDRESS): BOOLEAN; (* Perform a wildcard match on a string. pattern - pointer to the pattern string to match against string - pointer to the string to be matched result - success(TRUE) or failure(FALSE) *) PROCEDURE FindFirst(pattern: ADDRESS; path: AnchorPathPtr): LONGINT; (* Search for multilevel pattern match. pattern - pointer to an ASCII string path - pointer to an initialized AnchorPath structure result - 0 if success, non-zero for any error (see above) *) PROCEDURE FindNext(path: AnchorPathPtr): LONGINT; (* Locate next match for a file pattern. path - pointer to an AnchorPath structure which has been initialized by a call to FindFirst() result - 0 for success, non-zero for any error (see above) *) PROCEDURE FreeAnchorChain(path: AnchorPathPtr); (* Free an allocated anchor chain. path - AnchorPath structure initialized by calls to FindFirst() and/or FindNext() *) PROCEDURE CompareLock(lock1: FileLock; lock2: FileLock): LONGINT; (* Compares two locks for "equality". lock1 - pointer to a lock lock2 - pointer to a lock result - return code as documented above *) PROCEDURE FindTaskResList(): ResListPtr; (* Find a pointer to current task's ResList. result - pointer to most recent ResList for your task or NIL (if nothing is being tracked) *) PROCEDURE CreateTaskResList(): ResListPtr; (* Create a new nested ResList for this task. result - pointer to the new list or NIL (if failure) *) PROCEDURE FreeResList(freeList: ResListPtr); (* NOT DOCUMENTED *) PROCEDURE FreeTrackedItem(item: DefaultTrackerPtr); (* Free a tracked item from a ResList. item - pointer to the tracker for this resource *) PROCEDURE GetTracker(): DefaultTrackerPtr; (* Get a tracking node for resource tracking. result - pointer to a DefaultTracker or NIL (if the allocation failed) *) PROCEDURE GetAccess(tracker: DefaultTrackerPtr): TrackedResourcePtr; (* Locks access to a tracked resource. tracker - the tracker for the resource you want to reclaim result - pointer to the resource or NIL (if the resource is gone) *) PROCEDURE FreeAccess(tracker: DefaultTrackerPtr); (* Decrements use count for a tracked item. tracker - pointer to the DefaultTracker for this item *) PROCEDURE FreeDAList(node: DirectoryEntryPtr); (* Free a DosAllocMem (DA) list. node - pointer to the first node to free *) PROCEDURE AddDANode(data: ADDRESS; daList: DirectoryEntryPtr; length: LONGINT; id: LONGINT): DirectoryEntryPtr; (* Add a new entry to a DAList. data - pointer to the data to be copied to the deName field of the new node. See length parameter daList - address of a DA list header for this node length - if 0, data is assumed to be a null terminated string. Otherwise, length gives the amount of memory to copy to the deName field id - id is the secondary sort key/type code. This will be the deType variable of the new code result - a pointer to the node just added to the DAList (or NIL, if an error occurred) *) PROCEDURE AddDADevs(daList: DirectoryEntryPtr; select: DeviceListFlagsSet): LONGCARD; (* Get private copy of DevInfo list. daList - pointer to a DA list header select - the selection mask which determines which devices will be added to the DA list result - the number of entries actually added to the user's DA list *) PROCEDURE Strcmp(s1: ADDRESS; s2: ADDRESS): LONGINT; (* Compare two strings, ignoring case. s1 - pointer to null terminated string s2 - pointer to null terminated string result - less than zero if s1s2 *) PROCEDURE Strncmp(s1: ADDRESS; s2: ADDRESS; length: LONGINT): LONGINT; (* Compare two strings for n bytes, ignoring case. s1 - pointer to null terminated string s2 - pointer to null terminated string length - maximum number of characters to compare result - see Strcmp() *) PROCEDURE Toupper(char: CHAR): CHAR; (* Convert character to uppercase. char - a character result - an uppercase character *) PROCEDURE SyncRun(name: ADDRESS; command: ADDRESS; input: FileHandle; output: FileHandle): LONGINT; (* Load a process and wait for its completion. name - a pointer to the filename of the process you wish to load and run command - a pointer to the arguments you wish to pass to this process input - the standard input for the new process (NIL means default) output - the standard output for the new process (NIL means default) result - return code of the process executed (if positive or zero) or error (if negative) *) (* Added V32 of arp.library *) PROCEDURE ASyncRun(name: ADDRESS; command: ADDRESS; pcb: ProcessControlBlockPtr): LONGINT; (* Create an ansynchronous process. name - pointer to command name. If you do not supply a value on the pcbLoadedCode variable this must be a valid pathname or resident program name. If you provide already loaded code, the name does not need to refer to an actual program file or resident code, of course command - pointer to the commands you wish to pass to this argument. This may be NIL, but it must not exceed 256 characters in length. Note that IO redirection must be performed by the caller. Also note that some programs appear to have bugs in dealing with 0 length or NIL command lines. To safely pass a NIL command line, you should pass a string consisting of a newline and a null, i.e. "\n". This is defined above pcb - only pcbStackSize and pcbPro must be initialized by you result - if this function succeeds, a positive value, corresponding to the number of the CLI created will be returned. If no CLI is created, the value returned will be zero. If there is an error, then the return will be negative, and one of the documented error returns *) PROCEDURE SpawnShell(name: ADDRESS; command: ADDRESS; shell: NewShellPtr): LONGINT; (* NOT DOCUMENTED *) PROCEDURE LoadPrg(name: ADDRESS): BPTR; (* Load a program by searching path. name - pointer to the null terminated pathname of the command to load result - a BPTR to the loaded code, or NIL, of an error occurred *) PROCEDURE PreParse(source: ADDRESS; dest: ADDRESS): BOOLEAN; (* Create a tokenized string suitable for PatternMatch. source - pointer to wildcarded unparsed string dest - pointer to a buffer to place the parsed string in result - TRUE if any wildcards at all were encountered, FALSE otherwise *) (* Added V33 of arp.library *) PROCEDURE StampToStr(dateTime: DateTimePtr): BOOLEAN; (* Convert DateStamp portion of DateTime structure to string. dateTime - a pointer to an initialized DateTime structure result - a non-zero return indicates that the DateStamp was invalid. Zero indicates that everything went according to plan *) PROCEDURE StrToStamp(dateTime: DateTimePtr): BOOLEAN; (* Convert ASCII portion of DateTime structure to a DateStamp. dateTime - a pointer to an initialized DateTime structure result - see StampToStr() *) PROCEDURE ObtainResidentPrg(name: ADDRESS): ResidentProgramNodePtr; (* Obtains a resident program for your use. name - pointer to a null terminated pathname result - pointer to the resident program node for the program. If NIL, an error occurred *) PROCEDURE AddResidentPrg(segment: BPTR; name: ADDRESS): ResidentProgramNodePtr; (* Add a program to the resident list. segment - BPTR as returned by LoadSeg() name - pointer to a null terminated pathname result - pointer to the resident program node for the program or NIL (if it could not be added) *) PROCEDURE RemResidentPrg(name: ADDRESS): LONGINT; (* Remove a program from the resident list, freeing it's node and code segments. name - a pointer to a null terminated pathname result - zero (everything is O.K.) or non-zero (code is in use) *) PROCEDURE UnLoadPrg(segment: BPTR); (* Unload a program received from LoadPrg(). segment - pointer to a segment obtained from LoadPrg() *) PROCEDURE LMult(a: LONGINT; b: LONGINT): LONGINT; (* Perform a long multiply. a - a 32 bit signed number b - a 32 bit signed number result - the 32 bit result of a*b *) PROCEDURE LDiv(a: LONGINT; b: LONGINT): LONGINT; (* Perform a long divide. a - a 32 bit signed number b - a 32 bit signed number result - the 32 bit result of a/b *) PROCEDURE LMod(a: LONGINT; b: LONGINT): LONGINT; (* Perform a long modulus, doing canonical thing with sign. a - a 32 bit signed number b - a 32 bit signed number result - the 32 bit result of a MOD b, with sign of a *) PROCEDURE CheckSumPrg(node: ResidentProgramNodePtr): LONGINT; (* Calculate the checksum on a resident program. node - pointer to a resident program node result - a newly calculated checksum *) PROCEDURE TackOn(pathname: ADDRESS; filename: ADDRESS); (* Correctly add a filename to an existing pathname. pathname - pointer to the pathname to be augmented filename - pointer to the filename to augment pathname with *) PROCEDURE BaseName(name: ADDRESS): ADDRESS; (* Return basename of pathname. name - pointer to a valid pathname result - pointer to start of basename *) PROCEDURE ReleaseResidentPrg(segment: BPTR): ResidentProgramNodePtr; (* If segment is resident, decrement usage count. segment - pointer to a loaded code segment result - the corresponding node if found *) (* Added V36 of arp.library *) PROCEDURE SPrintf(buffer: ADDRESS; string: ADDRESS; stream: ADDRESS): LONGINT; (* NOT DOCUMENTED *) PROCEDURE GetKeywordIndex(key: ADDRESS; template: ADDRESS): LONGINT; (* NOT DOCUMENTED *) PROCEDURE ArpOpenLibrary(name: ADDRESS; version: LONGINT): LibraryPtr; (* NOT DOCUMENTED *) PROCEDURE ArpAllocFReq(): FileRequesterPtr; (* NOT DOCUMENTED *) END ARP.