-- FTPDefs.mesa, Edit: HGM July 28, 1980 8:38 PM -- Copyright Xerox Corporation 1979, 1980 FTPDefs: DEFINITIONS = BEGIN -- **********************! Version !*********************** ftpMajorVersion: Byte = 6; ftpMinorVersion: Byte = 0; -- **********************! File System !*********************** -- file types FileSystem: TYPE = POINTER TO FileSystemObject; FileSystemObject: TYPE = RECORD [dummy: UNSPECIFIED]; VirtualFilename: TYPE = POINTER TO VirtualFilenameObject; VirtualFilenameObject: TYPE = RECORD [device, directory, name, version: STRING]; Status: TYPE = {primary, secondary}; Intent: TYPE = {enumeration, retrieval, deletion, renaming, unspecified}; EnumerateFilesIntent: TYPE = Intent[enumeration..deletion]; DumpFileIntent: TYPE = Intent[enumeration..retrieval]; FileInfo: TYPE = POINTER TO FileInfoObject; FileInfoObject: TYPE = RECORD [ fileType: FileType, byteSize: CARDINAL, byteCount: LONG CARDINAL, creationDate, writeDate, readDate, author: STRING]; FileType: TYPE = {text, binary, unknown}; ConcreteFileType: TYPE = FileType[text..binary]; Mode: TYPE = {read, write, append, writeThenRead, readThenWrite}; FileHandle: TYPE = POINTER TO FileHandleObject; FileHandleObject: TYPE = RECORD [dummy: UNSPECIFIED]; -- file primitives FilePrimitives: TYPE = POINTER TO FilePrimitivesObject; FilePrimitivesObject: TYPE = RECORD [ CreateFileSystem: PROCEDURE [bufferSize: CARDINAL] RETURNS [fileSystem: FileSystem], DestroyFileSystem: PROCEDURE [fileSystem: FileSystem], DecomposeFilename, ComposeFilename: PROCEDURE [ fileSystem: FileSystem, absoluteFilename: STRING, virtualFilename: VirtualFilename], InspectCredentials: PROCEDURE [ fileSystem: FileSystem, status: Status, user, password: STRING], EnumerateFiles: PROCEDURE [ fileSystem: FileSystem, files: STRING, intent: EnumerateFilesIntent, processFile: PROCEDURE [UNSPECIFIED, STRING, FileInfo], processFileData: UNSPECIFIED], OpenFile: PROCEDURE [ fileSystem: FileSystem, file: STRING, mode: Mode, fileTypePlease: BOOLEAN, info: FileInfo] RETURNS [fileHandle: FileHandle, fileType: FileType], ReadFile: PROCEDURE [fileSystem: FileSystem, fileHandle: FileHandle, sendBlock: PROCEDURE [UNSPECIFIED, POINTER, CARDINAL], sendBlockData: UNSPECIFIED], WriteFile: PROCEDURE [fileSystem: FileSystem, fileHandle: FileHandle, receiveBlock: PROCEDURE [UNSPECIFIED, POINTER, CARDINAL] RETURNS [CARDINAL], receiveBlockData: UNSPECIFIED], CloseFile: PROCEDURE [fileSystem: FileSystem, fileHandle: FileHandle, aborted: BOOLEAN], DeleteFile: PROCEDURE [fileSystem: FileSystem, file: STRING], RenameFile: PROCEDURE [fileSystem: FileSystem, currentFile, newFile: STRING]]; -- file system AltoFilePrimitives: PROCEDURE RETURNS [filePrimitives: FilePrimitives]; -- **********************! Mail System !*********************** -- mail types MailSystem: TYPE = POINTER TO MailSystemObject; MailSystemObject: TYPE = RECORD [dummy: UNSPECIFIED]; Mailbox: TYPE = POINTER TO MailboxObject; MailboxObject: TYPE = RECORD [ number: CARDINAL, mailbox, location: STRING, located, delivered: BOOLEAN, nextMailbox: Mailbox]; MessageInfo: TYPE = POINTER TO MessageInfoObject; MessageInfoObject: TYPE = RECORD [ byteCount: LONG CARDINAL, deliveryDate: STRING, opened, deleted: BOOLEAN]; -- mail primitives MailPrimitives: TYPE = POINTER TO MailPrimitivesObject; MailPrimitivesObject: TYPE = RECORD [ CreateMailSystem: PROCEDURE [filePrimitives: FilePrimitives, bufferSize: CARDINAL] RETURNS [mailSystem: MailSystem, forwardingProvided: BOOLEAN], DestroyMailSystem: PROCEDURE [mailSystem: MailSystem], InspectCredentials: PROCEDURE [ mailSystem: MailSystem, status: Status, user, password: STRING], LocateMailboxes: PROCEDURE [mailSystem: MailSystem, localMailboxList: Mailbox], StageMessage: PROCEDURE [mailSystem: MailSystem, receiveBlock: PROCEDURE [UNSPECIFIED, POINTER, CARDINAL] RETURNS [CARDINAL], receiveBlockData: UNSPECIFIED], DeliverMessage: PROCEDURE [mailSystem: MailSystem, localMailboxList: Mailbox], ForwardMessage: PROCEDURE [mailSystem: MailSystem, remoteMailboxList: Mailbox], RetrieveMessages: PROCEDURE [mailSystem: MailSystem, localMailbox: Mailbox, processMessage: PROCEDURE [MessageInfo], sendBlock: PROCEDURE [UNSPECIFIED, POINTER, CARDINAL], sendBlockData: UNSPECIFIED]]; -- mail systems SysMailPrimitives, SomeMailPrimitives: PROCEDURE RETURNS [mailPrimitives: MailPrimitives]; -- **********************! Communication System !*********************** -- communication types CommunicationSystem: TYPE = POINTER TO CommunicationSystemObject; CommunicationSystemObject: TYPE = RECORD [dummy: UNSPECIFIED]; Connection: TYPE = POINTER TO ConnectionObject; ConnectionObject: TYPE = RECORD [dummy: UNSPECIFIED]; Port: TYPE = POINTER TO PortObject; PortObject: TYPE = RECORD [dummy: UNSPECIFIED]; BytePointer: TYPE = POINTER TO BytePointerObject; BytePointerObject: TYPE = RECORD [ address: POINTER, offset: BOOLEAN, count: CARDINAL]; Byte: TYPE = [0..377B]; -- communication primitives CommunicationPrimitives: TYPE = POINTER TO CommunicationPrimitivesObject; CommunicationPrimitivesObject: TYPE = RECORD [ CreateCommunicationSystem: PROCEDURE RETURNS [communicationSystem: CommunicationSystem], DestroyCommunicationSystem: PROCEDURE [communicationSystem: CommunicationSystem], OpenConnection: PROCEDURE [communicationSystem: CommunicationSystem, remoteHost: STRING, remoteSocket: LONG CARDINAL, receiveSeconds: CARDINAL] RETURNS [connection: Connection], CloseConnection: PROCEDURE [ communicationSystem: CommunicationSystem, connection: Connection], ActivatePort: PROCEDURE [ communicationSystem: CommunicationSystem, localSocket: LONG CARDINAL, serviceConnection: PROCEDURE [UNSPECIFIED, Connection, STRING], serviceConnectionData: UNSPECIFIED, receiveSeconds: CARDINAL, filter: PROCEDURE [STRING,Purpose], purpose: Purpose ] RETURNS [port: Port], DeactivatePort: PROCEDURE [communicationSystem: CommunicationSystem, port: Port], SendBytes: PROCEDURE [communicationSystem: CommunicationSystem, connection: Connection, bytePointer: BytePointer], ReceiveBytes: PROCEDURE [communicationSystem: CommunicationSystem, connection: Connection, bytePointer: BytePointer, settleForLess: BOOLEAN], SendByte: PROCEDURE [ communicationSystem: CommunicationSystem, connection: Connection, byte: Byte], ReceiveByte: PROCEDURE [communicationSystem: CommunicationSystem, connection: Connection, settleForNone: BOOLEAN] RETURNS [byte: Byte, settledForNone: BOOLEAN], ProduceDiscontinuity, ConsumeDiscontinuity, ForceOutput: PROCEDURE [ communicationSystem: CommunicationSystem, connection: Connection]]; -- communication system PupCommunicationPrimitives: PROCEDURE RETURNS [communicationPrimitives: CommunicationPrimitives]; -- **********************! Signals !*********************** -- error FTPError: SIGNAL [ftpError: FtpError, message: STRING]; -- Note: To add a new error: -- 1) Add corresponding message to FTPAccessories.VerbalizeFtpError. -- 2) Modify error categories below as necessary. -- 3) Modify FTPProtocol.SignalToCode and CodeToSignal as necessary. -- error codes FtpError: TYPE = { -- communication errors noSuchHost, connectionTimedOut, connectionRejected, connectionClosed, noRouteToNetwork, noNameLookupResponse, -- credential errors credentialsMissing, noSuchPrimaryUser, noSuchSecondaryUser, incorrectPrimaryPassword, incorrectSecondaryPassword, requestedAccessDenied, -- file errors illegalFilename, noSuchFile, fileAlreadyExists, fileBusy, noRoomForFile, fileDataError, -- dump errors errorBlockInDumpFile, unrecognizedDumpFileBlock, dumpFileBlockTooLong, dumpFileCheckSumInError, -- mail errors noValidRecipients, noSuchMailbox, -- client errors filePrimitivesNotSpecified, mailPrimitivesNotSpecified, communicationPrimitivesNotSpecified, filesModuleNotLoaded, mailModuleNotLoaded, noConnectionEstablished, connectionAlreadyEstablished, connectionNotOpenedForFiles, connectionNotOpenedForMail, illegalProcedureCallSequence, fileGroupDesignatorUnexpected, filenameUnexpected, -- protocol errors protocolVersionMismatch, functionNotImplemented, inputDiscontinuityUnexpected, outputDiscontinuityUnexpected, illegalProtocolSequence, protocolParameterListMissing, illegalProtocolParameterList, unrecognizedProtocolParameter, missingProtocolParameter, duplicateProtocolParameter, illegalBooleanParameter, illegalFileAttribute, illegalFileType, unrecognizedProtocolErrorCode, noSuchRecipientNumber, duplicateMailboxException, unrecognizedMailboxExceptionErrorCode, missingMessageLength, messageLongerThanAdvertised, messageShorterThanAdvertised, -- internal errors, stringTooLong, queueInconsistent, unexpectedEndOfFile, -- unidentified errors unidentifiedTransientError, unidentifiedPermanentError, unidentifiedError, -- pseudo error (meaning none) ok}; -- error categories CommunicationError: TYPE = FtpError[noSuchHost..noNameLookupResponse]; CredentialError: TYPE = FtpError[credentialsMissing..requestedAccessDenied]; FileError: TYPE = FtpError[illegalFilename..fileDataError]; DumpError: TYPE = FtpError[errorBlockInDumpFile..dumpFileCheckSumInError]; MailError: TYPE = FtpError[noValidRecipients..noSuchMailbox]; ClientError: TYPE = FtpError[filePrimitivesNotSpecified..filenameUnexpected]; ProtocolError: TYPE = FtpError[protocolVersionMismatch..messageShorterThanAdvertised]; InternalError: TYPE = FtpError[stringTooLong..unexpectedEndOfFile]; UnidentifiedError: TYPE = FtpError[unidentifiedTransientError..unidentifiedError]; -- private error categories UndefinedFunctionError: PRIVATE TYPE = FtpError[protocolVersionMismatch..functionNotImplemented]; ProtocolSequenceError: PRIVATE TYPE = FtpError[inputDiscontinuityUnexpected..illegalProtocolSequence]; IllegalParameterListError: PRIVATE TYPE = FtpError[protocolParameterListMissing..illegalFileAttribute]; -- **********************! Common Procedures !*********************** -- program primitives FTPInitialize, FTPFinalize: PROCEDURE; -- parameter primitives FTPSetBufferSize: PROCEDURE [pages: CARDINAL]; FTPCatchUnidentifiedErrors: PROCEDURE [setting: BOOLEAN]; -- **********************! User (Common) Procedures !*********************** -- program primitives FTPCreateUser: PROCEDURE [ filePrimitives: FilePrimitives, communicationPrimitives: CommunicationPrimitives] RETURNS [ftpuser: FTPUser]; FTPDestroyUser: PROCEDURE [ftpuser: FTPUser]; -- connection primitives FTPSetContactSocket: PROCEDURE [ ftpuser: FTPUser, socket: LONG CARDINAL, purpose: Purpose]; FTPOpenConnection: PROCEDURE [ ftpuser: FTPUser, host: STRING, purpose: Purpose, remoteInsignia: STRING]; FTPRenewConnection, FTPCloseConnection: PROCEDURE [ftpuser: FTPUser]; -- trace primitives FTPEnableTrace: PROCEDURE [ftpuser: FTPUser, writeString: PROCEDURE [STRING]]; FTPDisableTrace: PROCEDURE [ftpuser: FTPUser]; -- access primitive FTPSetCredentials: PROCEDURE [ ftpuser: FTPUser, status: Status, user, password: STRING]; -- **********************! User (Files) Procedures !*********************** -- file enumeration primitive FTPEnumerateFiles: PROCEDURE [ftpuser: FTPUser, remoteFiles: STRING, intent: Intent, processFile: PROCEDURE [UNSPECIFIED, STRING, VirtualFilename, FileInfo], processFileData: UNSPECIFIED]; -- file manipulation primitives FTPStoreFile, FTPRetrieveFile: PROCEDURE [ ftpuser: FTPUser, localFile, remoteFile: STRING, fileType: FileType] RETURNS [byteCount: LONG CARDINAL]; FTPTransferFile: PROCEDURE [ srcFtpuser: FTPUser, srcFile: STRING, dstFtpuser: FTPUser, dstFile: STRING, fileType: FileType, transferFile: POINTER TO TransferFile, transferFileData: UNSPECIFIED] RETURNS [byteCount: LONG CARDINAL]; TransferFile: TYPE = PROCEDURE [transferFileData: UNSPECIFIED, receiveBlock: PROCEDURE [UNSPECIFIED, POINTER, CARDINAL] RETURNS [CARDINAL], receiveBlockData: UNSPECIFIED, sendBlock: PROCEDURE [UNSPECIFIED, POINTER, CARDINAL], sendBlockData: UNSPECIFIED]; FTPDeleteFile: PROCEDURE [ftpuser: FTPUser, remoteFile: STRING]; FTPRenameFile: PROCEDURE [ftpuser: FTPUser, currentFile, newFile: STRING]; -- filename primitives FTPSetFilenameDefaults: PROCEDURE [ ftpuser: FTPUser, status: Status, virtualFilename: VirtualFilename]; FTPNoteFilenameUsed: PROCEDURE [ ftpuser: FTPUser, absoluteFilename: STRING, virtualFilename: VirtualFilename]; -- **********************! User (Dump) Procedures !*********************** FTPInventoryDumpFile: PROCEDURE [ ftpuser: FTPUser, remoteDumpFile: STRING, intent: DumpFileIntent, processFile: PROCEDURE [UNSPECIFIED, STRING, VirtualFilename, FileInfo], processFileData: UNSPECIFIED]; FTPBeginDumpFile: PROCEDURE [ftpuser: FTPUser, remoteDumpFile: STRING]; FTPEndDumpFile: PROCEDURE [ftpuser: FTPUser]; -- **********************! User (Mail) Procedures !*********************** -- delivery primitives FTPBeginDeliveryOfMessage: PROCEDURE [ftpuser: FTPUser]; FTPSendRecipientOfMessage: PROCEDURE [ ftpuser: FTPUser, mailboxName: STRING, -- mailboxHostName and dmsName are going away soon mailboxHostName: STRING ← NIL, dmsName: STRING ← NIL]; FTPIdentifyNextRejectedRecipient: PROCEDURE [ftpuser: FTPUser, errorMessage: STRING] RETURNS [recipientNumber: CARDINAL, recipientError: RecipientError]; RecipientError: TYPE = {noSuchMailbox, noForwardingProvided, unspecifiedTransientError, unspecifiedPermanentError, unspecifiedError}; FTPSendBlockOfMessage: PROCEDURE [ ftpuser: FTPUser, source: POINTER, byteCount: CARDINAL]; FTPEndDeliveryOfMessage: PROCEDURE [ftpuser: FTPUser]; -- retrieval primitives FTPBeginRetrievalOfMessages: PROCEDURE [ftpuser: FTPUser, mailboxName: STRING]; FTPIdentifyNextMessage: PROCEDURE [ftpuser: FTPUser, messageInfo: MessageInfo]; FTPRetrieveBlockOfMessage: PROCEDURE [ ftpuser: FTPUser, destination: POINTER, maxWordCount: CARDINAL] RETURNS [actualByteCount: CARDINAL]; FTPEndRetrievalOfMessages: PROCEDURE [ftpuser: FTPUser]; -- **********************! Server (Common) Procedures !*********************** FTPCreateListener: PROCEDURE [purpose: Purpose, filePrimitives: FilePrimitives, mailPrimitives: MailPrimitives, communicationPrimitives: CommunicationPrimitives, backstopServer: POINTER TO BackstopServer, backstopServerData: UNSPECIFIED, filter: PROCEDURE[STRING,Purpose] ← RejectNothing] RETURNS [ftplistener: FTPListener]; RejectNothing: PROCEDURE [STRING,Purpose]; RejectThisConnection: ERROR [error: STRING]; Purpose: TYPE = {files, mail, filesAndMail}; SingularPurpose: TYPE = Purpose[files..mail]; BackstopServer: TYPE = PROCEDURE [backstopServerData: UNSPECIFIED, purpose: SingularPurpose, originOfRequest, localInsignia: STRING, server: PROCEDURE]; FTPDestroyListener: PROCEDURE [ftplistener: FTPListener, abortServers: BOOLEAN]; -- **********************! Externally Visible Objects !*********************** -- Note: The client manipulates the object handles -- but not the objects themselves. -- user state information FTPUser: TYPE = POINTER TO FTPUserObject; FTPUserObject: PRIVATE TYPE = RECORD [ filePrimitives: FilePrimitives, fileSystem: FileSystem, communicationPrimitives: CommunicationPrimitives, communicationSystem: CommunicationSystem, remoteFtpSocket, remoteMtpSocket: LONG CARDINAL, ftper, mtper: FTPer, propertyList, primaryPropertyList, secondaryPropertyList: PropertyList, purpose: Purpose, state: UserState, intent: Intent, nextBlockType: Byte, numberOfRecipients, numberOfValidRecipients: CARDINAL, numberOfBytesExpected, numberOfBytesReceived: LONG CARDINAL]; UserState: PRIVATE TYPE = {unconnected, connected, enumeratingFiles, inventoryingDumpFile, dumpFileBeingSent, messageRecipientsBeingSent, initialMailboxExceptionsBeingReceived, messageTextBeingSent, finalMailboxExceptionsBeingReceived, messageDelivered, messageHeaderPending, messageTextPending, mailboxExhausted}; -- listener state information FTPListener: TYPE = POINTER TO FTPListenerObject; FTPListenerObject: PRIVATE TYPE = RECORD [ filePrimitives: FilePrimitives, mailPrimitives: MailPrimitives, communicationPrimitives: CommunicationPrimitives, communicationSystem: CommunicationSystem, backstopServer: BackstopServer, backstopServerData: UNSPECIFIED, ftpCharterObject, mtpCharterObject: CharterObject, ftpPort, mtpPort: Port, serverQueueObject: QueueObject]; -- **********************! Externally Invisible Objects !*********************** -- Note: These objects are declared here because they or their handles -- appear in the externally visible objects declared above. -- connection state information FTPer: PRIVATE TYPE = POINTER TO FTPerObject; FTPerObject: PRIVATE TYPE = RECORD [ communicationPrimitives: CommunicationPrimitives, communicationSystem: CommunicationSystem, connection: Connection, totalByteCount: LONG CARDINAL, inputString, outputString: STRING, tracing: BOOLEAN, writeString: PROCEDURE [STRING], directionOfLastTrace: TraceDirection]; TraceDirection: PRIVATE TYPE = {in, out}; -- property list PropertyList: PRIVATE TYPE = DESCRIPTOR FOR ARRAY Property OF STRING; PropertyListObject: PRIVATE TYPE = ARRAY Property OF STRING; Property: PRIVATE TYPE = {userName, userPassword, connectName, connectPassword, directory, serverFilename, device, nameBody, version, type, endOfLineConvention, byteSize, size, creationDate, writeDate, readDate, author, userAccount, mailbox, sender, length, dateReceived, opened, deleted}; FileProperty: PRIVATE TYPE = Property[directory..author]; -- server charter Charter: PRIVATE TYPE = POINTER TO CharterObject; CharterObject: PRIVATE TYPE = RECORD [ ftplistener: FTPListener, purpose: SingularPurpose]; -- queue and queue element Queue: PRIVATE TYPE = POINTER TO QueueObject; QueueObject: PRIVATE TYPE = MONITORED RECORD [ head, tail: Element, elementCount: CARDINAL, identifiersCoincide: IdentifiersCoincide, elementDequeued, elementUnlocked: CONDITION]; IdentifiersCoincide: PRIVATE TYPE = PROCEDURE [UNSPECIFIED, UNSPECIFIED] RETURNS [BOOLEAN]; Element: PRIVATE TYPE = POINTER TO ElementObject; ElementObject: PRIVATE TYPE = RECORD [ previous, next: Element, identifier: UNSPECIFIED, allocated, locked, exclusive: BOOLEAN]; END. -- of FTPDefs