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><SP></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 * |-><-| T - Telnet format effectors
247 * E - EBCDIC| | C - Carriage Control (ASA)
248 * / \
249 * I - Image
250 * L <byte size> - 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><SP></code> R <code><SP></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><CRLF></code> or <code><NL></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 = "211" SP *TCHAR CRLF
792 * feature-listing = "211-" *TCHAR CRLF
793 * 1*( SP feature CRLF )
794 * "211 End" 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<space><d><net-prt><d><net-addr><d><tcp-port><d>
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><d></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><net-prt></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><net-addr></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><tcp-port></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 * <text indicating server is entering extended passive mode> (<d><d><d><tcp-port><d>)
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<space><net-prt>
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 < space > 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 }