View Javadoc

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