-- Copyright (C) 1979, 1980, 1984, 1985 by Xerox Corporation. All rights reserved. -- FTPCold.mesa -- MAS May 19, 1980 6:03 PM -- HGM 18-Sep-85 2:29:09 DIRECTORY FTPDefs, FTPPrivateDefs, Heap USING [systemZone], MDSStorage USING [Node, String, Free, FreeNodeNil, FreeString], String USING [AppendString]; FTPCold: MONITOR IMPORTS Heap, MDSStorage, String, 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 ¬ MDSStorage.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] ¬ MDSStorage.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 MDSStorage.FreeString[ftpsystem.propertyNames[property]]; ENDLOOP; -- release system object ftpsystem ¬ MDSStorage.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 ¬ Heap.systemZone.NEW[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 ¬ MDSStorage.String[maxStringLength]; ftper.outputString ¬ MDSStorage.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 MDSStorage.FreeString[inputString]; IF outputString # NIL THEN MDSStorage.FreeString[outputString]; -- release ftper object Heap.systemZone.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