Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/flexstor/common/io/xfile/ftp/FtpSession.java


1   /*
2    * FtpSession.java
3    *
4    * Copyright $Date: 2003/08/11 02:22:47 $ FLEXSTOR.net Inc.
5    *
6    * This work is licensed for use and distribution under license terms found at
7    * http://www.flexstor.org/license.html
8    *
9    */
10  
11  package com.flexstor.common.io.xfile.ftp;
12  
13  import java.io.BufferedReader;
14  import java.io.BufferedWriter;
15  import java.io.IOException;
16  import java.io.InputStream;
17  import java.io.InputStreamReader;
18  import java.io.OutputStream;
19  import java.io.OutputStreamWriter;
20  import java.io.StringReader;
21  import java.net.InetAddress;
22  import java.net.ServerSocket;
23  import java.net.Socket;
24  import java.net.UnknownHostException;
25  
26  import com.flexstor.common.settings.Settings;
27  public class FtpSession 
28  
29  {
30      private final boolean debug = true;
31      private static String ANONYMOUS_USER = "anonymous";
32      private static String ANONYMOUS_PASSWD = "test@flexstor.com";
33      private static String CR_LF = "\r\n";
34      private BufferedReader reader;
35      private BufferedWriter writer;
36      static final public char ASCII_TYPE = 'A';
37      static final public char IMAGE_TYPE = 'I';
38      static final public char EBCDIC_TYPE = 'E';
39      static final public char COMPRESSED_MODE = 'C';
40      static final public char STREAMING_MODE = 'S';
41      static final public char BLOCK_MODE = 'B';
42      private BufferedReader in;
43      //private PrintWriter out;
44      private BufferedWriter out;
45      private ServerSocket m_dataSocket;
46      //static final public char NON_PRINT_FORMAT = 'N';
47      static final public char NON_PRINT_FORMAT = 'N';
48      private Socket m_dataXfrSocket;
49      private FtpResponse m_response;
50      private boolean isMacintosh = (System.getProperty("mrj.version") != null);
51  
52  
53      /**
54       * An id that identifies a session.
55       */
56      protected FtpSessionId ftpSessionId = null;
57      protected boolean bSessionTerminated  = false;
58      protected Socket socket      = null;
59      protected boolean   bPassive = true;            // PASSIVE/ACTIVE socket switch
60      protected Socket passiveSocket = null;
61      
62      /**
63       * Idea is that there should not be any other way to create a ftp session than
64       * asking ftp session pool to create one.
65       */
66      public FtpSession ( FtpSessionId sessionId )
67      {
68        this.ftpSessionId = sessionId;
69        
70        // Get the user selection for data port type. Default is PASSIVE
71        bPassive = Settings.getBoolean(Settings.FTP_PASSIVE);
72        if (bPassive == true)
73        {
74          System.out.println("FTP Data Port will be PASSIVE");
75        }
76        
77        else
78        {
79          System.out.println("FTP Data Port will be ACTIVE");
80        }
81  
82      }
83      
84      public FtpSessionId getSessionId ()
85      {
86        return ftpSessionId;
87      }
88      public void connect ()
89        throws java.net.UnknownHostException, IOException
90      {
91          socket = new Socket( ftpSessionId.getServerName(), ftpSessionId.getServerPort() );
92  
93          in  = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );
94          out = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ) );
95  
96          setResponse();
97      }
98  
99    public void transferMode(char mode)
100     throws IOException
101     {
102       sendCommand("MODE " + mode);
103     }
104 
105   public void sendUserName(String userName)
106     throws IOException
107     {
108       sendCommand("USER " + userName);
109     }
110 
111   public void sendPassword(String password)
112     throws IOException
113     {
114       sendCommand("PASS " + password);
115     }
116 
117 
118     protected void readResponse()
119     {
120        try
121        {
122         StringBuffer buffer = new StringBuffer();
123         while (true) {
124       while (!reader.ready()) {
125       try { Thread.sleep(10L); }
126       catch (InterruptedException exc) {}
127       }
128       String line = reader.readLine();
129       buffer.append(line);
130       buffer.append('\n');
131       break;
132       }
133 
134       }
135       catch(Exception ex)
136        {
137             System.out.println("Exception occured while reading response " + ex);
138        }
139     }
140 
141 
142 
143     public void changeWorkingDirectory(String path)
144     throws IOException
145     {
146       sendCommand("CWD " + path);
147     }
148 
149     public void changeToParentDirectory()
150     throws IOException
151     {
152       sendCommand("CDUP");
153     }
154 
155     public void logout()
156     throws IOException
157     {
158        sendCommand("QUIT");
159        bSessionTerminated = true;
160     }
161     public boolean isSessionTerminated ()
162     {
163        return bSessionTerminated;
164     }
165 
166     /**
167     *
168     *
169     */
170     public void dataPort()
171      throws IOException, UnknownHostException
172     {
173       // Create a PASSIVE or ACTIVE data socket
174       if (bPassive == true)
175       {
176         // Create a PASSIVE socket
177         passiveSocket = createPassiveDataSocket();
178       }
179       
180       else
181       {
182         // Create an ACTIVE socket
183         StringBuffer command = new StringBuffer("PORT ");
184         String host = InetAddress.getLocalHost().getHostAddress();
185         command.append(host.replace('.', ','));
186         if (m_dataSocket != null)
187       m_dataSocket.close();
188         m_dataSocket = new ServerSocket(0);
189         int port = m_dataSocket.getLocalPort();
190         command.append(',');
191         command.append(port/256);
192         command.append(',');
193         command.append(port%256);
194         sendCommand( command.toString() );
195       }
196     } // dataPort
197 
198    public void representationType(char type)
199     throws IOException
200    {
201       representationType(type, NON_PRINT_FORMAT);
202       transferMode(COMPRESSED_MODE);
203    }
204 
205    public void representationType(char type, char format)
206     throws IOException
207    {
208       //sendCommand("TYPE " + type + ' ' + format);
209       sendCommand("TYPE " + type);
210    }
211 
212 
213    public FtpInputStream retrieveBinary(String path)
214     throws IOException
215    {
216       transferMode(COMPRESSED_MODE);
217       sendCommand("RETR " + path);
218 
219 //      if (!getResponse().isPositivePreliminary())
220 //        return null;
221       if ( getResponse().likelyToFail() )
222           return null;
223 
224 //      m_dataXfrSocket = m_dataSocket.accept();
225       m_dataXfrSocket = getSocket();
226       if (m_dataXfrSocket == null)
227       {
228         return null;
229       }
230       
231       InputStream istr = m_dataXfrSocket.getInputStream();
232       //InputStreamReader in = new InputStreamReader(istr);
233       return new FtpInputStream(istr, this);
234     }
235 
236 
237 
238   public FtpReader retrieve(String path)
239     throws IOException
240     {
241       sendCommand("RETR " + path);
242 //      System.out.println("The response is " + getResponse().getMessage());
243 //      if (!getResponse().isPositivePreliminary())
244 //       return null;
245       if ( getResponse().likelyToFail() )
246          return null;
247 
248 //      m_dataXfrSocket = m_dataSocket.accept();
249       m_dataXfrSocket = getSocket();
250       if (m_dataXfrSocket == null)
251       {
252         return null;
253       }
254       
255       InputStream istr = m_dataXfrSocket.getInputStream();
256       InputStreamReader in = new InputStreamReader(istr);
257       return new FtpReader(in, this);
258     }
259 
260   public FtpWriter store(String path)
261     throws IOException
262     {
263       sendCommand("STOR " + path);
264 //      if (!getResponse().isPositivePreliminary())
265 //       return null;
266       if ( getResponse().likelyToFail() )
267         return null; // Actually it should throw exception with proper response message
268 
269 //      m_dataXfrSocket = m_dataSocket.accept();
270       m_dataXfrSocket = getSocket();
271       if (m_dataXfrSocket == null)
272       {
273         return null;
274       }
275       
276       OutputStream ostr = m_dataXfrSocket.getOutputStream();
277       OutputStreamWriter out = new OutputStreamWriter(ostr);
278       return new FtpWriter(out, this);
279     }
280     
281   public FtpOutputStream storeBinary(String path)
282     throws IOException
283     {
284       transferMode(COMPRESSED_MODE);
285       sendCommand("STOR " + path);
286 //      System.out.println("STOR message is " + getResponse().getMessage());
287 //      System.out.println("STOR return code is " + getResponse().getReturnCode() );
288 //      if ( !getResponse().isPositivePreliminary() )
289 //     return null;
290 
291        if ( getResponse().likelyToFail() )
292           return null;
293 
294 
295 //      m_dataXfrSocket   = m_dataSocket.accept();
296       m_dataXfrSocket = getSocket();
297       if (m_dataXfrSocket == null)
298       {
299         return null;
300       }
301       
302       OutputStream ostr = m_dataXfrSocket.getOutputStream();
303       //OutputStreamWriter out = new OutputStreamWriter(ostr);
304       //return new FtpWriter(out, this);
305       return new FtpOutputStream(ostr,this);
306     }
307     
308 
309   public FtpWriter append(String path) throws IOException
310     {
311       sendCommand("APPE " + path);
312 //      if (!getResponse().isPositivePreliminary())
313 //     return null;
314       if ( getResponse().likelyToFail() )
315          return null;
316 
317 //      m_dataXfrSocket = m_dataSocket.accept();
318       m_dataXfrSocket = getSocket();
319       if (m_dataXfrSocket == null)
320       {
321         return null;
322       }
323       
324       OutputStream ostr = m_dataXfrSocket.getOutputStream();
325       OutputStreamWriter out = new OutputStreamWriter(ostr);
326       return new FtpWriter(out, this);
327     }
328     
329   public void renameFrom(String path)
330     throws IOException
331     {
332       sendCommand("RNFR " + path);
333     }
334     
335   public void renameTo(String path)
336     throws IOException
337     {
338       sendCommand("RNTO " + path);
339     }
340     
341   public void delete(String path)
342     throws IOException
343     {
344       sendCommand("DELE " + path);
345     }
346     
347   public void removeDirectory(String path)
348     throws IOException
349     {
350       sendCommand("RMD " + path);
351     }
352     
353     
354   public void makeDirectory(String path)
355     throws IOException
356     {
357       sendCommand("MKD " + path);
358     }
359     
360     
361   public void printWorkingDirectory()
362     throws IOException
363     {
364       sendCommand("PWD");
365 
366     }
367    private FtpReader listWithSpaces(String path)
368     throws IOException
369    {
370 //       System.out.println("This path has spaces, needs special processing"); 
371        sendCommand("CWD " + path);
372 //      if (getResponse().isPositiveCompletion()){
373             //System.out.println("CWD successful..");
374 //            return list(null);
375       if ( getResponse().likelyToSucceed() )
376       {
377            return list( null );
378 
379       }else{
380             //System.out.println("Dir/File does not exist for CWD");
381             String failureMessage = "No such file or directory";
382             StringReader sReader = new StringReader(failureMessage);
383             return new FtpReader(sReader, this);
384       }
385       
386    }
387     
388     public FtpReader list(String path)
389     throws IOException
390     {
391         if (path == null)
392 
393           sendCommand("LIST");
394         
395         else
396           {
397           if(path.indexOf(" ")>-1) return listWithSpaces(path);
398           else  sendCommand("LIST " + path);
399           //sendCommand("LIST " + path);
400           }
401 
402 //        if ( !getResponse().isPositivePreliminary() )
403 //          return null;
404 //         System.out.println ("Response "+getResponse().getMessage());
405          if ( getResponse().likelyToFail() )
406            return null;
407            
408         //System.out.println("accepting the socket..");
409 
410 //        m_dataXfrSocket = m_dataSocket.accept();
411          m_dataXfrSocket = getSocket();
412          if (m_dataXfrSocket == null)
413          {
414             return null;
415          }
416       
417         //System.out.println("getting the instream");
418         InputStream istr = m_dataXfrSocket.getInputStream();
419         //System.out.println("making a reader to return..");
420         InputStreamReader in = new InputStreamReader(istr);
421         FtpReader reader = new FtpReader(in, this);
422         return reader;
423       
424     }
425     
426     
427     public FtpReader list()
428     throws IOException
429     {
430       return list(null);
431     }
432     
433     void setResponse()
434     throws IOException 
435     {
436       m_response = new FtpResponse(in);
437     }
438     
439     
440   public FtpReader nameList(String path)   throws IOException
441     {
442       if (path == null)
443         sendCommand("NLIST");
444       else
445       sendCommand("NLST " + path);
446 //      if (!getResponse().isPositivePreliminary())
447 //      return null;
448 
449       if ( getResponse().likelyToFail() )
450       return null;
451 
452         
453  //     m_dataXfrSocket = m_dataSocket.accept();
454       m_dataXfrSocket = getSocket();
455       if (m_dataXfrSocket == null)
456       {
457         return null;
458       }
459       
460       InputStream istr = m_dataXfrSocket.getInputStream();
461       InputStreamReader in = new InputStreamReader(istr);
462       return new FtpReader(in, this);
463     }
464 
465   public FtpReader nameList() throws IOException
466     {
467       return nameList(null);
468     }
469     
470     
471   void closeTransferSocket()
472     throws IOException 
473     {
474       if(m_dataXfrSocket==null) return;
475       m_dataXfrSocket.close();
476       setResponse();
477     }
478     
479   private void sendCommand(String command)
480     throws IOException
481     {
482       
483       if(!isMacintosh)
484       {
485         out.write(command);
486         out.newLine();
487         out.flush();
488       }
489       else
490       {
491        out.write(command);
492        out.write("\r\n");
493        out.flush();
494       }
495 
496       setResponse();
497     }
498 
499   public FtpResponse getResponse()
500     {
501       return m_response;
502     }
503 
504 
505   /**
506   *
507   *
508   */
509   protected Socket createPassiveDataSocket()
510     throws IOException  
511   {
512          // PASSIVE command - tells the server to listen for
513          // a connection attempt rather than initiating it
514          sendCommand("PASV");
515          FtpResponse response = getResponse(); 
516          
517          // Validate the reply 
518          String sReturnCode = response.getReturnCode();
519          System.out.println("FTP PASV command return code: " + sReturnCode);
520          if (sReturnCode.equals("227") == false)
521          {
522             System.out.println("FTP - Invalid return code for 'PASV' command: " + sReturnCode);
523             return null;
524          }
525          
526          // Get the actual reply message text
527          String sReply = response.getMessage();
528          System.out.println("FTP PASV command response message: " + sReply);
529          
530          // The reply to PASV is in the form:
531          // 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).
532          // where h1..h4 are the IP address to connect and
533          // p1,p2 the port number
534          // Example:
535          // 227 Entering Passive Mode (128,3,122,1,15,87).
536 
537          // extract the IP data string from between the brackets
538          int bracket1 = sReply.indexOf('(');
539          int bracket2 = sReply.indexOf(')');
540          if ((bracket1 == -1) || (bracket2 == -1))
541          {
542             System.out.println("FTP - Invalid reply for 'PASV' command, missing bracket(s): " + sReply);
543          }
544                   
545          String ipData = sReply.substring(bracket1+1,bracket2);
546          int parts[] = new int[6];
547 
548          int len = ipData.length();
549          int partCount = 0;
550          StringBuffer buf = new StringBuffer();
551 
552          // loop thru and examine each char
553          for (int i = 0; i < len && partCount <= 6; i++) 
554          {
555              char ch = ipData.charAt(i);
556              if (Character.isDigit(ch))
557              {
558                  buf.append(ch);
559              }
560              
561              else if (ch != ',') 
562              {
563                  System.out.println("FTP - Malformed PASV reply (a): " + sReply);
564                  return null;
565              }
566 
567              // get the part
568              if (ch == ',' || i+1 == len) 
569              { // at end or at separator
570                  try 
571                  {
572                      parts[partCount++] = Integer.parseInt(buf.toString());
573                      buf.setLength(0);
574                  }
575                  
576                  catch (NumberFormatException ex) 
577                  {
578                      System.out.println("FTP - Malformed PASV reply (b): " + sReply);
579                      return null;
580                  }
581              } // ch if
582          } // for i
583 
584          // assemble the IP address
585          // we try connecting, so we don't bother checking digits etc
586          String ipAddress = parts[0] + "."+ parts[1]+ "." + parts[2] + "." + parts[3];
587 
588          // assemble the port number
589          int port = (parts[4] << 8) + parts[5];
590 
591          // create the socket
592          return new Socket(ipAddress, port);
593     
594   } // createPassiveDataSocket
595 
596   /**
597   *
598   *
599   */
600   protected Socket getSocket()
601     throws IOException  
602   {
603     // Get the appropriate data socket depending on the specified mode (PASSIVE/ACTIVE)
604     if (bPassive == true)
605     {
606         System.out.println("FTP - using PASSIVE data socket: " + passiveSocket.toString());
607         return(passiveSocket);
608     }
609     
610     else
611     {
612         // Return the ACTIVE socket
613         Socket activeSocket = m_dataSocket.accept();
614         System.out.println("FTP - using ACTIVE data socket: " + activeSocket.toString());
615         return(activeSocket); 
616     }
617   } // get Socket
618 
619 } // FtpSession
620 
621 
622 
623 
624 
625