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

Quick Search    Search Deep

Source code: cxtable/xDownloadLinlyn.java


1   package cxtable;
2   
3   /*this is a modified Linlyn (under the KDE artistic license)...
4   it is for future filesharing issues...not currently in use...  */
5   
6   
7    import java.io.*;
8    import java.net.*;
9    import java.util.*;
10  
11      public class xDownloadLinlyn extends Thread{
12     
13      // FOR DEBUGGING: set the variable to "true"
14        private boolean DEBUG = false;
15      private String dir="";
16       private String server,file; private int port;private xDownloadListener xdl;
17      // constructor needs servername, username and passwd
18        
19  
20    public xDownloadLinlyn(String _server, int _port, String _file, xDownloadListener _xdl)
21        {
22           port = _port; server = _server; file = _file;xdl=_xdl;
23        }
24      public xDownloadLinlyn(String _server,  String _file, xDownloadListener _xdl)
25        {
26           port = CNTRL_PORT; server = _server; file = _file;xdl=_xdl;
27        }
28      public void setDir(String d)
29      {
30      dir=d;
31      }
32      
33      
34      public void run()
35        {  String contents="";
36           try { 
37              ftpConnect(server);
38                  } 
39              catch(IOException ioe) {
40                xdl.dl_error(file, ioe); return;}
41          try{
42          contents = download(false);
43            }
44          catch(Exception e)
45            {xdl.dl_error(file,e); return;}
46          xdl.process(file,contents);
47          return;
48        }
49        
50        private String download(boolean asc)
51        throws IOException {
52           if (dir.equals("")==false){ftpSetDir(dir);}
53           ftpSetTransferType(asc);
54           dsock = ftpGetDataSock();
55           InputStream is = dsock.getInputStream();
56           ftpSendCmd("RETR "+file);
57        
58           String cont = getAsString(is);
59           ftpLogout();
60           return cont;
61        }   
62      ///////////////// private fields ////////////////////
63        private boolean pauser = false;  // it's a hack. We're going to 
64            // stall (refuse further requests) till we get a reply back 
65            // from server for the current request.
66     
67        private String getAsString(InputStream is) {
68           int c=0;
69           char lineBuffer[]=new char[128], buf[]=lineBuffer;
70           int room= buf.length, offset=0;
71           try {
72           loop: 
73              while (true) {
74                // read chars into a buffer which grows as needed
75                 switch (c = is.read() ) {
76                    case -1: 
77                       break loop;
78                    
79                    default: 
80                       if (--room < 0) {
81                          buf = new char[offset + 128];
82                          room = buf.length - offset - 1;
83                          System.arraycopy(lineBuffer, 0, 
84                                          buf, 0, offset);
85                          lineBuffer = buf;
86                       }
87                       buf[offset++] = (char) c;
88                       break;
89                 }
90              }
91           } 
92              catch(IOException ioe) {
93                 ioe.printStackTrace();}
94           if ((c == -1) && (offset == 0)) {
95              return null;
96           }
97           return String.copyValueOf(buf, 0, offset);
98        }
99     
100       private void ftpConnect(String server)
101       throws IOException {
102         // Set up socket, control streams, connect to ftp server
103         // Open socket to server control port 21
104          csock = new Socket(server, port);
105         // Open control streams
106          InputStream cis = csock.getInputStream();
107          dcis =  new BufferedReader(new InputStreamReader(cis));
108          OutputStream cos = csock.getOutputStream();
109          pos = new PrintWriter(cos, true); // set auto flush true.
110         // See if server is alive or dead... 
111          String numerals = responseHandler(null); 
112          if(numerals.substring(0,3).equals("220")) // ftp server alive
113             ; // System.out.println("Connected to ftp server");
114          else System.err.println("Error connecting to ftp server.");
115       }
116       
117       private void ftpSetDir(String dir)
118       throws IOException { 
119         // cwd to dir
120          ftpSendCmd("CWD "+dir);
121       }
122    
123       private void ftpSetTransferType(boolean asc)
124       throws IOException {
125       // set file transfer type
126          String ftype = (asc? "A" : "I");
127          ftpSendCmd("TYPE "+ftype);
128       }    
129    
130       private Socket ftpGetDataSock()
131       throws IOException {
132         // Go to PASV mode, capture server reply, parse for socket setup
133         // V2.1: generalized port parsing, allows more server variations
134          String reply = ftpSendCmd("PASV");
135       
136         // New technique: just find numbers before and after ","!
137          StringTokenizer st = new StringTokenizer(reply, ",");
138          String[] parts = new String[6]; // parts, incl. some garbage
139          int i = 0; // put tokens into String array
140          while(st.hasMoreElements()) {
141             // stick pieces of host, port in String array
142             try {
143                parts[i] = st.nextToken();
144                i++;
145             } 
146                catch(NoSuchElementException nope){
147                   nope.printStackTrace();}
148          } // end getting parts of host, port
149       
150         // Get rid of everything before first "," except digits
151          String[] possNum = new String[3];
152          for(int j = 0; j < 3; j++) {
153             // Get 3 characters, inverse order, check if digit/character
154             possNum[j] = parts[0].substring(parts[0].length() - (j + 1),
155                                  parts[0].length() - j); // next: digit or character?
156             if(!Character.isDigit(possNum[j].charAt(0)))
157                possNum[j] = "";
158          }
159          parts[0] = possNum[2] + possNum[1] + possNum[0];
160         // Get only the digits after the last ","
161          String[] porties = new String[3];
162          for(int k = 0; k < 3; k++) {
163             // Get 3 characters, in order, check if digit/character
164             // May be less than 3 characters
165             if((k + 1) <= parts[5].length())
166                porties[k] = parts[5].substring(k, k + 1);
167             else porties[k] = "FOOBAR"; // definitely not a digit!
168             // next: digit or character?
169             if(!Character.isDigit(porties[k].charAt(0)))
170                porties[k] = "";
171          } // Have to do this one in order, not inverse order
172          parts[5] = porties[0] + porties[1] + porties[2];
173         // Get dotted quad IP number first
174          String ip = parts[0]+"."+parts[1]+"."+parts[2]+"."+parts[3];
175       
176         // Determine port
177          int port = -1;
178          try { // Get first part of port, shift by 8 bits.
179             int big = Integer.parseInt(parts[4]) << 8;
180             int small = Integer.parseInt(parts[5]);
181             port = big + small; // port number
182          } 
183             catch(NumberFormatException nfe) {
184                nfe.printStackTrace();}
185          if((ip != null) && (port != -1))
186          
187             dsock = new Socket(ip, port);
188          else throw new IOException();
189          return dsock;
190       }
191    
192       private String ftpSendCmd(String cmd)
193       throws IOException
194       { // This sends a dialog string to the server, returns reply
195       // V2.0 Updated to parse multi-string responses a la RFC 959
196       // Prints out only last response string of the lot.
197          if (pauser) // i.e. we already issued a request, and are
198                   // waiting for server to reply to it.  
199          {
200             if (dcis != null)
201             {
202                String discard = dcis.readLine(); // will block here
203                     // preventing this further client request until server
204                     // responds to the already outstanding one.
205                if (DEBUG) {
206                   System.out.println("keeping handler in sync"+
207                                     " by discarding next response: ");
208                   System.out.println(discard);
209                }
210                pauser = false;
211             }
212          }
213          pos.print(cmd + "\r\n" );
214          pos.flush(); 
215          String response = responseHandler(cmd);
216          return response;
217       }
218    
219      // new method to read multi-line responses
220      // responseHandler: takes a String command or null and returns
221      // just the last line of a possibly multi-line response
222       private String responseHandler(String cmd) 
223       throws IOException
224       { // handle more than one line returned
225          String reply = this.responseParser(dcis.readLine());
226          String numerals = reply.substring(0, 3);
227          String hyph_test = reply.substring(3, 4);
228          String next = null;
229          if(hyph_test.equals("-")) {
230             // Create "tester", marks end of multi-line output
231             String tester = numerals + " ";
232             boolean done = false;
233             while(!done) { // read lines til finds last line
234                next = dcis.readLine();
235                 // Read "over" blank line responses
236                while (next.equals("") || next.equals("  ")) {
237                   next = dcis.readLine();
238                }
239             
240                 // If next starts with "tester", we're done
241                if(next.substring(0,4).equals(tester))
242                   done = true;
243             }
244          
245             if(DEBUG)
246                if(cmd != null)
247                   System.out.println("Response to: "+cmd+" was: "+next);
248                else
249                   System.out.println("Response was: "+next);
250             return next;
251          
252          } 
253          else // "if (hyph_test.equals("-")) not true"
254             if(DEBUG)
255                if(cmd != null)
256                   System.out.println("Response to: "+cmd+" was: "+reply);
257                else
258                   System.out.println("Response was: "+reply);
259          return reply;
260       }
261    
262     // responseParser: check first digit of first line of response
263     // and take action based on it; set up to read an extra line
264     // if the response starts with "1"
265       private String responseParser(String resp)
266       throws IOException
267       { // Check first digit of resp, take appropriate action.
268          String digit1 = resp.substring(0, 1);
269          if(digit1.equals("1")) {
270             // server to act, then give response
271             if(DEBUG) System.out.println("in 1 handler");
272             // set pauser
273             pauser = true;
274             return resp;
275          }
276          else if(digit1.equals("2")) { // do usual handling
277             if(DEBUG) System.out.println("in 2 handler");
278             // reset pauser
279             pauser = false;
280             return resp;
281          }
282          else if(digit1.equals("3") || digit1.equals("4")
283                 || digit1.equals("5")) { // do usual handling
284             if(DEBUG) System.out.println("in 3-4-5 handler");
285             return resp;
286          }
287          else { // not covered, so return null
288             return null;
289          }
290       }
291    
292    
293       private void ftpLogout() {// logout, close streams
294          try { 
295             if(DEBUG) System.out.println("sending BYE");
296             pos.print("BYE" + "\r\n" );
297             pos.flush();
298             pos.close();
299             dcis.close();
300             csock.close();
301             dsock.close();
302          } 
303             catch(IOException ioe) {
304                ioe.printStackTrace();}
305       }
306    
307    
308       private static final int CNTRL_PORT = 21;
309       private Socket csock = null;
310       private Socket dsock = null;
311       private BufferedReader dcis;
312       private PrintWriter pos;
313    }
314 
315 /*this software is based on Peter van der Linden and Steve Lynch's "Linlyn" ftp
316 utility.  The "upload" and "append" routines have been removed.  It has been threaded, and this
317 particular edit makes it purely the client download end with no upload
318 capabilities.  The "Linlyn" program is readily available at Peter's site
319 (<insert link>) and is licensed under the "Artistic License".
320 */