Source Code Cross Referenced for FTPControlSocket.java in  » Groupware » hipergate » com » enterprisedt » net » ftp » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Groupware » hipergate » com.enterprisedt.net.ftp 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         *
003:         *  Java FTP client library.
004:         *
005:         *  Copyright (C) 2000-2003 Enterprise Distributed Technologies Ltd
006:         *
007:         *  www.enterprisedt.com
008:         *
009:         *  This library is free software; you can redistribute it and/or
010:         *  modify it under the terms of the GNU Lesser General Public
011:         *  License as published by the Free Software Foundation; either
012:         *  version 2.1 of the License, or (at your option) any later version.
013:         *
014:         *  This library is distributed in the hope that it will be useful,
015:         *  but WITHOUT ANY WARRANTY; without even the implied warranty of
016:         *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
017:         *  Lesser General Public License for more details.
018:         *
019:         *  You should have received a copy of the GNU Lesser General Public
020:         *  License along with this library; if not, write to the Free Software
021:         *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022:         *
023:         *  Bug fixes, suggestions and comments should be sent to bruce@enterprisedt.com
024:         *
025:         *  Change Log:
026:         *
027:         *        $Log: FTPControlSocket.java,v $
028:         *        Revision 1.1.1.1  2005/06/23 15:22:59  smontoro
029:         *        hipergate backend
030:         *
031:         *        Revision 1.1  2004/02/07 03:15:20  hipergate
032:         *        v2.0 pre-alpha
033:         *
034:         *        Revision 1.6  2003/05/31 14:53:44  bruceb
035:         *        1.2.2 changes
036:         *
037:         *        Revision 1.5  2003/01/29 22:46:08  bruceb
038:         *        minor changes
039:         *
040:         *        Revision 1.4  2002/11/19 22:01:25  bruceb
041:         *        changes for 1.2
042:         *
043:         *        Revision 1.3  2001/10/09 20:53:46  bruceb
044:         *        Active mode changes
045:         *
046:         *        Revision 1.1  2001/10/05 14:42:04  bruceb
047:         *        moved from old project
048:         *
049:         *
050:         */package com.enterprisedt.net.ftp;
051:
052:        import java.io.IOException;
053:        import java.io.PrintWriter;
054:        import java.io.BufferedReader;
055:        import java.io.InputStream;
056:        import java.io.OutputStream;
057:        import java.io.InputStreamReader;
058:        import java.io.OutputStreamWriter;
059:        import java.io.Writer;
060:
061:        import java.net.Socket;
062:        import java.net.ServerSocket;
063:        import java.net.InetAddress;
064:
065:        /**
066:         *  Supports client-side FTP operations
067:         *
068:         *  @author             Bruce Blackshaw
069:         *      @version        $Revision: 1.1.1.1 $
070:         *
071:         */
072:        public class FTPControlSocket {
073:
074:            /**
075:             *  Revision control id
076:             */
077:            private static String cvsId = "@(#)$Id: FTPControlSocket.java,v 1.1.1.1 2005/06/23 15:22:59 smontoro Exp $";
078:
079:            /**
080:             *   Standard FTP end of line sequence
081:             */
082:            static final String EOL = "\r\n";
083:
084:            /**
085:             *   The control port number for FTP
086:             */
087:            static final int CONTROL_PORT = 21;
088:
089:            /**
090:             *   Used to flag messages
091:             */
092:            private static final String DEBUG_ARROW = "---> ";
093:
094:            /**
095:             *   Start of password message
096:             */
097:            private static final String PASSWORD_MESSAGE = DEBUG_ARROW + "PASS";
098:
099:            /**
100:             *   Controls if responses sent back by the
101:             *   server are sent to assigned output stream
102:             */
103:            private boolean debugResponses = false;
104:
105:            /**
106:             *  Output stream debug is written to, 
107:             *  stdout by default
108:             */
109:            private PrintWriter log = new PrintWriter(System.out);
110:
111:            /**
112:             *  The underlying socket.
113:             */
114:            private Socket controlSock = null;
115:
116:            /**
117:             *  The write that writes to the control socket
118:             */
119:            private Writer writer = null;
120:
121:            /**
122:             *  The reader that reads control data from the
123:             *  control socket
124:             */
125:            private BufferedReader reader = null;
126:
127:            /**
128:             *   Constructor. Performs TCP connection and
129:             *   sets up reader/writer. Allows different control
130:             *   port to be used
131:             *
132:             *   @param   remoteHost   Remote hostname
133:             *   @param   controlPort  port for control stream
134:             *   @param   millis       the length of the timeout, in milliseconds
135:             *   @param   log          the new logging stream
136:             */
137:            public FTPControlSocket(String remoteHost, int controlPort,
138:                    PrintWriter log, int timeout) throws IOException,
139:                    FTPException {
140:
141:                setLogStream(log);
142:
143:                // ensure we get debug from initial connection sequence
144:                debugResponses(true);
145:                controlSock = new Socket(remoteHost, controlPort);
146:                setTimeout(timeout);
147:                initStreams();
148:                validateConnection();
149:
150:                // switch off debug - user can switch on from this point
151:                debugResponses(false);
152:            }
153:
154:            /**
155:             *   Constructor. Performs TCP connection and
156:             *   sets up reader/writer. Allows different control
157:             *   port to be used
158:             *
159:             *   @param   remoteAddr   Remote inet address
160:             *   @param   controlPort  port for control stream
161:             *   @param   millis       the length of the timeout, in milliseconds
162:             *   @param   log          the new logging stream
163:             */
164:            public FTPControlSocket(InetAddress remoteAddr, int controlPort,
165:                    PrintWriter log, int timeout) throws IOException,
166:                    FTPException {
167:
168:                setLogStream(log);
169:
170:                // ensure we get debug from initial connection sequence
171:                debugResponses(true);
172:                controlSock = new Socket(remoteAddr, controlPort);
173:                setTimeout(timeout);
174:                initStreams();
175:                validateConnection();
176:
177:                // switch off debug - user can switch on from this point
178:                debugResponses(false);
179:            }
180:
181:            /**
182:             *   Checks that the standard 220 reply is returned
183:             *   following the initiated connection
184:             */
185:            private void validateConnection() throws IOException, FTPException {
186:
187:                String reply = readReply();
188:                validateReply(reply, "220");
189:            }
190:
191:            /**
192:             *  Obtain the reader/writer streams for this
193:             *  connection
194:             */
195:            private void initStreams() throws IOException {
196:
197:                // input stream
198:                InputStream is = controlSock.getInputStream();
199:                reader = new BufferedReader(new InputStreamReader(is));
200:
201:                // output stream
202:                OutputStream os = controlSock.getOutputStream();
203:                writer = new OutputStreamWriter(os);
204:            }
205:
206:            /**
207:             *  Get the name of the remote host
208:             *
209:             *  @return  remote host name
210:             */
211:            String getRemoteHostName() {
212:                InetAddress addr = controlSock.getInetAddress();
213:                return addr.getHostName();
214:            }
215:
216:            /**
217:             *   Set the TCP timeout on the underlying control socket.
218:             *
219:             *   If a timeout is set, then any operation which
220:             *   takes longer than the timeout value will be
221:             *   killed with a java.io.InterruptedException.
222:             *
223:             *   @param millis The length of the timeout, in milliseconds
224:             */
225:            void setTimeout(int millis) throws IOException {
226:
227:                if (controlSock == null)
228:                    throw new IllegalStateException(
229:                            "Failed to set timeout - no control socket");
230:
231:                controlSock.setSoTimeout(millis);
232:            }
233:
234:            /**
235:             *  Quit this FTP session and clean up.
236:             */
237:            public void logout() throws IOException {
238:
239:                if (log != null) {
240:                    log.flush();
241:                    log = null;
242:                }
243:
244:                IOException ex = null;
245:                try {
246:                    writer.close();
247:                } catch (IOException e) {
248:                    ex = e;
249:                }
250:                try {
251:                    reader.close();
252:                } catch (IOException e) {
253:                    ex = e;
254:                }
255:                try {
256:                    controlSock.close();
257:                } catch (IOException e) {
258:                    ex = e;
259:                }
260:                if (ex != null)
261:                    throw ex;
262:            }
263:
264:            /**
265:             *  Request a data socket be created on the
266:             *  server, connect to it and return our
267:             *  connected socket.
268:             *
269:             *  @param  active   if true, create in active mode, else
270:             *                   in passive mode
271:             *  @return  connected data socket
272:             */
273:            FTPDataSocket createDataSocket(FTPConnectMode connectMode)
274:                    throws IOException, FTPException {
275:
276:                if (connectMode == FTPConnectMode.ACTIVE) {
277:                    return new FTPDataSocket(createDataSocketActive());
278:                } else { // PASV
279:                    return new FTPDataSocket(createDataSocketPASV());
280:                }
281:            }
282:
283:            /**
284:             *  Request a data socket be created on the Client
285:             *  client on any free port, do not connect it to yet.
286:             *
287:             *  @return  not connected data socket
288:             */
289:            ServerSocket createDataSocketActive() throws IOException,
290:                    FTPException {
291:
292:                // use any available port
293:                ServerSocket socket = new ServerSocket(0);
294:
295:                // get the local address to which the control socket is bound.
296:                InetAddress localhost = controlSock.getLocalAddress();
297:
298:                // send the PORT command to the server
299:                setDataPort(localhost, (short) socket.getLocalPort());
300:
301:                return socket;
302:            }
303:
304:            /**
305:             *  Helper method to convert a byte into an unsigned short value
306:             *
307:             *  @param  value   value to convert
308:             *  @return  the byte value as an unsigned short
309:             */
310:            private short toUnsignedShort(byte value) {
311:                return (value < 0) ? (short) (value + 256) : (short) value;
312:            }
313:
314:            /**
315:             *  Convert a short into a byte array
316:             *
317:             *  @param  value   value to convert
318:             *  @return  a byte array
319:             */
320:            protected byte[] toByteArray(short value) {
321:
322:                byte[] bytes = new byte[2];
323:                bytes[0] = (byte) (value >> 8); // bits 1- 8
324:                bytes[1] = (byte) (value & 0x00FF); // bits 9-16
325:                return bytes;
326:            }
327:
328:            /**
329:             *  Sets the data port on the server, i.e. sends a PORT
330:             *  command
331:             *
332:             *  @param  host    the local host the server will connect to
333:             *  @param  portNo  the port number to connect to
334:             */
335:            private void setDataPort(InetAddress host, short portNo)
336:                    throws IOException, FTPException {
337:
338:                byte[] hostBytes = host.getAddress();
339:                byte[] portBytes = toByteArray(portNo);
340:
341:                // assemble the PORT command
342:                String cmd = new StringBuffer("PORT ").append(
343:                        toUnsignedShort(hostBytes[0])).append(",").append(
344:                        toUnsignedShort(hostBytes[1])).append(",").append(
345:                        toUnsignedShort(hostBytes[2])).append(",").append(
346:                        toUnsignedShort(hostBytes[3])).append(",").append(
347:                        toUnsignedShort(portBytes[0])).append(",").append(
348:                        toUnsignedShort(portBytes[1])).toString();
349:
350:                // send command and check reply
351:                String reply = sendCommand(cmd);
352:                validateReply(reply, "200");
353:            }
354:
355:            /**
356:             *  Request a data socket be created on the
357:             *  server, connect to it and return our
358:             *  connected socket.
359:             *
360:             *  @return  connected data socket
361:             */
362:            Socket createDataSocketPASV() throws IOException, FTPException {
363:
364:                // PASSIVE command - tells the server to listen for
365:                // a connection attempt rather than initiating it
366:                String reply = sendCommand("PASV");
367:                validateReply(reply, "227");
368:
369:                // The reply to PASV is in the form:
370:                // 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).
371:                // where h1..h4 are the IP address to connect and
372:                // p1,p2 the port number
373:                // Example:
374:                // 227 Entering Passive Mode (128,3,122,1,15,87).
375:                // NOTE: PASV command in IBM/Mainframe returns the string
376:                // 227 Entering Passive Mode 128,3,122,1,15,87	(missing 
377:                // brackets)
378:
379:                // extract the IP data string from between the brackets
380:                int startIP = reply.indexOf('(');
381:                int endIP = reply.indexOf(')');
382:
383:                // allow for IBM missing brackets around IP address
384:                if (startIP < 0 && endIP < 0) {
385:                    startIP = reply.toUpperCase().lastIndexOf("MODE") + 4;
386:                    endIP = reply.length();
387:                }
388:
389:                String ipData = reply.substring(startIP + 1, endIP);
390:                int parts[] = new int[6];
391:
392:                int len = ipData.length();
393:                int partCount = 0;
394:                StringBuffer buf = new StringBuffer();
395:
396:                // loop thru and examine each char
397:                for (int i = 0; i < len && partCount <= 6; i++) {
398:
399:                    char ch = ipData.charAt(i);
400:                    if (Character.isDigit(ch))
401:                        buf.append(ch);
402:                    else if (ch != ',') {
403:                        throw new FTPException("Malformed PASV reply: " + reply);
404:                    }
405:
406:                    // get the part
407:                    if (ch == ',' || i + 1 == len) { // at end or at separator
408:                        try {
409:                            parts[partCount++] = Integer.parseInt(buf
410:                                    .toString());
411:                            buf.setLength(0);
412:                        } catch (NumberFormatException ex) {
413:                            throw new FTPException("Malformed PASV reply: "
414:                                    + reply);
415:                        }
416:                    }
417:                }
418:
419:                // assemble the IP address
420:                // we try connecting, so we don't bother checking digits etc
421:                String ipAddress = parts[0] + "." + parts[1] + "." + parts[2]
422:                        + "." + parts[3];
423:
424:                // assemble the port number
425:                int port = (parts[4] << 8) + parts[5];
426:
427:                // create the socket
428:                return new Socket(ipAddress, port);
429:            }
430:
431:            /**
432:             *  Send a command to the FTP server and
433:             *  return the server's reply
434:             *
435:             *  @return  reply to the supplied command
436:             */
437:            String sendCommand(String command) throws IOException {
438:
439:                log(DEBUG_ARROW + command);
440:
441:                // send it
442:                writer.write(command + EOL);
443:                writer.flush();
444:
445:                // and read the result
446:                return readReply();
447:            }
448:
449:            /**
450:             *  Read the FTP server's reply to a previously
451:             *  issued command. RFC 959 states that a reply
452:             *  consists of the 3 digit code followed by text.
453:             *  The 3 digit code is followed by a hyphen if it
454:             *  is a muliline response, and the last line starts
455:             *  with the same 3 digit code.
456:             *
457:             *  @return  reply string
458:             */
459:            String readReply() throws IOException {
460:
461:                String firstLine = reader.readLine();
462:                if (firstLine == null || firstLine.length() == 0)
463:                    throw new IOException("Unexpected null reply received");
464:
465:                StringBuffer reply = new StringBuffer(firstLine);
466:
467:                log(reply.toString());
468:
469:                String replyCode = reply.toString().substring(0, 3);
470:
471:                // check for multiline response and build up
472:                // the reply
473:                if (reply.charAt(3) == '-') {
474:
475:                    boolean complete = false;
476:                    while (!complete) {
477:                        String line = reader.readLine();
478:                        if (line == null)
479:                            throw new IOException(
480:                                    "Unexpected null reply received");
481:
482:                        log(line);
483:
484:                        if (line.length() > 3
485:                                && line.substring(0, 3).equals(replyCode)
486:                                && line.charAt(3) == ' ') {
487:                            reply.append(line.substring(3));
488:                            complete = true;
489:                        } else { // not the last line
490:                            reply.append(" ");
491:                            reply.append(line);
492:                        }
493:                    } // end while
494:                } // end if
495:                return reply.toString();
496:            }
497:
498:            /**
499:             *  Validate the response the host has supplied against the
500:             *  expected reply. If we get an unexpected reply we throw an
501:             *  exception, setting the message to that returned by the
502:             *  FTP server
503:             *
504:             *  @param   reply              the entire reply string we received
505:             *  @param   expectedReplyCode  the reply we expected to receive
506:             *
507:             */
508:            FTPReply validateReply(String reply, String expectedReplyCode)
509:                    throws IOException, FTPException {
510:
511:                // all reply codes are 3 chars long
512:                String replyCode = reply.substring(0, 3);
513:                String replyText = reply.substring(4);
514:                FTPReply replyObj = new FTPReply(replyCode, replyText);
515:
516:                if (replyCode.equals(expectedReplyCode))
517:                    return replyObj;
518:
519:                // if unexpected reply, throw an exception
520:                throw new FTPException(replyText, replyCode);
521:            }
522:
523:            /**
524:             *  Validate the response the host has supplied against the
525:             *  expected reply. If we get an unexpected reply we throw an
526:             *  exception, setting the message to that returned by the
527:             *  FTP server
528:             *
529:             *  @param   reply               the entire reply string we received
530:             *  @param   expectedReplyCodes  array of expected replies
531:             *  @return  an object encapsulating the server's reply
532:             *
533:             */
534:            FTPReply validateReply(String reply, String[] expectedReplyCodes)
535:                    throws IOException, FTPException {
536:
537:                // all reply codes are 3 chars long
538:                String replyCode = reply.substring(0, 3);
539:                String replyText = reply.substring(4);
540:
541:                FTPReply replyObj = new FTPReply(replyCode, replyText);
542:
543:                for (int i = 0; i < expectedReplyCodes.length; i++)
544:                    if (replyCode.equals(expectedReplyCodes[i]))
545:                        return replyObj;
546:
547:                // got this far, not recognised
548:                throw new FTPException(replyText, replyCode);
549:            }
550:
551:            /**
552:             *  Switch debug of responses on or off
553:             *
554:             *  @param  on  true if you wish to have responses to
555:             *              stdout, false otherwise
556:             */
557:            void debugResponses(boolean on) {
558:                debugResponses = on;
559:            }
560:
561:            /**
562:             *  Set the logging stream, replacing
563:             *  stdout. If null log supplied, logging is
564:             *  switched off
565:             *
566:             *  @param log  the new logging stream
567:             */
568:            void setLogStream(PrintWriter log) {
569:                if (log != null)
570:                    this .log = log;
571:                else
572:                    debugResponses = false;
573:            }
574:
575:            /**
576:             *  Log a message, if logging is set up
577:             * 
578:             *  @param msg	message to log
579:             */
580:            void log(String msg) {
581:                if (debugResponses && log != null) {
582:                    if (!msg.startsWith(PASSWORD_MESSAGE))
583:                        log.println(msg);
584:                    else
585:                        log.println(PASSWORD_MESSAGE + " ********");
586:                }
587:            }
588:
589:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.