1 /**
2 * This file is part of Waarp Project.
3 *
4 * Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
5 * COPYRIGHT.txt in the distribution for a full listing of individual contributors.
6 *
7 * All Waarp Project is free software: you can redistribute it and/or modify it under the terms of
8 * the GNU General Public License as published by the Free Software Foundation, either version 3 of
9 * the License, or (at your option) any later version.
10 *
11 * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 * Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along with Waarp . If not, see
16 * <http://www.gnu.org/licenses/>.
17 */
18 package org.waarp.ftp.core.command;
19
20 import org.waarp.ftp.core.command.internal.ConnectionCommand;
21 import org.waarp.ftp.core.command.internal.IncorrectCommand;
22 import org.waarp.ftp.core.command.internal.UnimplementedCommand;
23 import org.waarp.ftp.core.command.internal.UnknownCommand;
24 import org.waarp.ftp.core.file.FtpFile;
25 import org.waarp.ftp.core.session.FtpSession;
26
27 /**
28 * This class must reassemble all the commands that could be implemented. The comment says the
29 * object of the command and the kind of returned codes that could follow this command.<br>
30 * <br>
31 * Command structure:<br>
32 * Main class<br>
33 * Previous Valid Command (null means all are valid)<br>
34 * Next Valid Commands (none means all are valid)<br>
35 *
36 * @author Frederic Bregier
37 *
38 */
39 public enum FtpCommandCode {
40 // XXX CONNECTION
41 /**
42 * Command to simulate the beginning of a connection in order to force the authentication step.<br>
43 *
44 *
45 * 120->220<br>
46 * 220<br>
47 * 421<br>
48 */
49 Connection(
50 ConnectionCommand.class,
51 null,
52 org.waarp.ftp.core.command.access.USER.class, org.waarp.ftp.core.command.rfc2389.FEAT.class),
53 // XXX ACCESS CONTROL COMMAND
54 /**
55 * The argument field is a Telnet string identifying the user. The user identification is that
56 * which is required by the server for access to its file system. This command will normally be
57 * the first command transmitted by the user after the control connections are made (some
58 * servers may require this). Additional identification information in the form of a password
59 * and/or an account command may also be required by some servers. Servers may allow a new USER
60 * command to be entered at any point in order to change the access control and/or accounting
61 * information. This has the effect of flushing any user, password, and account information
62 * already supplied and beginning the login sequence again. All transfer parameters are
63 * unchanged and any file transfer in progress is completed under the old access control
64 * parameters.<br>
65 *
66 * 230<br>
67 * 530<br>
68 * 500, 501, 421<br>
69 * 331, 332<br>
70 */
71 USER(org.waarp.ftp.core.command.access.USER.class, ConnectionCommand.class),
72 /**
73 * The argument field is a Telnet string specifying the user's password. This command must be
74 * immediately preceded by the user name command, and, for some sites, completes the user's
75 * identification for access control. Since password information is quite sensitive, it is
76 * desirable in general to "mask" it or suppress typeout. It appears that the server has no
77 * foolproof way to achieve this. It is therefore the responsibility of the user-FTP process to
78 * hide the sensitive password information.<br>
79 *
80 *
81 * 230<br>
82 * 202<br>
83 * 530<br>
84 * 500, 501, 503, 421<br>
85 * 332<br>
86 */
87 PASS(org.waarp.ftp.core.command.access.PASS.class, null),
88 /**
89 * The argument field is a Telnet string identifying the user's account. The command is not
90 * necessarily related to the USER command, as some sites may require an account for login and
91 * others only for specific access, such as storing files. In the latter case the command may
92 * arrive at any time.<br>
93 * <br>
94 *
95 * There are reply codes to differentiate these cases for the automation: when account
96 * information is required for login, the response to a successful PASSword command is reply
97 * code 332. On the other hand, if account information is NOT required for login, the reply to a
98 * successful PASSword command is 230; and if the account information is needed for a command
99 * issued later in the dialogue, the server should return a 332 or 532 reply depending on
100 * whether it stores (pending receipt of the ACCounT command) or discards the command,
101 * respectively.<br>
102 *
103 *
104 * 230<br>
105 * 202<br>
106 * 530<br>
107 * 500, 501, 503, 421<br>
108 */
109 ACCT(org.waarp.ftp.core.command.access.ACCT.class, null),
110 /**
111 * This command allows the user to work with a different directory or dataset for file storage
112 * or retrieval without altering his login or accounting information. Transfer parameters are
113 * similarly unchanged. The argument is a pathname specifying a directory or other system
114 * dependent file group designator.<br>
115 *
116 *
117 * 250<br>
118 * 500, 501, 502, 421, 530, 550<br>
119 */
120 CWD(org.waarp.ftp.core.command.directory.CWD.class, null),
121 /**
122 * This command is a special case of CWD, and is included to simplify the implementation of
123 * programs for transferring directory trees between operating systems having different syntaxes
124 * for naming the parent directory. The reply codes shall be identical to the reply codes of
125 * CWD. See Appendix II for further details.<br>
126 *
127 *
128 * 200<br>
129 * 500, 501, 502, 421, 530, 550<br>
130 */
131 CDUP(org.waarp.ftp.core.command.directory.CDUP.class, null),
132 /**
133 * This command allows the user to mount a different file system data structure without altering
134 * his login or accounting information. Transfer parameters are similarly unchanged. The
135 * argument is a pathname specifying a directory or other system dependent file group
136 * designator.<br>
137 * <br>
138 * As for now, this command will not be implemented, so returns 502.<br>
139 *
140 *
141 * 202, 250<br>
142 * 500, 501, 502, 421, 530, 550<br>
143 */
144 // XXX 502
145 SMNT(org.waarp.ftp.core.command.directory.SMNT.class, null),
146 /**
147 * This command terminates a USER, flushing all I/O and account information, except to allow any
148 * transfer in progress to be completed. All parameters are reset to the default settings and
149 * the control connection is left open. This is identical to the state in which a user finds
150 * himself immediately after the control connection is opened. A USER command may be expected to
151 * follow.<br>
152 * <br>
153 *
154 * 120<br>
155 * 220<br>
156 * 220<br>
157 * 421<br>
158 * 500, 502<br>
159 */
160 REIN(org.waarp.ftp.core.command.access.REIN.class, null,
161 org.waarp.ftp.core.command.access.USER.class),
162 /**
163 * This command terminates a USER and if file transfer is not in progress, the server closes the
164 * control connection. If file transfer is in progress, the connection will remain open for
165 * result response and the server will then close it. If the user-process is transferring files
166 * for several USERs but does not wish to close and then reopen connections for each, then the
167 * REIN command should be used instead of QUIT.<br>
168 * <br>
169 *
170 * An unexpected close on the control connection will cause the server to take the effective
171 * action of an abort (ABOR) and a logout (QUIT).<br>
172 *
173 *
174 * 221<br>
175 * 500<br>
176 */
177 QUIT(org.waarp.ftp.core.command.access.QUIT.class, null),
178
179 // XXX TRANSFER PARAMETER COMMAND
180 /**
181 * The argument is a HOST-PORT specification for the data port to be used in data connection.
182 * There are defaults for both the user and server data ports, and under normal circumstances
183 * this command and its reply are not needed. If this command is used, the argument is the
184 * concatenation of a 32-bit internet host address and a 16-bit TCP port address. This address
185 * information is broken into 8-bit fields and the value of each field is transmitted as a
186 * decimal number (in character string representation). The fields are separated by commas. A
187 * port command would be:<br>
188 * <br>
189 *
190 * <pre>
191 * PORT h1,h2,h3,h4,p1,p2
192 * </pre>
193 *
194 * where h1 is the high order 8 bits of the internet host address.<br>
195 *
196 *
197 *
198 * 200<br>
199 * 500, 501, 421, 530<br>
200 */
201 PORT(org.waarp.ftp.core.command.parameter.PORT.class, null),
202 /**
203 * This command requests the server-DTP to "listen" on a data port (which is not its default
204 * data port) and to wait for a connection rather than initiate one upon receipt of a transfer
205 * command. The response to this command includes the host and port address this server is
206 * listening on.<br>
207 *
208 *
209 *
210 * 227<br>
211 * 500, 501, 502, 421, 530<br>
212 */
213 PASV(org.waarp.ftp.core.command.parameter.PASV.class, null),
214 /**
215 * The argument specifies the representation type as described in the Section on Data
216 * Representation and Storage. Several types take a second parameter. The first parameter is
217 * denoted by a single Telnet character, as is the second Format parameter for ASCII and EBCDIC;
218 * the second parameter for local byte is a decimal integer to indicate Bytesize. The parameters
219 * are separated by a <code><SP></code> (Space, ASCII code 32).<br>
220 * <br>
221 *
222 * The following codes are assigned for type:<br>
223 *
224 * <pre>
225 * \ /
226 * A - ASCII | | N - Non-print
227 * |-><-| T - Telnet format effectors
228 * E - EBCDIC| | C - Carriage Control (ASA)
229 * / \
230 * I - Image
231 * L <byte size> - Local byte Byte size
232 * </pre>
233 *
234 * The default representation type is ASCII Non-print. If the Format parameter is changed, and
235 * later just the first argument is changed, Format then returns to the Non-print default.<br>
236 *
237 * 200<br>
238 * 500, 501, 504, 421, 530<br>
239 */
240 TYPE(org.waarp.ftp.core.command.parameter.TYPE.class, null),
241 /**
242 * The argument is a single Telnet character code specifying file structure described in the
243 * Section on Data Representation and Storage.<br>
244 * <br>
245 *
246 * The following codes are assigned for structure:<br>
247 *
248 * <pre>
249 * F - FtpFile (no record structure)
250 * R - Record structure
251 * P - Page structure
252 * </pre>
253 *
254 * The default structure is FtpFile.<br>
255 *
256 *
257 * 200<br>
258 * 500, 501, 504, 421, 530<br>
259 */
260 STRU(org.waarp.ftp.core.command.parameter.STRU.class, null),
261 /**
262 * The argument is a single Telnet character code specifying the data transfer modes described
263 * in the Section on Transmission Modes.<br>
264 * <br>
265 *
266 * The following codes are assigned for transfer modes:<br>
267 *
268 * <pre>
269 * S - Stream
270 * B - Block
271 * C - Compressed
272 * </pre>
273 *
274 * The default transfer mode is Stream.<br>
275 *
276 *
277 * 200<br>
278 * 500, 501, 504, 421, 530<br>
279 */
280 MODE(org.waarp.ftp.core.command.parameter.MODE.class, null),
281
282 // XXX FTP SERVICE COMMAND
283 /**
284 * This command causes the server-DTP to transfer a copy of the file, specified in the pathname,
285 * to the server- or user-DTP at the other end of the data connection. The status and contents
286 * of the file at the server site shall be unaffected.<br>
287 *
288 * 125, 150<br>
289 * (110)<br>
290 * 226, 250<br>
291 * 425, 426, 451<br>
292 * 450, 550<br>
293 * 500, 501, 421, 530<br>
294 */
295 RETR(org.waarp.ftp.core.command.service.RETR.class, null),
296 /**
297 * This command causes the server-DTP to accept the data transferred via the data connection and
298 * to store the data as a file at the server site. If the file specified in the pathname exists
299 * at the server site, then its contents shall be replaced by the data being transferred. A new
300 * file is created at the server site if the file specified in the pathname does not already
301 * exist.<br>
302 *
303 *
304 * 125, 150<br>
305 * (110)<br>
306 * 226, 250<br>
307 * 425, 426, 451, 551, 552<br>
308 * 532, 450, 452, 553<br>
309 * 500, 501, 421, 530<br>
310 */
311 STOR(org.waarp.ftp.core.command.service.STOR.class, null),
312 /**
313 * This command behaves like STOR except that the resultant file is to be created in the current
314 * directory under a name unique to that directory. The 250 Transfer Started response must
315 * include the name generated.<br>
316 *
317 *
318 * 125, 150<br>
319 * (110)<br>
320 * 226, 250<br>
321 * 425, 426, 451, 551, 552<br>
322 * 532, 450, 452, 553<br>
323 * 500, 501, 421, 530<br>
324 */
325 STOU(org.waarp.ftp.core.command.service.STOU.class, null),
326 /**
327 * This command causes the server-DTP to accept the data transferred via the data connection and
328 * to store the data in a file at the server site. If the file specified in the pathname exists
329 * at the server site, then the data shall be appended to that file; otherwise the file
330 * specified in the pathname shall be created at the server site.<br>
331 *
332 *
333 * 125, 150<br>
334 * (110)<br>
335 * 226, 250<br>
336 * 425, 426, 451, 551, 552<br>
337 * 532, 450, 452, 553<br>
338 * 500, 501, 421, 530<br>
339 */
340 APPE(org.waarp.ftp.core.command.service.APPE.class, null),
341 /**
342 * This command may be required by some servers to reserve sufficient storage to accommodate the
343 * new file to be transferred. The argument shall be a decimal integer representing the number
344 * of bytes (using the logical byte size) of storage to be reserved for the file. For files sent
345 * with record or page structure a maximum record or page size (in logical bytes) might also be
346 * necessary; this is indicated by a decimal integer in a second argument field of the command.
347 * This second argument is optional, but when present should be separated from the first by the
348 * three Telnet characters <code><SP></code> R <code><SP></code>. This command shall
349 * be followed by a STORe or APPEnd command. The ALLO command should be treated as a NOOP (no
350 * operation) by those servers which do not require that the maximum size of the file be
351 * declared beforehand, and those servers interested in only the maximum record or page size
352 * should accept a dummy value in the first argument and ignore it.<br>
353 *
354 *
355 * 125, 150<br>
356 * 226, 250<br>
357 * 425, 426, 451<br>
358 * 450<br>
359 * 500, 501, 502, 421, 530<br>
360 */
361 ALLO(org.waarp.ftp.core.command.service.ALLO.class, null),
362 /**
363 * The argument field represents the server marker at which file transfer is to be restarted.
364 * This command does not cause file transfer but skips over the file to the specified data
365 * checkpoint. This command shall be immediately followed by the appropriate FTP service command
366 * which shall cause file transfer to resume.<br>
367 * <br>
368 * The current implementation allows restart only on Stream since others would imply to store
369 * those informations somewhere (how?).<br>
370 * <br>
371 * However, it could be changed if necessary by modifying the {@link FtpFile} restartMarker
372 * method.<br>
373 * <br>
374 * This command will accept commands of transfer parameter following since some clients do this.<br>
375 *
376 * 500, 501, 502, 421, 530<br>
377 * 350<br>
378 */
379 REST(
380 org.waarp.ftp.core.command.service.REST.class,
381 null,
382 org.waarp.ftp.core.command.service.RETR.class,
383 org.waarp.ftp.core.command.service.STOR.class,
384 org.waarp.ftp.core.command.service.STOU.class,
385 org.waarp.ftp.core.command.service.APPE.class,
386 org.waarp.ftp.core.command.parameter.PORT.class,
387 org.waarp.ftp.core.command.parameter.PASV.class,
388 org.waarp.ftp.core.command.parameter.TYPE.class,
389 org.waarp.ftp.core.command.parameter.STRU.class,
390 org.waarp.ftp.core.command.parameter.MODE.class),
391 /**
392 * This command specifies the old pathname of the file which is to be renamed. This command must
393 * be immediately followed by a "rename to" RNTO command specifying the new file pathname.<br>
394 *
395 *
396 * 450, 550<br>
397 * 500, 501, 502, 421, 530<br>
398 * 350<br>
399 */
400 RNFR(
401 org.waarp.ftp.core.command.service.RNFR.class,
402 null,
403 org.waarp.ftp.core.command.service.RNTO.class),
404 /**
405 * This command specifies the new pathname of the file specified in the immediately preceding
406 * "rename from" RNFR command. Together the two commands cause a file to be renamed. <br>
407 *
408 * 250<br>
409 * 532, 553<br>
410 * 500, 501, 502, 503, 421, 530<br>
411 */
412 RNTO(
413 org.waarp.ftp.core.command.service.RNTO.class,
414 org.waarp.ftp.core.command.service.RNFR.class),
415 /**
416 * This command tells the server to abort the previous FTP service command and any associated
417 * transfer of data. The abort command may require "special action", as discussed in the Section
418 * on FTP Commands, to force recognition by the server. No action is to be taken if the previous
419 * command has been completed (including data transfer). The control connection is not to be
420 * closed by the server, but the data connection must be closed.<br>
421 * <br>
422 *
423 * There are two cases for the server upon receipt of this command: (1) the FTP service command
424 * was already completed, or (2) the FTP service command is still in progress.<br>
425 * <br>
426 *
427 * In the first case, the server closes the data connection (if it is open) and responds with a
428 * 226 reply, indicating that the abort command was successfully processed.<br>
429 * <br>
430 *
431 * In the second case, the server aborts the FTP service in progress and closes the data
432 * connection, returning a 426 reply to indicate that the service request terminated abnormally.
433 * The server then sends a 226 reply, indicating that the abort command was successfully
434 * processed.<br>
435 *
436 *
437 * 225, 226<br>
438 * 500, 501, 502, 421<br>
439 */
440 ABOR(org.waarp.ftp.core.command.service.ABOR.class, null),
441 /**
442 * This command causes the file specified in the pathname to be deleted at the server site. If
443 * an extra level of protection is desired (such as the query, "Do you really wish to delete?"),
444 * it should be provided by the user-FTP process.<br>
445 *
446 *
447 * 250<br>
448 * 450, 550<br>
449 * 500, 501, 502, 421, 530<br>
450 */
451 DELE(org.waarp.ftp.core.command.service.DELE.class, null),
452 /**
453 * This command causes the directory specified in the pathname to be removed as a directory (if
454 * the pathname is absolute) or as a subdirectory of the current working directory (if the
455 * pathname is relative).<br>
456 *
457 *
458 * 250<br>
459 * 500, 501, 502, 421, 530, 550<br>
460 */
461 RMD(org.waarp.ftp.core.command.service.RMD.class, null),
462 /**
463 * This command causes the directory specified in the pathname to be created as a directory (if
464 * the pathname is absolute) or as a subdirectory of the current working directory (if the
465 * pathname is relative).<br>
466 *
467 * 257<br>
468 * 500, 501, 502, 421, 530, 550<br>
469 */
470 MKD(org.waarp.ftp.core.command.service.MKD.class, null),
471 /**
472 * This command causes the name of the current working directory to be returned in the reply.<br>
473 *
474 * 257<br>
475 * 500, 501, 502, 421, 550<br>
476 */
477 PWD(org.waarp.ftp.core.command.service.PWD.class, null),
478 /**
479 * This command causes a list to be sent from the server to the passive DTP. If the pathname
480 * specifies a directory or other group of files, the server should transfer a list of files in
481 * the specified directory. If the pathname specifies a file then the server should send current
482 * information on the file. A null argument implies the user's current working or default
483 * directory. The data transfer is over the data connection in type ASCII or type EBCDIC. (The
484 * user must ensure that the TYPE is appropriately ASCII or EBCDIC). Since the information on a
485 * file may vary widely from system to system, this information may be hard to use automatically
486 * in a program, but may be quite useful to a human user.<br>
487 * <br>
488 * The option '-a' is accepted but ignored.<br>
489 *
490 *
491 * 125, 150<br>
492 * 226, 250<br>
493 * 425, 426, 451<br>
494 * 450<br>
495 * 500, 501, 502, 421, 530<br>
496 */
497 LIST(org.waarp.ftp.core.command.service.LIST.class, null),
498 /**
499 * This command causes a directory listing to be sent from server to user site. The pathname
500 * should specify a directory or other system-specific file group descriptor; a null argument
501 * implies the current directory. The server will return a stream of names of files and no other
502 * information. The data will be transferred in ASCII or EBCDIC type over the data connection as
503 * valid pathname strings separated by <code><CRLF></code> or <code><NL></code>.
504 * (Again the user must ensure that the TYPE is correct.) This command is intended to return
505 * information that can be used by a program to further process the files automatically. For
506 * example, in the implementation of a "multiple get" function.<br>
507 * <br>
508 * The option '-l' is accepted and turns to LIST command.<br>
509 *
510 *
511 * 125, 150<br>
512 * 226, 250<br>
513 * 425, 426, 451<br>
514 * 450<br>
515 * 500, 501, 502, 421, 530<br>
516 */
517 NLST(org.waarp.ftp.core.command.service.NLST.class, null),
518 /**
519 * This command is used by the server to provide services specific to his system that are
520 * essential to file transfer but not sufficiently universal to be included as commands in the
521 * protocol. The nature of these services and the specification of their syntax can be stated in
522 * a reply to the HELP SITE command.<br>
523 * <br>
524 * As for now, this command will not be implemented, so returns 502.<br>
525 * <br>
526 *
527 * 200<br>
528 * 202<br>
529 * 500, 501, 530<br>
530 */
531 SITE(org.waarp.ftp.core.command.info.SITE.class, null),
532 /**
533 * This command is used to find out the type of operating system at the server. The reply shall
534 * have as its first word one of the system names listed in the current version of the Assigned
535 * Numbers document.<br>
536 * <br>
537 * Returns "UNIX Type: L8".<br>
538 *
539 * 215<br>
540 * 500, 501, 502, 421<br>
541 */
542 SYST(org.waarp.ftp.core.command.info.SYST.class, null),
543 /**
544 * This command shall cause a status response to be sent over the control connection in the form
545 * of a reply. The command may be sent during a file transfer (along with the Telnet IP and
546 * Synch signals--see the Section on FTP Commands) in which case the server will respond with
547 * the status of the operation in progress, or it may be sent between file transfers. In the
548 * latter case, the command may have an argument field. If the argument is a pathname, the
549 * command is analogous to the "list" command except that data shall be transferred over the
550 * control connection. If a partial pathname is given, the server may respond with a list of
551 * file names or attributes associated with that specification. If no argument is given, the
552 * server should return general status information about the server FTP process. This should
553 * include current values of all transfer parameters and the status of connections.<br>
554 *
555 *
556 * 211, 212, 213<br>
557 * 450<br>
558 * 500, 501, 502, 421, 530<br>
559 */
560 STAT(org.waarp.ftp.core.command.info.STAT.class, null),
561 /**
562 * This command shall cause the server to send helpful information regarding its implementation
563 * status over the control connection to the user. The command may take an argument (e.g., any
564 * command name) and return more specific information as a response. The reply is type 211 or
565 * 214. It is suggested that HELP be allowed before entering a USER command. The server may use
566 * this reply to specify site-dependent parameters, e.g., in response to HELP SITE.<br>
567 *
568 *
569 * 211, 214<br>
570 * 500, 501, 502, 421<br>
571 */
572 HELP(org.waarp.ftp.core.command.info.HELP.class, null),
573 /**
574 * This command does not affect any parameters or previously entered commands. It specifies no
575 * action other than that the server send an OK reply.<br>
576 *
577 *
578 * 200<br>
579 * 500 421<br>
580 */
581 NOOP(org.waarp.ftp.core.command.info.NOOP.class, null),
582
583 // XXX RFC775
584
585 /**
586 * Change to a new working directory. Same as CWD<br>
587 *
588 *
589 * 250<br>
590 * 500, 501, 502, 421, 530, 550<br>
591 */
592 XCWD(org.waarp.ftp.core.command.rfc775.XCWD.class, null),
593 /**
594 * Change to the parent of the current working directory. Same as CDUP.<br>
595 *
596 *
597 * 200<br>
598 * 500, 501, 502, 421, 530, 550<br>
599 */
600 XCUP(org.waarp.ftp.core.command.rfc775.XCUP.class, null),
601 /**
602 * Remove the directory. Same as RMD.<br>
603 *
604 * 250<br>
605 * 500, 501, 502, 421, 530, 550<br>
606 */
607 XRMD(org.waarp.ftp.core.command.rfc775.XRMD.class, null),
608 /**
609 * Make a directory. Same as MKD.<br>
610 *
611 * 257<br>
612 * 500, 501, 502, 421, 530, 550<br>
613 */
614 XMKD(org.waarp.ftp.core.command.rfc775.XMKD.class, null),
615 /**
616 * Print the current working directory. Same as PWD.<br>
617 *
618 * 257<br>
619 * 500, 501, 502, 421, 550<br>
620 */
621 XPWD(org.waarp.ftp.core.command.rfc775.XPWD.class, null),
622
623 // XXX RFC3659
624 /**
625 * The FTP command, MODIFICATION TIME (MDTM), can be used to determine when a file in the server
626 * NVFS was last modified.<br>
627 * <br>
628 *
629 * The "pathname" specifies an object in the NVFS that may be the object of a RETR command.
630 * Attempts to query the modification time of files that exist but are unable to be retrieved
631 * may generate an error- response, or can result in a positive response carrying a time-val
632 * with an unspecified value, the choice being made by the server-PI.<br>
633 * <br>
634 *
635 * The server-PI will respond to the MDTM command with a 213 reply giving the last modification
636 * time of the file whose pathname was supplied, or a 550 reply if the file does not exist, the
637 * modification time is unavailable, or some other error has occurred.<br>
638 *
639 *
640 * 213<br>
641 * 500, 501, 550<br>
642 */
643 MDTM(org.waarp.ftp.core.command.rfc3659.MDTM.class, null),
644 /**
645 * The FTP command, SIZE OF FILE (SIZE), is used to obtain the transfer size of a file from the
646 * server-FTP process. This is the exact number of octets (8 bit bytes) that would be
647 * transmitted over the data connection should that file be transmitted. This value will change
648 * depending on the current STRUcture, MODE, and TYPE of the data connection or of a data
649 * connection that would be created were one created now. Thus, the result of the SIZE command
650 * is dependent on the currently established STRU, MODE, and TYPE parameters.<br>
651 * <br>
652 *
653 * The SIZE command returns how many octets would be transferred if the file were to be
654 * transferred using the current transfer structure, mode, and type. This command is normally
655 * used in conjunction with the RESTART (REST) command when STORing a file to a remote server in
656 * STREAM mode, to determine the restart point. The server-PI might need to read the partially
657 * transferred file, do any appropriate conversion, and count the number of octets that would be
658 * generated when sending the file in order to correctly respond to this command. Estimates of
659 * the file transfer size MUST NOT be returned; only precise information is acceptable.<br>
660 *
661 *
662 * 213<br>
663 * 500, 501, 550<br>
664 */
665 SIZE(org.waarp.ftp.core.command.rfc3659.SIZE.class, null),
666 /**
667 * The MLSD command is intended to standardize the file and directory information returned by
668 * the server-FTP process. This command differs from the LIST command in that the format of the
669 * replies is strictly defined although extensible.<br>
670 * <br>
671 *
672 * MLSD lists the contents of a directory if a directory is named, otherwise a 501 reply is
673 * returned. If no object is named, the current directory is assumed. That will cause MLSD to
674 * list the contents of the current directory.<br>
675 *
676 *
677 * 125, 150<br>
678 * 226, 250<br>
679 * 425, 426, 451<br>
680 * 450<br>
681 * 500, 501, 502, 421, 530<br>
682 */
683 MLSD(org.waarp.ftp.core.command.rfc3659.MLSD.class, null),
684 /**
685 * The MLST command is intended to standardize the file and directory information returned by
686 * the server-FTP process. This command differs from the LIST command in that the format of the
687 * replies is strictly defined although extensible.<br>
688 * <br>
689 *
690 * MLST provides data about exactly the object named on its command line, and no others. If no
691 * object is named, the current directory is assumed. That will cause MLST to send a one-line
692 * response, describing the current directory itself.<br>
693 *
694 * 125, 150<br>
695 * 226, 250<br>
696 * 425, 426, 451<br>
697 * 450<br>
698 * 500, 501, 502, 421, 530<br>
699 */
700 MLST(org.waarp.ftp.core.command.rfc3659.MLST.class, null),
701
702 // XXX RFC2389
703 /**
704 * The FEAT command consists solely of the word "FEAT". It has no parameters or arguments.<br>
705 * <br>
706 *
707 * Where a server-FTP process does not support the FEAT command, it will respond to the FEAT
708 * command with a 500 or 502 reply. This is simply the normal "unrecognized command" reply that
709 * any unknown command would elicit. Errors in the command syntax, such as giving parameters,
710 * will result in a 501 reply.<br>
711 * <br>
712 *
713 * Server-FTP processes that recognize the FEAT command, but implement no extended features, and
714 * therefore have nothing to report, SHOULD respond with the "no-features" 211 reply. However,
715 * as this case is practically indistinguishable from a server-FTP that does not recognize the
716 * FEAT command, a 500 or 502 reply MAY also be used. The "no-features" reply MUST NOT use the
717 * multi-line response format, exactly one response line is required and permitted.<br>
718 * <br>
719 *
720 * Replies to the FEAT command MUST comply with the following syntax. Text on the first line of
721 * the reply is free form, and not interpreted, and has no practical use, as this text is not
722 * expected to be revealed to end users. The syntax of other reply lines is precisely defined,
723 * and if present, MUST be exactly as specified.<br>
724 * <br>
725 *
726 * <pre>
727 * feat-response = error-response / no-features / feature-listing
728 * no-features = "211" SP *TCHAR CRLF
729 * feature-listing = "211-" *TCHAR CRLF
730 * 1*( SP feature CRLF )
731 * "211 End" CRLF
732 * feature = feature-label [ SP feature-parms ]
733 * feature-label = 1*VCHAR
734 * feature-parms = 1*TCHAR
735 * </pre>
736 *
737 * Note that each feature line in the feature-listing begins with a single space. That space is
738 * not optional, nor does it indicate general white space. This space guarantees that the
739 * feature line can never be misinterpreted as the end of the feature-listing, but is required
740 * even where there is no possibility of ambiguity.<br>
741 * <br>
742 *
743 * Each extension supported must be listed on a separate line to facilitate the possible
744 * inclusion of parameters supported by each extension command. The feature-label to be used in
745 * the response to the FEAT command will be specified as each new feature is added to the FTP
746 * command set. Often it will be the name of a new command added, however this is not required.
747 * In fact it is not required that a new feature actually add a new command. Any parameters
748 * included are to be specified with the definition of the command concerned. That specification
749 * shall also specify how any parameters present are to be interpreted.<br>
750 * <br>
751 *
752 * The feature-label and feature-parms are nominally case sensitive, however the definitions of
753 * specific labels and parameters specify the precise interpretation, and it is to be expected
754 * that those definitions will usually specify the label and parameters in a case independent
755 * manner. Where this is done, implementations are recommended to use upper case letters when
756 * transmitting the feature response.<br>
757 * <br>
758 *
759 * The FEAT command itself is not included in the list of features supported, support for the
760 * FEAT command is indicated by return of a reply other than a 500 or 502 reply.<br>
761 *
762 *
763 * 211<br>
764 * 500, 501, 550<br>
765 */
766 FEAT(org.waarp.ftp.core.command.rfc2389.FEAT.class, null),
767 /**
768 * The OPTS (options) command allows a user-PI to specify the desired behavior of a server-FTP
769 * process when another FTP command (the target command) is later issued. The exact behavior,
770 * and syntax, will vary with the target command indicated, and will be specified with the
771 * definition of that command. Where no OPTS behavior is defined for a particular command there
772 * are no options available for that command.<br>
773 *
774 *
775 * 200<br>
776 * 451, 500, 501, 550<br>
777 */
778 OPTS(org.waarp.ftp.core.command.rfc2389.OPTS.class, null),
779
780 // XXX RFC2428
781 /**
782 * The EPRT command allows for the specification of an extended address for the data connection.
783 * The extended address MUST consist of the network protocol as well as the network and
784 * transport addresses. The format of EPRT is:<br>
785 * <br>
786 *
787 * <pre>
788 * EPRT<space><d><net-prt><d><net-addr><d><tcp-port><d>
789 * </pre>
790 *
791 * <br>
792 * The EPRT command keyword MUST be followed by a single space (ASCII 32). Following the space,
793 * a delimiter character (<code><d></code>) MUST be specified. The delimiter character
794 * MUST be one of the ASCII characters in range 33-126 inclusive. The character "|" (ASCII 124)
795 * is recommended unless it coincides with a character needed to encode the network address.<br>
796 *
797 * The <code><net-prt></code> argument MUST be an address family number defined by IANA in
798 * the latest Assigned Numbers RFC (RFC 1700 [RP94] as of the writing of this document). This
799 * number indicates the protocol to be used (and, implicitly, the address length). This document
800 * will use two of address family numbers from [RP94] as examples, according to the following
801 * table:<br>
802 * <br>
803 *
804 * <pre>
805 * AF Number Protocol
806 * --------- --------
807 * 1 Internet Protocol, Version 4 [Pos81a]
808 * 2 Internet Protocol, Version 6 [DH96]
809 * </pre>
810 *
811 * <br>
812 * The <code><net-addr></code> is a protocol specific string representation of the network
813 * address. For the two address families specified above (AF Number 1 and 2), addresses MUST be
814 * in the following format:<br>
815 * <br>
816 *
817 * <pre>
818 * AF Number Address Format Example
819 * --------- -------------- -------
820 * 1 dotted decimal 132.235.1.2
821 * 2 IPv6 string 1080::8:800:200C:417A
822 * representations
823 * defined in [HD96]
824 * </pre>
825 *
826 * <br>
827 * The <code><tcp-port></code> argument must be the string representation of the number of
828 * the TCP port on which the host is listening for the data connection.<br>
829 *
830 *
831 * 200<br>
832 * 500, 501, 522, 421, 530<br>
833 */
834 EPRT(org.waarp.ftp.core.command.rfc2428.EPRT.class, null),
835 /**
836 * The EPSV command requests that a server listen on a data port and wait for a connection. The
837 * EPSV command takes an optional argument. The response to this command includes only the TCP
838 * port number of the listening connection. The format of the response, however, is similar to
839 * the argument of the EPRT command. This allows the same parsing routines to be used for both
840 * commands. In addition, the format leaves a place holder for the network protocol and/or
841 * network address, which may be needed in the EPSV response in the future. The response code
842 * for entering passive mode using an extended address MUST be 229. The interpretation of this
843 * code, according to [PR85] is:<br>
844 * <br>
845 *
846 * <pre>
847 * 2yz Positive Completion
848 * x2z Connections
849 * xy9 Extended Passive Mode Entered
850 * </pre>
851 *
852 * <br>
853 * The text returned in response to the EPSV command MUST be:<br>
854 * <br>
855 *
856 * <pre>
857 * <text indicating server is entering extended passive mode> (<d><d><d><tcp-port><d>)
858 * </pre>
859 *
860 * <br>
861 * The portion of the string enclosed in parentheses MUST be the exact string needed by the EPRT
862 * command to open the data connection, as specified above.<br>
863 * <br>
864 *
865 * The first two fields contained in the parenthesis MUST be blank. The third field MUST be the
866 * string representation of the TCP port number on which the server is listening for a data
867 * connection. The network protocol used by the data connection will be the same network
868 * protocol used by the control connection. In addition, the network address used to establish
869 * the data connection will be the same network address used for the control connection. An
870 * example response string follows:<br>
871 * <br>
872 *
873 * <pre>
874 * Entering Extended Passive Mode (|||6446|)
875 * </pre>
876 *
877 * <br>
878 * The standard negative error codes 500 and 501 are sufficient to handle all errors involving
879 * the EPSV command (e.g., syntax errors).<br>
880 * <br>
881 *
882 * When the EPSV command is issued with no argument, the server will choose the network protocol
883 * for the data connection based on the protocol used for the control connection. However, in
884 * the case of proxy FTP, this protocol might not be appropriate for communication between the
885 * two servers. Therefore, the client needs to be able to request a specific protocol. If the
886 * server returns a protocol that is not supported by the host that will be connecting to the
887 * port, the client MUST issue an ABOR (abort) command to allow the server to close down the
888 * listening connection. The client can then send an EPSV command requesting the use of a
889 * specific network protocol, as follows:<br>
890 * <br>
891 *
892 * <pre>
893 * EPSV<space><net-prt>
894 * </pre>
895 *
896 * <br>
897 * If the requested protocol is supported by the server, it SHOULD use the protocol. If not, the
898 * server MUST return the 522 error messages as outlined in section 2.<br>
899 * <br>
900 *
901 * <b>The following part is not implemented.</b><br>
902 * Finally, the EPSV command can be used with the argument "ALL" to inform Network Address
903 * Translators that the EPRT command (as well as other data commands) will no longer be used. An
904 * example of this command follows:<br>
905 * <br>
906 *
907 * <pre>
908 * EPSV < space > ALL
909 * </pre>
910 *
911 * <br>
912 * Upon receipt of an EPSV ALL command, the server MUST reject all data connection setup
913 * commands other than EPSV (i.e., EPRT, PORT, PASV, et al.). This use of the EPSV command is
914 * further explained in section 4.<br>
915 *
916 *
917 * 229<br>
918 * 500, 501, 502, 522, 421, 530<br>
919 */
920 EPSV(org.waarp.ftp.core.command.rfc2428.EPSV.class, null),
921
922 // XXX EXTENSIONS
923
924 /**
925 * Compute CRC on pathname given as argument. Return on control network as 250 "CRC" is CRC of
926 * file "pathname"<br>
927 *
928 * 250<br>
929 * 500, 501, 502, 504, 421, 530<br>
930 */
931 XCRC(org.waarp.ftp.core.command.extension.XCRC.class, null),
932 /**
933 * Compute MD5 on pathname given as argument. Return on control network as 250 "MD5" is MD5 of
934 * file "pathname"<br>
935 *
936 * 250<br>
937 * 500, 501, 502, 504, 421, 530<br>
938 */
939 XMD5(org.waarp.ftp.core.command.extension.XMD5.class, null),
940 /**
941 * Compute SHA-1 on pathname given as argument. Return on control network as 250 "SHA1" is SHA-1
942 * of file "pathname"<br>
943 *
944 * 250<br>
945 * 500, 501, 502, 504, 421, 530<br>
946 */
947 XSHA1(org.waarp.ftp.core.command.extension.XSHA1.class, null),
948
949 // XXX GLOBAL OPERATION
950 /**
951 * Unknown Command from control network<br>
952 * Always return 500<br>
953 */
954 Unknown(UnknownCommand.class, null),
955 /**
956 * Unimplemented command<br>
957 * Always return 502<br>
958 */
959 Unimplemented(UnimplementedCommand.class, null),
960 /**
961 * Bad sequence of commands<br>
962 * Always return 503<br>
963 */
964 IncorrectSequence(IncorrectCommand.class, null),
965
966 // XXX INTERNAL FUNCTION
967
968 /**
969 * Shutdown command (internal password protected command).<br>
970 * Shutdown the FTP service<br>
971 */
972 INTERNALSHUTDOWN(
973 org.waarp.ftp.core.command.internal.INTERNALSHUTDOWN.class,
974 null),
975 /**
976 * Change the Limit of the global bandwidth.<br>
977 * No argument reset to default, 1 argument change both write and read to same value, 2
978 * arguments stand for write then read limit.<br>
979 * Limit is written in byte/s. Example: "LIMITBANDWIDTH 104857600 104857600" stands for 100MB/s
980 * limitation globaly.<br>
981 * -1 means no limit
982 */
983 LIMITBANDWIDTH(
984 org.waarp.ftp.core.command.internal.LIMITBANDWIDTH.class,
985 null),
986
987 // XXX RFC 4217 on SSL/TLS support through commands
988 /**
989 * After an AUTH => equivalent to REIN so no more authenticated, USER is mandatory,
990 * except if PROT is used in between.<br>
991 * So the order will be:<br>
992 * whatever until authenticated -> AUTH xxx -> USER or [PBSZ 0] / PROT xxx / USER<br>
993 * <br>
994 * Security-Enhanced login commands (only new replies listed)<br>
995 * USER<br>
996 * 232<br>
997 * 336<br>
998 * <br>
999 * Data channel commands (only new replies listed)<br>
1000 * STOR<br>
1001 * 534, 535<br>
1002 * STOU<br>
1003 * 534, 535<br>
1004 * RETR<br>
1005 * 534, 535<br>
1006 * LIST<br>
1007 * 534, 535<br>
1008 * NLST<br>
1009 * 534, 535<br>
1010 * APPE<br>
1011 * 534, 535
1012 */
1013 /**
1014 * Security Association Setup AUTH TLS (Control) or AUTH SSL (Control and Data)<br>
1015 * 234*<br>
1016 * 502, 504, 534*, 431* 500, 501, 421<br>
1017 * <br>
1018 * AUTH TLS -> 234 -> USER or ([PBSZ 0] PROT P then USER) -> 2xy
1019 */
1020 AUTH(org.waarp.ftp.core.command.rfc4217.AUTH.class, null,
1021 org.waarp.ftp.core.command.rfc4217.PROT.class,
1022 org.waarp.ftp.core.command.rfc4217.PBSZ.class,
1023 org.waarp.ftp.core.command.access.USER.class),
1024 /**
1025 * Security Association Setup<br>
1026 * CCC (Control SSL Off)<br>
1027 * 200<br>
1028 * 500, 533*, 534*
1029 */
1030 CCC(org.waarp.ftp.core.command.rfc4217.CCC.class, null),
1031 /**
1032 * Data protection negotiation commands<br>
1033 * PROT P (Data)<br>
1034 * PROT C (Data SSL Off)<br>
1035 * 200<br>
1036 * 504, 536*, 503, 534*, 431* 500, 501, 421, 530
1037 */
1038 PROT(org.waarp.ftp.core.command.rfc4217.PROT.class, null),
1039 /**
1040 * Data protection negotiation commands<br>
1041 * PBSZ 0<br>
1042 * 200<br>
1043 * 503, 500, 501, 421, 530
1044 */
1045 PBSZ(org.waarp.ftp.core.command.rfc4217.PBSZ.class, null);
1046
1047 /**
1048 * The Class that implements this command
1049 */
1050 public Class<? extends AbstractCommand> command;
1051
1052 /**
1053 * Previous positive class that must precede this command (null means any)
1054 */
1055 public Class<? extends AbstractCommand> previousValid;
1056
1057 /**
1058 * Next valids class that could follow this command (null means any)
1059 */
1060 public Class<?>[] nextValids;
1061
1062 private FtpCommandCode(Class<? extends AbstractCommand> command,
1063 Class<? extends AbstractCommand> previousValid,
1064 Class<?>... nextValids) {
1065 this.command = command;
1066 this.previousValid = previousValid;
1067 this.nextValids = nextValids;
1068 }
1069
1070 /**
1071 * Get the corresponding AbstractCommand object from the line received from the client
1072 * associated with the handler
1073 *
1074 * @param session
1075 * @param line
1076 * @return the AbstractCommand from the line received from the client
1077 */
1078 public static AbstractCommand getFromLine(FtpSession session, String line) {
1079 FtpCommandCode ftpCommandCode = null;
1080 String newline = line;
1081 if (newline == null) {
1082 ftpCommandCode = FtpCommandCode.Unknown;
1083 newline = "";
1084 }
1085 String command = null;
1086 String arg = null;
1087 if (newline.indexOf(' ') == -1) {
1088 command = newline;
1089 arg = null;
1090 } else {
1091 command = newline.substring(0, newline.indexOf(' '));
1092 arg = newline.substring(newline.indexOf(' ') + 1);
1093 if (arg.length() == 0) {
1094 arg = null;
1095 }
1096 }
1097 String COMMAND = command.toUpperCase();
1098 try {
1099 ftpCommandCode = FtpCommandCode.valueOf(COMMAND);
1100 } catch (IllegalArgumentException e) {
1101 ftpCommandCode = FtpCommandCode.Unknown;
1102 }
1103 AbstractCommand abstractCommand;
1104 try {
1105 abstractCommand = ftpCommandCode.command.newInstance();
1106 } catch (InstantiationException e) {
1107 abstractCommand = new UnknownCommand();
1108 abstractCommand.setArgs(session, COMMAND, arg, Unknown);
1109 return abstractCommand;
1110 } catch (IllegalAccessException e) {
1111 abstractCommand = new UnknownCommand();
1112 abstractCommand.setArgs(session, COMMAND, arg, Unknown);
1113 return abstractCommand;
1114 }
1115 abstractCommand.setArgs(session, COMMAND, arg, ftpCommandCode);
1116 return abstractCommand;
1117 }
1118
1119 /**
1120 * True if the command is a Store like operation (APPE, STOR, STOU, ...)
1121 *
1122 * @param command
1123 * @return True if the command is a Store like operation (APPE, STOR, STOU, ...)
1124 */
1125 public static boolean isStoreLikeCommand(FtpCommandCode command) {
1126 return command == APPE || command == STOR || command == STOU;
1127 }
1128
1129 /**
1130 * True if the command is a Retrieve like operation (RETR, ...)
1131 *
1132 * @param command
1133 * @return True if the command is a Retrieve like operation (RETR, ...)
1134 */
1135 public static boolean isRetrLikeCommand(FtpCommandCode command) {
1136 return command == RETR;
1137 }
1138
1139 /**
1140 * True if the command is a Retrieve or Store like operation
1141 *
1142 * @param command
1143 * @return True if the command is a Retrieve or Store like operation
1144 */
1145 public static boolean isStorOrRetrLikeCommand(FtpCommandCode command) {
1146 return isRetrLikeCommand(command) || isStoreLikeCommand(command);
1147 }
1148
1149 /**
1150 * True if the command is a List like operation (LIST, NLST, MLSD, MLST, ...)
1151 *
1152 * @param command
1153 * @return True if the command is a List like operation (LIST, NLST, MLSD, MLST, ...)
1154 */
1155 public static boolean isListLikeCommand(FtpCommandCode command) {
1156 return command == LIST || command == NLST || command == MLSD ||
1157 command == MLST;
1158 }
1159
1160 /**
1161 * True if the command is using a Data connection
1162 *
1163 * @param command
1164 * @return True if the command is using a Data Connection
1165 */
1166 public static boolean isDataConnectionUsageCommand(FtpCommandCode command) {
1167 return isRetrLikeCommand(command) || isStoreLikeCommand(command) || isListLikeCommand(command);
1168 }
1169
1170 /**
1171 * True if the command is a special operation (QUIT, ABOR, NOOP, STAT, ...)
1172 *
1173 * @param command
1174 * @return True if the command is a special operation (QUIT, ABOR, NOOP, STAT, ...)
1175 */
1176 public static boolean isSpecialCommand(FtpCommandCode command) {
1177 return command == QUIT || command == ABOR || command == NOOP ||
1178 command == STAT;
1179 }
1180
1181 /**
1182 * True if the command is Ssl related (AUTH, PBSZ, PROT, USER, PASS, ACCT)
1183 *
1184 * @param command
1185 * @return True if the command is Ssl related (AUTH, PBSZ, PROT, USER, PASS, ACCT)
1186 */
1187 public static boolean isSslOrAuthCommand(FtpCommandCode command) {
1188 return command == AUTH || command == PBSZ || command == PROT
1189 || command == AUTH || command == PASS || command == ACCT;
1190 }
1191
1192 /**
1193 * True if the command is an extension operation (XMD5, XCRC, XSHA1, ...)
1194 *
1195 * @param command
1196 * @return True if the command is an extension operation (XMD5, XCRC, XSHA1, ...)
1197 */
1198 public static boolean isExtensionCommand(FtpCommandCode command) {
1199 return command == XMD5 || command == XCRC || command == XSHA1 ||
1200 command == INTERNALSHUTDOWN || command == LIMITBANDWIDTH;
1201 }
1202
1203 @Override
1204 public String toString() {
1205 return name();
1206 }
1207 }