RFC 959
File Transfer Protocol
๐ฌ RFC 959: FILE TRANSFER PROTOCOL (FTP) ๐
Okay bestie, this is the one. FTP ๐ It's the OG file transfer protocol, and this doc is the official spec for it. Let's get into the title block first so you know who's behind it โจ
Written by J. Postel and J. Reynolds from ISI ๐ง, dated October 1985 ๐. It's a Network Working Group document, and it obsoletes RFC 765 (IEN 149) ๐ฆ, which means this is the newer, upgraded version of the old FTP spec. It doesn't say anything about updating other RFCs, so nothing else gets touched.
Also, the memo is the official specification of FTP, and distribution is unlimited ๐. No gatekeeping here, bestie ๐ซถ
Status of this Memo โจ
Okay so this part is basically the "here's what's new" section ๐ The memo is the official FTP spec with unlimited distribution, and this edition adds some new optional commands ๐ฅ:
- CDUP (Change to Parent Directory) ๐ธ
- SMNT (Structure Mount) ๐ง
- STOU (Store Unique) ๐
- RMD (Remove Directory) ๐ซง
- MKD (Make Directory) ๐ฆ
- PWD (Print Directory) โจ
- SYST (System) ๐
Also, this spec is compatible with the previous edition ๐ฅฐ Basically nothing breaks, which is so iconic of them.
1. INTRODUCTION ๐
Okay so FTP has four main goals ๐ First, promoting file sharing (programs and/or data) ๐ Second, letting people use remote computers indirectly or implicitly (aka through programs) ๐ค Third, shielding users from differences in file storage across hosts ๐ก๏ธ Fourth, transferring data reliably and efficiently ๐ฏ It's usable straight from a terminal, but it's mainly built for programs to use, not humans, so you know it's giving automata energy ๐ค๐
The design goal is pretty chill but ambitious: serve everyone from maxi-hosts and mini-hosts to personal workstations and TACs ๐ฅ๏ธโจ, while keeping the protocol simple and easy to implement ๐งธ
This doc assumes you already know TCP [2] and the Telnet Protocol [3] ๐ Those are both in the ARPA-Internet protocol handbook [1] ๐ Read those first, bestie.
2. OVERVIEW ๐ฆ
This section covers the history, the terminology, and the FTP model ๐ง Only the terms with special meaning in FTP get defined here, and some of them are super FTP-specific, so you might wanna jump to the model section while you're reading the terms ๐
2.1. HISTORY ๐
FTP has had a long glow-up over the years ๐ท Appendix III is a chronological list of RFCs about FTP ๐๏ธ It starts with the very first file transfer ideas from 1971 for M.I.T. hosts (RFC 114), plus the discussion in RFC 141 ๐
Then it gets messy in the best way ๐ญ RFC 172 gave a user-level file transfer protocol between hosts (including terminal IMPs) ๐ฅ๏ธ RFC 265 restated it for more review, and RFC 281 suggested more changes ๐ RFC 294 proposed the "Set Data Type" transaction in January 1982 ๐
Next, RFC 354 obsoleted RFCs 264 and 265 ๐ At this point FTP was defined as a way to move files between HOSTs on the ARPANET, with the main job being efficient, reliable file transfer and letting you use remote file storage easily ๐ซถ RFC 385 commented on errors, emphasis points, and new additions ๐ RFC 414 gave a status report on the working server and user FTPs ๐ RFC 430 (issued in 1973, plus a bunch of other RFCs too many to name) kept the comments coming ๐ฃ๏ธ Finally an "official" FTP document came out as RFC 454 ๐
By July 1973 a lot had changed, but the general structure stayed the same ๐งฑ RFC 542 became the new "official" spec to reflect those changes ๐ Problem is, lots of implementations based on the older spec never got updated ๐ฌ
In 1974, RFCs 607 and 614 kept the FTP convo going ๐ฌ RFC 624 proposed more design changes and small tweaks ๐ ๏ธ In 1975, RFC 686, titled "Leaving Well Enough Alone" ๐ talked about the differences between all the early and later versions of FTP ๐ง RFC 691 then gave a small revision of RFC 686 about print files ๐จ๏ธ
Then the switch from NCP to TCP as the underlying protocol happened ๐ and out of all those efforts came a whole phoenix moment ๐ฅ๐ฆโ๐ฅ: RFC 765, the spec for FTP on TCP โจ
This edition is basically a cleanup ๐งน It fixes some minor documentation errors, explains some protocol features better, and adds some new optional commands ๐
Here are the new optional commands in this edition ๐:
- CDUP - Change to Parent Directory ๐ธ
- SMNT - Structure Mount ๐ง
- STOU - Store Unique ๐
- RMD - Remove Directory ๐ซง
- MKD - Make Directory ๐ฆ
- PWD - Print Directory โจ
- SYST - System ๐
And yes, this spec is compatible with the previous edition ๐ฅฐ A program that follows the previous spec should automatically be in conformance with this one too. Literally no drama ๐
2.2. TERMINOLOGY ๐
Okay, here's the vocab list. Some of these terms are very FTP-specific, so don't panic if they feel like a lot ๐ซถ
ASCII ๐ค The ASCII character set is as defined in the ARPA-Internet Protocol Handbook ๐ In FTP, ASCII characters are the lower half of an eight-bit code set, which means the most significant bit is zero ๐งธ
access controls ๐ These define users' access privileges for using a system and for the files in it ๐ช They're needed to stop unauthorized or accidental file use ๐ โโ๏ธ It's the server-FTP process's call whether to invoke access controls ๐
byte size ๐ There are two byte sizes that matter in FTP: the logical byte size of the file, and the transfer byte size used when data is sent ๐ฆ The transfer byte size is always 8 bits ๐ฏ It's not necessarily the byte size the data is stored in on the system, and it's not necessarily the logical byte size used to interpret the data's structure ๐ง
control connection ๐๏ธ This is the communication path between the USER-PI and SERVER-PI for swapping commands and replies ๐ฌ It follows the Telnet Protocol ๐
data connection ๐ A full duplex connection that transfers data in a specified mode and type ๐ The data can be part of a file, a whole file, or a bunch of files ๐ The path can run between a server-DTP and a user-DTP, or between two server-DTPs ๐ค
data port ๐ช The passive data transfer process "listens" on the data port for the active transfer process to connect and open the data connection ๐
DTP ๐ The data transfer process sets up and manages the data connection ๐ ๏ธ A DTP can be passive or active ๐
End-of-Line โฉ๏ธ This is the sequence that separates printing lines ๐ It's Carriage Return followed by Line Feed ๐
EOF ๐ The end-of-file condition that marks the end of a file being transferred ๐ฌ
EOR ๐งฑ The end-of-record condition that marks the end of a record being transferred ๐๏ธ
error recovery ๐ฉน A procedure that lets a user recover from certain errors, like a failure of either host system or the transfer process ๐ช In FTP, this can mean restarting a transfer at a given checkpoint ๐ฉ
FTP commands ๐จ A set of commands carrying control info from the user-FTP to the server-FTP process ๐ซถ
file ๐ An ordered set of computer data (programs included), of arbitrary length, uniquely identified by a pathname ๐
mode ๐๏ธ The mode is how data gets transferred over the data connection ๐ฆ It defines the data format during transfer, including EOR and EOF ๐งฉ The transfer modes are described in the Section on Transmission Modes ๐
NVT ๐ฅ๏ธ The Network Virtual Terminal, as defined in the Telnet Protocol ๐
NVFS ๐บ๏ธ The Network Virtual File System: a concept for a standard network file system with standard commands and pathname conventions ๐งธ
page ๐ A file can be structured as a set of independent parts called pages ๐งฉ FTP supports sending discontinuous files as independent indexed pages ๐
pathname ๐ค๏ธ The character string a user has to type into a file system to identify a file ๐๏ธ It usually has device and/or directory names, plus a file name ๐ FTP does not yet specify a standard pathname convention, so each user has to follow the file naming conventions of the file systems involved ๐
PI ๐ง The protocol interpreter ๐ค The user and server sides of the protocol have separate roles, implemented as a user-PI and a server-PI ๐ฏโโ๏ธ
record ๐๏ธ A sequential file can be structured as a number of contiguous parts called records ๐ FTP supports record structures, but a file doesn't have to have one ๐
reply ๐ A reply is an acknowledgment (positive or negative) that the server sends to the user over the control connection in response to FTP commands ๐ฌ It's a completion code (error codes included) followed by a text string ๐ข The codes are for programs to read, and the text is usually for humans ๐ซถ
server-DTP ๐ฐ๏ธ The data transfer process in its normal "active" state sets up the data connection with the "listening" data port ๐ It sets up transfer and storage parameters and moves data when its PI tells it to ๐ It can also be put into a "passive" state to listen for a connection instead of starting one ๐
server-FTP process ๐ฐ A process (or set of processes) that does file transfer together with a user-FTP process and possibly another server ๐ค It has two parts: a protocol interpreter (PI) and a data transfer process (DTP) ๐งฉ
server-PI ๐ The server protocol interpreter "listens" on Port L for a connection from a user-PI and sets up a control connection ๐ It takes standard FTP commands from the user-PI, sends replies, and runs the server-DTP ๐
type ๐จ The data representation type used for transfer and storage ๐ผ๏ธ Type implies certain transformations between when data is stored and when it's transferred ๐ The representation types are described in the Section on Establishing Data Connections ๐
user ๐โโ๏ธ A person, or a process acting for a person, who wants file transfer service ๐ A human can talk directly to a server-FTP process, but using a user-FTP process is preferred, since the protocol is designed with automata in mind ๐ค
user-DTP ๐ซง The data transfer process "listens" on the data port for a connection from a server-FTP process ๐ If two servers are transferring data between themselves, the user-DTP is inactive ๐ค
user-FTP process ๐ธ
Part 1 of 12 done, bestie ๐ The user-FTP process entry is cut off here, so the next part picks up from there. Stay tuned ๐ซถ
A set of functions that work together to perform file transfer with one or more server-FTP processes. It has a protocol interpreter, a data transfer process, and a user interface, and the user interface lets a local language be used in the command-reply dialogue with the user. ๐ธ
user-PI
The user protocol interpreter starts the control connection from its port U to the server-FTP process, sends FTP commands, and runs the user-DTP if that process is part of the file transfer. ๐
2.3. THE FTP MODEL โจ
With all of those definitions in mind, the model in Figure 1 can be drawn for an FTP service. ๐ฆ
-------------
|/---------\|
|| User || --------
||Interface|<--->| User |
|\----^----/| --------
---------- | | |
|/------\| FTP Commands |/----V----\|
||Server|<---------------->| User ||
|| PI || FTP Replies || PI ||
|\--^---/| |\----^----/|
| | | | | |
-------- |/--V---\| Data |/----V----\| --------
| File |<--->|Server|<---------------->| User |<--->| File |
|System| || DTP || Connection || DTP || |System|
-------- |\------/| |\---------/| --------
---------- -------------
Server-FTP USER-FTP
NOTES: 1. The data connection may be used in either direction.
- The data connection need not exist all of the time.
Figure 1 Model for FTP Use
In the Figure 1 model, the user-protocol interpreter starts the control connection. The control connection follows the Telnet protocol. When the user asks for something, standard FTP commands get generated by the user-PI and sent to the server process over the control connection. (The user MAY set up a direct control connection to the server-FTP, from a TAC terminal for example, and generate standard FTP commands on their own, skipping the user-FTP process.) Standard replies come back from the server-PI to the user-PI over the control connection, responding to each command. ๐
The FTP commands set the parameters for the data connection (data port, transfer mode, representation type, and structure) and say what kind of file system operation should happen (store, retrieve, append, delete, etc.). The user-DTP or its designate SHOULD "listen" on the specified data port, and the server starts the data connection and data transfer following those parameters. Something to note: the data port does NOT have to live on the same host that sends the FTP commands over the control connection, but the user or the user-FTP process MUST ensure a "listen" on the specified data port. It also ought to be noted that the data connection can be used for simultaneous sending and receiving. ๐ฅ
Now picture a different situation, where a user wants to move files between two hosts and neither one is the local host. The user sets up control connections to both servers and then arranges a data connection between them. That way, the control information goes to the user-PI, but the data is transferred between the server data transfer processes. Here's the model for that server-to-server setup. ๐ง
Control ------------ Control
---------->| User-FTP |<-----------
| | User-PI | |
| | "C" | |
V ------------ V
-------------- --------------
| Server-FTP | Data Connection | Server-FTP |
| "A" |<---------------------->| "B" |
-------------- Port (A) Port (B) --------------
Figure 2
The protocol requires that the control connections stay open while data transfer is in progress. The user is responsible for asking for the control connections to close when they're done with the FTP service, but it's the server that actually does the closing. The server MAY abort data transfer if the control connections get closed without a command. ๐ฅบ
The Relationship between FTP and Telnet
The FTP uses the Telnet protocol on the control connection. There are two ways to pull this off. First, the user-PI or the server-PI MAY build the rules of the Telnet Protocol directly into their own procedures. Second, the user-PI or the server-PI MAY use the Telnet module that's already in the system. โจ
Ease of implementation, code sharing, and modular programming all point toward the second approach. Efficiency and independence point toward the first. In practice, FTP relies on very little of the Telnet Protocol, so the first approach doesn't necessarily mean a lot of code. ๐
3. DATA TRANSFER FUNCTIONS ๐
Files only ever move over the data connection. The control connection carries the commands that describe what needs doing, along with the replies to those commands (see the Section on FTP Replies). A bunch of commands handle moving data between hosts, including the MODE command, which says how the bits of the data get sent, and the STRU and TYPE commands, which define how the data is represented. Transmission and representation are mostly independent of each other, BUT the "Stream" transmission mode depends on the file structure attribute, and if "Compressed" transmission mode is used, the filler byte's nature depends on the representation type. ๐
3.1. DATA REPRESENTATION AND STORAGE ๐
Data moves from a storage device on the sending host to a storage device on the receiving host. Often the data has to be transformed along the way, since the two systems store data differently. For example, NVT-ASCII gets stored differently on different systems. DEC TOPS-20s usually store NVT-ASCII as five 7-bit ASCII characters, left-justified in a 36-bit word. IBM Mainframes store NVT-ASCII as 8-bit EBCDIC codes. Multics stores NVT-ASCII as four 9-bit characters in a 36-bit word. It's a good idea to convert characters to the standard NVT-ASCII representation when sending text between systems that are different from each other. The sending and receiving sites would have to do the necessary conversions between the standard representation and their own internal ones. ๐
A different problem comes up when sending binary data (not character codes) between hosts with different word lengths. It isn't always obvious how the sender should send the data and how the receiver should store it. For example, when sending 32-bit bytes from a system with 32-bit words to a system with 36-bit words, it MAY be desirable (for efficiency and usefulness reasons) to store the 32-bit bytes right-justified in a 36-bit word on the latter system. Either way, the user SHOULD have the option of specifying data representation and transformation functions. It SHOULD be noted that FTP only provides very limited data type representations. Any transformations beyond that limited set SHOULD be done by the user directly. ๐ซถ
3.1.1. DATA TYPES
Data representations are handled in FTP by the user specifying a representation type. This type MAY define a byte size for interpretation either implicitly (as in ASCII or EBCDIC) or explicitly (as in Local byte), and that size is called the "logical byte size." This has nothing to do with the byte size used for sending over the data connection, which is called the "transfer byte size," so the two SHOULD NOT be mixed up. For example, NVT-ASCII has a logical byte size of 8 bits. If the type is Local byte, the TYPE command has a required second parameter that specifies the logical byte size. The transfer byte size is always 8 bits. ๐
3.1.1.1. ASCII TYPE
This is the default type and it MUST be accepted by all FTP implementations. It's mainly meant for transferring text files, unless both hosts would find the EBCDIC type more convenient. โจ
The sender converts the data from an internal character representation into the standard 8-bit NVT-ASCII representation (see the Telnet specification). The receiver converts the data from that standard form into its own internal form. ๐
Following the NVT standard, the <CRLF> sequence SHOULD be used wherever it's needed to mark the end of a line of text. (See the discussion of file structure at the end of the Section on Data Representation and Storage.) ๐ธ
Using the standard NVT-ASCII representation means the data MUST be interpreted as 8-bit bytes. ๐ฆ
The Format parameter for ASCII and EBCDIC types is discussed below. ๐
3.1.1.2. EBCDIC TYPE
This type is meant for efficient transfers between hosts that use EBCDIC for their internal character representation. ๐
For transmission, the data is represented as 8-bit EBCDIC characters. The character code is the only difference between the functional specs of the EBCDIC and ASCII types. ๐
End-of-line (as opposed to end-of-record, see the discussion of structure) will probably be pretty rare with the EBCDIC type for marking structure, but when it's needed, the <NL> character SHOULD be used. ๐
3.1.1.3. IMAGE TYPE
The data is sent as contiguous bits, which get packed into the 8-bit transfer bytes for transfer. The receiving site MUST store the data as contiguous bits. The storage system's structure might require padding the file (or each record, for a record-structured file) out to some convenient boundary (byte, word, or block). This padding MUST be all zeros, MAY only occur at the end of the file (or at the end of each record), and there MUST be a way to identify the padding bits so they can be stripped off when the file is retrieved. The padding transformation SHOULD be well publicized so that a user can process a file at the storage site. ๐
Image type is meant for efficient storage and retrieval of files and for transferring binary data. It is RECOMMENDED that all FTP implementations accept this type. ๐ฅ
3.1.1.4. LOCAL TYPE โจ
Okay bestie, now we're getting into the nitty gritty of how the bytes actually get packed ๐๐
3.1.1.4. BYTE SIZE (continued)
Data travels in logical bytes sized by the second parameter, Byte size, which is obligatory ๐ซถ The Byte size value MUST be a decimal integer, and there's no default, so you gotta actually give it one ๐ข The logical byte size isn't always the same as the transfer byte size ๐ฆ If they're different, the logical bytes get packed contiguously, ignoring the transfer byte boundaries, with any padding needed at the end ๐ธ
When the data hits the receiving host, it gets transformed depending on the logical byte size and the host itself โจ That transformation MUST be invertible (so you can get an identical file back if you use the same parameters), and implementors SHOULD publicize it well ๐ฃ It's giving transparency, periodt ๐
Say you're sending 36-bit floating-point numbers to a host with a 32-bit word ๐ง You could send them as Local byte with a logical byte size of 36 ๐ The receiving host would then be expected to store the logical bytes so they're easy to manipulate. In this case, putting the 36-bit logical bytes into 64-bit double words SHOULD suffice ๐
Another example: a pair of hosts with a 36-bit word size might send data to each other in words by using TYPE L 36 ๐ The data gets sent in 8-bit transmission bytes, packed so that 9 transmission bytes carry two host words ๐
3.1.1.5. FORMAT CONTROL
The types ASCII and EBCDIC also take a second (OPTIONAL) parameter ๐ It says what kind of vertical format control, if any, is attached to a file ๐ FTP defines these data representation types:
A character file can be sent to a host for one of three purposes: printing, storage and later retrieval, or processing ๐จ๏ธ If a file is sent for printing, the receiving host MUST know how the vertical format control is represented ๐ญ If it's stored and retrieved later, it MUST be possible to get the file back in exactly the same form ๐ And finally, it SHOULD be possible to move a file to another host and process it there without undue trouble โจ One ASCII or EBCDIC format just can't cover all three of these, so the types take a second parameter that picks one of these three formats ๐ฆ
3.1.1.5.1. NON PRINT
This is the default format if the second (format) parameter is left out ๐ธ Non-print format MUST be accepted by all FTP implementations, no exceptions bestie ๐
The file doesn't need any vertical format information ๐ง If it gets passed to a printer process, that process MAY just assume standard values for spacing and margins ๐
Usually this format is used for files that are going to be processed or just stored ๐
3.1.1.5.2. TELNET FORMAT CONTROLS
The file contains ASCII/EBCDIC vertical format controls (like <CR>, <LF>, <NL>, <VT>, <FF>) that the printer process will interpret properly ๐จ๏ธ <CRLF>, in exactly this sequence, also means end-of-line ๐ซถ
3.1.1.5.2. CARRIAGE CONTROL (ASA)
The file contains ASA (FORTRAN) vertical format control characters ๐ (Go check out RFC 740 Appendix C, plus Communications of the ACM, Vol. 7, No. 10, p. 606, October 1964, if you want the deep cut ๐ค) In a line or record formatted per the ASA Standard, the first character doesn't get printed ๐ Instead, it's used to decide how the paper moves before the rest of the record gets printed, and it SHOULD be used exactly that way ๐
The ASA Standard defines these control characters:
Character Vertical Spacing
blank Move paper up one line
0 Move paper up two lines
1 Move paper to top of next page
+ No movement, i.e., overprint
Clearly there MUST be some way for a printer process to tell where the structural entity ends ๐ค If the file has record structure, no sweat, because records get explicitly marked during transfer and storage ๐
If it doesn't have record structure, the <CRLF> end-of-line sequence separates the printing lines, but the ASA controls override those format effectors ๐
3.1.2. DATA STRUCTURES
On top of the different representation types, FTP lets you specify a file's structure ๐๏ธ FTP defines three file structures:
file-structure, where there is no internal structure and the file is considered to be a continuous sequence of data bytes,
record-structure, where the file is made up of sequential records,
and page-structure, where the file is made up of independent indexed pages.
File-structure is the default if the STRUcture command hasn't been used ๐ But both file and record structures MUST be accepted for "text" files (that's files with TYPE ASCII or EBCDIC) by all FTP implementations ๐ซถ A file's structure affects both its transfer mode (see the Section on Transmission Modes) and how it's interpreted and stored ๐ฆ
The "natural" structure of a file depends on which host stores it ๐ฅ๏ธ A source-code file is usually stored on an IBM Mainframe in fixed length records, but on a DEC TOPS-20 it's a stream of characters split into lines, for example by <CRLF> ๐ If files are going to move usefully between sites this different, one site has to be able to recognize the other's assumptions about the file ๐ง
Some sites are naturally file-oriented and others are naturally record-oriented, so trouble can happen if a file with one structure gets sent to a host oriented to the other ๐ฌ If a text file is sent with record-structure to a file-oriented host, that host SHOULD apply an internal transformation based on the record structure ๐ That transformation SHOULD be useful, and it MUST also be invertible, so an identical file can be retrieved using record structure ๐
If a file is sent with file-structure to a record-oriented host, the question is what criteria the host should use to split the file into records it can process locally ๐ค If that split is needed, the FTP implementation SHOULD use the end-of-line sequence (<CRLF> for ASCII, or <NL> for EBCDIC text files) as the delimiter โ๏ธ If an implementation takes this approach, it MUST be prepared to reverse the transformation if the file gets retrieved with file-structure ๐
3.1.2.1. FILE STRUCTURE
File structure is the default if the STRUcture command hasn't been used ๐ธ
In file-structure there's no internal structure, and the file is treated as a continuous sequence of data bytes ๐ง
3.1.2.2. RECORD STRUCTURE
Record structures MUST be accepted for "text" files (that's files with TYPE ASCII or EBCDIC) by all FTP implementations ๐
In record-structure, the file is made up of sequential records ๐
3.1.2.3. PAGE STRUCTURE
To transmit files that are discontinuous, FTP defines a page structure ๐ฆ These are sometimes called "random access files" or even "holey files" ๐ณ๏ธ In these files, there can be other information attached to the file as a whole (like a file descriptor), to a section of the file (like page access controls), or both ๐ In FTP, those sections of the file are called pages ๐
Each page is sent with a page header, so it can support different page sizes and their extra info ๐ The page header has these defined fields:
- Header Length
The number of logical bytes in the page header, including this byte. The minimum header length is 4 โจ
- Page Index
The logical page number of this section of the file. It isn't the transmission sequence number of this page. It's the index used to identify this page of the file ๐
- Data Length
The number of logical bytes in the page data. The minimum data length is 0 ๐ซง
- Page Type
The type of page. These page types are defined:
0 = Last Page: This marks the end of a paged structured transmission. The header length MUST be 4, and the data length MUST be 0 ๐1 = Simple Page: This is the normal type for simple paged files with no page-level control info attached. The header length MUST be 4 ๐2 = Descriptor Page: This type transmits the descriptive info for the file as a whole ๐3 = Access Controlled Page: This type adds an extra header field for paged files with page-level access control info. The header length MUST be 5 ๐
- Optional Fields
More header fields MAY be used to supply per-page control info, like per-page access control ๐งฉ
All fields are one logical byte long ๐ The logical byte size is set by the TYPE command. See Appendix I for more details and a specific case at the page structure ๐
A note of caution about parameters, bestie: a file MUST be stored and retrieved with the same parameters if the retrieved version is supposed to be identical to the one originally sent ๐ญ And flipping it around, FTP implementations MUST return a file identical to the original if the parameters used to store and retrieve it are the same ๐
3.2. ESTABLISHING DATA CONNECTIONS โจ
The mechanics of transferring data come down to two things: setting up the data connection on the right ports, and choosing the parameters for the transfer ๐. Both the user-DTP and the server-DTP have a default data port. The user-process default is the same as the control connection port, which is U. The server-process default is the port right next to the control connection port, which is L-1 โจ.
The transfer byte size is 8-bit bytes. That only matters for the actual transfer, though. It has zero say in how the data is represented in a host's file system ๐
The passive data transfer process (this could be a user-DTP or a second server-DTP) shall "listen" on the data port before sending a transfer request command. The FTP request command decides which direction the data goes. Once the server gets the transfer request, it initiates the data connection to the port. When the connection is up, the DTPs start transferring data, and the server-PI sends a confirming reply to the user-PI ๐ฆ
Every FTP implementation must support the default data ports, and only the USER-PI can start a change to non-default ports ๐
The user can also pick an alternate data port with the PORT command. This is useful if they want a file dumped on a TAC line printer or pulled from a third party host. In the third party case, the user-PI sets up control connections with both server-PIs. One server gets told (by an FTP command) to "listen" for a connection that the other one will start. The user-PI sends one server-PI a PORT command with the data port of the other. Last step: both get the appropriate transfer commands. The exact sequence of commands and replies between the user-controller and the servers is defined in the Section on FTP Replies ๐ง
Generally, the server is the one responsible for keeping the data connection alive. It opens it and it closes it ๐ซถ The exception is when the user-DTP is sending data in a transfer mode that needs the connection closed to signal EOF. The server MUST close the data connection under these conditions:
- The server has finished sending data in a transfer mode that requires a close to indicate EOF.
- The server receives an ABORT command from the user.
- The port specification is changed by a command from the user.
- The control connection is closed, legally or otherwise.
- An irrecoverable error condition occurs.
Otherwise, closing is a server option. If the server uses that option, it has to tell the user-process with either a 250 or 226 reply, and only one of those ๐ญ
3.3. DATA CONNECTION MANAGEMENT ๐
Default Data Connection Ports: All FTP implementations must support the default data connection ports, and only the User-PI may start using non-default ports. Iconic rule, no notes ๐
Negotiating Non-Default Data Ports: The User-PI can specify a non-default user side data port with the PORT command. The User-PI can also ask the server side to pick a non-default server side data port with the PASV command. A connection is defined by its pair of addresses, so either of those actions is enough to get a different data connection. It's still allowed to do both, so you can use new ports on both ends of the data connection ๐ธ
Reuse of the Data Connection: When you're using stream mode, the end of the file has to be marked by closing the connection. This causes a problem if you want to send several files in one session. TCP has to keep the connection record around for a timeout period so that communication stays reliable, which means the connection can't be reopened right away ๐
There are two ways around this. The first is to negotiate a non-default port. The second is to use another transfer mode.
A quick comment on transfer modes: stream mode is inherently unreliable, because you can't tell whether the connection closed early or not. The other transfer modes (Block, Compressed) don't close the connection to mark the end of a file. They have enough FTP encoding that the data connection can be parsed to find the end of the file. So with those modes, you can leave the data connection open for multiple file transfers โจ
3.4. TRANSMISSION MODES ๐ฆ
Next up is picking the right transmission mode. There are three modes. One formats the data and allows restart procedures. One also compresses the data for efficient transfer. The last one passes the data along with little or no processing. In that last case, the mode works together with the structure attribute to decide what kind of processing happens. In compressed mode, the representation type decides the filler byte ๐
Every data transfer must finish with an end-of-file (EOF) marker. That marker can be stated explicitly, or it can be implied by closing the data connection. For files with record structure, all the end-of-record markers (EOR) are explicit, the final one included. For files sent in page structure, a "last-page" page type is used ๐
NOTE: In the rest of this section, byte means "transfer byte" except where explicitly stated otherwise.
For standardized transfer, the sending host translates its internal end of line or end of record denotation into the representation the transfer mode and file structure call for. The receiving host does the inverse translation back to its own internal denotation. An IBM Mainframe record count field may not be recognized at another host, so the end-of-record information might be sent as a two byte control code in Stream mode, or as a flagged bit in a Block or Compressed mode descriptor. End-of-line in an ASCII or EBCDIC file with no record structure should be marked with <CRLF> or <NL>, respectively. Since these conversions are extra work for some systems, identical systems moving non-record structured text files may want to use a binary representation and stream mode instead ๐
The following transmission modes are defined in FTP:
3.4.1. STREAM MODE ๐
The data is sent as a stream of bytes. There's no restriction on the representation type, and record structures are allowed ๐
In a record structured file, EOR and EOF are each marked by a two-byte control code. The first byte of the control code is all ones, which is the escape character. The second byte has the low order bit on and zeros everywhere else for EOR, and the second low order bit on for EOF. In other words, the byte is 1 for EOR and 2 for EOF. EOR and EOF can be marked together on the last byte sent by turning on both low order bits, which gives 3. If a byte of all ones was meant to be sent as data, it should be repeated in the second byte of the control code ๐
If the structure is a file structure, EOF is marked by the sending host closing the data connection, and every byte is a data byte ๐
3.4.2. BLOCK MODE ๐งฑ
The file is sent as a series of data blocks, each preceded by one or more header bytes. The header bytes hold a count field and a descriptor code. The count field gives the total length of the data block in bytes, which marks where the next data block begins (there are no filler bits). The descriptor code can flag: the last block in the file (EOF), the last block in the record (EOR), a restart marker (see the Section on Error Recovery and Restart), or suspect data (i.e., data that's suspected of errors and isn't reliable). That last code is NOT intended for error control within FTP. It's for sites that swap certain kinds of data (e.g., seismic or weather data) and need to send and receive all of it despite local errors (like "magnetic tape read errors"), while still marking which parts are suspect ๐ธ Record structures are allowed in this mode, and any representation type can be used โจ
The header is three bytes. Out of its 24 bits, the 16 low order bits shall represent the byte count, and the 8 high order bits shall represent the descriptor codes, as shown below ๐
+----------------+----------------+----------------+
| Descriptor | Byte Count |
| 8 bits | 16 bits |
+----------------+----------------+----------------+
The descriptor codes are set as bit flags in the descriptor byte. Four codes have been assigned, and each code number is the decimal value of its matching bit in the byte.
Code Meaning
128 End of data block is EOR
64 End of data block is EOF
32 Suspected errors in data block
16 Data block is a restart marker
With this encoding, more than one descriptor condition can exist for a block at the same time. As many bits as needed can be flagged ๐ฅ
The restart marker is embedded in the data stream as an integral number of 8-bit bytes. Those bytes are printable characters in the language being used over the control connection (e.g., default--NVT-ASCII). <SP> (Space, in the appropriate language) must not be used WITHIN a restart marker ๐
For example, to send a six-character marker, you'd send the following:
+--------+--------+--------+
|Descrptr| Byte count |
|code= 16| = 6 |
+--------+--------+--------+
+--------+--------+--------+
| Marker | Marker | Marker |
| 8 bits | 8 bits | 8 bits |
+--------+--------+--------+
+--------+--------+--------+
| Marker | Marker | Marker |
| 8 bits | 8 bits | 8 bits |
+--------+--------+--------+
3.4.3. COMPRESSED MODE ๐
There are three kinds of information to send: regular data, sent as a byte string; compressed data, made of replications or filler; and control information, sent as a two-byte escape sequence. If n>0 bytes (up to 127) of regular data are sent, those n bytes are preceded by a byte whose left-most bit is set to 0, and whose right-most 7 bits hold the number n ๐ง
Byte string:
1 7 8 8
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|0| n | | d(1) | ... | d(n) |
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
^ ^
|---n bytes---|
of data
Okay so we're picking up mid-compressed-mode, bestie ๐ง๐ Here's the rest of it:
A plain run of data is just n data bytes, written d(1),..., d(n). The count n has to be positive, so an empty run is a no-go ๐ โโ๏ธ
To squash n copies of the same data byte d into 2 bytes total, you send this ๐ฆ
2 6 8
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|1 0| n | | d |
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
Filler is even cuter ๐ธ A string of n filler bytes can be squished into just one byte, and the filler byte depends on the representation type. If the type is ASCII or EBCDIC, the filler is <SP> (Space, ASCII code 32, EBCDIC code 64). If the type is Image or Local byte, the filler is a zero byte.
2 6
+-+-+-+-+-+-+-+-+
|1 1| n |
+-+-+-+-+-+-+-+-+
The escape sequence is a double byte ๐. The first byte is the escape byte (all zeros), and the second byte holds descriptor codes, which are defined in Block mode. Those descriptor codes mean the same thing here as they do in Block mode, and they apply to the string of bytes that comes right after.
Compressed mode is giving "more bandwidth on huge transfers for a little extra CPU cost" ๐ It's most useful for shrinking printer files, like the ones RJE hosts generate ๐จ๏ธโจ
3.5. ERROR RECOVERY AND RESTART ๐
Real talk: there's no way to detect bits that get lost or scrambled during data transfer. That job belongs to TCP ๐ซถ BUT there's a restart procedure to protect users from big system failures, including a host failing, an FTP-process failing, or the underlying network failing ๐
The restart procedure is only defined for block and compressed modes of data transfer. The sender of the data has to insert a special marker code into the data stream, along with some marker information. That marker information only means something to the sender, but it has to be made of printable characters in the default or negotiated language of the control connection (ASCII or EBCDIC). The marker could stand for a bit-count, a record-count, or anything else that lets a system identify a data checkpoint ๐ The receiver, if it implements the restart procedure, marks the matching position of that marker in its own system and hands that information back to the user.
If a system failure happens, the user can restart the transfer by pointing at the marker with the FTP restart procedure ๐ Here's how it plays out:
The sender inserts an appropriate marker block into the data stream at a convenient spot. The receiving host marks the matching data point in its file system and tells the user the last known sender and receiver marker information. That info goes either directly, or over the control connection in a 110 reply, depending on who the sender is ๐จ If a system failure happens, the user or controller process restarts the server at the last server marker by sending a restart command with the server's marker code as its argument. The restart command goes over the control connection and is immediately followed by the command that was running when the failure happened, like RETR, STOR or LIST ๐โโ๏ธ๐จ
4. FILE TRANSFER FUNCTIONS ๐
The communication channel from the user-PI to the server-PI is set up as a TCP connection from the user to the standard server port ๐ The user protocol interpreter is responsible for sending FTP commands and interpreting the replies it gets back. The server-PI interprets commands, sends replies, and directs its DTP to set up the data connection and transfer the data. If the second party to the data transfer (the passive transfer process) is the user-DTP, then it's governed through the internal protocol of the user-FTP host. If it's a second server-DTP, then it's governed by its PI, acting on commands from the user-PI ๐ The FTP replies get their own section next. When we describe a few of the commands in this section, it helps to be explicit about the possible replies ๐
4.1. FTP COMMANDS ๐
4.1.1. ACCESS CONTROL COMMANDS ๐
The following commands specify access control identifiers. Command codes are shown in parentheses ๐
USER NAME (USER)
The argument field is a Telnet string identifying the user. The user identification is whatever the server requires to access its file system. This command will normally be the first command the user sends after the control connections are made (some servers may require this). Some servers also want extra identification in the form of a password and/or an account command ๐ชช Servers may allow a new USER command at any point, to change the access control and/or accounting information. That flushes any user, password, and account information already supplied and starts the login sequence over. All transfer parameters stay unchanged, and any file transfer in progress finishes under the old access control parameters ๐
PASSWORD (PASS)
The argument field is a Telnet string specifying the user's password. This command must be immediately preceded by the user name command, and for some sites it completes the user's identification for access control ๐๏ธ Password info is super sensitive, so it's generally desirable to "mask" it or suppress typeout. It appears the server has no foolproof way to do that, so it's the responsibility of the user-FTP process to hide the sensitive password information ๐๐
ACCOUNT (ACCT)
The argument field is a Telnet string identifying the user's account. This command isn't necessarily related to the USER command, since some sites require an account for login and others only for specific access, like storing files. In the latter case the command may arrive at any time ๐งพ
There are reply codes to tell these cases apart for automation ๐ค When account information is required for login, the reply to a successful PASSword command is reply code 332. On the other hand, if account information is NOT required for login, the reply to a successful PASSword command is 230. And if account information is needed for a command issued later in the dialogue, the server should return a 332 or 532 reply, depending on whether it stores the command (pending receipt of the ACCounT command) or discards it, respectively ๐
CHANGE WORKING DIRECTORY (CWD)
This command lets the user work with a different directory or dataset for file storage or retrieval, without altering their login or accounting information ๐ Transfer parameters are similarly unchanged. The argument is a pathname specifying a directory or other system-dependent file group designator โจ
CHANGE TO PARENT DIRECTORY (CDUP)
This command is a special case of CWD. It's included to simplify programs that transfer directory trees between operating systems with different syntaxes for naming the parent directory ๐ณ The reply codes shall be identical to the reply codes of CWD. See Appendix II for further details ๐ฆ
STRUCTURE MOUNT (SMNT)
This command lets the user mount a different file system data structure without altering their login or accounting information ๐ฟ Transfer parameters are similarly unchanged. The argument is a pathname specifying a directory or other system-dependent file group designator ๐ง
REINITIALIZE (REIN)
This command terminates a USER, flushing all I/O and account information. The one exception: it lets any transfer in progress finish. All parameters reset to their default settings, and the control connection stays open. This is identical to the state a user finds themselves in right after the control connection is opened. A USER command may be expected to follow ๐
LOGOUT (QUIT)
This command terminates a USER. If no file transfer is in progress, the server closes the control connection. If a file transfer is in progress, the connection stays open for the result response, and then the server closes it ๐ช If the user-process is transferring files for several USERs but doesn't want to close and reopen connections for each one, it should use the REIN command instead of QUIT ๐
An unexpected close on the control connection will make the server take the effective action of an abort (ABOR) and a logout (QUIT) ๐ญ
4.1.2. TRANSFER PARAMETER COMMANDS โ๏ธ
All data transfer parameters have default values. The commands that specify data transfer parameters are only required if the default values need to change ๐๏ธ The default value is the last specified value, or if no value has been specified, the standard default value stated here. That means the server must "remember" the applicable default values ๐ง The commands may come in any order, except that they must precede the FTP service request. The following commands specify data transfer parameters:
DATA PORT (PORT)
The argument is a HOST-PORT specification for the data port to be used in the data connection. Both the user and server data ports have defaults, and under normal circumstances this command and its reply aren't needed ๐ โโ๏ธ If this command is used, the argument is the concatenation of a 32-bit internet host address and a 16-bit TCP port address. That address information is broken into 8-bit fields, and each field's value is transmitted as a decimal number (in character string representation). The fields are separated by commas. A PORT command would look like this:
PORT h1,h2,h3,h4,p1,p2
where h1 is the high order 8 bits of the internet host address ๐
PASSIVE (PASV)
This command asks the server-DTP to "listen" on a data port (one that isn't its default data port) and to wait for a connection, rather than initiating one when it gets a transfer command ๐ The response to this command includes the host and port address this server is listening on ๐
REPRESENTATION TYPE (TYPE)
okay so the argument is the representation type, and the Section on Data Representation and Storage has the full tea ๐ซโจ. Some types take a second parameter. The first parameter is one single Telnet character, same as the second Format parameter for ASCII and EBCDIC. For local byte, the second parameter is a decimal integer that sets the Bytesize. The parameters get separated by a <SP> (Space, ASCII code 32) ๐
These are the codes assigned for type:
\ /
A - ASCII | | N - Non-print
|-><-| T - Telnet format effectors
E - EBCDIC| | C - Carriage Control (ASA)
/ \
I - Image
L <byte size> - Local byte Byte size
The default representation type is ASCII Non-print ๐
. If you change the Format parameter and then later change just the first argument, Format goes right back to the Non-print default, no cap ๐
FILE STRUCTURE (STRU) ๐ฆ
The argument is a single Telnet character code that sets the file structure. You can read all about it in the Section on Data Representation and Storage.
These are the codes assigned for structure:
F - File (no record structure)
R - Record structure
P - Page structure
The default structure is File ๐ธ
TRANSFER MODE (MODE) ๐ง
The argument is a single Telnet character code that picks the data transfer mode. The modes are described in the Section on Transmission Modes, so go peek there if you're curious ๐
These are the codes assigned for transfer modes:
S - Stream
B - Block
C - Compressed
The default transfer mode is Stream ๐
4.1.3. FTP SERVICE COMMANDS โจ
Okay, these commands are the main event ๐ฌ They define the file transfer, or the file system function, that the user is asking for. The argument of an FTP service command is normally a pathname. Pathname syntax has to match the server site conventions (with standard defaults applying) and the language conventions of the control connection, so it's giving very organized energy ๐ The suggested default handling is to use the last specified device, directory, or file name, or the standard default defined for local users ๐
The commands can come in any order, with two exceptions. A "rename from" command MUST be followed by a "rename to" command, and the restart command MUST be followed by the interrupted service command (for example, STOR or RETR). When data gets transferred in response to FTP service commands, it SHALL always go over the data connection, except for certain informative replies. Here are the FTP service requests:
RETRIEVE (RETR) ๐ฅ
This command makes the server-DTP send a copy of the file, named in the pathname, to the server- or user-DTP at the other end of the data connection. The status and contents of the file at the server site SHALL be unaffected, so the original stays exactly as it is ๐ซถ
STORE (STOR) ๐ค
This command makes the server-DTP accept the data coming over the data connection and store it as a file at the server site. If the file named in the pathname already exists at the server site, its contents SHALL be replaced by the data being transferred. If the file doesn't exist yet, a new file gets created at the server site ๐
STORE UNIQUE (STOU) ๐
This command acts like STOR, except the resulting file gets created in the current directory under a name that's unique to that directory. The 250 Transfer Started response MUST include the name that got generated โจ
APPEND (with create) (APPE) ๐
This command makes the server-DTP accept the data coming over the data connection and store it in a file at the server site. If the file named in the pathname already exists at the server site, the data SHALL be appended to that file. Otherwise, the file named in the pathname SHALL be created at the server site ๐ธ
ALLOCATE (ALLO) ๐
Some servers MAY require this command to reserve enough storage for the new file being transferred. The argument SHALL be a decimal integer for the number of bytes (using the logical byte size) of storage to reserve for the file. For files sent with record or page structure, a maximum record or page size (in logical bytes) might also be needed. That gets indicated by a decimal integer in a second argument field of the command. The second argument is optional, but when it's there, it SHOULD be separated from the first by the three Telnet characters <SP> R <SP>. This command SHALL be followed by a STORe or APPEnd command. Servers that don't need the maximum file size declared beforehand SHOULD treat ALLO as a NOOP (no operation), and servers that only care about the maximum record or page size SHOULD accept a dummy value in the first argument and ignore it ๐งธ
RESTART (REST) โฏ๏ธ
The argument field is the server marker where file transfer is supposed to restart. This command doesn't start a transfer. It skips over the file to the specified data checkpoint. This command SHALL be immediately followed by the appropriate FTP service command, which is the thing that actually makes the transfer resume ๐
RENAME FROM (RNFR) ๐ท๏ธ
This command names the old pathname of the file that's getting renamed. It MUST be immediately followed by a "rename to" command that gives the new file pathname ๐
RENAME TO (RNTO) ๐ท๏ธ
This command gives the new pathname for the file named in the immediately preceding "rename from" command. Together, the two commands rename a file ๐
ABORT (ABOR) ๐
This command tells the server to abort the previous FTP service command and any data transfer tied to it. The abort command MAY need "special action", which is covered in the Section on FTP Commands, to get the server to recognize it. If the previous command has already completed (data transfer included), there's nothing to do. The server MUST NOT close the control connection, but the data connection MUST be closed ๐ญ
There are two cases for the server when it gets this command: (1) the FTP service command already finished, or (2) the FTP service command is still running.
In the first case, the server closes the data connection (if it's open) and responds with a 226 reply, which means the abort command got processed successfully ๐ฅณ
In the second case, the server aborts the FTP service that's in progress and closes the data connection, returning a 426 reply to say the service request ended abnormally. After that, the server sends a 226 reply, which means the abort command got processed successfully ๐ซ
DELETE (DELE) ๐๏ธ
This command deletes the file named in the pathname at the server site. If you want an extra layer of protection, like asking "Do you really wish to delete?", that SHOULD be handled by the user-FTP process ๐
REMOVE DIRECTORY (RMD) ๐
This command removes the directory named in the pathname as a directory (if the pathname is absolute) or as a subdirectory of the current working directory (if the pathname is relative). See Appendix II ๐ท
MAKE DIRECTORY (MKD) ๐
This command creates the directory named in the pathname as a directory (if the pathname is absolute) or as a subdirectory of the current working directory (if the pathname is relative). See Appendix II ๐
PRINT WORKING DIRECTORY (PWD) ๐
This command gets the name of the current working directory sent back in the reply. See Appendix II ๐ฆ
LIST (LIST) ๐
This command makes the server send a list to the passive DTP. If the pathname points to a directory or another group of files, the server SHOULD transfer a list of the files in that directory. If the pathname points to a single file, the server SHOULD send current info on that file. A null argument means the user's current working or default directory. The data transfer goes over the data connection in type ASCII or type EBCDIC. (The user MUST make sure the TYPE is set to ASCII or EBCDIC, as appropriate.) Info about a file can vary wildly from system to system, so it can be hard for a program to use automatically, but it can be super useful for a human user ๐ฉโ๐ป
NAME LIST (NLST) ๐
This command makes the server send a directory listing to the user site. The pathname SHOULD name a directory or another system-specific file group descriptor. A null argument means the current directory. The server returns a stream of file names and nothing else. The data gets transferred in ASCII or EBCDIC type over the data connection as valid pathname strings separated by <CRLF> or <NL>. (Again, the user MUST make sure the TYPE is correct ๐) This command is meant to return info that a program can use to process the files automatically. For example, it's how a "multiple get" function works ๐ซถ
SITE PARAMETERS (SITE) ๐ ๏ธ
The server uses this command to provide services specific to its system. These services are essential to file transfer but not universal enough to be commands in the protocol. The nature of these services, and how their syntax works, can be explained in a reply to the HELP SITE command ๐ง
SYSTEM (SYST) ๐ป
This command finds out what type of operating system the server is running. The reply SHALL have as its first word one of the system names listed in the current version of the Assigned Numbers document [4] โจ
STATUS (STAT)
Okay so STAT is the "what's the vibe on the server?" command ๐ It SHALL cause a status response to be sent over the control connection in the form of a reply โจ. You can send it during a file transfer (along with the Telnet IP and Synch signals, see the Section on FTP Commands ๐ง), and then the server will respond with the status of the operation in progress. Or you can send it between transfers, and then the command MAY have an argument field. If the argument is a pathname, STAT is giving total "list" energy, except the data SHALL be transferred over the control connection ๐. If you give a partial pathname, the server MAY respond with a list of file names or attributes that match ๐ธ. If there's no argument at all, the server SHOULD return general status info about the server FTP process ๐, including the current values of all transfer parameters and the status of connections ๐.
HELP (HELP) ๐
This command SHALL cause the server to send helpful info about its implementation status over the control connection to the user ๐ซถ. The command MAY take an argument (like any command name) and return more specific info as a response. The reply is type 211 or 214 ๐. It is suggested that HELP be allowed before entering a USER command, which is honestly smart ๐ง . The server MAY use this reply to specify site-dependent parameters, e.g., in response to HELP SITE ๐.
NOOP (NOOP) ๐ด
This command does not affect any parameters or previously entered commands. It specifies no action other than that the server send an OK reply ๐. Zero drama, total iconic do-nothing energy ๐
.
The File Transfer Protocol follows the specifications of the Telnet protocol for all communications over the control connection ๐. Since the language used for Telnet communication may be a negotiated option, all references in the next two sections will be to the "Telnet language" and the corresponding "Telnet end-of-line code". Currently, one MAY take these to mean NVT-ASCII and <CRLF> ๐ฆ. No other specifications of the Telnet protocol will be cited.
FTP commands are "Telnet strings" terminated by the "Telnet end of line code" ๐งต. The command codes themselves are alphabetic characters terminated by the character <SP> (Space) if parameters follow and Telnet-EOL otherwise. The command codes and the semantics of commands are described in this section ๐. The detailed syntax of commands is specified in the Section on Commands, the reply sequences are discussed in the Section on Sequencing of Commands and Replies, and scenarios illustrating the use of commands are provided in the Section on Typical FTP Scenarios ๐บ๏ธ.
FTP commands may be partitioned as those specifying access-control identifiers, data transfer parameters, or FTP service requests ๐๏ธ. Certain commands (such as ABOR, STAT, QUIT) may be sent over the control connection while a data transfer is in progress. Some servers MAY not be able to monitor the control and data connections simultaneously, in which case some special action will be necessary to get the server's attention ๐. The following ordered format is tentatively RECOMMENDED:
- User system inserts the Telnet "Interrupt Process" (IP) signal in the Telnet stream.
- User system sends the Telnet "Synch" signal.
- User system inserts the command (e.g., ABOR) in the Telnet stream.
- Server PI, after receiving "IP", scans the Telnet stream for EXACTLY ONE FTP command.
For other servers this may not be necessary, but the actions listed above SHOULD have no unusual effect ๐ค.
4.2. FTP REPLIES โจ
Replies to File Transfer Protocol commands are devised to ensure the synchronization of requests and actions in the process of file transfer, and to guarantee that the user process always knows the state of the Server ๐ง . Every command MUST generate at least one reply, although there MAY be more than one. In the latter case, the multiple replies MUST be easily distinguished ๐. In addition, some commands occur in sequential groups, such as USER, PASS and ACCT, or RNFR and RNTO ๐. The replies show the existence of an intermediate state if all preceding commands have been successful. A failure at any point in the sequence necessitates the repetition of the entire sequence from the beginning ๐ญ.
The details of the command-reply sequence are made explicit in a set of state diagrams below ๐บ๏ธ.
An FTP reply consists of a three digit number (transmitted as three alphanumeric characters) followed by some text ๐ข. The number is intended for use by automata to determine what state to enter next. The text is intended for the human user ๐. It is intended that the three digits contain enough encoded information that the user-process (the User-PI) will not need to examine the text, and it MAY either discard the text or pass it on to the user, as appropriate. In particular, the text may be server-dependent, so there are likely to be varying texts for each reply code ๐ญ.
A reply is defined to contain the 3-digit code, followed by Space <SP>, followed by one line of text (where some maximum line length has been specified), and terminated by the Telnet end-of-line code ๐. There will be cases, however, where the text is longer than a single line. In these cases the complete text MUST be bracketed so the User-process knows when it MAY stop reading the reply (i.e. stop processing input on the control connection) and go do other things ๐ฆ. This requires a special format on the first line to indicate that more than one line is coming, and another on the last line to designate it as the last. At least one of these MUST contain the appropriate reply code to indicate the state of the transaction. To satisfy all factions, it was decided that both the first and last line codes SHOULD be the same ๐ค.
Thus the format for multi-line replies is that the first line will begin with the exact required reply code, followed immediately by a Hyphen, "-" (also known as Minus), followed by text. The last line will begin with the same code, followed immediately by Space <SP>, optionally some text, and the Telnet end-of-line code ๐.
For example:
123-First line
Second line
234 A line beginning with numbers
123 The last line
The user-process then simply needs to search for the second occurrence of the same reply code, followed by <SP> (Space), at the beginning of a line, and ignore all intermediary lines ๐. If an intermediary line begins with a 3-digit number, the Server MUST pad the front to avoid confusion ๐ซง.
This scheme allows standard system routines to be used for reply information (such as for the STAT reply), with "artificial" first and last lines tacked on ๐งฉ. In rare cases where these routines are able to generate three digits and a Space at the beginning of any line, the beginning of each text line SHOULD be offset by some neutral text, like Space ๐ซ .
This scheme assumes that multi-line replies MAY not be nested ๐ช.
The three digits of the reply each have a special significance ๐ฎ. This is intended to allow a range of very simple to very sophisticated responses by the user-process. The first digit denotes whether the response is good, bad or incomplete. (Referring to the state diagram), an unsophisticated user-process will be able to determine its next action (proceed as planned, redo, retrench, etc.) by simply examining this first digit ๐. A user-process that wants to know approximately what kind of error occurred (e.g. file system error, command syntax error) MAY examine the second digit, reserving the third digit for the finest gradation of information (e.g., RNTO command without a preceding RNFR) ๐.
There are five values for the first digit of the reply code ๐:
1yz Positive Preliminary reply ๐: The requested action is being initiated. Expect another reply before proceeding with a new command. (The user-process sending another command before the completion reply would be in violation of protocol, but server-FTP processes SHOULD queue any commands that arrive while a preceding command is in progress.) This type of reply can be used to indicate that the command was accepted and the user-process MAY now pay attention to the data connections, for implementations where simultaneous monitoring is difficult. The server-FTP process MAY send at most, one 1yz reply per command.
2yz Positive Completion reply โ
: The requested action has been successfully completed. A new request MAY be initiated.
3yz Positive Intermediate reply โธ๏ธ: The command has been accepted, but the requested action is being held in abeyance, pending receipt of further information. The user SHOULD send another command specifying this information. This reply is used in command sequence groups.
4yz Transient Negative Completion reply ๐ฅบ: The command was not accepted and the requested action did not take place, but the error condition is temporary and the action MAY be requested again. The user SHOULD return to the beginning of the command sequence, if any. It is difficult to assign a meaning to "transient", particularly when two distinct sites (Server- and User-processes) have to agree on the interpretation ๐ค. Each reply in the 4yz category might have a slightly different time value, but the intent is that the user-process is encouraged to try again. A rule of thumb in determining if a reply fits into the 4yz or the 5yz (Permanent Negative) category is that replies are 4yz if the commands can be repeated without any change in command form or in properties of the User or Server (e.g., the command is spelled the same with the same arguments used; the user does not change his file access or user name; the server does not put up a new implementation.) ๐
5yz Permanent Negative Completion reply ๐: The command was not accepted and the requested action did not take place. The User-process is discouraged from repeating the exact request (in the same sequence). Even some "permanent" error conditions can be corrected, so the human user MAY want to direct his User-process to reinitiate the command sequence by direct action at some point in the future (e.g., after the spelling has been changed, or the user has altered his directory status.) ๐ซ
The following function groupings are encoded in the second digit:
x0z Syntax - These replies refer to syntax errors, syntactically correct commands that don't fit any functional category, unimplemented or superfluous commands.
x1z Information - These are replies to requests for information, such as status or help.
x2z Connections - Replies referring to the control and data connections.
x3z Authentication and accounting - Replies for the login process and accounting procedures.
x4z Unspecified as yet.
x5z File system - These replies indicate the status of the Server file system vis-a-vis the requested transfer or other file system action.
Okay so the third digit is where the drama is ๐
It gives a finer gradation of meaning inside each function category, and the second digit is what picks the category, bestie ๐ธ The list just below will show you exactly what I mean โจ Quick heads-up though: the text attached to each reply is RECOMMENDED, rather than mandatory, and it MAY even change depending on the command it's paired with ๐ The reply codes, on the other hand, MUST strictly follow the specifications in the last section ๐ฅ So Server implementations SHOULD NOT invent new codes for situations that are only slightly different. They SHOULD adapt codes that are already defined instead ๐ซถ
<pink>Now, a command like TYPE or ALLO whose successful execution doesn't give the user-process any new information will get a 200 reply ๐</pink> If the command isn't implemented by a particular Server-FTP process because it has no relevance to that computer system (ALLO at a TOPS20 site, for example), a Positive Completion reply is still desired ๐ง so the simple User-process knows it can keep going. That's where 202 comes in, with reply text like: "No storage allocation necessary." ๐ But if the command asks for a non-site-specific action and it's unimplemented, the response is 502 ๐ And 504 is the refinement for a command that IS implemented but asks for an unimplemented parameter ๐
### 4.2.1. Reply Codes by Function Groups โจ
200 Command okay. 500 Syntax error, command unrecognized. This MAY include errors such as command line too long. 501 Syntax error in parameters or arguments. 202 Command not implemented, superfluous at this site. 502 Command not implemented. 503 Bad sequence of commands. 504 Command not implemented for that parameter.
110 Restart marker reply. In this case, the text is exact and not left to the particular implementation; it MUST read: MARK yyyy = mmmm Where yyyy is User-process data stream marker, and mmmm server's equivalent marker (note the spaces between markers and "="). 211 System status, or system help reply. 212 Directory status. 213 File status. 214 Help message. On how to use the server or the meaning of a particular non-standard command. This reply is useful only to the human user. 215 NAME system type. Where NAME is an official system name from the list in the Assigned Numbers document.
120 Service ready in nnn minutes. 220 Service ready for new user. 221 Service closing control connection. Logged out if appropriate. 421 Service not available, closing control connection. This MAY be a reply to any command if the service knows it MUST shut down. 125 Data connection already open; transfer starting. 225 Data connection open; no transfer in progress. 425 Can't open data connection. 226 Closing data connection. Requested file action successful (for example, file transfer or file abort). 426 Connection closed; transfer aborted. 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).
230 User logged in, proceed. 530 Not logged in. 331 User name okay, need password. 332 Need account for login. 532 Need account for storing files.
150 File status okay; about to open data connection. 250 Requested file action okay, completed. 257 "PATHNAME" created. 350 Requested file action pending further information. 450 Requested file action not taken. File unavailable (e.g., file busy). 550 Requested action not taken. File unavailable (e.g., file not found, no access). 451 Requested action aborted. Local error in processing. 551 Requested action aborted. Page type unknown. 452 Requested action not taken. Insufficient storage space in system. 552 Requested file action aborted. Exceeded storage allocation (for current directory or dataset). 553 Requested action not taken. File name not allowed.
### 4.2.2. Numeric Order List of Reply Codes ๐
<lavender>Same codes as above, just lined up in numeric order so you can find them fast ๐</lavender>
110 Restart marker reply. In this case, the text is exact and not left to the particular implementation; it MUST read: MARK yyyy = mmmm Where yyyy is User-process data stream marker, and mmmm server's equivalent marker (note the spaces between markers and "="). 120 Service ready in nnn minutes. 125 Data connection already open; transfer starting. 150 File status okay; about to open data connection.
200 Command okay. 202 Command not implemented, superfluous at this site. 211 System status, or system help reply. 212 Directory status. 213 File status. 214 Help message. On how to use the server or the meaning of a particular non-standard command. This reply is useful only to the human user. 215 NAME system type. Where NAME is an official system name from the list in the Assigned Numbers document. 220 Service ready for new user. 221 Service closing control connection. Logged out if appropriate. 225 Data connection open; no transfer in progress. 226 Closing data connection. Requested file action successful (for example, file transfer or file abort). 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). 230 User logged in, proceed. 250 Requested file action okay, completed. 257 "PATHNAME" created.
331 User name okay, need password. 332 Need account for login. 350 Requested file action pending further information.
421 Service not available, closing control connection. This MAY be a reply to any command if the service knows it MUST shut down. 425 Can't open data connection. 426 Connection closed; transfer aborted. 450 Requested file action not taken. File unavailable (e.g., file busy). 451 Requested action aborted: local error in processing. 452 Requested action not taken. Insufficient storage space in system.
500 Syntax error, command unrecognized. This MAY include errors such as command line too long. 501 Syntax error in parameters or arguments. 502 Command not implemented. 503 Bad sequence of commands. 504 Command not implemented for that parameter. 530 Not logged in. 532 Need account for storing files. 550 Requested action not taken. File unavailable (e.g., file not found, no access). 551 Requested action aborted: page type unknown. 552 Requested file action aborted. Exceeded storage allocation (for current directory or dataset). 553 Requested action not taken. File name not allowed.
---
# 5. DECLARATIVE SPECIFICATIONS ๐
## 5.1. MINIMUM IMPLEMENTATION
In order to make FTP workable without needless error messages, the following minimum implementation is REQUIRED for all servers:
TYPE - ASCII Non-print MODE - Stream STRUCTURE - File, Record COMMANDS - USER, QUIT, PORT, TYPE, MODE, STRU, for the default values RETR, STOR, NOOP.
The default values for transfer parameters are:
TYPE - ASCII Non-print MODE - Stream STRU - File
<mint>All hosts MUST accept the above as the standard defaults. ๐งธ</mint>
## 5.2. CONNECTIONS ๐
The server protocol interpreter SHALL "listen" on Port L. The user or user protocol interpreter SHALL initiate the full-duplex control connection. Server- and user- processes SHOULD follow the conventions of the Telnet protocol as specified in the ARPA-Internet Protocol Handbook [1]. Servers are under no obligation to provide for editing of command lines and MAY require that it be done in the user host. The control connection SHALL be closed by the server at the user's request after all transfers and replies are completed.
The user-DTP MUST "listen" on the specified data port; this MAY be the default user port (U) or a port specified in the PORT command. The server SHALL initiate the data connection from its own default data port (L-1) using the specified user data port. The direction of the transfer and the port used will be determined by the FTP service command.
Note that all FTP implementation MUST support data transfer using the default port, and that only the USER-PI MAY initiate the use of non-default ports.
<cyan>When data is to be transferred between two servers, A and B (refer to Figure 2), the user-PI, C, sets up control connections with both server-PI's. One of the servers, say A, is then sent a PASV command telling it to "listen" on its data port rather than initiate a connection when it receives a transfer service command. When the user-PI receives an acknowledgment to the PASV command, which includes the identity of the host and port being listened on, the user-PI then sends A's port, a, to B in a PORT command; a reply is returned. The user-PI MAY then send the corresponding service commands to A and B. Server B initiates the connection and the transfer proceeds. The command-reply sequence is listed below where the messages are vertically synchronous but horizontally asynchronous:</cyan>
User-PI - Server A User-PI - Server B ------------------ ------------------
C->A : Connect C->B : Connect C->A : PASV A->C : 227 Entering Passive Mode. A1,A2,A3,A4,a1,a2 C->B : PORT A1,A2,A3,A4,a1,a2 B->C : 200 Okay C->A : STOR C->B : RETR B->A : Connect to HOST-A, PORT-a
Figure 3
The data connection SHALL be closed by the server under the conditions we covered in the Section on Establishing Data Connections ๐. If the data connection is being closed after a transfer and closing it isn't needed to show end-of-file, the server MUST close it immediately ๐. Waiting until after a new transfer command is a total no-go, because the user-process already checked the data connection to see if it needs to do a "listen" ๐. Remember, the user MUST "listen" on a closed data port BEFORE sending the transfer request. To prevent a race condition, the server sends a 226 reply after closing the data connection. If the connection is left open, it sends a "file transfer completed" 250 reply instead. Either way, the user-PI SHOULD wait for one of these replies before issuing a new transfer command ๐ซถ.
Anytime either the user or the server notices that the other side is closing the connection, it SHOULD promptly read any remaining data queued on the connection and issue the close on its own side ๐งน.
## 5.3. COMMANDS ๐
The commands are Telnet character strings sent over the control connections, just like we described in the Section on FTP Commands ๐. The command functions and semantics live in the Section on Access Control Commands, Transfer Parameter Commands, FTP Service Commands, and Miscellaneous Commands. The command syntax is specified right here โจ.
Each command starts with a command code, followed by an argument field. Command codes are four or fewer alphabetic characters, and upper and lower case are treated identically ๐. So any of these could mean the retrieve command:
RETR Retr retr ReTr rETr
The same goes for parameter values, like A or a for ASCII TYPE ๐ค. The command codes and argument fields are separated by one or more spaces.
The argument field is a variable length character string that ends with `<CRLF>` (Carriage Return, Line Feed) for NVT-ASCII representation. Other negotiated languages might use a different end of line character ๐. It SHOULD be noted that the server takes no action until it receives the end of line code ๐.
The syntax is written below in NVT-ASCII. Every character in the argument field is an ASCII character, including any ASCII represented decimal integers ๐ข. Square brackets mark an optional argument field. If the option isn't taken, the appropriate default is implied ๐.
### 5.3.1. FTP COMMANDS ๐ฆ
Here are the FTP commands, bestie:
USER <SP> <username> <CRLF> PASS <SP> <password> <CRLF> ACCT <SP> <account-information> <CRLF> CWD <SP> <pathname> <CRLF> CDUP <CRLF> SMNT <SP> <pathname> <CRLF> QUIT <CRLF> REIN <CRLF> PORT <SP> <host-port> <CRLF> PASV <CRLF> TYPE <SP> <type-code> <CRLF> STRU <SP> <structure-code> <CRLF> MODE <SP> <mode-code> <CRLF> RETR <SP> <pathname> <CRLF> STOR <SP> <pathname> <CRLF> STOU <CRLF> APPE <SP> <pathname> <CRLF> ALLO <SP> <decimal-integer> [<SP> R <SP> <decimal-integer>] <CRLF> REST <SP> <marker> <CRLF> RNFR <SP> <pathname> <CRLF> RNTO <SP> <pathname> <CRLF> ABOR <CRLF> DELE <SP> <pathname> <CRLF> RMD <SP> <pathname> <CRLF> MKD <SP> <pathname> <CRLF> PWD <CRLF> LIST [<SP> <pathname>] <CRLF> NLST [<SP> <pathname>] <CRLF> SITE <SP> <string> <CRLF> SYST <CRLF> STAT [<SP> <pathname>] <CRLF> HELP [<SP> <string>] <CRLF> NOOP <CRLF>
### 5.3.2. FTP COMMAND ARGUMENTS ๐ง
Here's the syntax for the argument fields above, written in BNF notation where it applies ๐:
<username> ::= <string> <password> ::= <string> <account-information> ::= <string> <string> ::= <char> | <char><string> <char> ::= any of the 128 ASCII characters except <CR> and <LF> <marker> ::= <pr-string> <pr-string> ::= <pr-char> | <pr-char><pr-string> <pr-char> ::= printable characters, any ASCII code 33 through 126 <byte-size> ::= <number> <host-port> ::= <host-number>,<port-number> <host-number> ::= <number>,<number>,<number>,<number> <port-number> ::= <number>,<number> <number> ::= any decimal integer 1 through 255 <form-code> ::= N | T | C <type-code> ::= A [<sp> <form-code>]
| E [<sp> <form-code>] |
|---|
| I |
| L <sp> <byte-size> |
<structure-code> ::= F | R | P <mode-code> ::= S | B | C <pathname> ::= <string> <decimal-integer> ::= any decimal integer
## 5.4. SEQUENCING OF COMMANDS AND REPLIES ๐ฌ
Users and servers are meant to have an alternating dialogue, like a good text thread ๐ฌ. The user sends an FTP command, and the server responds with a prompt primary reply. The user SHOULD wait for this initial primary success or failure response before sending any more commands.
Some commands need a second reply, and the user SHOULD also wait for it ๐ฐ๏ธ. These replies can report on the progress or completion of a file transfer, or on the closing of the data connection. They're secondary replies to file transfer commands.
One important group of informational replies is the connection greetings ๐. Normally, a server sends a 220 reply, "awaiting input", once the connection is complete. The user SHOULD wait for this greeting before sending any commands. If the server can't accept input right away, it SHOULD immediately send a 120 "expected delay" reply, and then a 220 reply when it's ready. That way the user knows not to hang up during a delay ๐.
### Spontaneous Replies ๐ฃ
Sometimes "the system" has a message to send to a user (usually all users), like "System going down in 15 minutes" ๐ฑ. FTP has no provision for sending that kind of spontaneous information from the server to the user. It is RECOMMENDED that such information be queued in the server-PI and delivered to the user-PI in the next reply, which might make that reply multi-line ๐ฆ.
The table below lists the alternative success and failure replies for each command. These MUST be strictly adhered to. A server MAY substitute text in the replies, but the meaning and action implied by the code numbers and by the specific command reply sequence cannot be changed ๐ซ.
### Command-Reply Sequences ๐๏ธ
In this section, the command-reply sequence is laid out. Each command is listed with its possible replies, and command groups are listed together. Preliminary replies come first, with their succeeding replies indented under them. Then come the positive and negative completion replies, and finally the intermediary replies, with the remaining commands from the sequence following. This listing is the basis for the state diagrams, which will be presented separately ๐ง .
Connection Establishment 120 220 220 421 Login USER 230 530 500, 501, 421 331, 332 PASS 230 202 530 500, 501, 503, 421 332 ACCT 230 202 530 500, 501, 503, 421 CWD 250 500, 501, 502, 421, 530, 550 CDUP 200 500, 501, 502, 421, 530, 550 SMNT 202, 250 500, 501, 502, 421, 530, 550 Logout REIN 120 220 220 421 500, 502 QUIT 221 500
Transfer parameters PORT 200 500, 501, 421, 530 PASV 227 500, 501, 502, 421, 530 MODE 200 500, 501, 504, 421, 530 TYPE 200 500, 501, 504, 421, 530 STRU 200 500, 501, 504, 421, 530 File action commands ALLO 200 202 500, 501, 504, 421, 530 REST 500, 501, 502, 421, 530 350 STOR 125, 150 (110) 226, 250 425, 426, 451, 551, 552 532, 450, 452, 553 500, 501, 421, 530 STOU 125, 150 (110) 226, 250 425, 426, 451, 551, 552 532, 450, 452, 553 500, 501, 421, 530 RETR 125, 150 (110) 226, 250 425, 426, 451 450, 550 500, 501, 421, 530
LIST 125, 150 226, 250 425, 426, 451 450 500, 501, 502, 421, 530 NLST 125, 150 226, 250 425, 426, 451 450 500, 501, 502, 421, 530 APPE 125, 150 (110) 226, 250 425, 426, 451, 551, 552 532, 450, 550, 452, 553 500, 501, 502, 421, 530 RNFR 450, 550 500, 501, 502, 421, 530 350 RNTO 250 532, 553 500, 501, 502, 503, 421, 530 DELE 250 450, 550 500, 501, 502, 421, 530 RMD 250 500, 501, 502, 421, 530, 550 MKD 257 500, 501, 502, 421, 530, 550 PWD 257 500, 501, 502, 421, 550 ABOR 225, 226 500, 501, 502, 421
Informational commands SYST 215 500, 501, 502, 421 STAT 211, 212, 213 450 500, 501, 502, 421, 530 HELP 211, 214 500, 501, 502, 421 Miscellaneous commands SITE 200 202 500, 501, 530 NOOP 200 500 421
# 6. STATE DIAGRAMS ๐ธ
okay so this part is my absolute favourite ๐ฆ we're looking at state diagrams for a super simple FTP implementation. Only the first digit of the reply codes gets used here, so you just check the 1, 2, 3, 4 or 5 and that's it ๐
The command groupings weren't random, bestie. The way they were sorted was by building a model for each command, then grouping the ones with structurally identical models together ๐งฉ
For each command or command sequence there are three possible outcomes: success (S), failure (F), and error (E). In the diagrams we use **B** for "begin" and **W** for "wait for reply" โจ
We'll start with the diagram for the biggest group of FTP commands ๐
1,3 +---+ ----------->| E |
| +---+ |
+---+ cmd +---+ 2 +---+
| B | ----------> | W | ----------> | S |
+---+ +---+ +---+
| 4,5 +---+ |
----------->| F | +---+
This diagram models the commands:
ABOR, ALLO, DELE, CWD, CDUP, SMNT, HELP, MODE, NOOP, PASV, QUIT, SITE, PORT, SYST, STAT, RMD, MKD, PWD, STRU, and TYPE.
The other big group gets a very similar diagram ๐
3 +---+ ----------->| E |
| +---+ |
+---+ cmd +---+ 2 +---+
| B | ----------> | W | ----------> | S |
+---+ --->+---+ +---+
| 4,5 +---+ | ||
|---|---|---|
| 1 | -----------> | F |
----- +---+
This diagram models the commands:
APPE, LIST, NLST, REIN, RETR, STOR, and STOU.
Now, this second model could also work for the first group. The only real difference is that in the first group, 100 series replies are unexpected, so they get treated as errors. The second group expects them (some may even require them) ๐ Remember that at most, one 100 series reply is allowed per command. That detail is literally everything ๐
Next up are the diagrams for command *sequences*. The simplest one is the rename sequence ๐
+---+ RNFR +---+ 1,2 +---+
| B | ----------> | W | ----------> | E |
+---+ +---+ -->+---+
3 | | 4,5 | -------------- ------ |
| +---+ | |||
|---|---|---|---|
| -------------> | S | ||
| 1,3 | +---+ | ||
| 2 | -------- |
V | | | +---+ RNTO +---+ 4,5 ----->+---+
| ----------> | W | ----------> | F |
+---+ +---+ +---+
The restart command gets its own simple model too โจ
+---+ REST +---+ 1,2 +---+
| B | ----------> | W | ----------> | E |
+---+ +---+ -->+---+
3 | | 4,5 | -------------- ------ |
| +---+ | |||
|---|---|---|---|
| -------------> | S | ||
| 3 | +---+ | ||
| 2 | -------- |
V | | | +---+ cmd +---+ 4,5 ----->+---+
| ----------> | W | ----------> | F |
+---+ -->+---+ +---+
| 1 |
------
Where "cmd" is APPE, STOR, or RETR.
Honestly, all three of these models are giving the same vibe ๐ฆ The restart one only differs from the rename one in how it handles 100 series replies at the second stage. Same reminder again: at most, one 100 series reply is allowed per command ๐
Last but definitely not least is the login sequence, which is the most complicated diagram of the whole bunch ๐ญ๐ซถ
1 +---+ USER +---+------------->+---+
| B | ----------> | W | 2 ----> | E |
+---+ +---+------ | -->+---+
3 | | 4,5 | | | -------------- ----- | | |
| 1 |
V | | | | +---+ PASS +---+ 2 | ------>+---+
| ----------> | W | -------------> | S |
+---+ +---+ ---------->+---+
3 | |4,5| | | -------------- -------- |
| 1,3 |
V | 2| | | +---+ ACCT +---+-- | ----->+---+
| ----------> | W | 4,5 --------> | F |
+---+ +---+------------->+---+
Finally, there's a generalized diagram that can model the whole command and reply interchange, which is basically the big-picture view of everything above ๐
------------------------------------
Begin | |
| V |
|---|
| +---+ cmd +---+ 2 +---+ |
-->| |------->| |---------->| | |
| W | S | ----- |
-->| | -->| |----- | | |
| +---+ | +---+ 4,5 | +---+ | |||
|---|---|---|---|---|---|
| 1 | 3 | +---+ | |||
| ---- | ----> | F | ----- | ||
| +---+ |
-------------------
V End
# 7. TYPICAL FTP SCENARIO ๐ง
User at host U wanting to transfer files to/from host S:
Okay, so the user will usually talk to the server through a mediating user-FTP process ๐
Here's what a typical scenario looks like. The user-FTP prompts are shown in parentheses, `---->` means commands going from host U to host S, and `<----` means replies going from host S back to host U โจ
LOCAL COMMANDS BY USER ACTION INVOLVED
ftp (host) multics<CR> Connect to host S, port L, establishing control connections. <---- 220 Service ready <CRLF>. username Doe <CR> USER Doe<CRLF>----> <---- 331 User name ok, need password<CRLF>. password mumble <CR> PASS mumble<CRLF>----> <---- 230 User logged in<CRLF>. retrieve (local type) ASCII<CR> (local pathname) test 1 <CR> User-FTP opens local file in ASCII. (for. pathname) test.pl1<CR> RETR test.pl1<CRLF> ----> <---- 150 File status okay; about to open data connection<CRLF>. Server makes data connection to port U.
<---- 226 Closing data connection, file transfer successful<CRLF>. type Image<CR> TYPE I<CRLF> ----> <---- 200 Command OK<CRLF> store (local type) image<CR> (local pathname) file dump<CR> User-FTP opens local file in Image. (for.pathname) >udd>cn>fd<CR> STOR >udd>cn>fd<CRLF> ----> <---- 550 Access denied<CRLF> terminate QUIT <CRLF> ----> Server closes all connections.
# 8. CONNECTION ESTABLISHMENT ๐
Here's the setup part, bestie ๐ซถ The FTP control connection gets set up over TCP, between the user process at port U and the server process at port L. This protocol is assigned the service port 21 (25 octal), so L=21 ๐
# APPENDIX I - PAGE STRUCTURE ๐โจ
Okay so this appendix is all about why FTP needs to support **page structure** in the first place. ๐ง The main reason is that TOPS-20 systems need to send files to each other efficiently, especially the files used by NLS.
TOPS-20's file system is built around pages, and the operating system is at its most efficient when it handles files as pages. It gives applications an interface so that most of them can view files as sequential streams of characters. A few applications poke at the underlying page structures directly, though, and some of those end up creating **holey files** ๐ณ๏ธ.
A TOPS-20 disk file is made of four things: a pathname, a page table, a (possibly empty) set of pages, and a set of attributes. ๐
The pathname is given in the RETR or STOR command. It includes the directory name, the file name, the file name extension, and the generation number.
The page table can hold up to `2**18` entries. Each entry is either EMPTY or points to a page. If the entry isn't empty, it also has some page-specific access bits, so not every page in a file needs the same access protection. ๐
> A page is a contiguous set of 512 words of 36 bits each.
The attributes of the file live in the File Descriptor Block (FDB). They hold things like the creation time, write time, and read time, the writer's byte-size, the end-of-file pointer, the count of reads and writes, backup system tape numbers, and so on. ๐
Here's the tea: there is NO requirement that the entries in the page table be contiguous. There can be empty page table slots sitting between occupied ones. ๐ The end-of-file pointer is also just a number. Nothing says it has to point at the "last" datum in the file. Ordinary sequential I/O calls in TOPS-20 leave the end-of-file pointer right after the last datum written, but other operations can leave it somewhere else if a particular programming system needs that.
Both of these special cases, "holey" files and end-of-file pointers that are NOT at the end of the file, show up with NLS data files. โจ
TOPS-20 paged files can be sent using the FTP transfer parameters `TYPE L 36`, `STRU P`, and `MODE S`. Honestly, any mode could be used here. ๐
Every page of information comes with a header. Each header field is a logical byte, and since the TYPE is `L 36`, each one is a TOPS-20 word. ๐
The header fields are:
- **Word 0: Header Length.** The header length is 5.
- **Word 1: Page Index.** If the data is a disk file page, this is the number of that page in the file's page map. Empty pages (holes) in the file are simply not sent. A hole is NOT the same thing as a page of zeros, so keep that straight! ๐
- **Word 2: Data Length.** This is the number of data words in the page, following the header. So the total length of the transmission unit is the Header Length plus the Data Length. ๐งฎ
- **Word 3: Page Type.** A code for what type of chunk this is. A data page is type 3, and the FDB page is type 2.
- **Word 4: Page Access Control.** The access bits associated with the page in the file's page map. This full word quantity gets put into AC2 of an SPACS by the program reading from net to disk. ๐
After the header come Data Length data words. Right now Data Length is either 512 for a data page or 31 for an FDB. Trailing zeros in a disk file page may be discarded, which makes Data Length less than 512 in that case. ๐ซง
---
# APPENDIX II - DIRECTORY COMMANDS ๐๐ธ
Okay, UNIX has a tree-like directory structure where directories are as easy to manipulate as ordinary files. So it makes sense to expand the FTP servers on those machines with commands for creating directories. Other ARPA-Internet hosts have tree-like directories too (TOPS-20 and Multics, for example), so these commands are written to be as general as possible. ๐ณ
Four directory commands were added to FTP:
- `MKD pathname`: Make a directory with the name "pathname".
- `RMD pathname`: Remove the directory with the name "pathname".
- `PWD`: Print the current working directory name.
- `CDUP`: Change to the parent of the current working directory.
The "pathname" argument should be created (or removed) as a subdirectory of the current working directory, unless the "pathname" string has enough information to tell the server otherwise. For instance, "pathname" could be an absolute pathname (in UNIX and Multics), or it could look something like `<abso.lute.path>` on TOPS-20. ๐งญ
## REPLY CODES ๐ฌ
The CDUP command is basically a special case of CWD. It's included so programs that transfer directory trees between operating systems with different syntaxes for naming the parent directory are easier to write. The reply codes for CDUP be identical to the reply codes of CWD.
The reply codes for RMD be identical to the reply codes for its file analogue, DELE.
The reply codes for MKD are a bit more complicated, though. A freshly created directory will probably be the target of a future CWD command. Unfortunately, the argument to MKD might not always be a suitable argument for CWD. For example, that happens when a TOPS-20 subdirectory is created by giving just the subdirectory name. With a TOPS-20 server FTP, this command sequence:
MKD MYDIR CWD MYDIR
will fail. The new directory can only be referred to by its "absolute" name. For example, if the MKD command above were issued while connected to the directory `<DFRANKLIN>`, the new subdirectory could only be referred to as `<DFRANKLIN.MYDIR>`. ๐ฌ
Even on UNIX and Multics, the argument given to MKD might not be suitable. If it's a "relative" pathname (meaning a pathname interpreted relative to the current directory), the user would need to be in that same current directory to reach the subdirectory. Depending on the application, that can be a real pain. It isn't very robust in any case. ๐
So to fix all of this, the server should return a line of this form after an MKD command completes successfully:
257<space>"<directory-name>"<space><commentary>
In other words, the server tells the user exactly what string to use when referring to the new directory. โจ The directory name can contain any character. Embedded double-quotes get escaped by doubling them (the "quote-doubling" convention).
For example, a user connects to the directory /usr/dm and creates a subdirectory named pathname:
CWD /usr/dm 200 directory changed to /usr/dm MKD pathname 257 "/usr/dm/pathname" directory created
Here's an example with an embedded double quote:
MKD foo"bar 257 "/usr/dm/foo""bar" directory created CWD /usr/dm/foo"bar 200 directory changed to /usr/dm/foo"bar
If a subdirectory with the same name already exists, that's an error, and the server must return an "access denied" error reply in that case. ๐ซ
CWD /usr/dm 200 directory changed to /usr/dm MKD pathname 521-"/usr/dm/pathname" directory already exists; 521 taking no action.
The failure replies for MKD are analogous to those for its file-creating cousin, STOR. Also, an "access denied" return is given if a file with the same name as the subdirectory would conflict with creating that subdirectory. This is a problem on UNIX, but it shouldn't be one on TOPS-20. ๐
Because the PWD command returns the same type of information as a successful MKD command, a successful PWD command uses the 257 reply code as well. ๐
## SUBTLETIES ๐
These commands are going to be most useful when transferring subtrees from one machine to another, so pay close attention here: the argument to MKD is to be interpreted as a subdirectory of the current working directory, unless it contains enough information for the destination host to tell otherwise. Here's a hypothetical example of its use in the TOPS-20 world:
CWD <some.where> 200 Working directory changed MKD overrainbow 257 "<some.where.overrainbow>" directory created CWD overrainbow 431 No such directory CWD <some.where.overrainbow> 200 Working directory changed
CWD <some.where> 200 Working directory changed to <some.where> MKD <unambiguous> 257 "<unambiguous>" directory created CWD <unambiguous>
The first example makes a subdirectory of the connected directory. The argument in the second example contains enough information for TOPS-20 to tell that the `<unambiguous>` directory is a top-level directory. ๐ง
Also notice that in the first example the user "violated" the protocol by trying to access the freshly created directory with a name other than the one TOPS-20 returned. That could have caused problems if there had been an `<overrainbow>` directory already. It's an ambiguity inherent in some TOPS-20 implementations. Similar considerations apply to the RMD command. ๐
The point is this: except where doing so would violate a host's conventions for denoting relative versus absolute pathnames, the host should treat the operands of the MKD and RMD commands as subdirectories. And the 257 reply to the MKD command must always contain the absolute pathname of the created directory. ๐ซถ
# APPENDIX III - RFCs on FTP ๐
Okay bestie, this is the receipts list ๐งพ every FTP RFC that came before this one, going all the way back to the 1970s. The whole family tree is right here. ๐ณโจ
- Bhushan, Abhay, "A File Transfer Protocol", RFC 114 (NIC 5823), MIT-Project MAC, 16 April 1971.
- Harslem, Eric, and John Heafner, "Comments on RFC 114 (A File Transfer Protocol)", RFC 141 (NIC 6726), RAND, 29 April 1971.
- Bhushan, Abhay, et al, "The File Transfer Protocol", RFC 172 (NIC 6794), MIT-Project MAC, 23 June 1971.
- Braden, Bob, "Comments on DTP and FTP Proposals", RFC 238 (NIC 7663), UCLA/CCN, 29 September 1971.
- Bhushan, Abhay, et al, "The File Transfer Protocol", RFC 265 (NIC 7813), MIT-Project MAC, 17 November 1971.
- McKenzie, Alex, "A Suggested Addition to File Transfer Protocol", RFC 281 (NIC 8163), BBN, 8 December 1971.
- Bhushan, Abhay, "The Use of "Set Data Type" Transaction in File Transfer Protocol", RFC 294 (NIC 8304), MIT-Project MAC, 25 January 1972.
- Bhushan, Abhay, "The File Transfer Protocol", RFC 354 (NIC 10596), MIT-Project MAC, 8 July 1972.
- Bhushan, Abhay, "Comments on the File Transfer Protocol (RFC 354)", RFC 385 (NIC 11357), MIT-Project MAC, 18 August 1972.
- Hicks, Greg, "User FTP Documentation", RFC 412 (NIC 12404), Utah, 27 November 1972.
- Bhushan, Abhay, "File Transfer Protocol (FTP) Status and Further Comments", RFC 414 (NIC 12406), MIT-Project MAC, 20 November 1972.
- Braden, Bob, "Comments on File Transfer Protocol", RFC 430 (NIC 13299), UCLA/CCN, 7 February 1973.
- Thomas, Bob, and Bob Clements, "FTP Server-Server Interaction", RFC 438 (NIC 13770), BBN, 15 January 1973.
- Braden, Bob, "Print Files in FTP", RFC 448 (NIC 13299), UCLA/CCN, 27 February 1973.
- McKenzie, Alex, "File Transfer Protocol", RFC 454 (NIC 14333), BBN, 16 February 1973.
- Bressler, Bob, and Bob Thomas, "Mail Retrieval via FTP", RFC 458 (NIC 14378), BBN-NET and BBN-TENEX, 20 February 1973.
- Neigus, Nancy, "File Transfer Protocol", RFC 542 (NIC 17759), BBN, 12 July 1973.
- Krilanovich, Mark, and George Gregg, "Comments on the File Transfer Protocol", RFC 607 (NIC 21255), UCSB, 7 January 1974.
- Pogran, Ken, and Nancy Neigus, "Response to RFC 607 - Comments on the File Transfer Protocol", RFC 614 (NIC 21530), BBN, 28 January 1974.
- Krilanovich, Mark, George Gregg, Wayne Hathaway, and Jim White, "Comments on the File Transfer Protocol", RFC 624 (NIC 22054), UCSB, Ames Research Center, SRI-ARC, 28 February 1974.
- Bhushan, Abhay, "FTP Comments and Response to RFC 430", RFC 463 (NIC 14573), MIT-DMCG, 21 February 1973.
- Braden, Bob, "FTP Data Compression", RFC 468 (NIC 14742), UCLA/CCN, 8 March 1973.
- Bhushan, Abhay, "FTP and Network Mail System", RFC 475 (NIC 14919), MIT-DMCG, 6 March 1973.
- Bressler, Bob, and Bob Thomas "FTP Server-Server Interaction - II", RFC 478 (NIC 14947), BBN-NET and BBN-TENEX, 26 March 1973.
- White, Jim, "Use of FTP by the NIC Journal", RFC 479 (NIC 14948), SRI-ARC, 8 March 1973.
- White, Jim, "Host-Dependent FTP Parameters", RFC 480 (NIC 14949), SRI-ARC, 8 March 1973.
- Padlipsky, Mike, "An FTP Command-Naming Problem", RFC 506 (NIC 16157), MIT-Multics, 26 June 1973.
- Day, John, "Memo to FTP Group (Proposal for File Access Protocol)", RFC 520 (NIC 16819), Illinois, 25 June 1973.
- Merryman, Robert, "The UCSD-CC Server-FTP Facility", RFC 532 (NIC 17451), UCSD-CC, 22 June 1973.
- Braden, Bob, "TENEX FTP Problem", RFC 571 (NIC 18974), UCLA/CCN, 15 November 1973.
- McKenzie, Alex, and Jon Postel, "Telnet and FTP Implementation - Schedule Change", RFC 593 (NIC 20615), BBN and MITRE, 29 November 1973.
- Sussman, Julie, "FTP Error Code Usage for More Reliable Mail Service", RFC 630 (NIC 30237), BBN, 10 April 1974.
- Postel, Jon, "Revised FTP Reply Codes", RFC 640 (NIC 30843), UCLA/NMC, 5 June 1974.
- Harvey, Brian, "Leaving Well Enough Alone", RFC 686 (NIC 32481), SU-AI, 10 May 1975.
- Harvey, Brian, "One More Try on the FTP", RFC 691 (NIC 32700), SU-AI, 28 May 1975.
- Lieb, J., "CWD Command of FTP", RFC 697 (NIC 32963), 14 July 1975.
- Harrenstien, Ken, "FTP Extension: XSEN", RFC 737 (NIC 42217), SRI-KL, 31 October 1977.
- Harrenstien, Ken, "FTP Extension: XRSQ/XRCP", RFC 743 (NIC 42758), SRI-KL, 30 December 1977.
- Lebling, P. David, "Survey of FTP Mail and MLFL", RFC 751, MIT, 10 December 1978.
- Postel, Jon, "File Transfer Protocol Specification", RFC 765, ISI, June 1980.
- Mankins, David, Dan Franklin, and Buzz Owen, "Directory Oriented FTP Commands", RFC 776, BBN, December 1980.
- Padlipsky, Michael, "FTP Unique-Named Store Command", RFC 949, MITRE, July 1985.
# REFERENCES ๐
- [1] Feinler, Elizabeth, "Internet Protocol Transition Workbook", Network Information Center, SRI International, March 1982.
- [2] Postel, Jon, "Transmission Control Protocol - DARPA Internet Program Protocol Specification", RFC 793, DARPA, September 1981.
- [3] Postel, Jon, and Joyce Reynolds, "Telnet Protocol Specification", RFC 854, ISI, May 1983.
- [4] Reynolds, Joyce, and Jon Postel, "Assigned Numbers", RFC 943, ISI, April 1985.
๐ฆ where this page comes from
- ietf: rfc959 1985-10
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms