RFC 3659
Extensions to FTP
RFC 3659: Extensions to FTP π
okay bestie, this one is the Extensions to FTP spec by P. Hethmon of Hethmon Software, published March 2007 πΈ It's a Standards Track doc, so it's an official Internet protocol spec, not just a vibe. It updates RFC 959 (the original FTP spec) and doesn't obsolete anything. Basically it's the glow-up pack for FTP β¨
Status of This Memo π
this doc specifies an Internet standards track protocol for the Internet community, and it's literally asking for discussion and suggestions for improvements π«Ά for the current standardization state, check the "Internet Official Protocol Standards" (STD 1) list. distribution of this memo is unlimited, so share away π¦
Copyright Notice Β©οΈ
Copyright (C) The IETF Trust (2007). π
Abstract β¨
so this doc adds new FTP commands that give you listings of remote directories in a defined format, and lets you restart interrupted data transfers in STREAM mode π₯ it also allows character sets other than US-ASCII, and defines an optional virtual file storage structure, which is giving flexible and iconic π
Table of Contents ποΈ
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Document Conventions . . . . . . . . . . . . . . . . . . . . . 3
2.1. Basic Tokens . . . . . . . . . . . . . . . . . . . . . . 4
2.2. Pathnames. . . . . . . . . . . . . . . . . . . . . . . . 4
2.3. Times. . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.4. Server Replies . . . . . . . . . . . . . . . . . . . . . 7
2.5. Interpreting Examples. . . . . . . . . . . . . . . . . . 8
3. File Modification Time (MDTM). . . . . . . . . . . . . . . . . 8
3.1. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2. Error Responses. . . . . . . . . . . . . . . . . . . . . 9
3.3. FEAT Response for MDTM . . . . . . . . . . . . . . . . . 10
3.4. MDTM Examples. . . . . . . . . . . . . . . . . . . . . . 10
4. File SIZE. . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.1. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.2. Error Responses. . . . . . . . . . . . . . . . . . . . . 12
4.3. FEAT Response for SIZE . . . . . . . . . . . . . . . . . 12
4.4. Size Examples. . . . . . . . . . . . . . . . . . . . . . 12
5. Restart of Interrupted Transfer (REST) . . . . . . . . . . . . 13
5.1. Restarting in STREAM Mode. . . . . . . . . . . . . . . . 14
5.2. Error Recovery and Restart . . . . . . . . . . . . . . . 14
5.3. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 15
5.4. FEAT Response for REST . . . . . . . . . . . . . . . . . 16
5.5. REST Example . . . . . . . . . . . . . . . . . . . . . . 17
6. A Trivial Virtual File Store (TVFS). . . . . . . . . . . . . . 17
6.1. TVFS File Names. . . . . . . . . . . . . . . . . . . . . 18
6.2. TVFS Pathnames . . . . . . . . . . . . . . . . . . . . . 18
6.3. FEAT Response for TVFS . . . . . . . . . . . . . . . . . 20
6.4. OPTS for TVFS. . . . . . . . . . . . . . . . . . . . . . 21
6.5. TVFS Examples. . . . . . . . . . . . . . . . . . . . . . 21
7. Listings for Machine Processing (MLST and MLSD). . . . . . . . 23
7.1. Format of MLSx Requests. . . . . . . . . . . . . . . . . 23
7.2. Format of MLSx Response. . . . . . . . . . . . . . . . . 24
7.3. File Name Encoding . . . . . . . . . . . . . . . . . . . 26
7.4. Format of Facts. . . . . . . . . . . . . . . . . . . . . 28
7.5. Standard Facts . . . . . . . . . . . . . . . . . . . . . 28
7.6. System Dependent and Local Facts . . . . . . . . . . . . 36
7.7. MLSx Examples. . . . . . . . . . . . . . . . . . . . . . 37
7.8. FEAT Response for MLSx . . . . . . . . . . . . . . . . . 49
7.9. OPTS Parameters for MLST . . . . . . . . . . . . . . . . 51
8. Impact on Other FTP Commands . . . . . . . . . . . . . . . . . 54
9. Character Sets and Internationalization. . . . . . . . . . . . 55
10. IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 55
10.1. The OS Specific Fact Registry. . . . . . . . . . . . . . 56
10.2. The OS Specific Filetype Registry. . . . . . . . . . . . 56
11. Security Considerations. . . . . . . . . . . . . . . . . . . . 57
12. Normative References . . . . . . . . . . . . . . . . . . . . . 58
Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . . . 59
1. Introduction β¨
okay so this doc updates the File Transfer Protocol (FTP) [3] π it adds four new commands: "SIZE", "MDTM", "MLST", and "MLSD". it also modifies the existing command "REST". the "SIZE" and "MDTM" commands, plus the REST changes, have been in wide use for years, and the other two are brand new π§
these commands let a client restart an interrupted transfer in transfer modes that weren't previously supported in any documented way, and get a directory listing in a machine friendly, predictable format π€π
there's also an optional structure for the server's file store (NVFS) defined here. servers that support it can tell clients about it in a standard way, so clients get more certainty when they build and interpret pathnames π¦
2. Document Conventions π
this doc uses the conventions defined in BCP 14, RFC 2119 [4]. that's what tells you how to read the capitalized imperative words like MUST, SHOULD, etc. π
it also uses notation from STD 9, RFC 959 [3]. the terms "reply", "user", "NVFS" (Network Virtual File System), "file", "pathname", "FTP commands", "DTP" (data transfer process), "user-FTP process", "user-PI" (user protocol interpreter), "user-DTP", "server-FTP process", "server-PI", "server-DTP", "mode", "type", "NVT" (Network Virtual Terminal), "control connection", "data connection", and "ASCII" all mean what they mean there π
syntax is written in Augmented BNF from [5]. some general ABNF definitions get used all over the place, and they'll be defined later in this section. on a first read, it's fine to just remember they exist and skip ahead to the next section π
2.1. Basic Tokens π
this doc imports the core ABNF definitions from Appendix A of [5]. that's where you'll find basics like ALPHA, DIGIT, SP, etc. it also adds these terms π
TCHAR = VCHAR / SP / HTAB ; visible plus white space
RCHAR = ALPHA / DIGIT / "," / "." / ":" / "!" /
"@" / "#" / "$" / "%" / "^" /
"&" / "(" / ")" / "-" / "_" /
"+" / "?" / "/" / "\" / "'" /
DQUOTE ; <"> -- double quote character (%x22)
SCHAR = RCHAR / "=" ;
VCHAR (from [5]), RCHAR, SCHAR, and TCHAR are basic character types. they're different subsets of ASCII that get used in different commands and responses π«Ά
token = 1*RCHAR
a "token" is a string whose exact meaning depends on where it's used π§ sometimes it's a value from a set that's maintained somewhere else. other times, one party to an FTP conversation made it up from whatever sources it found relevant πΈ
note that string literals in ABNF are case insensitive. this doc keeps that convention, which means the FTP commands added here can be written in any case. so "MDTM" is the same as "mdtm", "Mdtm", "MdTm", and so on π but ALPHA is case sensitive, so a "token" is case sensitive too. that's true unless this doc says otherwise, or a different spec that defines the values for a particular context says otherwise π
2.2. Pathnames πΊοΈ
a bunch of FTP commands take pathnames as arguments, or send them back in replies. when the MLST command is supported (you'll see it in the FEAT response [6]), pathnames have to be sent in one of these two formats π₯
pathname = utf-8-name / raw
utf-8-name = <a UTF-8 encoded Unicode string>
raw = <any string that is not a valid UTF-8 encoding>
the sender (user-PI or server-PI) picks which format to use π¦ UTF-8 encodings [2] have enough internal structure that, in practice, you can always tell whether UTF-8 or raw was used in the cases where it matters β¨ it's nice for the user-PI to display a pathname from the server-PI correctly, but way more important that it can keep and resend the exact same pathname when needed π implementations are advised against converting a UTF-8 pathname into a local charset that can't represent the full Unicode character repertoire, and then trying to undo that conversion later π ASCII is a subset of UTF-8, and see also [1] πΈ
unless something says otherwise, the pathname ends at the CRLF that ends the FTP command, or the CRLF that ends a reply. any trailing spaces before that CRLF are part of the name π exactly one space comes right before the pathname and separates it from the syntax element before it. any extra spaces are part of the pathname too π see [7] for a fuller explanation of character encoding issues. all implementations supporting MLST MUST support [7] π
Note: for pathnames sent over a data connection, there's no way to represent a pathname with the characters CR and LF next to each other and still tell that apart from the end of line. so pathnames with the CRLF pair can't be sent over a data connection. data connections only carry file names that server-FTP sends to user-FTP as the result of one of the directory listing commands. files with CRLF in their names either have that sequence converted to some other form, one that can be recognised and turned back into CRLF correctly, or they get left out of the listing π
implementations should also watch out: the FTP control connection uses Telnet NVT conventions [8], and if the Telnet IAC character is part of a pathname sent over the control connection, it MUST be correctly escaped as the Telnet protocol defines π«Ά
NVT also tells apart CR, LF, and the end of line CRLF. so it would let pathnames with CR and LF in them get sent correctly. but since that sequence can't go over a data connection (as part of the result of a LIST, NLST, or MLSD command), those pathnames are best avoided π
implementors should also be aware that even though Telnet NVT conventions are used over the control connections, Telnet option negotiation MUST NOT be attempted. see section 4.1.2.12 of [9] π₯
2.2.1. Pathname Syntax π§©
except where TVFS is supported (see section 6), this spec doesn't impose any syntax on pathnames. it also doesn't restrict which character set pathnames get built from π that doesn't mean the NVFS has to make sense of every possible pathname. server-PIs can limit the syntax of valid pathnames in their NVFS in whatever way fits their implementation or underlying file system π and a server-PI can parse a pathname and give meaning to the components it finds β¨
2.2.2. Wildcarding β¨
Okay bestie, so for the commands in this spec, every pathname gets read literally π«Ά If you give a pathname as a parameter, the file with that exact name is the one that's meant. Nothing in the pathname counts as special or "magic," so no pattern matching is allowed (apart from exact equality) between your pathname and the files sitting in the server-FTP's NVFS π
If you want wildcards, you'll have to get a listing of the directory (or directories) you care about and write your own file-name selection logic π§
2.3. Times β°
Here's how a time value is built:
time-val = 14DIGIT [ "." 1*DIGIT ]
The first fourteen digits are mandatory and read left to right. The first four are the year, which ranges from 1000 to 9999. Next come two digits for the month (01 to 12), two for the day of the month (01 to 31), two for the hour (00 to 23), two for minutes past the hour (00 to 59), and finally two for seconds past the minute, which go from 00 to 60. Only a 60 happens during a leap second π Years in the tenth century or earlier just can't be written down. Honestly, that's not considered a serious defect of the protocol, so we're good π
The optional digits come after a period and give decimal fractions of a second. You can use whatever precision fits the situation, but implementations MUST NOT add precision to time-vals where that precision doesn't exist in the underlying value being transmitted. No making up decimals, bestie π ββοΈ
Symbolically, a time-val looks like this:
YYYYMMDDHHMMSS.sss
The "." and the digits after it ("sss") are optional. However, the "." MUST NOT appear unless at least one digit follows it β¨
Time values are always in UTC (GMT) and always use the Gregorian calendar, no matter what calendar the server's location was using at that date and time πΈ
The technical differences between GMT, TAI, UTC, UT1, UT2, and friends aren't covered here. A server-FTP process should always use the same time reference so the times it returns stay consistent. Clients aren't expected to be time synchronized with the server, so any little difference between time standards isn't considered important π¦
2.4. Server Replies π¬
Section 4.2 of [3] defines the format and meaning of replies that the server-PI sends to FTP commands from the user-PI. This spec uses those reply conventions exactly as they are π
error-response = error-code SP *TCHAR CRLF
error-code = ("4" / "5") 2DIGIT
Quick heads up, implementors: the ABNF in this document (and in other FTP-related documents, but not the one in [3]) sometimes shows replies in the one-line format. Unless it's explicitly stated, that doesn't mean multi-line responses aren't allowed. Implementors should assume that, unless stated otherwise, any reply to any FTP command (QUIT included) may use the multi-line format described in [3] π
Throughout this document, replies get identified by the three-digit code at their start. So when you see "500 reply," it just means a reply from the server-PI that uses the three-digit code "500" π
2.5. Interpreting Examples π
In the FTP dialog examples in this document, lines starting with "C> " were sent over the control connection from the user-PI to the server-PI. Lines starting with "S> " were sent over the control connection from the server-PI to the user-PI. Each group of lines starting with "D> " was sent from the server-PI to the user-PI over a data connection that was created just for those lines and closed right after π None of the examples show data going from the client to the server over a data connection. The prefixes, including that one space, were added for this document and aren't part of the data exchanged between client and server, so don't go copying them π
3. File Modification Time (MDTM) π°οΈ
The FTP command MODIFICATION TIME (MDTM) can be used to find out when a file in the server NVFS was last modified. This command has been around in lots of FTP servers for years, as a buddy of the REST command for STREAM mode, so it's widely available π§ That said, where it's supported, the "modify" fact that comes back from the new MLST command is recommended as a superior alternative π
When you're trying to restart a RETRieve, the user-FTP can use the MDTM command or the "modify" fact to check whether the source file's modification time is more recent than the modification time of the partially transferred file. If it is, the source file has most likely changed, and restarting the incomplete transfer would be unsafe π
The user- and server-FTPs' clocks aren't necessarily synchronised, so user-FTPs that want to use this method should usually grab the file's modification time from the server before the initial RETRieval. Then they compare it with the modification time they get before a RESTart. If they differ, the files may have changed, and a RESTart would be inadvisable. If that's not possible, the user-FTP should make sure to allow for possible clock skew when comparing times β³
When you're trying to restart a STORe, the User FTP can use the MDTM command to find the modification time of the partially transferred file. If that's older than the modification time of the file about to be STORed, the source file has most likely changed, and restarting the file transfer would be unsafe π
Quick note: MLST (described below), where it's available, can give you this info and much more. That gives an even better indication that a file has changed and that restarting a transfer wouldn't give valid results π¦
And one more thing: this applies to any RESTart attempt, no matter what mode the file transfer is in π
3.1. Syntax π
The syntax for the MDTM command is:
mdtm = "MdTm" SP pathname CRLF
Like all FTP commands, the "MDTM" command label is case-insensitive πΈ
The "pathname" points to an object in the NVFS that could be the object of a RETR command. Attempts to ask for the modification time of files that exist but can't be retrieved might produce an error-response. Or they might give a positive response with a time-val that has an unspecified value. The server-PI gets to pick which one happens π
The server-PI will answer the MDTM command with a 213 reply giving the last modification time of the file named by the pathname, or with a 550 reply if the file doesn't exist, the modification time isn't available, or some other error has happened π
mdtm-response = "213" SP time-val CRLF /
error-response
Note that when the 213 response is sent (meaning there's no error), the format MUST be exactly as specified. Multi-line responses are not permitted π«
3.2. Error Responses π¬
If the command is parsed correctly but the modification time isn't available, either because the pathname points to nothing that exists or because the info isn't available for that entity, then a 550 reply should be sent. If the command can't be parsed correctly, a 500 or 501 reply should be sent, as specified in [3]. Various 4xy replies are possible too, in the right circumstances π
3.3. FEAT Response for MDTM π§
When replying to the FEAT command [6], a server-FTP process that supports the MDTM command MUST include a line containing the single word "MDTM". This MAY be sent in upper case, lower case, or a mix of both (it's case-insensitive), but it SHOULD be sent in upper case only. So the response SHOULD be:
C> Feat
S> 211- <any descriptive text>
S> ...
S> MDTM
S> ...
S> 211 End
The ellipses are placeholders for other features that could be listed, but they're not required. The one-space indentation on the feature lines is mandatory [6] π
3.4. MDTM Examples π
Let's pretend there are three files (A, B, and C), a directory D, two files whose names end in the string "ile6", and no other files at all. Then the MDTM command might behave like this. The "C>" lines are commands from the user-PI to the server-PI, and the "S>" lines are the server-PI's replies π
C> MDTM A
S> 213 19980615100045.014
C> MDTM B
S> 213 19980615100045.014
C> MDTM C
S> 213 19980705132316
C> MDTM D
S> 550 D is not retrievable
C> MDTM E
S> 550 No file named "E"
C> mdtm file6
S> 213 19990929003355
C> MdTm 19990929043300 File6
S> 213 19991005213102
C> MdTm 19990929043300 file6
S> 550 19990929043300 file6: No such file or directory.
From that, we can tell that A and B were last modified at the same time (to the nearest millisecond), and that C was modified 20 days and several hours later π¦
The times are in GMT. So file A was modified on June 15th, 1998, at about 11am in London (summer time was in effect then), or at 8pm in Melbourne, Australia, or at 6am in New York. Those are all the same absolute time, obviously π The location where the file was modified, and so the local wall clock time there, isn't available β°
There's no file named "E" in the current directory, but there are files named "file6" and "19990929043300 File6." The modification times of those two were obtained. There's no file named "19990929043300 file6" π«Ά
4. File SIZE π
The FTP command SIZE OF FILE (SIZE) gets the transfer size of a file from the server-FTP process. That's the exact number of octets (8-bit bytes) that would be sent over the data connection if the file were transmitted. This value changes depending on the current STRUcture, MODE, and TYPE of the data connection, or of a data connection that would be created if one were made right now. So the result of the SIZE command depends on the STRU, MODE, and TYPE parameters that are currently set π
The SIZE command returns how many octets would be transferred if the file were sent using the current transfer structure, mode, and type. It's normally used alongside the RESTART (REST) command when STORing a file to a remote server in STREAM mode, to figure out the restart point. The server-PI might need to read the partially transferred file, do any appropriate conversion, and count the octets that would be generated when sending the file, so it can respond to this command correctly π§ Estimates of the file transfer size MUST NOT be returned. Only precise information is acceptable π
4.1. Syntax β¨
okay so the SIZE command has a super simple shape, bestie π
size = "Size" SP pathname CRLF
the server-PI answers with a 213 reply giving the transfer size of the file you named π. if the file doesn't exist, the size isn't available, or something else went wrong, you get an error response instead π. the number you get back works with the RESTART (REST) command for mode STREAM, as long as you don't change the transfer mode and type in the meantime π¦
size-response = "213" SP 1*DIGIT CRLF /
error-response
ngl, when there's no error the 213 response MUST be exactly as specified π and multi-line responses are not allowed. no rambling replies, periodt π ββοΈ
4.2. Error Responses
okay so when the command parses fine but the size can't be given, maybe because the pathname points at nothing, or because the file can't be transferred in the current MODE and TYPE (or at all), then a 550 reply should be sent π. if the command can't be parsed at all, a 500 or 501 reply should be sent instead, as specified in [3] π§
here's the tea π«Ά: getting a 550 back from a SIZE command MUST NOT be taken by the client as proof that the file can't be transferred in the current MODE and TYPE. the server might just throw that error for other reasons too, like if the processing overhead is considered too great π. there are also some other 4xy replies that can show up in the right situations πΈ
4.3. FEAT Response for SIZE
when a server-FTP process replies to the FEAT command [6], and it supports the SIZE command, it MUST include a line containing the single word "SIZE" β¨. the word is case insensitive, and it MAY be sent in any mixture of upper or lower case, but it SHOULD be sent in upper case, so the response SHOULD look like this:
C> FEAT
S> 211- <any descriptive text>
S> ...
S> SIZE
S> ...
S> 211 END
the ellipses are just placeholders for other features that might be in there, they're not required π¦. the one-space indentation of the feature lines is mandatory [6], so don't skip it π
4.4. Size Examples
okay picture this π: a text file called "Example" sitting on a Unix(TM) server, where every end of line is one single octet. say the file has 112 lines and 1830 octets total. then the SIZE command would go like this:
C> TYPE I
S> 200 Type set to I.
C> size Example
S> 213 1830
C> TYPE A
S> 200 Type set to A.
C> Size Example
S> 213 1942
notice that with TYPE=A, SIZE reports an extra 112 octets π. those are the extra octets that get inserted, one at the end of each line, so the end-of-line stuff works right during a TYPE=A transfer β¨. other systems might need different tweaks to the transfer format when switching between TYPEs and MODEs, and the SIZE command takes all of that into account π
heads up bestie: working out the size this precisely can take a lot of effort on the server-PI's side. so user-PIs should not use this command unless the precision is essential, like when they're about to restart an interrupted transfer π. for everything else, the "Size" fact of the MLST command (see section 7.5.7) ought be requested instead π
5. Restart of Interrupted Transfer (REST) π
okay so if a file is only partly transferred, you don't wanna resend the whole thing π. both sides need a way to agree on where in the data stream the transfer should pick back up π«Ά
the FTP specification [3] has three modes of data transfer: STREAM, Block, and Compressed. in Block and Compressed modes, the data stream is formatted so restart markers can be embedded in it π. the sending DTP can drop a restart marker in with whatever info it needs to restart from that point. the receiving DTP keeps a list of those markers and matches them up with how the file is being saved. to restart, the receiver just sends back the last restart marker, and both sides know how to pick up again π¦. quick note: STD 9, RFC 959 [3] has some flaws in its description of the restart mechanism, so check section 4.1.3.4 of RFC 1123 [9] for the corrections π
5.1. Restarting in STREAM Mode
in STREAM mode, the data connection is just a stream of unformatted octets π. you can't put explicit restart markers in there, because they'd look exactly like data π΅. that's why the FTP specification [3] didn't give STREAM mode a way to do restarts. but honestly, you don't really need explicit markers here, since the octet offset into the data stream can imply the restart marker π
because the data stream is the file in STREAM mode, a different data stream means a different file. so an offset always points to the same position within a file β¨. in other modes besides STREAM, though, the same file can be sent using quite different octet sequences and still be rebuilt into the one identical file π§©. so an offset into the data stream in those modes wouldn't give an unambiguous restart point π ββοΈ
if the data representation TYPE is IMAGE and the STRUcture is File, then for lots of systems the file is stored in exactly the same format it gets sent in π°. that makes it pretty easy for the receiver to figure out how much data it already got, and tell the sender the offset to restart from β¨. with other representation types and structures, it takes more effort, but you can always find the offset with finite (though maybe not negligible) effort πͺ. in the worst case, an FTP process might need to open a data connection to itself, set the right transfer type and structure, send the file, and count the octets it sends π€―
if the user-FTP process wants to restart a retrieve, it can directly work out the restart marker and send it in the RESTART command π. but if it wants to restart sending the file, it has to figure out how much data was already sent and correctly received and saved π€. so there's a new FTP command for getting that info, and that's exactly what the SIZE command is for, as documented in section 4 π§
5.2. Error Recovery and Restart
okay so STREAM mode transfers with FILE STRUcture can be restarted even when no restart marker was sent along with the data itself πΈ. you do it with the SIZE command (if you need it), together with the RESTART (REST) command, and one of the standard file transfer commands π
when using TYPE ASCII or IMAGE, the SIZE command returns the number of octets that would actually be transferred if the file were sent between the two systems. so with type IMAGE, SIZE normally gives the number of octets in the file π. with type ASCII, SIZE gives the number of octets in the file including any changes needed to satisfy the TYPE ASCII CR-LF end-of-line convention β¨
5.3. Syntax
the syntax for the REST command, when the current transfer mode is STREAM, is:
rest = "Rest" SP 1*DIGIT CRLF
the number tells the server how many octets of the immediately-following transfer to skip sending, so the transmission effectively restarts later on π¦. a value of zero effectively turns restart off, so the entire file gets sent π. the server-PI answers the REST command with a 350 reply, which means the REST parameter got saved π. then another command, which should be either RETR or STOR, should follow to finish the restart π
rest-response = "350" SP *TCHAR CRLF /
error-response
server-FTP processes are allowed to let other transfer commands, like APPE and STOU, complete a restart, but that's not recommended π. STOU (store unique) is undefined in this usage, because storing the rest of a file into a unique file name is rarely going to be useful π ββοΈ. if APPE (append) is permitted, it MUST act identically to STOR when a restart marker has been set π₯. in both cases, octets from the data connection get placed into the file at the location the restart marker points to β¨
the REST command is meant to finish a failed transfer. using it with RETR is pretty well defined in every case, because the client is the one responsible for merging the retrieved data with the partially retrieved file π§©. the client can use the data however it wants, or re-retrieve data it already got before π. with STOR, though, the server has to insert the data into the named file π¬. the results are undefined if a client uses REST for anything other than restarting a transfer of a file that previously failed to fully transfer π. especially if the restart marker set with REST isn't at the end of the data the server has stored (as the server reports it), or if the STOR that follows REST doesn't give enough data to extend the destination file to at least its previous size, then the effects are undefined π
the REST command must be the last command issued right before the data transfer command that's supposed to cause a restarted (rather than complete) transfer π. issuing REST at any other time is undefined πΈ. the server-PI might respond to a badly placed REST command with an error response to the following command (if it isn't a restartable data transfer command), or it might save the restart value and apply it to the next data transfer command, or it might just silently ignore the bad restart attempt π€·ββοΈ. because of this, a user-PI that sent a REST command but didn't successfully send the following data transfer command, for any reason, should send another REST command before the next data transfer command π. if that transfer shouldn't be restarted, then "REST 0" should be issued π
an error response will only follow a REST command when the server doesn't implement the command, or when the restart marker value is syntactically invalid for the current transfer mode (like, in STREAM mode, if anything other than one or more digits shows up in the REST parameter) π . any other errors, including stuff like a restart marker being out of range, should be reported when the following transfer command is issued. those errors will make that transfer request get rejected, with an error saying the restart attempt was invalid π€
5.4. FEAT Response for REST
if a server-FTP process supports RESTart in STREAM mode, as specified here, it MUST include a line containing exactly the string "REST STREAM" in its response to the FEAT command [6] β¨. the string isn't case sensitive, but it SHOULD be sent in upper case π. if REST isn't supported at all, or is only supported in block or compressed modes, then the REST line MUST NOT be included in the FEAT response π ββοΈ. where it's required, the response SHOULD be:
C> feat
S> 211- <any descriptive text>
S> ...
S> REST STREAM
S> ...
S> 211 end
the ellipses are placeholders for other features that could be included, and they're not required π¦. the one-space indentation of the feature lines is mandatory [6], so keep those spaces π«Ά
5.5. REST Example β¨
Okay so picture this: a big file transfer got cut off after 802816 octets had landed π. The previous transfer was in TYPE=I (binary, bestie πΎ), and we've double-checked that the file on the server hasn't changed since. Here's how the restart plays out π
C> TYPE I
S> 200 Type set to I.
C> PORT 127,0,0,1,15,107
S> 200 PORT command successful.
C> REST 802816
S> 350 Restarting at 802816. Send STORE or RETRIEVE
C> RETR cap60.pl198.tar
S> 150 Opening BINARY mode data connection
[...]
S> 226 Transfer complete.
6. A Trivial Virtual File Store (TVFS) π§
Okay, the vibe of FTP has always been pretty chill about how a server stores its files (that's the NVFS ποΈ). This spec doesn't change that. BUT servers have started copying the naming style of the UNIX(TM) file system, and honestly it's giving organized π . So you get a tree π³ made of directories, and each directory can hold other directories, plain files, or both. Every file and directory has a name relative to the directory that holds it, except the root directory at the very top, which lives inside nothing, so it has no name of its own (main character of the tree, no cap π).
Everything above is totally compatible with the standard FTP NVFS and access stuff. "CWD" moves you into a subdirectory, "CDUP" may be offered to go back to the parent, and the usual file commands ("RETR", "STOR", the rename commands, and so on) work on files in the current directory.
BUT here's the thing π: FTP doesn't guarantee any way to get back to a directory you left, and it's often super handy to reference files without changing directories. That's where the Trivial Virtual File Store (TVFS) comes in β¨. If a server implements it, it gives you exactly that mechanism. Iconic.
6.1. TVFS File Names π
If a server does TVFS, no elementary file name shall contain the character "/". Now, if the natural file store underneath lets files or directories have "/" in their names, the server-PI doing TVFS must encode that character somehow whenever names go out to the user-PI, and reverse the encoding when names come back in from the user-PI. Not optional, babe π«Ά.
The spec doesn't pick the encoding method. If some other character is already illegal in the underlying store, a simple swap (transliteration) might be enough. If there's no decent substitute character, you're probably going to need something fancier, maybe with an escape character π.
Apart from the unnamed root directory, a TVFS file name may not be empty. Every other name has at least one character π.
Except for "/", any valid IS10646 character [10] is allowed in a TVFS file name. When names get sent over the wire, they're encoded in UTF-8 [2] πΈ. Quick heads up: the two-character sequence CR LF inside a file name makes that name impossible to send over a data connection π. So you should avoid it, and if that's truly impossible, it MUST be encoded in some reversible way.
6.2. TVFS Pathnames π¦
A TVFS "Pathname" is the name of a target file or directory combined with the names of zero or more directories around it. This lets you reference the target even when the server's "current working directory" isn't the directory right next to it π§.
By definition, every TVFS file or directory name is also a TVFS pathname. That pathname works to reference the file from the directory that contains it, which means that directory has to be the server-FTP's current working directory.
Other TVFS pathnames get built by sticking a directory name onto the front of an existing pathname and separating the two with a "/". The new pathname works to reference the file or directory from the directory that contains the newly added directory name π.
When you keep extending a pathname until the directory you added is the unnamed root directory, the pathname starts with "/". That's called a fully qualified pathname π. You can't extend a fully qualified pathname any further, since by definition nothing contains the root, and since the root has no name, nothing can represent it inside another directory. A fully qualified pathname works to reference the named file or directory from anywhere in the virtual file store, no matter what the current working directory is β¨.
Any pathname that isn't fully qualified is a "relative pathname". It only correctly points to the intended file when the server-FTP's current working directory is a directory where that relative pathname is valid π« .
As a special case, the pathname "/" means the root directory π. The root has no directory or file name, but it does have a pathname. This special pathname can only be used all by itself as a reference to the root directory. You can't combine it with other pathnames using the rules above, because that would produce two consecutive "/" characters, which is an undefined sequence π ββοΈ.
6.2.1. Notes π
- It is not required, or expected, that there be only one fully qualified pathname that will reference any particular file or directory. Multiple paths can point to the same thing, and that's fine π¦.
- As a caveat, even though the TVFS file store is basically tree structured, there is no requirement that any file or directory have only one parent directory. So yeah, things can have more than one parent πΏ.
- As defined, no TVFS pathname will ever contain two consecutive "/" characters. Such a name is not illegal, however, and the server may define it for any purpose that suits it. Clients implementing this specification should not assume any semantics for such names π.
- Similarly, other than the special case path that refers to the root directory, no TVFS pathname constructed as defined here will ever end with the "/" character. Such names are also not illegal, but they are undefined π€·ββοΈ.
- While any legal IS10646 character is permitted to occur in a TVFS file or directory name, other than "/", server FTP implementations are not required to support all possible IS10646 characters. The subset supported is entirely up to the server. The case (where it exists) of the characters that make up file, directory, and pathnames may be significant. Unless determined otherwise by means unspecified here, clients should assume that all such names are comprised of characters whose case is significant. Servers are free to treat case (or any other attribute) of a name as irrelevant, and hence map two names that appear to be distinct onto the same underlying file π€.
- There are no defined "magic" names, like ".", ".." or "C:". Servers may implement such names, with any semantics they choose, but are not required to do so πͺ.
- TVFS imposes no particular semantics or properties upon files, guarantees no access control schemes, or any of the other common properties of a file store. Only the naming scheme is defined π .
6.3. FEAT Response for TVFS π
When a server sends a response to the FEAT command [6] and wants to show it supports the TVFS as defined here, it includes a line that begins with the four characters "TVFS". The casing doesn't matter (any mix is fine), but servers SHOULD send upper case π .
A response to the FEAT command MUST NOT be returned unless the server actually implements TVFS as defined here. No faking it, bestie π«.
Later specs might add to the TVFS definition. Any additions should be announced by appending extra text to the TVFS feature line, and any such specs will define what that extra text means β¨.
Until a spec like that exists, servers should not put anything after "TVFS" on the TVFS feature line. Clients, though, should be ready to handle arbitrary text after those four characters and just ignore anything they don't recognize π«Ά.
Here's what a FEAT response looks like from a server that only implements this spec:
C> feat
S> 211- <any descriptive text>
S> ...
S> TVFS
S> ...
S> 211 end
The ellipses are just placeholders where other features could go, and they're not required πΈ. The one-space indentation of the feature lines is mandatory [6], and it doesn't count toward the first four characters when you're looking for the feature listing π.
The TVFS feature adds no new commands to the FTP command set π.
6.4. OPTS for TVFS π·
There are no options in this TVFS spec, so there's no OPTS command defined. Nothing to see here, lol π.
6.5. TVFS Examples π§©
Let's imagine a TVFS file store. The root directory holds two directories (A and B) and two plain files (X and Y). Directory A holds two directories (C and D) and one other file (Z). Directory B holds just two plain files (P and Q). Directory C also has two plain files, and they're also named P and Q, by pure coincidence π―. Directory D is empty, meaning it has no files or directories. Here's the picture πΌοΈ:
(unnamed root)
/ | \ \
/ | \ \
A X B Y
/|\ / \
/ | \ / \
C D Z P Q
/ \
/ \
P Q
With that structure, these fully qualified pathnames exist:
/
/A
/B
/X
/Y
/A/C
/A/D
/A/Z
/A/C/P
/A/C/Q
/B/P
/B/Q
It's clear that none of the paths /, /A, /B, or /A/D refer to the same directory, since each one's contents are different. The same goes for /, /A, /A/C, and /A/D. However, /A/C and /B might be the same directory, and there isn't enough information to tell π€. Any of the other pathnames (/X, /Y, /A/Z, /A/C/P, /A/C/Q, /B/P, and /B/Q) may refer to the same underlying files, in almost any combination π.
If the server-FTP's current working directory is /A, then the following pathnames are valid too, along with all the fully qualified ones:
C
D
Z
C/P
C/Q
Each of these refers to the same file or directory as the matching fully qualified path with "/A/" added in front π.
Just because those pathnames exist doesn't mean the TVFS server will grant any kind of access rights to them, and it doesn't mean accessing the same file through different pathnames gets equal rights π.
When the current directory is /A, none of these relative paths are valid:
A
B
X
Y
B/P
B/Q
P
Q
Any of them could become valid if you change the server-FTP's current working directory to the right place π§. Also, the paths "P" and "Q" could point to different files depending on which directory gets selected to make them valid TVFS relative paths π.
7. Listings for Machine Processing (MLST and MLSD) β¨
okay so MLST and MLSD are the glow-up for file listings π . They standardize the file and directory info the server-FTP sends back. Unlike LIST, the reply format is strictly defined (but still extensible) π
There are two commands. MLST gives data about exactly the object named on its command line, and no others π¦. MLSD lists the contents of a directory if you name one, and otherwise sends back a 501 reply. If you don't name anything, the current directory is assumed. So MLST sends a one-line response describing the current directory itself, and MLSD lists what's inside it πΈ
From here on, MLSx means whichever of MLST or MLSD could go in that spot π§
These commands also extend the FTP protocol from STD 9, RFC 959 [3] and STD 3, RFC 1123 [9] so that 8-bit data can travel over the control connection. this is NOT about which character sets are 8-bit π It's about FTP implementations letting 8-bit bytes through in both directions, with every bit significant. All 256 possible octet values are allowed. MLSx takes both UTF-8/Unicode and "raw" forms as arguments, and it uses them in responses to MLST and MLSD, and to every other FTP command that takes pathnames β¨
7.1. Format of MLSx Requests
The MLST and MLSD commands each take one optional argument. It can be a directory name or, for MLST only, a file name. A "file name" here means the name of any entity in the server NVFS that isn't a directory. Where TVFS is supported, you can use any TVFS relative pathname that's valid in the current working directory, or any TVFS fully qualified pathname ποΈ If you give a directory name, MLSD MUST return a listing of that directory's contents. Otherwise it issues a 501 reply and does not open a data connection. For MLST, every case returns a single set of fact lines (usually just one line) about the named file or directory, sent over the control connection with no data connection needed π
If there's no argument, MLSD MUST return a listing of the current working directory, and MLST MUST return info about the current working directory itself. (We'll pretend those are the only two ways to say it, lol.) Here "contents of a directory" means whichever file or directory names (not pathnames) the server-PI will let you reference while that directory is the current one, and that the server-PI actually wants to show the user-PI π· Leaving out the argument is the only defined way to list the current directory, unless you already know a pathname that points to it. There is no defined shorthand name for the current directory. That doesn't stop a particular server-PI from having one, though π€·ββοΈ
No title, header, summary lines, or any other formatting ever shows up in the output of MLST or MLSD, beyond what's described below. Nothing extra, bestie π«
If the Client-FTP sends an invalid argument, the server-FTP MUST reply with an error code of 501 π
The syntax for the MLSx command looks like this:
mlst = "MLst" [ SP pathname ] CRLF
mlsd = "MLsD" [ SP pathname ] CRLF
7.2. Format of MLSx Response
Here's how a reply to an MLSx command is shaped π
mlst-response = control-response / error-response
mlsd-response = ( initial-response final-response ) /
error-response
control-response = "250-" [ response-message ] CRLF
1*( SP entry CRLF )
"250" [ SP response-message ] CRLF
initial-response = "150" [ SP response-message ] CRLF
final-response = "226" SP response-message CRLF
response-message = *TCHAR
data-response = *( entry CRLF )
entry = [ facts ] SP pathname
facts = 1*( fact ";" )
fact = factname "=" value
factname = "Size" / "Modify" / "Create" /
"Type" / "Unique" / "Perm" /
"Lang" / "Media-Type" / "CharSet" /
os-depend-fact / local-fact
os-depend-fact = <IANA assigned OS name> "." token
local-fact = "X." token
value = *SCHAR
When an MLSx command comes in, the server checks the parameter. If it's invalid, the server sends back an error-response. The parameter counts as invalid if the client issuing the command doesn't have permission to do the requested operation π
If the parameter is valid and the command is MLST, the server-PI sends the first (leading) line of the control response, then the entry for the given pathname (or the current directory if no pathname was given), then the terminating line. Normally you only get one entry. More entries are only allowed when they're needed to represent a file that has multiple "Type" facts returned. In that case, the pathname part of every response MUST be identical π―ββοΈ
Note that for MLST, the fact set is preceded by a space. That's there to make sure the fact set can't be accidentally read as the terminating line of the control response, and it's required even in cases where that couldn't happen. Exactly one space sits between the set of facts and the pathname. If there are no facts, there are exactly two leading spaces before the pathname. No spaces are allowed inside the facts. Any other spaces in the response count as part of the pathname π§
If the command was MLSD, the server opens a data connection as described in section 3.2 of STD 9, RFC 959 [3]. If that fails, the server returns an error-response. If everything's OK, the server returns the initial-response, sends the appropriate data-response over the new data connection, closes that connection, and then sends the final-response over the control connection. The grammar above defines the format of the data-response, which is the format of what goes over the data connection π¦
The data connection opened for an MLSD response is treated as if "TYPE L 8", "MODE S", and "STRU F" had been given. That's true no matter what FTP transfer type, mode, and structure were actually set. Those settings aren't changed for future commands either. This transfer type applies only to the data connection for this one command π¦ The content can be seen as a series of lines, but there is no maximum line length defined. Implementations should be prepared to handle arbitrarily long lines π
The facts part is a series of "file facts" about the file or directory named on the same line. Typical info includes the file size, last modification time, creation time, a unique identifier, and a file/directory flag ποΈ
The full format for a successful reply to MLSD looks like this:
facts SP pathname CRLF
facts SP pathname CRLF
facts SP pathname CRLF
...
The format is for machines, not humans, so it is very rigid π€ Implementations MUST NOT vary the format by, for example, adding extra spaces for readability, swapping spaces for tabs, including header or title lines, adding blank lines, or changing it in any other way. Exactly one space is always required after the set of facts (which may be empty). More spaces may appear on a line only if the pathname presented contains significant spaces. The set of facts must not contain any spaces anywhere inside it. Facts should only be provided on an output line if they both give relevant info about the file named on that same line and are in the set the user-PI asked for. See section 7.9 (page 51). There's no rule that every file has to get the same set of facts, or that the facts have to come in the same order for each file π
7.2.1. Error Responses to MLSx commands
Lots of the 4xy and 5xy replies defined in section 4.2 of STD 9, RFC 959 [3] can come back from MLST and MLSD π Syntax errors can produce 500 or 501 replies. Giving a pathname that exists but isn't a directory as the argument to MLSD gets you a 501 reply. If you give a name that doesn't exist, or one you don't have access permission to get directory info for, you'll get a 550 reply. Other replies (530, 553, 503, 504, and any of the 4xy replies) are also possible when the situation calls for them.
7.3. File Name Encoding
An FTP implementation that supports MLSx must be 8-bit clean. That's needed so it can send UTF-8 encoded file names. This spec recommends UTF-8 encoded file names, and FTP implementations SHOULD use UTF-8 whenever they can, so things stay as interoperable as possible π
File names aren't limited to UTF-8. Still, this standard doesn't specify how arbitrary character encodings should be treated. Applications are encouraged to treat non-UTF-8 file name encodings as plain octet sequences π§
Also, this encoding is separate from whatever encoding the file's contents use, even if the file contains character data π
More info on file name encoding for FTP can be found in "Internationalization of the File Transfer Protocol" [7] π π
7.3.1. Notes about the File Name β¨
okay so the file name in an MLST response should be the same name you typed in the MLST command π or, where TVFS is supported, a fully qualified TVFS path that points to the very same file π¦ If you didn't give MLST any argument, the server-PI can either send back an empty file name πΈ or a name that refers to the current directory, if one is available π§ And if TVFS is supported, a fully qualified pathname of the current directory SHOULD be returned, no debate π
File names in the output from an MLSD command SHOULD be unqualified names within the directory being listed, or within the current directory if you didn't give an argument π Basically, the directory you named in the MLSD command SHOULD NOT show up as part of any file name in the list π nobody needs that repeated, it's giving clutter π
If the server-FTP process can do it, and the "type" fact is being returned, it MAY return an entry whose type is "cdir" π That entry names the directory the listing came from. Where TVFS is supported, the name MAY be the fully qualified pathname of the directory, or MAY be any other pathname that's valid for referring to that directory from the server-FTP's current working directory π§ If there's more than one name, you can get multiple of these entries π Honestly the "cdir" entry is like a heading for the MLSD output π It is not required to be the first entry, though, and it can show up anywhere in the listing π¦
When TVFS is supported, a user-PI can point at any file or directory in the listing by combining a type "cdir" name with the right name from the directory listing, using the procedure in section 6.2 β¨ That's the glow-up combo π
Or, whether TVFS is supported or not, the user-PI can issue a CWD command ([3]) using a name of type "cdir" from the listing πΈ From that point on, it can reference the files from the MLSD response that the cdir came from, just by using the file name components of the listing π«Ά
7.4. Format of Facts
The "facts" for a file in a reply to an MLSx command are all the info about that file π¦ They're a series of keyword=value pairs, and each one is followed by a semi-colon (";") π A single fact can't have a semi-colon in its name or its value π ββοΈ The whole series of facts may not contain the space character π« If you want to know which characters can show up in a fact value, check the RCHAR definition in section 2.1 π Not every fact applies to every file, btw π¦
Here's a typical series of facts (I split it over two lines just so it fits here, not because that's how it's sent) π
size=4161;lang=en-US;modify=19970214165800;create=19961001124534;
type=file;x.myfact=foo,bar;
7.5. Standard Facts
This document defines a standard set of facts, and they're iconic π
size -- Size in octets
modify -- Last modification time
create -- Creation time
type -- Entry type
unique -- Unique id of file/directory
perm -- File permissions, whether read, write, execute is
allowed for the login id.
lang -- Language of the file name per IANA [11] registry.
media-type -- MIME media-type of file contents per IANA registry.
charset -- Character set per IANA registry (if not UTF-8)
Fact names are case-insensitive, so Size, size, SIZE, and SiZe are all the same fact π« β¨ no cap, it's the same vibe every time π
Operating system specific keywords can also be added, using the IANA operating system name as a prefix π§ (these are just examples, bestie):
OS/2.ea -- OS/2 extended attributes
MACOS.rf -- MacIntosh resource forks
UNIX.mode -- Unix file modes (permissions)
Implementations may define keywords for experimental or private use π§ͺ All of those keywords MUST begin with the two character sequence "x.". Since type names are case independent, "x." and "X." count as the same thing π For example:
x.ver -- Version information
x.desc -- File description
x.type -- File type
7.5.1. The Type Fact
The type fact needs its own special moment π Part of the drama with current practices is deciding when a file is a directory. If it's a directory, is it the current directory, a regular directory, or a parent directory? The MLST specification clears that up using the type fact π₯ The type fact tells you about the object listed on the same line of the MLST response π
Five values are possible for the type fact:
file -- a file entry
cdir -- the listed directory
pdir -- a parent directory
dir -- a directory or sub-directory
OS.name=type -- an OS or file system dependent file type
The syntax is defined as:
type-fact = type-label "=" type-val
type-label = "Type"
type-val = "File" / "cdir" / "pdir" / "dir" /
os-type
The value of the type fact (the "type-val") is a case independent string π
7.5.1.1. type=file
When you see type=file, it means the listed entry is a file with non-system data π It can be moved from one system to a totally different one and still be meaningful π¦ Main character file energy β¨
7.5.1.2. type=cdir
type=cdir means the listed entry has a pathname of the directory whose contents are being listed π It only ever comes back as part of an MLSD result when the type fact is included, and it gives a name for the listed directory along with facts about that directory π«Ά Think of it as the title of the listing, but in a machine friendly format π€ It can show up at any point in the listing, not only at the start, though it often does start there πΈ It can also appear more than once. It MUST NOT be included if the type fact isn't included, because otherwise the user-PI would have no way to tell the directory name apart from an entry inside the directory π
When the server-FTP supports TVFS, this name can be used to build pathnames that refer to the files and directories in the same MLSD output (see section 6.2) π§ Those pathnames are only expected to work while the server-PI is in the same spot in the NVFS file tree as when the MLSD command was issued, unless the pathname is fully qualified π
When TVFS is not supported, the only defined meaning for a "type=cdir" entry is this: as long as the server-PI's current working directory hasn't changed, a pathname of type "cdir" can be used as the argument to a CWD command, which changes the server-PI's current directory to the directory that was listed π¦
7.5.1.3. type=dir
If it's there, type=dir gives the name of a directory π These usually can't be moved from one system to another using RETR and friends π but they should (if the permissions allow it) be able to be the object of an MLSD command π
7.5.1.4. type=pdir
If it's there, type=pdir represents a pathname of the parent directory of the listed directory π It only shows up in an MLSD response when the type fact is included. It has all the properties of a type=dir, and a CWD command that uses the pathname from this entry should move the user up to a parent directory of the listed directory π If the listed directory is the current directory, a CDUP command may also end up changing to the named directory π§ User-FTP processes should note that not every response includes this info, and some systems may give multiple type=pdir responses π«
When TVFS is supported, a "type=pdir" name may be a relative pathname or a fully qualified pathname π¦ A relative pathname is relative to the directory being listed, not to the server-PI's current directory at the time π
For this type value, a "parent directory" is any directory that has an entry of type=dir referring to the directory where the type=pdir entry was found π So it's not required that all type=pdir entries refer to the same directory π The "unique" fact (if it's supported and supplied) can help you figure out whether the type=pdir entries are related π
7.5.1.5. System Defined Types
File types that are specific to one operating system or file system can be encoded with the "OS." type names π₯οΈ The format is:
os-type = "OS." os-name "=" os-kind
os-name = <an IANA registered operating system name>
os-kind = token
The "os-name" tells you which system type supports the particular localtype π§ OS specific types are registered with IANA using the procedures in section 10 π The "os-kind" gives the system dependent info about what type of file is listed β¨ Both the os-name and os-kind strings in an os-type are case independent, so "OS.unix=block" and "OS.Unix=BLOCK" are the same type (or would be, if such a type were registered) π«Ά
Note: when the underlying system has a file type that's basically an indirect pointer to another file, the NVFS should normally represent that type as the file the reference points to π₯ So the underlying basic file shows up more than once in the NVFS, and each time it has the "unique" fact with the same value, which tells you they're all the same file π User-PIs only need to transfer that file once. After that they can add their own indirect reference to make alternate names where they want them, or even copy the local file if that's the only way to get two names with the same content π A file that would be a reference to another file, if only that other file existed, may be represented in any appropriate OS dependent way, or not represented at all π
7.5.1.6. Multiple Types
If a file can validly and sensibly be treated by the server-PI as more than one of the types above, then multiple entries should be returned πΈ Each one gets its own "Type" fact of the right type, and each contains the same pathname π This can happen, for example, with a structured file that holds sub-files, where the server-PI lets the structured file be treated as one unit, or as a directory so the sub-files inside can be referenced π§ When that's done, the pathname returned with each entry MUST be identical to the others that represent the same file π«Ά no tea, no shade, same name every time π β¨
7.5.2. The unique Fact π¦
Okay so the unique fact is basically a unique ID tag π for each file or directory on the NVFS, as seen through a server-FTP process. Every pathname that points at the same underlying file should get the same value, and names that point at different files should get different values. The mapping between files and unique fact tokens has to be kept up and stay consistent for at least the lifetime of the control connection from user-PI to server-PI. Bestie, that's a whole commitment π
unique-fact = "Unique" "=" token
This one is meant for server-FTPs whose host system allows things like symbolic links, so the same file can show up in more than one directory on the server π The only conclusion you're allowed to draw is this: if two different names have the same unique fact value, they refer to the same underlying object. That's it, no extra conclusions π
ββοΈ The token should be treated as an opaque string when comparing, and it's case dependent. So "A" and "a" do not represent the same underlying object. Totally different vibes π
7.5.3. The modify Fact π°οΈ
The modify fact tells you the last time the content of a file (or a directory) was modified. Any change of substance to the file should make this value change. So if a change would make the result of a RETR command come out differently, the modify fact should change too β¨ User-PIs shouldn't assume that a different modify fact value means the file contents are definitely different from when they last retrieved it π Some systems might change the modify fact for other reasons, but that's discouraged wherever possible. Also, a file can change and then go back to exactly what it was before. That usually shows up as two separate changes to the modify fact value, so don't be confused if that happens π
For directories, this value should change whenever something happens to the directory that means different file names would (or might) appear in MLSD output for that directory π
modify-fact = "Modify" "=" time-val
7.5.4. The create Fact πΈ
The create fact says when a file or directory was first created. What "creation" actually means for this purpose isn't specified here, and it can differ from server to server π€·ββοΈ The one thing you can count on is that the value can never be a later time than the modify fact. Create is always the same or earlier, never later β³
create-fact = "Create" "=" time-val
Implementation Note: If you're implementing this fact on UNIX(TM) systems, heads up π§ The unix "stat" "st_ctime" field does not give you the creation time, and unix file systems don't record creation time at all. So UNIX (and POSIX) implementations will normally leave this fact out π
7.5.5. The perm Fact π
The perm fact shows which access rights the current FTP user has over the listed object. Its value is always an unordered sequence of alphabetic characters, so the order doesn't matter π
perm-fact = "Perm" "=" *pvals
pvals = "a" / "c" / "d" / "e" / "f" /
"l" / "m" / "p" / "r" / "w"
There are ten permission indicators defined right now, and a lot of them only make sense for certain object types π The indicators are case independent, so "d" and "D" mean the same thing π
Here's the breakdown, bestie:
The "a" permission applies to objects of type=file. It means the APPE (append) command may be applied to the file named π
The "c" permission applies to objects of type=dir (and type=pdir, type=cdir). It means files may be created in the directory named. In other words, a STOU command is likely to succeed, and STOR and APPE commands might succeed if the file named didn't exist before but is going to be created in the directory object that has the "c" permission. It also means the RNTO command is likely to succeed for names in the directory π‘
The "d" permission applies to all types. It means the object named may be deleted. So the RMD command may be applied to it if it's a directory, and otherwise the DELE command may be applied to it ποΈ
The "e" permission applies to the directory types. When it's set on an object of type=dir, type=cdir, or type=pdir, it means a CWD command naming the object should succeed, and the user should be able to enter the directory named πͺ For type=pdir, it also means the CDUP command may succeed (if this particular pathname is the one a CDUP would apply to.) π§
The "f" permission applies to objects and means the object named may be renamed. That is, it may be the object of an RNFR command βοΈ
The "l" permission applies to the directory file types and means the listing commands, LIST, NLST, and MLSD may be applied to the directory in question π
The "m" permission applies to directory types and means the MKD command may be used to create a new directory inside the directory under consideration π±
The "p" permission applies to directory types and means objects in the directory may be deleted, or (stretching the naming a little) that the directory may be purged π§Ή Note: it does not mean the RMD command can be used to remove the directory named itself. That's the "d" permission's job π
The "r" permission applies to type=file objects, and for some systems maybe to other types of objects too. It means the RETR command may be applied to that object π₯
The "w" permission applies to type=file objects, and for some systems maybe to other types of objects too. It means the STOR command may be applied to the object named π€
Note: Just because a permission indicator is set never means the matching command is guaranteed to work. It just means it might π€ Other system-specific limits, like limits on available space for storing files, can make an operation fail even when the permission flags said it was likely to succeed. The permissions are a guide only π§
Implementation note: These permissions are described here the way they apply to FTP commands. They may not map neatly onto the permissions the server's operating system uses π§© Servers are expected to work out these permission bits from the permission information the operating system provides. For example, to correctly figure out whether the "D" permission bit should be set on a directory for a server running on the UNIX(TM) operating system, the server should check that the directory named is empty, and that the user has write permission on both that directory and its parent directory π
Some systems might have more specific permissions than the ones listed here. Those systems should map them onto the defined flags as best they can πͺ Other systems might only have broader access controls. They'll generally have just a few possible combinations of permission flags, but they should still try to represent what's actually permitted π«Ά
7.5.6. The lang Fact π
The lang fact describes the natural language of the file name, for display purposes. Values should be taken from the IANA language registry. Check [12] for the syntax and procedures related to language tags π
lang-fact = "Lang" "=" token
Server-FTP implementations MUST NOT guess language values π« Language values have to be determined in an unambiguous way, like through file system tagging of language or through user configuration. Also, the lang fact tells you absolutely nothing about the content of a file. It's only about the encoding of its name π
7.5.7. The size Fact π
The size fact applies to non-directory file types and should always reflect the approximate size of the file. It should be as accurate as the server can make it without going to extraordinary lengths, like reading the entire file π¦ The size is expressed in units of octets of data in the file.
Because of limitations in some systems, Client-FTP implementations must understand this size may not be precise and may change between the time of an MLST and a RETR operation π
Clients that need highly accurate size information for some particular reason should use the SIZE command as defined in section 4 π The most common need for that kind of accuracy is probably in combination with the REST command described in section 5. The size fact, on the other hand, is for things like showing a human user roughly how big a file is, and maybe giving an idea of how long a transfer might take β±οΈ
size-fact = "Size" "=" 1*DIGIT
7.5.8. The media-type Fact π¨
The media-type fact represents the IANA media type of the named file, and it only applies to non-directory types. The values used must follow the guidelines set by the IANA registry ποΈ
media-type = "Media-Type" "=" <per IANA guidelines>
Server-FTP implementations MUST NOT guess media type values π
ββοΈ Media type values have to be determined in an unambiguous way, like through file system tagging of media-type or through user configuration. This fact tells you about the content of the named file π¬ Both the primary media type and any appropriate subtype should be given, separated by a slash "/" as is traditional π
7.5.9. The charset Fact π€
The charset fact gives the IANA character set name, or alias, for the encoded pathnames in an MLSx response. The default character set is UTF-8 unless specified otherwise. FTP implementations SHOULD use UTF-8 if possible to encourage maximum inter-operability π The value of this fact only applies to the pathname. It tells you nothing about the contents of the file π
charset-type = "Charset" "=" token
7.5.10. Required Facts π
Servers are not required to support any particular set of the available facts π«Ά However, servers SHOULD, if conceivably possible, support at least the type, perm, size, unique, and modify facts π
7.6. System Dependent and Local Facts π§
By using a system dependent fact, or a local fact, a server-PI can tell the user-PI information about the named file that's specific to the underlying file system π§
7.6.1. System Dependent Facts π₯οΈ
System dependent fact names are labeled by adding a prefix that identifies the specific information returned. The prefix is the name of the appropriate operating system, taken from the IANA maintained list of operating system names π·οΈ
The value of an OS dependent fact can be whatever fits the information available. It has to be encoded as a "token" as defined in section 2.1, though π
To allow reliable inter-operation between users of system dependent facts, the IANA will maintain a registry of system dependent fact names, their syntax, and the interpretation to be given to their values πΈ Registrations of system dependent facts are to be handled according to the procedures of section 10 β¨
7.6.2. Local Facts π
Okay so servers are also allowed to make up their own facts, whatever they want π These may be made available, but since nobody's really gonna know how to read them, server-PIs should be aware that clients will typically ignore any local facts provided π There's no registry for locally defined facts, so two servers could totally use the same local fact name to share wildly different info π That's why user-PIs should be hesitant about using any information in a locally defined fact unless they have some other specific assurance that they actually understand that fact π«Ά
Local fact names always start with X.. The rest of the name is a "token" (see section 2.1) πΈ The value of a local fact can be anything at all, as long as it can be encoded as a "token" β¨
7.7. MLSx Examples π¦
Bestie, these examples are all taken from real conversations between existing FTP clients and servers π So not every possible response format shows up, and that shouldn't be read as limiting what other server implementors can do. When the examples show OS dependent information, that's purely for demo purposes, showing some possible OS specific info that could be defined π§ Right now no OS specific facts or file types have been defined, so none of the examples should be treated as more preferred than any other possible similar definitions. Go check the IANA registries to see what types and facts have actually been defined π
Also, the examples were taken from implementations that were coded before this document was finished, so there could be some differences between the text here and the examples. If that happens, the example is to be treated as incorrect.
Yes, the example loses. The text is the source of truth π
In the examples, only the relevant commands and responses are included. That doesn't mean other commands (like authentication, directory modification, PORT or PASV commands, or similar stuff) wouldn't show up in a real connection. They might have been there, and got edited out before the examples were written π Also, the formats shown are what gets sent between client and server, not what the user of the client would normally ever see π
7.7.1. Simple MLST π
C> PWD
S> 257 "/tmp" is current directory.
C> MLst cap60.pl198.tar.gz
S> 250- Listing cap60.pl198.tar.gz
S> Type=file;Size=1024990;Perm=r; /tmp/cap60.pl198.tar.gz
S> 250 End
So the client first asked what the current directory was. That's just there for clarity, bestie π Then the client asked for facts about one specific file. The server sent back the 250- first control-response line, then one line of facts about the file, then the closing 250 line β¨ Whatever goes on the control-response line and the closing line is totally up to the server. Notice the fact line is indented by a single space. Also notice there are no spaces in the set of facts, until the one single space before the file name π¦ The file name on the fact line is the fully qualified pathname of the file.
The facts tell us the thing is a file, it's roughly 1024990 bytes (though a transfer could come out more or less than that, and storing it on the client's side might need a different number), and the connected user can retrieve it but can't really do anything else fun with it π
7.7.2. MLST of a directory π
C> PWD
S> 257 "/" is current directory.
C> MLst tmp
S> 250- Listing tmp
S> Type=dir;Modify=19981107085215;Perm=el; /tmp
S> 250 End
Again, the PWD is only for demo purposes π§ This time the fact line says the thing is a directory, it was last modified at 08:52:15 on the 7th of November, 1998 UTC, and the user can enter it and list what's inside, but can't modify it in any way π«Ά And yes, the fully qualified pathname of the directory is given too.
7.7.3. MLSD of a directory π¦
C> MLSD tmp
S> 150 BINARY connection open for MLSD tmp
D> Type=cdir;Modify=19981107085215;Perm=el; tmp
D> Type=cdir;Modify=19981107085215;Perm=el; /tmp
D> Type=pdir;Modify=19990112030508;Perm=el; ..
D> Type=file;Size=25730;Modify=19940728095854;Perm=; capmux.tar.z
D> Type=file;Size=1830;Modify=19940916055648;Perm=r; hatch.c
D> Type=file;Size=25624;Modify=19951003165342;Perm=r; MacIP-02.txt
D> Type=file;Size=2154;Modify=19950501105033;Perm=r; uar.netbsd.patch
D> Type=file;Size=54757;Modify=19951105101754;Perm=r; iptnnladev.1.0.sit.hqx
D> Type=file;Size=226546;Modify=19970515023901;Perm=r; melbcs.tif
D> Type=file;Size=12927;Modify=19961025135602;Perm=r; tardis.1.6.sit.hqx
D> Type=file;Size=17867;Modify=19961025135602;Perm=r; timelord.1.4.sit.hqx
D> Type=file;Size=224907;Modify=19980615100045;Perm=r; uar.1.2.3.sit.hqx
D> Type=file;Size=1024990;Modify=19980130010322;Perm=r; cap60.pl198.tar.gz
S> 226 MLSD completed
Okay, bestie, notice the fact lines over the data connection have no leading space πΈ There are also two type=cdir lines. These are two different names for the directory being listed: one is the fully qualified pathname, and the other is a local name relative to the server's current directory when the MLSD ran π All the other file names are relative to the listed directory, though the server could give a fully qualified pathname for the type=pdir line if it wanted to. This server chose not to π
The other files are a pretty boring set, but they're all in the directory. There's no particular order to the listing. They're not sorted by name, size, or modify time π
Also, capmux.tar.z has an empty perm fact, meaning the connected user has no permissions at all for that file π This server put the cdir and pdir lines before the directory contents, but it's not required to do that β¨ And the size fact doesn't give any meaningful info for a directory, so it isn't included in the fact lines for the directory types shown π§
7.7.4. A More Complex Example π
C> MLst test
S> 250- Listing test
S> Type=dir;Perm=el;Unique=keVO1+ZF4 test
S> 250 End
C> MLSD test
S> 150 BINARY connection open for MLSD test
D> Type=cdir;Perm=el;Unique=keVO1+ZF4; test
D> Type=pdir;Perm=e;Unique=keVO1+d?3; ..
D> Type=OS.unix=slink:/foobar;Perm=;Unique=keVO1+4G4; foobar
D> Type=OS.unix=chr-13/29;Perm=;Unique=keVO1+5G4; device
D> Type=OS.unix=blk-11/108;Perm=;Unique=keVO1+6G4; block
D> Type=file;Perm=awr;Unique=keVO1+8G4; writable
D> Type=dir;Perm=cpmel;Unique=keVO1+7G4; promiscuous
D> Type=dir;Perm=;Unique=keVO1+1t2; no-exec
D> Type=file;Perm=r;Unique=keVO1+EG4; two words
D> Type=file;Perm=r;Unique=keVO1+IH4; leading space
D> Type=file;Perm=r;Unique=keVO1+1G4; file1
D> Type=dir;Perm=cpmel;Unique=keVO1+7G4; incoming
D> Type=file;Perm=r;Unique=keVO1+1G4; file2
D> Type=file;Perm=r;Unique=keVO1+1G4; file3
D> Type=file;Perm=r;Unique=keVO1+1G4; file4
S> 226 MLSD completed
C> MLSD test/incoming
S> 150 BINARY connection open for MLSD test/incoming
D> Type=cdir;Perm=cpmel;Unique=keVO1+7G4; test/incoming
D> Type=pdir;Perm=el;Unique=keVO1+ZF4; ..
D> Type=file;Perm=awdrf;Unique=keVO1+EH4; bar
D> Type=file;Perm=awdrf;Unique=keVO1+LH4;
D> Type=file;Perm=rf;Unique=keVO1+1G4; file5
D> Type=file;Perm=rf;Unique=keVO1+1G4; file6
D> Type=dir;Perm=cpmdelf;Unique=keVO1+!s2; empty
S> 226 MLSD completed
For this one, the requested fact set got tweaked to drop the size and modify facts and add the unique fact π First, the client grabbed facts about a file name with MLST. No fully qualified pathname shows up this time, because the server couldn't figure that out π Once it knew the name was a directory, the client listed it. That listing also has no fully qualified pathname, for the same reason, so there's only a single type=cdir line β¨ This directory was made especially for the example, and it's packed with interesting stuff: some OS dependent file types, a few sub-directories, and some ordinary files π¦
We can't say much about the OS dependent file types, since everything about them is just possibilities π The OS type of this server is "unix" though, and that's one of the OS types in the IANA registry of Operating System names π
Of the three directories, no-exec gives this user no access at all π From the Unique values, we can tell promiscuous and incoming are actually the same directory π Its permissions say the connected user can basically do anything with it except delete it. That directory gets listed later, and it can't be deleted because it isn't empty π
Two of the normal files have spaces in their names π§ The file called " leading space" actually has two spaces in its name, one before the "l" and one between the "g" and the "s". The two spaces that separate the facts from the visible pathname make that super clear π The file writable has the a and w permission bits set, so the connected user should be able to STOR or APPE to it π₯
The other four names, file1, file2, file3, and file4, all point to the same underlying file, which you can tell from their unique values πΈ file1 and file2 are Unix "hard" links, and file3 and file4 are "soft" or "symbolic" links to the first two. None of that is visible through standard MLST facts. For FTP's purposes, it's enough to know they're all the same file: fetching any of them gets the same data, and storing data through any of them would change all of them at once π«Ά
Finally, the sub-directory incoming gets listed. Since promiscuous is the same directory, there's no point listing it again π Inside, file5 and file6 are just more names for the file1 file we already met π
Now check out the entry between bar and file5. It's hard to show in this document, but that's a file whose name is exactly three spaces (" "). The client can still tell what the name is from the output it gets, no problem β¨ The directory empty is, like its name says, empty, though that isn't shown here π§ It can be deleted, and so can bar and the three-space file. All the files in this directory can be renamed, because the UNIX semantics of the containing directory let it be modified π
7.7.5. More Accurate Time Information β
C> MLst file1
S> 250- Listing file1
S> Type=file;Modify=19990929003355.237; file1
S> 250 End
In this one, the server-FTP is saying file1 was last modified 237 milliseconds after 00:33:55 UTC on the 29th of September, 1999 β°
7.7.6. A Different Server π
C> MLST
S> 250-Begin
S> type=dir;unique=AQkAAAAAAAABCAAA; /
S> 250 End.
C> MLSD
S> 150 Opening ASCII mode data connection for MLS.
D> type=cdir;unique=AQkAAAAAAAABCAAA; /
D> type=dir;unique=AQkAAAAAAAABEAAA; bin
D> type=dir;unique=AQkAAAAAAAABGAAA; etc
D> type=dir;unique=AQkAAAAAAAAB8AwA; halflife
D> type=dir;unique=AQkAAAAAAAABoAAA; incoming
D> type=dir;unique=AQkAAAAAAAABIAAA; lib
D> type=dir;unique=AQkAAAAAAAABWAEA; linux
D> type=dir;unique=AQkAAAAAAAABKAEA; ncftpd
D> type=dir;unique=AQkAAAAAAAABGAEA; outbox
D> type=dir;unique=AQkAAAAAAAABuAAA; quake2
D> type=dir;unique=AQkAAAAAAAABQAEA; winstuff
S> 226 Listing completed.
C> MLSD linux
S> 150 Opening ASCII mode data connection for MLS.
D> type=cdir;unique=AQkAAAAAAAABWAEA; /linux
D> type=pdir;unique=AQkAAAAAAAABCAAA; /
D> type=dir;unique=AQkAAAAAAAABeAEA; firewall
D> type=file;size=12;unique=AQkAAAAAAAACWAEA; helo_world
D> type=dir;unique=AQkAAAAAAAABYAEA; kernel
D> type=dir;unique=AQkAAAAAAAABmAEA; scripts
D> type=dir;unique=AQkAAAAAAAABkAEA; security
S> 226 Listing completed.
C> MLSD linux/kernel
S> 150 Opening ASCII mode data connection for MLS.
D> type=cdir;unique=AQkAAAAAAAABYAEA; /linux/kernel
D> type=pdir;unique=AQkAAAAAAAABWAEA; /linux
D> type=file;size=6704;unique=AQkAAAAAAAADYAEA; k.config
D> type=file;size=7269221;unique=AQkAAAAAAAACYAEA; linux-2.0.36.tar.gz
D> type=file;size=12514594;unique=AQkAAAAAAAAEYAEA; linux-2.1.130.tar.gz
S> 226 Listing completed.
Okay so this server is serving a whole new look π
Its unique fact values come in a totally different format, and it gives the pdir entry a fully qualified pathname too. Iconic, honestly π¦
7.7.7. Some IANA Files πΈ
C> MLSD
S> 150 BINARY connection open for MLSD .
D> Type=cdir;Modify=19990219183438; /iana/assignments
D> Type=pdir;Modify=19990112030453; ..
D> Type=dir;Modify=19990219073522; media-types
D> Type=dir;Modify=19990112033515; character-set-info
D> Type=dir;Modify=19990112033529; languages
D> Type=file;Size=44242;Modify=19990217230400; character-sets
D> Type=file;Size=1947;Modify=19990209215600; operating-system-names
S> 226 MLSD completed
C> MLSD media-types
S> 150 BINARY connection open for MLSD media-types
D> Type=cdir;Modify=19990219073522; media-types
D> Type=cdir;Modify=19990219073522; /iana/assignments/media-types
D> Type=pdir;Modify=19990219183438; ..
D> Type=dir;Modify=19990112033045; text
D> Type=dir;Modify=19990219183442; image
D> Type=dir;Modify=19990112033216; multipart
D> Type=dir;Modify=19990112033254; video
D> Type=file;Size=30249;Modify=19990218032700; media-types
S> 226 MLSD completed
C> MLSD character-set-info
S> 150 BINARY connection open for MLSD character-set-info
D> Type=cdir;Modify=19990112033515; character-set-info
D> Type=cdir;Modify=19990112033515; /iana/assignments/character-set-info
D> Type=pdir;Modify=19990219183438; ..
D> Type=file;Size=1234;Modify=19980903020400; windows-1251
D> Type=file;Size=4557;Modify=19980922001400; tis-620
D> Type=file;Size=801;Modify=19970324130000; ibm775
D> Type=file;Size=552;Modify=19970320130000; ibm866
D> Type=file;Size=922;Modify=19960505140000; windows-1258
S> 226 MLSD completed
C> MLSD languages
S> 150 BINARY connection open for MLSD languages
D> Type=cdir;Modify=19990112033529; languages
D> Type=cdir;Modify=19990112033529; /iana/assignments/languages
D> Type=pdir;Modify=19990219183438; ..
D> Type=file;Size=2391;Modify=19980309130000; default
D> Type=file;Size=943;Modify=19980309130000; tags
D> Type=file;Size=870;Modify=19971026130000; navajo
D> Type=file;Size=699;Modify=19950911140000; no-bok
S> 226 MLSD completed
C> PWD
S> 257 "/iana/assignments" is current directory.
This example is giving IANA files, and it shows some of the IANA maintained files that matter for this spec, in MLSD format π Heads up: they deleted a bunch of entries to keep it short, so the real listings are way longer π
7.7.8. A Stress Test of Case (In)dependence π
This one is intense bestie π₯ It's here to show where case dependent strings are allowed in the MLSx commands, and where case independent strings are required.
First up, the MLSD command (shown here as MlsD) is case independent π«Ά Clients can type it in any case, or any mix of cases they want, and that goes for all FTP commands.
C> MlsD
S> 150 BINARY connection open for MLSD .
D> Type=pdir;Modify=19990929011228;Perm=el;Unique=keVO1+ZF4; ..
D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+Bd8; FILE2
D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+aG8; file3
D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+ag8; FILE3
D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+bD8; file1
D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+bD8; file2
D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+Ag8; File3
D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+bD8; File1
D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+Bd8; File2
D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+bd8; FILE1
S> 226 MLSD completed
Next, notice the labels of the facts β¨ They're case-independent strings too, so the server-FTP is allowed to return them in whatever case it likes. User-FTP needs to be ready for any case, though it can handle that by mapping the labels to a common case if it wants to.
Then look at how many type file objects came back: nine! π³ In a case-independent NVFS, those would be three different file names, file1, file2, and file3. In a case-dependent NVFS, all nine are different file names. Either is possible, since server-FTPs can implement a case dependent or a case independent NVFS. User-FTPs, though, must allow for case dependent selection of files to manipulate on the server.
Lastly, the value of the unique fact is case dependent, and this is the real plot twist π In this example, file1, File1, and file2 all have the same unique fact value, keVO1+bD8, so they all represent the same underlying file. But FILE1 has a different unique fact value (keVO1+bd8), so it's a different file. Same vibes for FILE2 and File2, which are two names for the same underlying file, while file3, File3, and FILE3 all represent different underlying files.
The sizes (the size fact) and last modification times (the modify fact) being the same in every case might just be a coincidence π
Nobody is suggesting that server operators build an NVFS that stresses the protocols this hard π Still, both user and server implementations must be prepared to deal with extreme examples like this one.
7.7.9. Example from Another Server π§
C> MlsD
S> 150 File Listing Follows in IMAGE / Binary mode.
D> type=cdir;modify=19990426150227;perm=el; /MISC
D> type=pdir;modify=19791231130000;perm=el; /
D> type=dir;modify=19990426150227;perm=el; CVS
D> type=dir;modify=19990426150228;perm=el; SRC
S> 226 Transfer finished successfully.
C> MlsD src
S> 150 File Listing Follows in IMAGE / Binary mode.
D> type=cdir;modify=19990426150228;perm=el; /MISC/src
D> type=pdir;modify=19990426150227;perm=el; /MISC
D> type=dir;modify=19990426150228;perm=el; CVS
D> type=dir;modify=19990426150228;perm=el; INSTALL
D> type=dir;modify=19990426150230;perm=el; INSTALLI
D> type=dir;modify=19990426150230;perm=el; TREES
S> 226 Transfer finished successfully.
C> MlsD src/install
S> 150 File Listing Follows in IMAGE / Binary mode.
D> type=cdir;modify=19990426150228;perm=el; /MISC/src/install
D> type=pdir;modify=19990426150228;perm=el; /MISC/src
D> type=file;modify=19990406234304;perm=r;size=20059; BOOTPC.C
D> type=file;modify=19980401170153;perm=r;size=278; BOOTPC.H
D> type=file;modify=19990413153736;perm=r;size=54220; BOOTPC.O
D> type=file;modify=19990223044003;perm=r;size=3389; CDROM.C
D> type=file;modify=19990413153739;perm=r;size=30192; CDROM.O
D> type=file;modify=19981119155324;perm=r;size=1055; CHANGELO
D> type=file;modify=19981204171040;perm=r;size=8297; COMMANDS.C
D> type=file;modify=19980508041749;perm=r;size=580; COMMANDS.H
...
D> type=file;modify=19990419052351;perm=r;size=54264; URLMETHO.O
D> type=file;modify=19980218161629;perm=r;size=993; WINDOWS.C
D> type=file;modify=19970912154859;perm=r;size=146; WINDOWS.H
D> type=file;modify=19990413153731;perm=r;size=16812; WINDOWS.O
D> type=file;modify=19990322174959;perm=r;size=129; _CVSIGNO
D> type=file;modify=19990413153640;perm=r;size=82536; _DEPEND
S> 226 Transfer finished successfully.
C> MLst src/install/windows.c
S> 250-Listing src/install/windows.c
S> type=file;perm=r;size=993; /misc/src/install/windows.c
S> 250 End
S> ftp> mlst SRC/INSTALL/WINDOWS.C
C> MLst SRC/INSTALL/WINDOWS.C
S> 250-Listing SRC/INSTALL/WINDOWS.C
S> type=file;perm=r;size=993; /misc/SRC/INSTALL/WINDOWS.C
S> 250 End
This server gives fully qualified pathnames for the pdir and cdir entries in MLSD listings πΊοΈ It also sorts its directory listing outputs, though it isn't required to. That might just be an artifact of the underlying file system access mechanisms, of course. Finally, the NVFS on this server is different from the earlier ones, because it implements its pathnames in a case independent manner π It seems to return files using the case the client used when the name was sent, and otherwise it picks the case of the names it returns with an algorithm known only to itself π€·ββοΈ
7.7.10. A Server Listing Itself πͺ
C> MLst f
S> 250-MLST f
S> Type=dir;Modify=20000710052229;Unique=AAD/AAAABIA; f
S> 250 End
C> CWD f
S> 250 CWD command successful.
C> MLSD
S> 150 Opening ASCII mode data connection for 'MLSD'.
D> Type=cdir;Unique=AAD/AAAABIA; .
D> Type=pdir;Unique=AAD/AAAAAAI; ..
D> Type=file;Size=987;Unique=AAD/AAAABIE; Makefile
D> Type=file;Size=20148;Unique=AAD/AAAABII; conf.c
D> Type=file;Size=11111;Unique=AAD/AAAABIM; extern.h
D> Type=file;Size=38721;Unique=AAD/AAAABIQ; ftpcmd.y
D> Type=file;Size=17922;Unique=AAD/AAAABIU; ftpd.8
D> Type=file;Size=60732;Unique=AAD/AAAABIY; ftpd.c
D> Type=file;Size=3127;Unique=AAD/AAAABIc; logwtmp.c
D> Type=file;Size=2294;Unique=AAD/AAAABIg; pathnames.h
D> Type=file;Size=7605;Unique=AAD/AAAABIk; popen.c
D> Type=file;Size=9951;Unique=AAD/AAAABIo; ftpd.conf.5
D> Type=file;Size=5023;Unique=AAD/AAAABIs; ftpusers.5
D> Type=file;Size=3547;Unique=AAD/AAAABIw; logutmp.c
D> Type=file;Size=2064;Unique=AAD/AAAABI0; version.h
D> Type=file;Size=20420;Unique=AAD/AAAAAAM; cmds.c
D> Type=file;Size=15864;Unique=AAD/AAAAAAg; ls.c
D> Type=file;Size=2898;Unique=AAD/AAAAAAk; ls.h
D> Type=file;Size=2769;Unique=AAD/AAAAAAo; lsextern.h
D> Type=file;Size=2042;Unique=AAD/AAAAAAs; stat_flags.h
D> Type=file;Size=5708;Unique=AAD/AAAAAAw; cmp.c
D> Type=file;Size=9280;Unique=AAD/AAAAAA0; print.c
D> Type=file;Size=4657;Unique=AAD/AAAAAA4; stat_flags.c
D> Type=file;Size=2664;Unique=AAD/AAAAAA8; util.c
D> Type=file;Size=10383;Unique=AAD/AAAABJ0; ftpd.conf.cat5
D> Type=file;Size=3631;Unique=AAD/AAAABJ4; ftpusers.cat5
D> Type=file;Size=17729;Unique=AAD/AAAABJ8; ftpd.cat8
S> 226 MLSD complete.
This one is a server showing off yet another implementation, and it's listing its own source code π€ Notice that it leaves the fully qualified path name out of its cdir and pdir entries, and out of the output from MLST too. Also, the facts requested got changed between the MLST and MLSD commands, though that exchange isn't shown here π
7.7.11. A Server with a Difference β¨
Here's a server that's a little bit different, and it's giving main character energy π
C> PASV
S> 227 Entering Passive Mode (127,0,0,1,255,46)
C> MLSD
S> 150 I tink I tee a trisector tree
D> Type=file;Unique=aaaaafUYqaaa;Perm=rf;Size=15741; x
D> Type=cdir;Unique=aaaaacUYqaaa;Perm=cpmel; /
D> Type=file;Unique=aaaaajUYqaaa;Perm=rf;Size=5760; x4
D> Type=dir;Unique=aaabcaUYqaaa;Perm=elf; sub
D> Type=file;Unique=aaaaagUYqaaa;Perm=rf;Size=8043; x1
D> Type=dir;Unique=aaab8aUYqaaa;Perm=cpmelf; files
D> Type=file;Unique=aaaaahUYqaaa;Perm=rf;Size=4983; x2
D> Type=file;Unique=aaaaaiUYqaaa;Perm=rf;Size=6854; x3
S> 226 That's all folks...
C> CWD sub
S> 250 CWD command successful.
C> PWD
S> 257 "/sub" is current directory.
C> PASV
S> 227 Entering Passive Mode (127,0,0,1,255,44)
C> MLSD
S> 150 I tink I tee a trisector tree
D> Type=dir;Unique=aaabceUYqaaa;Perm=elf; dir
D> Type=file;Unique=aaabcbUYqaaa;Perm=rf;Size=0; y1
D> Type=file;Unique=aaabccUYqaaa;Perm=rf;Size=0; y2
D> Type=file;Unique=aaabcdUYqaaa;Perm=rf;Size=0; y3
D> Type=pdir;Unique=aaaaacUYqaaa;Perm=cpmel; /
D> Type=pdir;Unique=aaaaacUYqaaa;Perm=cpmel; ..
D> Type=cdir;Unique=aaabcaUYqaaa;Perm=el; /sub
S> 226 That's all folks...
C> PASV
S> 227 Entering Passive Mode (127,0,0,1,255,42)
C> MLSD dir
S> 150 I tink I tee a trisector tree
D> Type=pdir;Unique=aaabcaUYqaaa;Perm=el; /sub
D> Type=pdir;Unique=aaabcaUYqaaa;Perm=el; ..
D> Type=file;Unique=aaab8cUYqaaa;Perm=r;Size=15039; mlst.c
D> Type=dir;Unique=aaabcfUYqaaa;Perm=el; ect
D> Type=cdir;Unique=aaabceUYqaaa;Perm=el; dir
D> Type=cdir;Unique=aaabceUYqaaa;Perm=el; /sub/dir
D> Type=dir;Unique=aaabchUYqaaa;Perm=el; misc
D> Type=file;Unique=aaab8bUYqaaa;Perm=r;Size=34589; ftpd.c
S> 226 That's all folks...
C> CWD dir/ect
S> 250 CWD command successful.
C> PWD
S> 257 "/sub/dir/ect" is current directory.
C> PASV
S> 227 Entering Passive Mode (127,0,0,1,255,40)
C> MLSD
S> 150 I tink I tee a trisector tree
D> Type=dir;Unique=aaabcgUYqaaa;Perm=el; ory
D> Type=pdir;Unique=aaabceUYqaaa;Perm=el; /sub/dir
D> Type=pdir;Unique=aaabceUYqaaa;Perm=el; ..
D> Type=cdir;Unique=aaabcfUYqaaa;Perm=el; /sub/dir/ect
S> 226 That's all folks...
C> CWD /files
S> 250 CWD command successful.
C> PASV
S> 227 Entering Passive Mode (127,0,0,1,255,36)
C> MLSD
S> 150 I tink I tee a trisector tree
D> Type=cdir;Unique=aaab8aUYqaaa;Perm=cpmel; /files
D> Type=pdir;Unique=aaaaacUYqaaa;Perm=cpmel; /
D> Type=pdir;Unique=aaaaacUYqaaa;Perm=cpmel; ..
D> Type=file;Unique=aaab8cUYqaaa;Perm=rf;Size=15039; mlst.c
D> Type=file;Unique=aaab8bUYqaaa;Perm=rf;Size=34589; ftpd.c
S> 226 That's all folks...
C> RNFR mlst.c
S> 350 File exists, ready for destination name
C> RNTO list.c
S> 250 RNTO command successful.
C> PASV
S> 227 Entering Passive Mode (127,0,0,1,255,34)
C> MLSD
S> 150 I tink I tee a trisector tree
D> Type=file;Unique=aaab8cUYqaaa;Perm=rf;Size=15039; list.c
D> Type=pdir;Unique=aaaaacUYqaaa;Perm=cpmel; /
D> Type=pdir;Unique=aaaaacUYqaaa;Perm=cpmel; ..
D> Type=file;Unique=aaab8bUYqaaa;Perm=rf;Size=34589; ftpd.c
D> Type=cdir;Unique=aaab8aUYqaaa;Perm=cpmel; /files
S> 226 That's all folks...
Okay so this server is giving total chaotic directory energy ππ. Its listings come back in what looks like completely random order, and the order even seems to shift as the contents change π. Maybe the directory is hashed under the hood, who knows π€·ββοΈ. Notice how the "pdir" and "cdir" entries are scattered in between everything else, no cap π . Also, this server doesn't show a "pdir" entry when you list the root of the virtual filestore πΈ, BUT it will throw in multiple "cdir" and "pdir" entries whenever it feels inclined π. And the messages? Obnoxiously "cute" ππ§.
7.8. FEAT Response for MLSx β¨
When a server-FTP answers FEAT, and it supports MLST, MLSD, plus internationalization of pathnames, it MUST say so π¦. The way it does that is by including an MLST feature line. Not only does that line show the basic support, it also tells you which MLST facts are available from the server, and which of those come back if the client never sends "OPTS MLST" π.
mlst-feat = SP "MLST" [SP factlist] CRLF
factlist = 1*( factname ["*"] ";" )
The initial space in the mlst-feat response is the one FEAT requires, and two spaces are not permitted π ββοΈ. If there's no factlist, the server-FTP is saying it does MLST but implements zero facts π, so only pathnames can come back. Honestly that's a minimal MLST implementation and useless for most practical purposes π. When the factlist is there, the factnames tell you what the server supports π₯. An asterisk after a factname means that fact will show up in MLST format responses until an "OPTS MLST" changes the list π. After that, FEAT puts the asterisk on whatever facts the most recent "OPTS MLST" selected π .
Note that there is no distinct FEAT output for MLSD. The presence of the MLST feature indicates that both MLST and MLSD are supported β¨.
7.8.1. Examples
C> Feat
S> 211- Features supported
S> REST STREAM
S> MDTM
S> SIZE
S> TVFS
S> UTF8
S> MLST Type*;Size*;Modify*;Perm*;Unique*;UNIX.mode;UNIX.chgd;X.hidden;
S> 211 End
Aside from some features that don't matter here, this server supports MLST with several, but not all, standard facts, and it sends all of them by default π. It also supports two OS dependent facts, plus one locally defined fact. The latter three must be requested expressly by the client for this server to supply them π§.
C> Feat
S> 211-Extensions supported:
S> CLNT
S> MDTM
S> MLST type*;size*;modify*;UNIX.mode*;UNIX.owner;UNIX.group;unique;
S> PASV
S> REST STREAM
S> SIZE
S> TVFS
S> Compliance Level: 19981201 (IETF mlst-05)
S> 211 End.
Again, besides some irrelevant features, this server indicates that it supports MLST, four of the standard facts, one of which ("unique") is not enabled by default, and several OS dependent facts, one of which is provided by the server by default π. This server actually supported more OS dependent facts. Others were deleted for the purposes of this document to comply with document formatting restrictions π.
C> FEAT
S> 211-Features supported
S> MDTM
S> MLST Type*;Size*;Modify*;Perm;Unique*;
S> REST STREAM
S> SIZE
S> TVFS
S> 211 End
This server has wisely chosen not to implement any OS dependent facts π. At the time of writing this document, no such facts have been defined (using the mechanisms of section 10.1), so rational support for them would be difficult at best π. All but one of the facts supported by this server are enabled by default π.
7.9. OPTS Parameters for MLST β¨
For the MLSx commands, the Client-FTP may specify a list of facts it wishes to be returned in all subsequent MLSx commands until another OPTS MLST command is sent π¦. The format is specified by:
mlst-opts = "OPTS" SP "MLST"
[ SP 1*( factname ";" ) ]
By sending the "OPTS MLST" command, the client asks the server to include only the facts listed as arguments in subsequent output from MLSx commands π . Facts not included in the "OPTS MLST" command MUST NOT be returned by the server. Facts that are included should be returned for each entry returned from the MLSx command where they meaningfully apply. Facts requested that are not supported, or that are inappropriate to the file or directory being listed, should simply be omitted from the MLSx output. This is not an error π«Ά. Note that where no factname arguments are present, the client is requesting that only the file names be returned. In this case, and in any other case where no facts are included in the result, the space that separates the fact names and their values from the file name is still required. That is, the first character of the output line will be a space (or two characters will be spaces when the line is returned over the control connection), and the file name will start immediately after it π.
Clients should note that generating values for some facts can be possible, but very expensive, for some servers. It is generally acceptable to retrieve any of the facts that the server offers as its default set before any "OPTS MLST" command has been given, however clients should use particular caution before requesting any facts not in that set. That is, while other facts may be available from the server, clients should refrain from requesting such facts unless there is a particular operational requirement for that particular information, which ought be more significant than perhaps simply improving the information displayed to an end user π.
Note, there is no "OPTS MLSD" command. The fact names set with the "OPTS MLST" command apply to both MLST and MLSD commands πΈ.
Servers are not required to accept "OPTS MLST" commands before authentication of the user-PI, but may choose to permit them π.
7.9.1. OPTS MLST Response
The "response-message" from [6] to a successful OPTS MLST command has the following syntax π.
mlst-opt-resp = "MLST OPTS" [ SP 1*( factname ";" ) ]
This defines the "response-message" as used in the "opts-good" message in RFC 2389 [6] β¨.
The facts named in the response are the ones the server will now include in MLST (and MLSD) responses, after processing the "OPTS MLST" command π―. Any facts from the request that the server doesn't support will be omitted from this response message. If no facts will be included, the list of facts will be empty. Note that the list of facts returned will be the same as those marked with a trailing asterisk ("*") in a subsequent FEAT command response π₯. There is no requirement that the order of the facts returned be the same as the order they were requested in, the order they appear in a FEAT command response, or the order facts are returned in MLST responses. The fixed string "MLST OPTS" in the response may be returned in any case, or mixture of cases π.
7.9.2. Examples
C> Feat
S> 211- Features supported
S> MLST Type*;Size;Modify*;Perm;Unique;UNIX.mode;UNIX.chgd;X.hidden;
S> 211 End
C> OptS Mlst Type;UNIX.mode;Perm;
S> 200 MLST OPTS Type;Perm;UNIX.mode;
C> Feat
S> 211- Features supported
S> MLST Type*;Size;Modify;Perm*;Unique;UNIX.mode*;UNIX.chgd;X.hidden;
S> 211 End
C> opts MLst lang;type;charset;create;
S> 200 MLST OPTS Type;
C> Feat
S> 211- Features supported
S> MLST Type*;Size;Modify;Perm;Unique;UNIX.mode;UNIX.chgd;X.hidden;
S> 211 End
C> OPTS mlst size;frogs;
S> 200 MLST OPTS Size;
C> Feat
S> 211- Features supported
S> MLST Type;Size*;Modify;Perm;Unique;UNIX.mode;UNIX.chgd;X.hidden;
S> 211 End
C> opts MLst unique type;
S> 501 Invalid MLST options
C> Feat
S> 211- Features supported
S> MLST Type;Size*;Modify;Perm;Unique;UNIX.mode;UNIX.chgd;X.hidden;
S> 211 End
For the purposes of this example, features other than MLST have been removed from the output to avoid clutter π§Ή. The example shows the initial default feature output for MLST. Then the client changes the requested facts. The first change selects facts that the server makes available, and the subsequent FEAT output shows the altered features being returned π. Next, the client tries to select some standard features that the server does not support. This is not an error, but the server simply ignores those requests, as the FEAT output that follows shows π. Then the client requests a non-standard, unsupported feature. The server ignores that, and selects only the supported features that were requested β¨. Lastly, the client sends a request containing a syntax error (spaces cannot appear in the factlist) π. The server-FTP sends an error response and completely ignores the request, leaving the fact set selected as it had been previously π.
Note that in all cases, except the error response, the response lists the facts that have been selected π .
C> Feat
S> 211- Features supported
S> MLST Type*;Size*;Modify*;Perm*;Unique*;UNIX.mode;UNIX.chgd;X.hidden;
S> 211 End
C> Opts MLST
S> 200 MLST OPTS
C> Feat
S> 211- Features supported
S> MLST Type;Size;Modify;Perm;Unique;UNIX.mode;UNIX.chgd;X.hidden;
S> 211 End
C> MLst tmp
S> 250- Listing tmp
S> /tmp
S> 250 End
C> OPTS mlst unique;size;
S> 200 MLST OPTS Size;Unique;
C> MLst tmp
S> 250- Listing tmp
S> Unique=keVO1+YZ5; /tmp
S> 250 End
C> OPTS mlst unique;type;modify;
S> 200 MLST OPTS Type;Modify;Unique;
C> MLst tmp
S> 250- Listing tmp
S> Type=dir;Modify=19990930152225;Unique=keVO1+YZ5; /tmp
S> 250 End
C> OPTS mlst fish;cakes;
S> 200 MLST OPTS
C> MLst tmp
S> 250- Listing tmp
S> /tmp
S> 250 End
C> OptS Mlst Modify;Unique;
S> 200 MLST OPTS Modify;Unique;
C> MLst tmp
S> 250- Listing tmp
S> Modify=19990930152225;Unique=keVO1+YZ5; /tmp
S> 250 End
C> opts MLst fish cakes;
S> 501 Invalid MLST options
C> MLst tmp
S> 250- Listing tmp
S> Modify=19990930152225;Unique=keVO1+YZ5; /tmp
S> 250 End
Okay so this example is all about what happens when you change which facts you ask for in your MLST commands π Every new OPTS call changes what shows up in the next MLST reply, iykyk. π¦
Also, a typo in your options doesn't wipe out what you already picked. Look at that 501 error: the facts stay exactly the same after it, which is so iconic of it π
And when no facts end up selected (on purpose, or because none of the ones you asked for were available), you get exactly two spaces before the pathname. Be precise, bestie π
8. Impact on Other FTP Commands β¨
Okay so MLST is the new main character, but it means the older FTP commands have to level up too π¦ Along with it, traditional FTP commands need to handle more than US-ASCII [1] or EBCDIC character sets. Generally speaking, supporting MLST means supporting arbitrary character sets wherever file names and directory names are allowed. That goes for both the arguments you send to these commands and the replies you get back, as appropriate πΈ
APPE RMD
CWD RNFR
DELE RNTO
MKD STAT
PWD STOR
RETR STOU
Bestie, the arguments to all of these commands should get handled the same way MLST commands and responses get handled when it comes to embedded spaces, CRs and NULs. See section 2.2 π«Ά
9. Character Sets and Internationalization π
Okay so FTP commands are protocol elements, and they're always expressed in ASCII. FTP responses are made of the numeric code (also a protocol element) plus a message that's usually there to inform the user π Normal users don't really touch the protocol elements directly. The user-FTP process builds the commands and reads the results in whatever way suits the particular user best. The explanatory text in responses generally has no particular meaning to the protocol, since the numeric codes give all the necessary info β¨ Server-PIs are free to write that text in any language that can be adequately represented in ASCII, or in an alternative language and representation that has been negotiated (see [7]) in that language and representation π
Pathnames are expected to be encoded in UTF-8, which means basically any character can show up in a pathname π Meaningful pathnames are defined by the server NVFS.
No restrictions at all are placed on the contents of files transferred using the FTP protocols π Unless the "media-type" fact is provided in a MLSx response, nor is any advice given here that would allow determining the content type. That info is assumed to come from other means.
10. IANA Considerations π§
This spec uses some lists of values that the IANA currently maintains, and it creates two new lists for the IANA to maintain. It doesn't add any values to any existing registries, so no drama there πΈ
The existing IANA registries used by this specification are modified using mechanisms specified elsewhere.
10.1. The OS-Specific Fact Registry
A registry of OS specific fact names shall be maintained by the IANA π The OS names for the OS portion of the fact name must be taken from the IANA's list of registered OS names. To add a fact name to this OS specific registry of OS specific facts, an applicant must send the IANA a request. That request specifies the OS name, the OS specific fact name, a definition of the syntax of the fact value (which must conform to the syntax of a token as given in this document), and a specification of the semantics to be associated with the particular fact and its values. Once the IANA gets an application like that, and the combination of OS name and OS specific fact name hasn't been previously defined, the IANA will add the specification to the registry π
Any examples of OS specific facts found in this document are to be treated as examples of possible OS specific facts. They don't count as part of the IANA's registry just because they're included in this document π ββοΈ
10.2. The OS-Specific Filetype Registry
A registry of OS specific file types shall be maintained by the IANA ποΈ The OS names for the OS portion of the fact name must be taken from the IANA's list of registered OS names. To add a file type to this OS specific registry of OS specific file types, an applicant must send the IANA a request. That request specifies the OS name, the OS specific file type, a definition of the syntax of the fact value (which must conform to the syntax of a token as given in this document), and a specification of the semantics to be associated with the particular fact and its values. Once the IANA gets an application like that, and the combination of OS name and OS specific file type hasn't been previously defined, the IANA will add the specification to the registry β¨
Any examples of OS specific file types found in this document are to be treated as potential OS specific file types only. They don't form part of the IANA's registry just because they appear in this document π¦
11. Security Considerations π¨
Okay, this part is serious, so listen up π This memo does not directly concern security. It isn't believed that any of the mechanisms documented here impact the security of FTP in any particular way.
BUT. Implementing the SIZE command, and maybe some of the facts of the MLSx commands, may put a considerable load on the server, which could lead to denial of service attacks π Servers have, however, implemented this for many years without significant reported difficulties, so it's not a total disaster.
The server-FTP should take care not to reveal sensitive information about files to unauthorised parties π In particular, some underlying filesystems provide a file identifier that, if known, can allow many of the filesystem protection mechanisms to be by-passed. That identifier would not be a suitable choice to use as the basis of the value of the unique fact. Do NOT build your unique fact on it, bestie π
The FEAT and OPTS commands may be issued before the FTP authentication has occurred [6]. This lets unauthenticated clients figure out which of the features defined here are supported, and negotiate the fact list for MLSx output. No actual MLSx commands may be issued, though, and no problems with permitting the selection of the format prior to authentication are foreseen π§
A general discussion of issues related to the security of FTP can be found in [13] π
12. Normative References π
- [1] Coded Character Set--7-bit American Standard Code for Information Interchange, ANSI X3.4-1986.
- [2] Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC 3629, November 2003.
- [3] Postel, J. and J. Reynolds, "File Transfer Protocol (FTP)", STD 9, RFC 959, October 1985.
- [4] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
- [5] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 4234, October 2005.
- [6] Hethmon, P. and R. Elz, "Feature negotiation mechanism for the File Transfer Protocol", RFC 2389, August 1998.
- [7] Curtin, B., "Internationalization of the File Transfer Protocol", RFC 2640, July 1999.
- [8] Postel, J. and J. Reynolds, "Telnet protocol Specification", STD 8, RFC 854, May 1983.
- [9] Braden, R,. "Requirements for Internet Hosts -- Application and Support", STD 3, RFC 1123, October 1989.
- [10] ISO/IEC 10646-1:1993 "Universal multiple-octet coded character set (UCS) -- Part 1: Architecture and basic multilingual plane", International Standard -- Information Technology, 1993.
- [11] Internet Assigned Numbers Authority. http://www.iana.org Email: iana@iana.org.
- [12] Phillips, A. and M. Davis, "Tags for Identifying Languages", BCP 47, RFC 4646, September 2006.
- [13] Allman, M. and S. Ostermann, "FTP Security Considerations" RFC 2577, May 1999.
Acknowledgments π«Ά
This document is a product of the FTPEXT working group of the IETF π
The following people are among those who have contributed to this document:
- Alex Belits
- D. J. Bernstein
- Dave Cridland
- Martin J. Duerst
- Bill Fenner (and the rest of the IESG)
- Paul Ford-Hutchinson
- Mike Gleason
- Mark Harris
- Stephen Head
- Alun Jones
- Andrew Main
- James Matthews
- Luke Mewburn
- Jan Mikkelsen
- Keith Moore
- Buz Owen
- Mark Symons
- Stephen Tihor
- and the entire FTPEXT working group of the IETF.
Apologies are offered to any inadvertently omitted π
The description of the modifications to the REST command and the MDTM and SIZE commands comes from a set of modifications suggested for STD 9, RFC 959 by Rick Adams in 1989. A document containing just those commands, edited by David Borman, has been merged with this document π
Mike Gleason, Alun Jones and Luke Mewburn provided access to FTP servers used in some of the examples π
All of the examples in this document are taken from actual client/server exchanges, though some have been edited for brevity, or to meet document formatting requirements.
RFC Editor Note π¨
Several of the examples in this document exceed the RFC standard line length of 72 characters. Since this document is a standards-track result of an IETF working group and is important to an IETF sub-community, the RFC Editor is publishing it with the margin violations. This is not a precedent.
Author's Address π
Paul Hethmon
Hethmon Software
10420 Jackson Oaks Way, Suite 201
Knoxville, TN 37922
EMail: phethmon@hethmon.com
Full Copyright Statement π
Copyright (C) The IETF Trust (2007).
This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.
This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Intellectual Property β¨
okay so the IETF is basically saying "we're not picking a side on whether anyone owns the rights to this tech" π they don't say whether any of the rights are valid or how far they reach, and they didn't go hunting for rights holders either π if you want the rules on rights for RFC documents, check BCP 78 and BCP 79 π
if you're an implementer or user and you want to see disclosures that were sent to the IETF Secretariat, or any promises of licenses, or what happened when someone tried to get a general license or permission for these proprietary rights, go to the IETF online IPR repository at http://www.ietf.org/ipr π that's the place for the receipts π§Ύ
and if you think there's a copyright, patent, patent application, or other proprietary right that might cover technology you'd need to build this standard, tell the IETF! send it to ietf-ipr@ietf.org π the whole community is counting on you to speak up π«Ά
Acknowledgement π
the RFC Editor function is currently funded by the Internet Society π so a big thank-you to them for keeping the lights on for the RFC series πβ¨
π¦ where this page comes from
- ietf: rfc3659 2007-03
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms