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.common.command;
22
23 import goldengate.common.exception.InvalidArgumentException;
24
25 /**
26 * Reply code references by different RFC.
27 *
28 * @author Frederic Bregier
29 *
30 */
31 public enum ReplyCode {
32 /**
33 * unofficial reply code for no value
34 */
35 REPLY_000_SPECIAL_NOSTATUS(0),
36 /**
37 * 110 Restart marker reply. In this case, the text is exact and not left to
38 * the particular implementation), it must read: MARK yyyy (mmmm Where yyyy
39 * is User-process data stream marker, and mmmm server's equivalent marker
40 * (note the spaces between markers and "=").
41 */
42 REPLY_110_RESTART_MARKER_REPLY(110),
43
44 /**
45 * 120 Service ready in nnn minutes.
46 */
47 REPLY_120_SERVICE_READY_IN_NNN_MINUTES(120),
48
49 /**
50 * 125 Data connection already open), transfer starting.
51 */
52 REPLY_125_DATA_CONNECTION_ALREADY_OPEN(125),
53
54 /**
55 * 150 File status okay), about to open data connection.
56 */
57 REPLY_150_FILE_STATUS_OKAY(150),
58
59 /**
60 * 200 Command okay.
61 */
62 REPLY_200_COMMAND_OKAY(200),
63
64 /**
65 * 202 Command not implemented, superfluous at this site.
66 */
67 REPLY_202_COMMAND_NOT_IMPLEMENTED(202),
68
69 /**
70 * 211 System status, or system help reply.
71 */
72 REPLY_211_SYSTEM_STATUS_REPLY(211),
73
74 /**
75 * 212 Directory status.
76 */
77 REPLY_212_DIRECTORY_STATUS(212),
78
79 /**
80 * 213 File status.
81 */
82 REPLY_213_FILE_STATUS(213),
83
84 /**
85 * 214 Help message. On how to use the server or the meaning of a particular
86 * non-standard command. This reply is useful only to the human user.
87 */
88 REPLY_214_HELP_MESSAGE(
89 214,
90 "This FTP server refers to RFC 959, RFC 775, RFC 2389 and RFC 3659"),
91
92 /**
93 * 215 NAME system type. Where NAME is an official system name from the list
94 * in the Assigned Numbers document.
95 */
96 REPLY_215_NAME_SYSTEM_TYPE(215),
97
98 /**
99 * 220 Service ready for new user.
100 */
101 REPLY_220_SERVICE_READY(220),
102
103 /**
104 * Service closing control connection. Logged out if appropriate.
105 */
106 REPLY_221_CLOSING_CONTROL_CONNECTION(221),
107
108 /**
109 * 225 Data connection open), no transfer in progress.
110 */
111 REPLY_225_DATA_CONNECTION_OPEN_NO_TRANSFER_IN_PROGRESS(225),
112
113 /**
114 * Closing data connection. Requested file action successful (for example,
115 * file transfer or file abort).
116 */
117 REPLY_226_CLOSING_DATA_CONNECTION(226),
118
119 /**
120 * 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).
121 */
122 REPLY_227_ENTERING_PASSIVE_MODE(227),
123
124 /**
125 * 229 Entering Extended Passive Mode (|n|addr|port|).
126 */
127 REPLY_229_ENTERING_PASSIVE_MODE(229),
128
129 /**
130 * 230 User logged in, proceed.
131 */
132 REPLY_230_USER_LOGGED_IN(230),
133
134 /**
135 * 250 Requested file action okay, completed.
136 */
137 REPLY_250_REQUESTED_FILE_ACTION_OKAY(250),
138
139 /**
140 * 257 "PATHNAME" created.
141 */
142 REPLY_257_PATHNAME_CREATED(257),
143
144 /**
145 * 331 User name okay, need password.
146 */
147 REPLY_331_USER_NAME_OKAY_NEED_PASSWORD(331),
148
149 /**
150 * 332 Need account for login.
151 */
152 REPLY_332_NEED_ACCOUNT_FOR_LOGIN(332),
153
154 /**
155 * 350 Requested file action pending further information.
156 */
157 REPLY_350_REQUESTED_FILE_ACTION_PENDING_FURTHER_INFORMATION(350),
158
159 /**
160 * 421 Service not available, closing control connection. This may be a
161 * reply to any command if the service knows it must shut down.
162 */
163 REPLY_421_SERVICE_NOT_AVAILABLE_CLOSING_CONTROL_CONNECTION(421),
164
165 /**
166 * 425 Can't open data connection.
167 */
168 REPLY_425_CANT_OPEN_DATA_CONNECTION(425),
169
170 /**
171 * 426 Connection closed), transfer aborted.
172 */
173 REPLY_426_CONNECTION_CLOSED_TRANSFER_ABORTED(426),
174
175 /**
176 * 450 Requested file action not taken. File unavailable (e.g.,
177 * file busy).
178 */
179 REPLY_450_REQUESTED_FILE_ACTION_NOT_TAKEN(450),
180
181 /**
182 * 451 Requested action aborted: local error in processing.
183 */
184 REPLY_451_REQUESTED_ACTION_ABORTED(451),
185
186 /**
187 * 452 Requested action not taken. Insufficient storage space in system.
188 */
189 REPLY_452_REQUESTED_ACTION_NOT_TAKEN(452),
190
191 /**
192 * 500 Syntax error, command unrecognized. This may include errors such as
193 * command line too long.
194 */
195 REPLY_500_SYNTAX_ERROR_COMMAND_UNRECOGNIZED(500),
196
197 /**
198 * 501 Syntax error in parameters or arguments.
199 */
200 REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS(501),
201
202 /**
203 * 502 Command not implemented.
204 */
205 REPLY_502_COMMAND_NOT_IMPLEMENTED(502),
206
207 /**
208 * 503 Bad sequence of commands.
209 */
210 REPLY_503_BAD_SEQUENCE_OF_COMMANDS(503),
211
212 /**
213 * 504 Command not implemented for that parameter.
214 */
215 REPLY_504_COMMAND_NOT_IMPLEMENTED_FOR_THAT_PARAMETER(504),
216
217 /**
218 * 522 Extended Port Failure - unknown network protocol.
219 */
220 REPLY_522_EXTENDED_PORT_FAILURE_UNKNOWN_NETWORK_PROTOCOL(522),
221
222 /**
223 * 530 Not logged in.
224 */
225 REPLY_530_NOT_LOGGED_IN(530),
226
227 /**
228 * 532 Need account for storing files.
229 */
230 REPLY_532_NEED_ACCOUNT_FOR_STORING_FILES(532),
231
232 /**
233 * 550 Requested action not taken. File unavailable (e.g., file not
234 * found, no access).
235 */
236 REPLY_550_REQUESTED_ACTION_NOT_TAKEN(550),
237
238 /**
239 * 551 Requested action aborted: page type unknown.
240 */
241 REPLY_551_REQUESTED_ACTION_ABORTED_PAGE_TYPE_UNKNOWN(551),
242
243 /**
244 * 552 Requested file action aborted. Exceeded storage allocation (for
245 * current directory or dataset).
246 */
247 REPLY_552_REQUESTED_FILE_ACTION_ABORTED_EXCEEDED_STORAGE(552),
248
249 /**
250 * 553 Requested action not taken. File name not allowed.
251 */
252 REPLY_553_REQUESTED_ACTION_NOT_TAKEN_FILE_NAME_NOT_ALLOWED(553);
253
254 /**
255 * Numerical code
256 */
257 private int code;
258
259 /**
260 * Message associated
261 */
262 private String mesg;
263
264 /**
265 * LF
266 */
267 public static final String LF = "\n";
268
269 /**
270 * CR NUL
271 */
272 public static final String CRNUL = "\r\0";
273
274 /**
275 * CR LF<br>
276 * A User Telnet MUST be able to send any of the forms: CR LF, CR NUL, and
277 * LF. A User Telnet on an ASCII host SHOULD have a user-controllable mode
278 * to send either CR LF or CR NUL when the user presses the "end-of-line"
279 * key, and CR LF SHOULD be the default.
280 */
281 public static final String CRLF = "\r\n";
282
283 /**
284 * Construct a Reply code from specific message
285 *
286 * @param code
287 * @param mesg
288 */
289 private ReplyCode(int code, String mesg) {
290 this.code = code;
291 this.mesg = getFinalMsg(code, mesg);
292 }
293
294 /**
295 * Return the final message formatted as needed from the code and the
296 * message
297 *
298 * @param code
299 * @param msg
300 * @return the final formatted message
301 */
302 public static String getFinalMsg(int code, String msg) {
303 StringBuilder builder = new StringBuilder();
304 builder.append(code);
305 if (msg.indexOf('\n') == -1) {
306 builder.append(' ');
307 builder.append(msg);
308 builder.append(ReplyCode.CRLF);
309 } else {
310 String[] lines = msg.split("\n");
311 // first line
312 builder.append('-');
313 builder.append(lines[0]);
314 builder.append(ReplyCode.CRLF);
315 // next lines
316 for (int i = 1; i < lines.length - 1; i ++) {
317 int firstBlank = lines[i].indexOf(' ');
318 if (firstBlank > 0) {
319 String firstParam = lines[i].substring(0, firstBlank);
320 boolean isInt = false;
321 try {
322 Integer.parseInt(firstParam);
323 isInt = true;
324 } catch (NumberFormatException e) {
325 // not a number
326 }
327 if (isInt) {
328 builder.append(" ");
329 }
330 }
331 builder.append(lines[i]);
332 builder.append(ReplyCode.CRLF);
333 }
334 // last line
335 builder.append(code);
336 builder.append(' ');
337 builder.append(lines[lines.length - 1]);
338 builder.append(ReplyCode.CRLF);
339 }
340 return builder.toString();
341 }
342
343 /**
344 * Construct a Reply Code from its name in Enum structure
345 *
346 * @param code
347 */
348 private ReplyCode(int code) {
349 this.code = code;
350 mesg = name().substring(6).replace('_', ' ') + ReplyCode.CRLF;
351 }
352
353 /**
354 * @return the code
355 */
356 public int getCode() {
357 return code;
358 }
359
360 /**
361 * @return the mesg
362 */
363 public String getMesg() {
364 return mesg;
365 }
366 /**
367 *
368 * @param code
369 * @return the associated ReplyCode from the given numerical code
370 * @throws InvalidArgumentException
371 */
372 public static ReplyCode getReplyCode(int code) throws InvalidArgumentException {
373 switch (code) {
374 case 0:
375 return REPLY_000_SPECIAL_NOSTATUS;
376 case 110:
377 return REPLY_110_RESTART_MARKER_REPLY;
378 case 120:
379 return REPLY_120_SERVICE_READY_IN_NNN_MINUTES;
380 case 125:
381 return REPLY_125_DATA_CONNECTION_ALREADY_OPEN;
382 case 150:
383 return REPLY_150_FILE_STATUS_OKAY;
384 case 200:
385 return REPLY_200_COMMAND_OKAY;
386 case 202:
387 return REPLY_202_COMMAND_NOT_IMPLEMENTED;
388 case 211:
389 return REPLY_211_SYSTEM_STATUS_REPLY;
390 case 212:
391 return REPLY_212_DIRECTORY_STATUS;
392 case 213:
393 return REPLY_213_FILE_STATUS;
394 case 214:
395 return REPLY_214_HELP_MESSAGE;
396 case 215:
397 return REPLY_215_NAME_SYSTEM_TYPE;
398 case 220:
399 return REPLY_220_SERVICE_READY;
400 case 221:
401 return REPLY_221_CLOSING_CONTROL_CONNECTION;
402 case 225:
403 return REPLY_225_DATA_CONNECTION_OPEN_NO_TRANSFER_IN_PROGRESS;
404 case 226:
405 return REPLY_226_CLOSING_DATA_CONNECTION;
406 case 227:
407 return REPLY_227_ENTERING_PASSIVE_MODE;
408 case 229:
409 return REPLY_229_ENTERING_PASSIVE_MODE;
410 case 230:
411 return REPLY_230_USER_LOGGED_IN;
412 case 250:
413 return REPLY_250_REQUESTED_FILE_ACTION_OKAY;
414 case 257:
415 return REPLY_257_PATHNAME_CREATED;
416 case 331:
417 return REPLY_331_USER_NAME_OKAY_NEED_PASSWORD;
418 case 332:
419 return REPLY_332_NEED_ACCOUNT_FOR_LOGIN;
420 case 350:
421 return REPLY_350_REQUESTED_FILE_ACTION_PENDING_FURTHER_INFORMATION;
422 case 421:
423 return REPLY_421_SERVICE_NOT_AVAILABLE_CLOSING_CONTROL_CONNECTION;
424 case 425:
425 return REPLY_425_CANT_OPEN_DATA_CONNECTION;
426 case 426:
427 return REPLY_426_CONNECTION_CLOSED_TRANSFER_ABORTED;
428 case 450:
429 return REPLY_450_REQUESTED_FILE_ACTION_NOT_TAKEN;
430 case 451:
431 return REPLY_451_REQUESTED_ACTION_ABORTED;
432 case 452:
433 return REPLY_452_REQUESTED_ACTION_NOT_TAKEN;
434 case 500:
435 return REPLY_500_SYNTAX_ERROR_COMMAND_UNRECOGNIZED;
436 case 501:
437 return REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS;
438 case 502:
439 return REPLY_502_COMMAND_NOT_IMPLEMENTED;
440 case 503:
441 return REPLY_503_BAD_SEQUENCE_OF_COMMANDS;
442 case 504:
443 return REPLY_504_COMMAND_NOT_IMPLEMENTED_FOR_THAT_PARAMETER;
444 case 522:
445 return REPLY_522_EXTENDED_PORT_FAILURE_UNKNOWN_NETWORK_PROTOCOL;
446 case 530:
447 return REPLY_530_NOT_LOGGED_IN;
448 case 532:
449 return REPLY_532_NEED_ACCOUNT_FOR_STORING_FILES;
450 case 550:
451 return REPLY_550_REQUESTED_ACTION_NOT_TAKEN;
452 case 551:
453 return REPLY_551_REQUESTED_ACTION_ABORTED_PAGE_TYPE_UNKNOWN;
454 case 552:
455 return REPLY_552_REQUESTED_FILE_ACTION_ABORTED_EXCEEDED_STORAGE;
456 case 553:
457 return REPLY_553_REQUESTED_ACTION_NOT_TAKEN_FILE_NAME_NOT_ALLOWED;
458 default:
459 throw new InvalidArgumentException("Unknown ReplyCode "+code);
460 }
461 }
462 }