View Javadoc

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>&lt;SP&gt;</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      *                          |-&gt;&lt;-| T - Telnet format effectors
228      *                E - EBCDIC|    | C - Carriage Control (ASA)
229      *                          /    \
230      *                I - Image
231      *                L &lt;byte size&gt; - 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>&lt;SP&gt;</code> R <code>&lt;SP&gt;</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>&lt;CRLF&gt;</code> or <code>&lt;NL&gt;</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     = &quot;211&quot; SP *TCHAR CRLF
729      *         feature-listing = &quot;211-&quot; *TCHAR CRLF
730      *                           1*( SP feature CRLF )
731      *                           &quot;211 End&quot; 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&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;
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>&lt;d&gt;</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>&lt;net-prt&gt;</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>&lt;net-addr&gt;</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>&lt;tcp-port&gt;</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      * &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;)
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&lt;space&gt;&lt;net-prt&gt;
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 &lt; space &gt; 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 }