Heading:
Mesa FTP Functional Specification
Page Numbers: Yes X: 527 Y: 10.5" First Page: 1
1. Introduction
1.1. Purpose
The File Transfer Package (FTP) is one means of several for accessing and manipulating remote files via the network. FTP provides primitives for storing, retrieving, deleting, renaming, and enumerating remote files. FTP trades in whole files, in contrast to a page-level access package, for example, which trades in smaller units (that is, pages of files), or CopyDisk, which trades in larger ones (that is, an entire disk).
FTP provides an interface to Alto, Maxc, IFS, and Juniper file systems, and any others that implement the long-standing File Transfer Protocol (FTP) described in [1].
In addition to providing file-related services, FTP provides primitives for delivering mail to and retrieving mail from remote mailboxes. FTP is thus also a means for accessing mailboxes on Maxc and any other host that implements the Mail Transfer Protocol (MTP) described in [2, 3].
1.2. Program Structure
Every FTP dialogue involves two parties, designated user and server, which are linked by a network connection. In point of fact, file and mail operations are implemented by separate servers and hence a dialogue in which operations of both types are carried out actually involves three parties: the local user, the remote file server, and the remote mail server. The FTP implementation, however, disguises the distinction between the two servers and presents to the client the illusion of a single server capable of handling both types of requests. At one end, a client program initiates and controls the dialogue by calling procedures provided by a local FTP User. At the other end, a passive FTP Server responds and replies to requests it receives from the distant FTP User. Several Servers can coexist within a single host, and hence several independent file transfers can proceed concurrently.
FTP Servers are created by one or more resident FTP Listeners in response to connection requests from distant FTP Users. Each Server is spawned as a separate Mesa process and competes for system resources with other local processes under the control of the scheduler. When the distant FTP User terminates its dialogue with the local FTP Server, the Server destroys itself.
The remainder of this document describes the client’s interface to the FTP User and Listener; the FTP Server has no real external interface. In the procedure descriptions presented throughout this document, the terms local and remote distinguish the host containing the described procedure from the distant host to which the first host is connected.
1.3. File Naming Conventions
FTP provides the client with two separate mechanisms for designating remote files: absolute filenames, which must conform to the file naming conventions of the remote file system; and virtual filenames, having a host-independent structure, which are mapped into absolute filenames by the remote file system. The purpose of this two fold scheme is, on the one hand, to permit the exact specification of remote filenames by human users familiar with remote file naming conventions and, on the other, to permit the mechanical generation of filenames by clients ignorant of such conventions.
Absolute filenames are STRINGs. Any internal structure an absolute filename might possess is indicated by delimiters embedded in the STRING. Virtual filenames, on the other hand, have four components--device, directory, name, and version--each of which is a STRING:
VirtualFilename: TYPE = POINTER TO VirtualFilenameObject;
VirtualFilenameObject: TYPE = RECORD [device, directory, name, version: STRING];
As part of its mapping operation, the remote file system combines these components to form a legal absolute filename (using appropriate field delimiters where necessary). The Maxc file system maps the device, directory, and version components of a virtual filename into the corresponding Tenex filename fields and maps the name component into the name and extension fields. The Alto file system ignores the device and directory components, maps the name component into the name and extension fields, and maps the version component into the corresponding Alto filename field. IFS ignores the device component, maps the directory component into the directory and subdirectory fields, and maps the name and version components into the corresponding IFS filename fields.
The client may use either or both of the file naming schemes outlined above, or a combination of the two. Whenever the local FTP User communicates a remote filename to the remote FTP Server, it sends both an absolute filename and a virtual filename. The absolute filename is that supplied by the client as a parameter to the FTP User procedure which initiates the exchange. The virtual filename is that supplied by the client in a previous call to the FTPSetFilenameDefaults procedure described in Section 3.3. If all components of the virtual filename are NIL (for example, if FTPSetFilenameDefaults is never called), the remote file is completely specified by the absolute filename. If the absolute filename is NIL, the remote file is completely specified by the virtual filename. If both the absolute and virtual filenames are non-NIL, the remote FTP Server has the option of using the virtual filename to default unspecified fields in the absolute filename.
The term file group designator denotes a filename, either absolute or virtual or both, which names a group of files, rather than a single file. File group designators often contain special characters that indicate wild or unspecified portions of the filename. The Maxc file system recognizes as a legitimate value for the device, directory, name, extension, and/or version field, the special character, asterisk (’*), denoting an arbitrary field value. The Alto file system recognizes the two special characters, asterisk (’*), denoting zero or more arbitrary characters, and pound sign (’#), denoting exactly one arbitrary character. IFS recognizes the special character, asterisk (’*), denoting zero or more arbitrary characters.
1.4. Exception Handling
Exceptional conditions encountered by FTP are reported to the client by means of a single signal, FTPError. In rare circumstances, the Mesa Runtime System may generate errors or signals that are neither handled by FTP nor reissued as FTPErrors. This fact complicates the client implementation in theory but typically not in practice. Although declared as a SIGNAL, FTPError is generally raised as an ERROR and so cannot be resumed by the client. However, exceptional conditions reported to a server backstop are issued as SIGNALs and can be resumed by the client, as described in Section 4.2. FTP restores itself to a consistent state after every error (in response to the UNWIND signal). Therefore if the client’s connection is timed out by the remote FTP Server, for example, the client can close and then reopen the connection without first having to destroy and recreate the local FTP User. Warning: don’t call FTP again from within a catch phrase.
FTPError has two parameters that pinpoint the exceptional condition encountered by FTP: an enumerated type, ftpError, to be interpreted by the client; and a STRING, message, to be interpreted by the human user. All error messages issued by FTP are centralized in a single FTPAccessories module (see Appendix I). To avoid incurring the space overhead associated with such strings, the programmer can omit this module from his configuration, causing FTP to supply a NIL whenever it would otherwise obtain a message from FTPAccessories.
Exceptional conditions reported via FTPError include not only those explicitly detected by FTP but also those that originate as signals within the local file, mail, or communication system. Furthermore, many of the errors reported by a local FTP User are actually detected by the remote FTP Server. In such cases, the User relays to the client the message supplied by the Server. If the Server provides no message, the User supplies the appropriate message from FTPAccessories in its place. Regardless of source, message STRINGs presented to the client may be assumed to remain intact only until the signal is unwound.
The errors that FTP may report to the client are summarized below and are explained in detail in Appendix A. The most prominent exceptional conditions which may be encounted by particular procedures are also listed with the descriptions of those procedures throughout this document. The errors classed below as protocol, internal, or unidentified errors theoretically can be generated by nearly every procedure. Because they are so pervasive in principle and rare in practice, such errors are excluded from the descriptions of the individual procedures to which they nevertheless apply:
FTPError: SIGNAL [ftpError: FtpError, message: STRING];
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, noSuchForwardingHost, noSuchDmsName,
-- 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};
CommunicationError: TYPE = FtpError[noSuchHost..noNameLookupResponse];
CredentialError: TYPE = FtpError[credentialsMissing..requestedAccessDenied];
FileError: TYPE = FtpError[illegalFilename..fileDataError];
DumpError: TYPE = FtpError[errorBlockInDumpFile..dumpFileCheckSumInError];
MailError: TYPE = FtpError[noValidRecipients..noSuchDmsName];
ClientError: TYPE = FtpError[filePrimitivesNotSpecified..filenameUnexpected];
ProtocolError: TYPE = FtpError[protocolVersionMismatch..messageShorterThanAdvertised];
InternalError: TYPE = FtpError[stringTooLong..unexpectedEndOfFile];
UnidentifiedError: TYPE = FtpError[unidentifiedTransientError..unidentifiedError];
2. FTP
2.1. Program Management Primitives
FTP provides two procedures for controlling its overall operation. The first, FTPInitialize, initializes FTP for operation by preparing the necessary internal data structures. The client must call this procedure before calling any other FTP procedures. Redundant calls simply increment a use count:
FTPInitialize: PROCEDURE;
The second procedure, FTPFinalize, finalizes FTP’s operation by disposing of FTP’s internal data structures after the client has destroyed any Users and Listener it created. The client must call no other FTP procedures (except FTPInitialize) once this procedure has been invoked. Calls corresponding to redundant calls to FTPInitialize simply decrement the use count:
FTPFinalize: PROCEDURE;
3. FTP User
3.1. Program Management Primitives
FTP provides two procedures for controlling local FTP Users, several of which can coexist within a single host. The first procedure, FTPCreateUser, creates a new FTP User founded upon the specified file and communication systems; the FTP User will access those systems solely by means of the specified filePrimitives and communicationPrimitives, respectively. The procedure returns a handle, ftpuser, to the newly created FTP User, which the client must retain and later present to any of the other procedures described in this section it invokes. The ftpuser is a pointer to a private record containing all of the state information the FTP User requires to function properly:
FTPCreateUser: PROCEDURE [filePrimitives: FilePrimitives, communicationPrimitives: CommunicationPrimitives] RETURNS [ftpuser: FTPUser];
FilePrimitives: TYPE = POINTER TO FilePrimitivesObject;
FilePrimitivesObject: TYPE = RECORD [...];
CommunicationPrimitives: TYPE = POINTER TO CommunicationPrimitivesObject;
CommunicationPrimitivesObject: TYPE = RECORD [...];
FTPUser: TYPE = POINTER TO FTPUserObject;
FTPUserObject: PRIVATE TYPE = RECORD[...];
Exceptions: communicationPrimitivesNotSpecified.
The filePrimitives parameter supplied by the client is a pointer to a public record containing descriptors for all of the procedures an FTP User requires to manipulate the local file system. An implementation for the Alto file system is provided as part of FTP, as described in Section 5.1. The client is also free to supply its own file primitives. The reader is referred to Appendix E for detailed motivation for and instruction in the use of this option.
The communicationPrimitives parameter supplied by the client is a pointer to a public record containing descriptors for all of the procedures an FTP User requires to manipulate the local communication system. An implementation for the Pup communication system is provided as part of FTP, as described in Section 5.3. The client is also free to supply its own communication primitives. The reader is referred to Appendix G for detailed motivation for and instruction in the use of this option.
The second procedure, FTPDestroyUser, destroys a previously created FTP User, reclaiming any local resources allocated to it and, if necessary, closing its connection to the remote FTP Server (which may involve a delay as control messages are exchanged via the network):
FTPDestroyUser: PROCEDURE [ftpuser: FTPUser];
FTPUser: TYPE = POINTER TO FTPUserObject;
FTPUserObject: PRIVATE TYPE = RECORD[...];
3.2. Connection Management Primitives
FTP provides three procedures for controlling communication with remote FTP Servers. The first, FTPOpenConnection, establishes a connection to an FTP Server at the designated host for the purpose of manipulating either remote files, mail, or filesAndMail. A single FTP User can support only one open connection at a time. The FTP User makes contact with the appropriate server(s) based upon the client’s stated purpose. Unless remoteInsignia is NIL, the procedure returns the insignia of the remote FTP Server. An insignia is textual information (for example, the Server’s host name, version number, and date of installation) which the client may wish to present to its human user. File and mail servers supply separate insignias. If purpose is filesAndMail, FTP concatenates the two (separated by a carriage return), unless the two insignias are identical, in which case it returns just one of them:
FTPOpenConnection: PROCEDURE [ftpuser: FTPUser, host: STRING, purpose: Purpose, remoteInsignia: STRING];
Purpose: TYPE = {files, mail, filesAndMail};
Exceptions: noSuchHost, connectionTimedOut, connectionRejected, connectionClosed, noRouteToNetwork, noNameLookupResponse, filePrimitivesNotSpecified, filesModuleNotLoaded, mailModuleNotLoaded, connectionAlreadyEstablished.
The second procedure, FTPRenewConnection, prevents a previously established but long inactive connection from being timed out and broken by the remote FTP Server. A Mesa FTP Server, for example, will break its connection to a remote FTP User after three minutes of inactivity. To preserve its connection, the client must punctuate such idle periods with calls to FTPRenewConnection (which may be invoked at any time, except during a remote file enumeration or dump file inventory, or during mail delivery or retrieval). Because file and mail operations are implemented by different servers, the client’s connection to one can be timed out because of inactivity while its connection to the other remains intact. To avoid such anomalies, the client must take care to exercise each connection with the required frequency:
FTPRenewConnection: PROCEDURE [ftpuser: FTPUser];
Exceptions: connectionTimedOut, connectionClosed, noRouteToNetwork, noConnectionEstablished, illegalProcedureCallSequence.
The third procedure, FTPCloseConnection, breaks a previously established connection to a remote FTP Server. Redundant calls are treated as no operations:
FTPCloseConnection: PROCEDURE [ftpuser: FTPUser];
The three connection management procedures described above block the client until the connection to the remote FTP Server has been established, renewed, or broken, respectively (which may involve a delay as control messages are exchanged via the network).
3.3. File Access and Specification Primitives
FTP provides two procedures for obtaining access to remote files and for assisting in the formulation of remote filenames. The first, FTPSetCredentials, specifies the primary or secondary credentials--user and password--that are implicitly to be employed in all subsequent procedure calls that attempt to access a remote file or mailbox. The credentials (that is, the contents of the STRINGs) are saved by FTPSetCredentials and transmitted to the remote FTP Server for inspection only when access to the remote file system is actually attempted. Primary credentials typically identify the user upon whose behalf the access is attempted (a la the Tenex Login command) while secondary credentials, when necessary, usually identify another area of the file system--in addition to the user’s own workspace--to which the user claims access (a la the Tenex Connect command). By setting both user and password to NIL, the client effectively retracts any previously specified credentials:
FTPSetCredentials: PROCEDURE [ftpuser: FTPUser, status: Status, user, password: STRING];
Status: TYPE = {primary, secondary};
The second procedure, FTPSetFilenameDefaults, specifies the primary or secondary virtualFilename that is implicitly to be employed (in combination with an explicitly specified primary or secondary absolute filename) in all subsequent procedure calls that attempt to manipulate a remote file. The reader is referred to Section 1.3 for a discussion of virtual filenames and their use. The virtual filename (that is, the contents of the RECORD and STRINGs) is saved by FTPSetFilenameDefaults and transmitted to the remote FTP Server for interpretation only when access to the remote file system is actually attempted. In this context, the adjectives primary and secondary refer to the first and second remote filenames in a procedure’s argument list. To rename a file, for example, the client must, in general, specify two virtual filenames, one (primary) specifying the file to be renamed, the other (secondary) its new name. By setting one or more components of the virtualFilename to NIL, the client effectively declines to specify, or retracts previously specified component value(s):
FTPSetFilenameDefaults: PROCEDURE [ftpuser: FTPUser, status: Status, virtualFilename: VirtualFilename];
Status: TYPE = {primary, secondary};
VirtualFilename: TYPE = POINTER TO VirtualFilenameObject;
VirtualFilenameObject: TYPE = RECORD [device, directory, name, version: STRING];
3.4. File Enumeration Primitives
FTP provides one procedure, FTPEnumerateFiles, for enumerating the members of a remote file group. For each file in the group whose file group designator, remoteFiles, is specified, the procedure supplies to a client-provided procedure, processFile, the client’s processFileData, the file’s absolute and virtual filenames, and a variety of other file information (FileInfo). The information provided in FileInfo is only as reliable as the remote file server. Bravo and/or the Alto file system are notoriously unreliable about file lengths (byteCount). The order in which filenames are presented to the client is host-dependent; alphabetical order is typical. The reader is referred to Section 1.3 for a discussion of virtual filenames and their use. Unknown or unspecified file information is rendered as unknown, zero, or NIL, as appropriate:
FTPEnumerateFiles: PROCEDURE [ftpuser: FTPUser, remoteFiles: STRING, intent: Intent,
processFile:
PROCEDURE [UNSPECIFIED, STRING, VirtualFilename, FileInfo],
processFileData:
UNSPECIFIED];
Intent: TYPE = {enumeration, retrieval, deletion, renaming, unspecified};
VirtualFilename: TYPE = POINTER TO VirtualFilenameObject;
VirtualFilenameObject: TYPE = RECORD [device, directory, name, version: STRING];
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};
Exceptions: connectionTimedOut, connectionClosed, noRouteToNetwork, credentialsMissing, noSuchPrimaryUser, noSuchSecondaryUser, incorrectPrimaryPassword, incorrectSecondaryPassword, requestedAccessDenied, illegalFilename, noSuchFile, noRoomForFile, fileDataError, noConnectionEstablished, connectionNotOpenedForFiles, illegalProcedureCallSequence.
The intent parameter supplied by the client declares the manner in which the client expects to manipulate the files whose names are presented to it. This information enables the FTP User to select intelligently from among several possible protocol strategies for effecting the enumeration. Since most such strategies occupy the remote FTP Server until the enumeration is complete, FTP prohibits processFile from calling local FTP User procedures, other than those implied by intent, that communicate with the remote Server. The client may specify any of the following intents:
1. An intent of enumeration declares that the client simply seeks the names of (and file information for) the members of the designated file group (for presentation to a human user, for example) and intends to manipulate the files in no other way during the course of the enumeration. More specifically, the client declares (and FTP insures) that processFile will make no calls to local FTP User procedures that communicate with the remote FTP Server.
2. An intent of retrieval declares that the client seeks to retrieve some or all (but possibly none) of the designated files and to manipulate them in no other way during the course of the enumeration. The client’s processFile procedure may retrieve the file whose name is presented to it by supplying that name to the FTPRetrieveFile procedure described in Section 3.5. More specifically, then, the client declares (and FTP insures) that processFile will make no calls to local FTP User procedures (other than FTPRetrieveFile) that communicate with the remote FTP Server.
3. An intent of deletion declares that the client seeks to delete some or all (but possibly none) of the designated files and to manipulate them in no other way during the course of the enumeration. The client’s processFile procedure may delete the file whose name is presented to it by supplying that name to the FTPDeleteFile procedure described in Section 3.6. More specifically, then, the client declares (and FTP insures) that processFile will make no calls to local FTP User procedures (other than FTPDeleteFile) that communicate with the remote FTP Server.
4. An intent of renaming declares that the client seeks to rename some or all (but possibly none) of the designated files and to manipulate them in no other way during the course of the enumeration. The client’s processFile procedure may rename the file whose name is presented to it by supplying that name to the FTPRenameFile procedure described in Section 3.6. More specifically, then, the client declares (and FTP insures) that processFile will make no calls to local FTP User procedures (other than FTPRenameFile) that communicate with the remote FTP Server. In point of fact, renaming is currently a synonym for unspecified (described below), and all filenames are spooled onto a local scratch file before any are presented to the client.
5. An intent of unspecified declares that the client seeks unconstrained access to the designated files. The client’s processFile procedure may retrieve, delete, or rename the file whose name is presented to it (or any other file, for that matter) by calling the appropriate FTP User procedure. More specifically, processFile may make calls to any local FTP User procedures it chooses, since FTP will have spooled all of the filenames onto a local scratch file (which FTP promptly deletes once it has served its purpose) before any are presented to the client.
3.5. File Transfer Primitives
FTP provides two procedures for transferring files between the local and remote file systems. The first, FTPStoreFile, stores in the remote file system a copy of the localFile the name of which and fileType--text or binary--are specified, creating a new remoteFile with the indicated name and returning its size in bytes, byteCount. The fileType parameter supplied by the client is used by the remote FTP Server in determining how to store the file in its file system (for example, on Maxc, text files are stored as 7-bit bytes, binary files as 8-bit bytes). The client may report the file’s type as unknown, in which case the local FTP User will attempt to determine it. The reader is referred to the discussion of the OpenFile procedure in Appendix E for a description of the algorithm used in making this determination:
FTPStoreFile: PROCEDURE [ftpuser: FTPUser, localFile, remoteFile: STRING, fileType: FileType] RETURNS [byteCount: LONG CARDINAL];
FileType: TYPE = {text, binary, unknown};
Exceptions: connectionTimedOut, connectionClosed, noRouteToNetwork, credentialsMissing, noSuchPrimaryUser, noSuchSecondaryUser, incorrectPrimaryPassword, incorrectSecondaryPassword, requestedAccessDenied, illegalFilename, noSuchFile, fileAlreadyExists, fileBusy, noRoomForFile, fileDataError, noConnectionEstablished, connectionNotOpenedForFiles, illegalProcedureCallSequence, filenameUnexpected.
Once the file has been stored, the client may invoke the FTPNoteFilenameUsed primitive described in Appendix D to determine the fully qualified absolute and/or virtual filename used by the remote FTP Server. The client can effect the remote storage of a whole group of local files by using FTPStoreFile (to store a single file) in conjunction with the EnumerateFiles procedure described in Appendix E (to enumerate the files to be stored). The FTPStoreFile procedure has yet another use in connection with the construction of remote dump files, as described in Appendix B.
The second procedure, FTPRetrieveFile, stores in the local file system a copy of the remoteFile whose name and fileType--text or binary--are specified, creating a new localFile with the indicated name and returning its size in bytes, byteCount. In rare cases, the fileType parameter supplied by the client is used by the remote FTP Server to disambiguate between two like-named files of different types. The client may (and often does) report the file’s type as unknown, in which case the remote FTP Server must select a file without it:
FTPRetrieveFile: PROCEDURE [ftpuser: FTPUser, localFile, remoteFile: STRING, fileType: FileType] RETURNS [byteCount: LONG CARDINAL];
FileType: TYPE = {text, binary, unknown};
Exceptions: connectionTimedOut, connectionClosed, noRouteToNetwork, credentialsMissing, noSuchPrimaryUser, noSuchSecondaryUser, incorrectPrimaryPassword, incorrectSecondaryPassword, requestedAccessDenied, illegalFilename, noSuchFile, fileBusy, noRoomForFile, fileDataError, errorBlockInDumpFile, unrecognizedDumpFileBlock, dumpFileBlockTooLong, dumpFileCheckSumInError, noConnectionEstablished, connectionNotOpenedForFiles, illegalProcedureCallSequence, fileGroupDesignatorUnexpected, filenameUnexpected.
Once the file has been retrieved, the client may invoke the FTPNoteFilenameUsed primitive described in Appendix D.3 to determine the fully qualified absolute and/or virtual filename used by the remote FTP Server. The client can effect the local storage of a whole group of remote files by using FTPRetrieveFile (to retrieve a single file) in conjunction with the FTPEnumerateFiles procedure described in Section 3.4 (to enumerate the files to be retrieved). The FTPRetrieveFile procedure has yet another use in connection with the loading of remote dump files, as described in Appendix B.
3.6. File Manipulation Primitives
FTP provides two procedures for manipulating existing remote files. The first, FTPDeleteFile, deletes the specified remoteFile, reclaiming the space it occupied on secondary storage:
FTPDeleteFile: PROCEDURE [ftpuser: FTPUser, remoteFile: STRING];
Exceptions: connectionTimedOut, connectionClosed, noRouteToNetwork, credentialsMissing, noSuchPrimaryUser, noSuchSecondaryUser, incorrectPrimaryPassword, incorrectSecondaryPassword, requestedAccessDenied, illegalFilename, noSuchFile, fileBusy, fileDataError, noConnectionEstablished, connectionNotOpenedForFiles, illegalProcedureCallSequence, fileGroupDesignatorUnexpected, filenameUnexpected.
Once the file has been deleted, the client may invoke the FTPNoteFilenameUsed primitive described in Appendix D to determine the fully qualified absolute and/or virtual filename used by the remote FTP Server. The client can effect the deletion of a whole group of remote files by using FTPDeleteFile (to delete a single file) in conjunction with the FTPEnumerateFiles procedure described in Section 3.4 (to enumerate the files to be deleted).
The second procedure, FTPRenameFile, renames the remote file the current name for which is specified by currentFile, assigning it the new remote name specified by newFile:
FTPRenameFile: PROCEDURE [ftpuser: FTPUser, currentFile, newFile: STRING];
Exceptions: connectionTimedOut, connectionClosed, noRouteToNetwork, credentialsMissing, noSuchPrimaryUser, noSuchSecondaryUser, incorrectPrimaryPassword, incorrectSecondaryPassword, requestedAccessDenied, illegalFilename, noSuchFile, fileAlreadyExists, fileBusy, noRoomForFile, fileDataError, noConnectionEstablished, connectionNotOpenedForFiles, illegalProcedureCallSequence, filenameUnexpected.
The client can effect the renaming of a whole group of remote files by using FTPRenameFile (to rename a single file) in conjunction with the FTPEnumerateFiles procedure described in Section 3.4 (to enumerate the files to be renamed).
4. FTP Listener
4.1. Program Management Primitives
FTP provides two procedures for controlling local FTP Listeners, several of which can coexist within a single host. The first procedure, FTPCreateListener, creates a new FTP Listener for the purpose of allowing remote manipulation of either local files, mail, or filesAndMail. The FTP Listener monitors the appropriate well-known socket(s) based upon the client’s stated purpose. The newly created FTP Listener and any FTP Servers it creates are founded upon the specified file, mail, and communication systems and will access those systems solely by means of the specified filePrimitives, mailPrimitives, and communicationPrimitives, respectively. A Server is destroyed when the User breaks its connection to it or after four minutes of inactivity. The procedure returns a handle, ftplistener, to the newly created FTP Listener, which the client must retain and later present to the FTPDestroyListener procedure described below. The ftplistener is a pointer to a private record containing all of the state information the FTP Listener requires to function properly:
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};
FilePrimitives: TYPE = POINTER TO FilePrimitivesObject;
FilePrimitivesObject: TYPE = RECORD [...];
MailPrimitives: TYPE = POINTER TO MailPrimitivesObject;
MailPrimitivesObject: TYPE = RECORD [...];
CommunicationPrimitives: TYPE = POINTER TO CommunicationPrimitivesObject;
CommunicationPrimitivesObject: TYPE = RECORD [...];
BackstopServer: TYPE = PROCEDURE [backstopServerData: UNSPECIFIED, purpose: SingularPurpose, originOfRequest, localInsignia: STRING, server: PROCEDURE];
SingularPurpose: TYPE = Purpose[files..mail];
FTPListener: TYPE = POINTER TO FTPListenerObject;
FTPListenerObject: PRIVATE TYPE = RECORD[...];
Exceptions: filePrimitivesNotSpecified, mailPrimitivesNotSpecified, communicationPrimitivesNotSpecified, filesModuleNotLoaded, mailModuleNotLoaded.
The filePrimitives parameter supplied by the client is a pointer to a public record containing descriptors for all of the procedures an FTP User requires to manipulate the local file system. An implementation for the Alto file system is provided as part of FTP, as described in Section 5.1. The client is also free to supply its own file primitives. The reader is referred to Appendix E for detailed motivation for and instruction in the use of this option.
The mailPrimitives parameter supplied by the client is a pointer to a public record containing descriptors for all of the procedures an FTP Server requires to manipulate the local mail system. A primitive set for a simple-minded mail system based upon the file primitives specified by the client are provided as part of the FTP implementation, as described in Section 5.2. The client is also free to supply its own mail primitives. The reader is referred to Appendix F for detailed motivation for and instruction in the use of this option.
The communicationPrimitives parameter supplied by the client is a pointer to a public record containing descriptors for all of the procedures an FTP User requires to manipulate the local communication system. An implementation for the Pup communication system is provided as part of FTP, as described in Section 5.3. The client is also free to supply its own communication primitives. The reader is referred to Appendix G for detailed motivation for and instruction in the use of this option.
The backstopServer and backstopServerData parameters optionally supplied (rather then set to NIL) enable the client to monitor the creation, execution, and destruction of FTP Servers. The reader is referred to Section 4.2 for detailed motivation for and instruction in the use of this option.
An optional filter procedure may be used to reject undesired connections. This is useful to keep a server from crashing because it runs out of resources. (The default doesn’t reject anything.) To reject a connection, filter should raise the ERROR RejectThisConnection. The text will be be returned to the machine attempting to establish the connection. If a connection is rejected, backstopServer is never called. If filter returns the connection will be accepted.
The second procedure, FTPDestroyListener, destroys a previously created FTP Listener, either destroying any of its Servers that remain in existence or waiting for them to terminate normally, as directed by abortServers, and reclaiming any local resources allocated to it. Destroying an FTP Server requires closing its connection to the remote FTP User (which may involve a delay as control messages are exchanged via the network):
FTPDestroyListener: PROCEDURE [ftplistener: FTPListener, abortServers: BOOLEAN];
FTPListener: TYPE = POINTER TO FTPListenerObject;
FTPListenerObject: PRIVATE TYPE = RECORD[...];
4.2. Server Monitoring
At least in principle, an FTP Listener is a process that creates local FTP Servers in response to connection requests from remote FTP Users. Each FTP Server is also a process. When a remote FTP User terminates its dialogue with a local FTP Server, the latter destroys itself. In the absence of more specific instructions from the client, this background activity continues, unattended and unobserved, until the client orders its termination via a call to FTPDestroyListener.
If it wishes, however, the client can monitor or, to a limited extent, influence the activity of local FTP Servers by supplying to FTPCreateListener a server backstop procedure to sit directly above each FTP Server in its thread of control. By means of such a procedure, a client can, for example:
1. dictate the handling of exceptional conditions encountered by an FTP Server.
2. control access to the local file or mail system on a per-host or per-network basis.
3. maintain a log of Listener/Server activity.
The client’s server backstop is called upon to oversee the execution of each new FTP Server. As parameters, it receives the backstopServerData supplied by the client in its call to FTPCreateListener; the purpose--either files or mail (never filesAndMail)--for which the new FTP Server is being created; the remote host, originOfRequest, on which the requesting FTP User resides; the localInsignia of the FTP Server, which the remote FTP User will return to its client via FTPOpenConnection; and a procedure, server, that represents the top-most level of the FTP Server itself:
BackstopServer: TYPE = PROCEDURE [backstopServerData: UNSPECIFIED, purpose: SingularPurpose, originOfRequest, localInsignia: STRING, server: PROCEDURE];
The server backstop is called immediately prior to the birth of each new FTP Server. It should initiate the server by calling it. Before doing so, it may modify or replace the localInsignia to be returned to the remote client. The insignia is textual information (for example, the Server’s host name, version number, and date of installation) which the remote client may wish to present to its human user.
The server backstop sits immediately atop the server throughout its lifetime and, therefore, by means of an appropriate catchphrase, can note and/or influence the processing of each FTPError encountered by the server. If the backstop RESUMEs such a SIGNAL, the server will abort the transaction that provoked the error, report the error to the remote FTP User, and await the initiation of another transaction. Before resuming the signal, the backstop may override (by modification) the message that will otherwise be reported to the remote FTP User. If the backstop CONTINUEs the signal and returns to its caller, the server will terminate the remote FTP User’s session, the connection will be closed, and the local FTP Server destroyed.
When the session is voluntarily terminated by the remote FTP User, the server will return to the server backstop. At that point, the backstop should return to its caller, and the local FTP Server will be destroyed.
The default server backstop provided by FTP simply catches and dispatches FTPErrors. It CONTINUEs the first CommunicationError or ProtocolError. Unless the catching of unidentified errors has been disabled via FTPCatchUnidentifiedErrors, it also CONTINUEs the first UnidentifiedError. All other errors it RESUMEs.
Notice that the interfaces do not provide any convient way for the client provided file system to interact with a particular instance of a server. For example, it is difficult for discover the address of the remote client so that it may be included in an error message. One possible solution to this problem is to provide a backstop procedure, and call it via the SIGNALing mechanisim. This requires catching of unidentified errors to be disabled.
5. FTP Support Systems
5.1. File Primitives
FTP provides a procedure for obtaining a file primitive set of the sort required by FTPCreateUser and FTPCreateListener. AltoFilePrimitives, returns a pointer to a public record containing descriptors for all of the procedures that an FTP User or Server requires to manipulate the standard Alto file system. It, along with the file primitive set to which it provides access, is implemented as a separate module(s), which must be bound together as described in Appendix I:
AltoFilePrimitives: PROCEDURE RETURNS [filePrimitives: FilePrimitives];
FilePrimitives: TYPE = POINTER TO FilePrimitivesObject;
FilePrimitivesObject: TYPE = RECORD [...];
Alternatively, the client can provide its own local file system interface by constructing the record of procedure descriptors it supplies to FTPCreateUser and/or FTPCreateListener. The reader is referred to Appendix E for detailed motivation for and instruction in the use of this option.
5.2. Mail Primitives
FTP provides one procedure, SysMailPrimitives (alias SomeMailPrimitives), for obtaining mail primitive sets of the sort required by FTPCreateListener. SysMailPrimitives returns a pointer to a public record containing descriptors for all of the procedures that an FTP Server requires to manipulate a simple-minded mail system implemented by means of the file primitives supplied by the client:
SysMailPrimitives, SomeMailPrimitives: PROCEDURE RETURNS [mailPrimitives: MailPrimitives];
MailPrimitives: TYPE = POINTER TO MailPrimitivesObject;
MailPrimitivesObject: TYPE = RECORD [...];
Alternatively, the client can provide its own local mail system interface by constructing the record of procedure descriptors it supplies to FTPCreateListener. The reader is referred to Appendix F for detailed motivation for and instruction in the use of this option.
5.3. Communication Primitives
FTP provides a procedure for obtaining a communication primitive set of the sort required by FTPCreateUser and FTPCreateListener. PupCommunicationPrimitives, returns a pointer to a public record containing descriptors for all of the procedures that an FTP User, Listener, or Server requires to manipulate the standard Pup communication system:
PupCommunicationPrimitives: PROCEDURE RETURNS [communicationPrimitives: CommunicationPrimitives];
CommunicationPrimitives: TYPE = POINTER TO CommunicationPrimitivesObject;
CommunicationPrimitivesObject: TYPE = RECORD [...];
Alternatively, the client can provide its own local communication system interface by constructing the record of procedure descriptors it supplies to FTPCreateUser and/or FTPCreateListener. The reader is referred to Appendix G for detailed motivation for and instruction in the use of this option.
References
1. John Shoch, "A File Transfer Protocol Using the BSP -- 4th edition," 15 July 1978, [Maxc1]<Pup>FtpSpec.press and FtpFigs.press
2. Ed Taft, "Pup Mail Transfer Protocol (Edition 6)," 11 February 1979, [Maxc1]<Pup>MailTransfer.press
3. Dave Crocker, John Vittal, Ken Pogran, and Austin Henderson, "Standard for the Format of ARPA Network Text Messages," 21 November 1977.