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