-- FTPCold.mesa - last edit: -- MAS May 19, 1980 6:03 PM -- HGM July 28, 1980 10:03 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY FTPDefs, FTPPrivateDefs, String USING [AppendString], Storage USING [Node, String, Free, FreeNodeNil, FreeString]; FTPCold: MONITOR IMPORTS String, Storage, FTPPrivateDefs EXPORTS FTPDefs, FTPPrivateDefs SHARES FTPDefs, FTPPrivateDefs = BEGIN OPEN FTPDefs, FTPPrivateDefs; ftpUseCount: CARDINAL ← 0; ftpsystem: FTPSystem ← NIL; -- **********************! Signals !*********************** FTPError: PUBLIC SIGNAL [ftpError: FtpError, message: STRING] = CODE; RejectThisConnection: PUBLIC ERROR [error: STRING] = CODE; LocateFtpSystemObject: PUBLIC PROCEDURE RETURNS [POINTER TO FTPSystem] = BEGIN -- return RETURN[@ftpsystem]; END; FTPInitialize: PUBLIC ENTRY PROCEDURE = BEGIN property: Property; strings: ARRAY Property OF STRING ← [ -- avoid clutter in Global frame "User-Name"L, "User-Password"L, "Connect-Name"L, "Connect-Password"L, "Directory"L, "Server-Filename"L, "Device"L, "Name-Body"L, "Version"L, "Type"L, "End-of-Line-Convention"L, "Byte-Size"L, "Size"L, "Creation-Date"L, "Write-Date"L, "Read-Date"L, "Author"L, "User-Account"L, "Mailbox"L, "Sender"L, "Length"L, "Date-received"L, "Opened"L, "Deleted"L]; -- Note: bufferSize expressed in pages; zero implies default. -- increment use count and continue iff no previous usage ftpUseCount ← ftpUseCount + 1; IF ftpUseCount > 1 THEN RETURN; -- allocate and initialize system object ftpsystem ← Storage.Node[SIZE[FTPSystemObject]]; ftpsystem↑ ← FTPSystemObject[ propertyNames:, userFilesLoaded: FALSE, userMailLoaded: FALSE, serverFilesLoaded: FALSE, serverMailLoaded: FALSE, accessoriesLoaded: FALSE, bufferSize: defaultBufferSize, catchUnidentifiedErrors: TRUE]; FOR property IN Property DO ftpsystem.propertyNames[property] ← Storage.String[ strings[property].length]; String.AppendString[ftpsystem.propertyNames[property], strings[property]]; ENDLOOP; -- note presence/absence of optional modules UserFilesLoaded[]; UserMailLoaded[]; ServerFilesLoaded[]; ServerMailLoaded[]; AccessoriesLoaded[]; END; FTPFinalize: PUBLIC ENTRY PROCEDURE = BEGIN property: Property; -- Note: Assumes that all users and listeners have been destroyed -- and that all servers have destroyed themselves. -- decrement use count ftpUseCount ← ftpUseCount - 1; IF ftpUseCount > 0 THEN RETURN; FOR property IN Property DO Storage.FreeString[ftpsystem.propertyNames[property]]; ENDLOOP; -- release system object ftpsystem ← Storage.FreeNodeNil[ftpsystem]; END; FTPSetBufferSize: PUBLIC PROCEDURE [pages: CARDINAL] = BEGIN -- set buffer size ftpsystem.bufferSize ← IF pages # 0 THEN pages ELSE defaultBufferSize; END; FTPCatchUnidentifiedErrors: PUBLIC PROCEDURE [setting: BOOLEAN] = BEGIN -- catch unidentified errors ftpsystem.catchUnidentifiedErrors ← setting; END; CreateFTPer: PUBLIC PROCEDURE [ communicationPrimitives: CommunicationPrimitives, communicationSystem: CommunicationSystem] RETURNS [ftper: FTPer] = BEGIN -- allocate and initialize ftper object ftper ← Storage.Node[SIZE[FTPerObject]]; ftper↑ ← FTPerObject[ communicationPrimitives: communicationPrimitives, communicationSystem: communicationSystem, connection: NIL, totalByteCount: 0, inputString: NIL, outputString: NIL, tracing: FALSE, writeString:, directionOfLastTrace: in]; -- allocate input/output strings BEGIN ENABLE UNWIND => DestroyFTPer[ftper]; ftper.inputString ← Storage.String[maxStringLength]; ftper.outputString ← Storage.String[maxStringLength]; END; -- enable END; DestroyFTPer: PUBLIC PROCEDURE [ftper: FTPer] = BEGIN OPEN ftper; -- close connection if any IF connection # NIL THEN communicationPrimitives.CloseConnection[communicationSystem, connection]; -- release input/output strings if any IF inputString # NIL THEN Storage.FreeString[inputString]; IF outputString # NIL THEN Storage.FreeString[outputString]; -- release ftper object Storage.Free[ftper]; END; -- **********************! Error Primitives !*********************** Abort: PUBLIC PROCEDURE [ftpError: FtpError] = BEGIN -- abort with default explanation AbortWithExplanation[ftpError, NIL]; END; AbortWithExplanation: PUBLIC PROCEDURE [ftpError: FtpError, message: STRING] = BEGIN keepTheFinkyDebuggerHappy: BOOLEAN ← TRUE; defaultMessage: STRING = [maxStringLength]; IF (message = NIL OR message.length = 0) AND ftpsystem.accessoriesLoaded THEN VerbalizeFtpError[ftpError, message ← defaultMessage]; IF message.length = 0 THEN message ← NIL; IF keepTheFinkyDebuggerHappy THEN ERROR FTPError[ftpError, message]; END; END. -- FTPCold