KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcraft > jsch > ChannelSftp


1 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
2 /*
3 Copyright (c) 2002,2003,2004,2005,2006 ymnk, JCraft,Inc. All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8   1. Redistributions of source code must retain the above copyright notice,
9      this list of conditions and the following disclaimer.
10
11   2. Redistributions in binary form must reproduce the above copyright
12      notice, this list of conditions and the following disclaimer in
13      the documentation and/or other materials provided with the distribution.
14
15   3. The names of the authors may not be used to endorse or promote products
16      derived from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */

29
30 package com.jcraft.jsch;
31
32 import java.io.*;
33
34 import java.util.Vector JavaDoc;
35
36 public class ChannelSftp extends ChannelSession{
37
38   private static final byte SSH_FXP_INIT= 1;
39   private static final byte SSH_FXP_VERSION= 2;
40   private static final byte SSH_FXP_OPEN= 3;
41   private static final byte SSH_FXP_CLOSE= 4;
42   private static final byte SSH_FXP_READ= 5;
43   private static final byte SSH_FXP_WRITE= 6;
44   private static final byte SSH_FXP_LSTAT= 7;
45   private static final byte SSH_FXP_FSTAT= 8;
46   private static final byte SSH_FXP_SETSTAT= 9;
47   private static final byte SSH_FXP_FSETSTAT= 10;
48   private static final byte SSH_FXP_OPENDIR= 11;
49   private static final byte SSH_FXP_READDIR= 12;
50   private static final byte SSH_FXP_REMOVE= 13;
51   private static final byte SSH_FXP_MKDIR= 14;
52   private static final byte SSH_FXP_RMDIR= 15;
53   private static final byte SSH_FXP_REALPATH= 16;
54   private static final byte SSH_FXP_STAT= 17;
55   private static final byte SSH_FXP_RENAME= 18;
56   private static final byte SSH_FXP_READLINK= 19;
57   private static final byte SSH_FXP_SYMLINK= 20;
58   private static final byte SSH_FXP_STATUS= 101;
59   private static final byte SSH_FXP_HANDLE= 102;
60   private static final byte SSH_FXP_DATA= 103;
61   private static final byte SSH_FXP_NAME= 104;
62   private static final byte SSH_FXP_ATTRS= 105;
63   private static final byte SSH_FXP_EXTENDED= (byte)200;
64   private static final byte SSH_FXP_EXTENDED_REPLY= (byte)201;
65
66   // pflags
67
private static final int SSH_FXF_READ= 0x00000001;
68   private static final int SSH_FXF_WRITE= 0x00000002;
69   private static final int SSH_FXF_APPEND= 0x00000004;
70   private static final int SSH_FXF_CREAT= 0x00000008;
71   private static final int SSH_FXF_TRUNC= 0x00000010;
72   private static final int SSH_FXF_EXCL= 0x00000020;
73
74   private static final int SSH_FILEXFER_ATTR_SIZE= 0x00000001;
75   private static final int SSH_FILEXFER_ATTR_UIDGID= 0x00000002;
76   private static final int SSH_FILEXFER_ATTR_PERMISSIONS= 0x00000004;
77   private static final int SSH_FILEXFER_ATTR_ACMODTIME= 0x00000008;
78   private static final int SSH_FILEXFER_ATTR_EXTENDED= 0x80000000;
79
80   public static final int SSH_FX_OK= 0;
81   public static final int SSH_FX_EOF= 1;
82   public static final int SSH_FX_NO_SUCH_FILE= 2;
83   public static final int SSH_FX_PERMISSION_DENIED= 3;
84   public static final int SSH_FX_FAILURE= 4;
85   public static final int SSH_FX_BAD_MESSAGE= 5;
86   public static final int SSH_FX_NO_CONNECTION= 6;
87   public static final int SSH_FX_CONNECTION_LOST= 7;
88   public static final int SSH_FX_OP_UNSUPPORTED= 8;
89 /*
90    SSH_FX_OK
91       Indicates successful completion of the operation.
92    SSH_FX_EOF
93      indicates end-of-file condition; for SSH_FX_READ it means that no
94        more data is available in the file, and for SSH_FX_READDIR it
95       indicates that no more files are contained in the directory.
96    SSH_FX_NO_SUCH_FILE
97       is returned when a reference is made to a file which should exist
98       but doesn't.
99    SSH_FX_PERMISSION_DENIED
100       is returned when the authenticated user does not have sufficient
101       permissions to perform the operation.
102    SSH_FX_FAILURE
103       is a generic catch-all error message; it should be returned if an
104       error occurs for which there is no more specific error code
105       defined.
106    SSH_FX_BAD_MESSAGE
107       may be returned if a badly formatted packet or protocol
108       incompatibility is detected.
109    SSH_FX_NO_CONNECTION
110       is a pseudo-error which indicates that the client has no
111       connection to the server (it can only be generated locally by the
112       client, and MUST NOT be returned by servers).
113    SSH_FX_CONNECTION_LOST
114       is a pseudo-error which indicates that the connection to the
115       server has been lost (it can only be generated locally by the
116       client, and MUST NOT be returned by servers).
117    SSH_FX_OP_UNSUPPORTED
118       indicates that an attempt was made to perform an operation which
119       is not supported for the server (it may be generated locally by
120       the client if e.g. the version number exchange indicates that a
121       required feature is not supported by the server, or it may be
122       returned by the server if the server does not implement an
123       operation).
124 */

125   private static final int MAX_MSG_LENGTH = 256* 1024;
126
127   public static final int OVERWRITE=0;
128   public static final int RESUME=1;
129   public static final int APPEND=2;
130
131 // private boolean interactive=true;
132
private boolean interactive=false;
133   private int seq=1;
134   private int[] ackid=new int[1];
135   private Buffer buf;
136   private Packet packet=new Packet(buf);
137
138   private String JavaDoc version="3";
139   private int server_version=3;
140
141 /*
142 10. Changes from previous protocol versions
143   The SSH File Transfer Protocol has changed over time, before it's
144    standardization. The following is a description of the incompatible
145    changes between different versions.
146 10.1 Changes between versions 3 and 2
147    o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.
148    o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were added.
149    o The SSH_FXP_STATUS message was changed to include fields `error
150       message' and `language tag'.
151 10.2 Changes between versions 2 and 1
152    o The SSH_FXP_RENAME message was added.
153 10.3 Changes between versions 1 and 0
154    o Implementation changes, no actual protocol changes.
155 */

156
157   private static final String JavaDoc file_separator=java.io.File.separator;
158   private static final char file_separatorc=java.io.File.separatorChar;
159
160   private String JavaDoc cwd;
161   private String JavaDoc home;
162   private String JavaDoc lcwd;
163
164   public void init(){
165   }
166
167   public void start() throws JSchException{
168     try{
169
170       PipedOutputStream pos=new PipedOutputStream();
171       io.setOutputStream(pos);
172       PipedInputStream pis=new MyPipedInputStream(pos, 32*1024);
173       io.setInputStream(pis);
174
175       Request request=new RequestSftp();
176       request.request(session, this);
177
178 /*
179       System.err.println("lmpsize: "+lmpsize);
180       System.err.println("lwsize: "+lwsize);
181       System.err.println("rmpsize: "+rmpsize);
182       System.err.println("rwsize: "+rwsize);
183 */

184
185       buf=new Buffer(rmpsize);
186       packet=new Packet(buf);
187       int i=0;
188       int length;
189       int type;
190       byte[] str;
191
192       // send SSH_FXP_INIT
193
sendINIT();
194
195       // receive SSH_FXP_VERSION
196
Header header=new Header();
197       header=header(buf, header);
198       length=header.length;
199       if(length > MAX_MSG_LENGTH){
200         throw new SftpException(SSH_FX_FAILURE, "Received message is too long: " + length);
201       }
202       type=header.type; // 2 -> SSH_FXP_VERSION
203
server_version=header.rid;
204       skip(length);
205       //System.err.println("SFTP protocol server-version="+server_version);
206

207       // send SSH_FXP_REALPATH
208
sendREALPATH(".".getBytes());
209
210       // receive SSH_FXP_NAME
211
header=header(buf, header);
212       length=header.length;
213       type=header.type; // 104 -> SSH_FXP_NAME
214
buf.rewind();
215       fill(buf.buffer, 0, length);
216       i=buf.getInt(); // count
217
str=buf.getString(); // filename
218
home=cwd=new String JavaDoc(str);
219       str=buf.getString(); // logname
220
// SftpATTRS.getATTR(buf); // attrs
221

222       lcwd=new File(".").getCanonicalPath();
223     }
224     catch(Exception JavaDoc e){
225       //System.err.println(e);
226
if(e instanceof JSchException) throw (JSchException)e;
227       if(e instanceof Throwable JavaDoc)
228         throw new JSchException(e.toString(), (Throwable JavaDoc)e);
229       throw new JSchException(e.toString());
230     }
231   }
232
233   public void quit(){ disconnect();}
234   public void exit(){ disconnect();}
235   public void lcd(String JavaDoc path) throws SftpException{
236     path=localAbsolutePath(path);
237     if((new File(path)).isDirectory()){
238       try{
239     path=(new File(path)).getCanonicalPath();
240       }
241       catch(Exception JavaDoc e){}
242       lcwd=path;
243       return;
244     }
245     throw new SftpException(SSH_FX_NO_SUCH_FILE, "No such directory");
246   }
247
248   /*
249       cd /tmp
250       c->s REALPATH
251       s->c NAME
252       c->s STAT
253       s->c ATTR
254   */

255   public void cd(String JavaDoc path) throws SftpException{
256     try{
257       path=remoteAbsolutePath(path);
258       
259       Vector JavaDoc v=glob_remote(path);
260       if(v.size()!=1){
261     throw new SftpException(SSH_FX_FAILURE, v.toString());
262       }
263       path=(String JavaDoc)(v.elementAt(0));
264       sendREALPATH(path.getBytes());
265
266       Header header=new Header();
267       header=header(buf, header);
268       int length=header.length;
269       int type=header.type;
270       buf.rewind();
271       fill(buf.buffer, 0, length);
272
273       if(type!=101 && type!=104){
274     throw new SftpException(SSH_FX_FAILURE, "");
275       }
276       int i;
277       if(type==101){
278         i=buf.getInt();
279         throwStatusError(buf, i);
280       }
281       i=buf.getInt();
282       byte[] str=buf.getString();
283       if(str!=null && str[0]!='/'){
284         str=(cwd+"/"+new String JavaDoc(str)).getBytes();
285       }
286       str=buf.getString(); // logname
287
i=buf.getInt(); // attrs
288

289       String JavaDoc newpwd=new String JavaDoc(str);
290       SftpATTRS attr=_stat(newpwd);
291       if((attr.getFlags()&SftpATTRS.SSH_FILEXFER_ATTR_PERMISSIONS)==0){
292         throw new SftpException(SSH_FX_FAILURE,
293                                 "Can't change directory: "+path);
294       }
295       if(!attr.isDir()){
296         throw new SftpException(SSH_FX_FAILURE,
297                                 "Can't change directory: "+path);
298       }
299       cwd=newpwd;
300     }
301     catch(Exception JavaDoc e){
302       if(e instanceof SftpException) throw (SftpException)e;
303       if(e instanceof Throwable JavaDoc)
304         throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
305       throw new SftpException(SSH_FX_FAILURE, "");
306     }
307   }
308
309   /*
310       put foo
311       c->s OPEN
312       s->c HANDLE
313       c->s WRITE
314       s->c STATUS
315       c->s CLOSE
316       s->c STATUS
317   */

318   public void put(String JavaDoc src, String JavaDoc dst) throws SftpException{
319     put(src, dst, null, OVERWRITE);
320   }
321   public void put(String JavaDoc src, String JavaDoc dst, int mode) throws SftpException{
322     put(src, dst, null, mode);
323   }
324   public void put(String JavaDoc src, String JavaDoc dst,
325           SftpProgressMonitor monitor) throws SftpException{
326     put(src, dst, monitor, OVERWRITE);
327   }
328   public void put(String JavaDoc src, String JavaDoc dst,
329           SftpProgressMonitor monitor, int mode) throws SftpException{
330     src=localAbsolutePath(src);
331     dst=remoteAbsolutePath(dst);
332
333 //System.err.println("src: "+src+", "+dst);
334
try{
335       Vector JavaDoc v=glob_remote(dst);
336       int vsize=v.size();
337       if(vsize!=1){
338         if(vsize==0){
339           if(isPattern(dst))
340             throw new SftpException(SSH_FX_FAILURE, dst);
341           else
342             dst=Util.unquote(dst);
343         }
344         throw new SftpException(SSH_FX_FAILURE, v.toString());
345       }
346       else{
347         dst=(String JavaDoc)(v.elementAt(0));
348       }
349
350 //System.err.println("dst: "+dst);
351

352       boolean isRemoteDir=isRemoteDir(dst);
353
354       v=glob_local(src);
355 //System.err.println("glob_local: "+v+" dst="+dst);
356
vsize=v.size();
357
358       StringBuffer JavaDoc dstsb=null;
359       if(isRemoteDir){
360         if(!dst.endsWith("/")){
361         dst+="/";
362         }
363         dstsb=new StringBuffer JavaDoc(dst);
364       }
365       else if(vsize>1){
366         throw new SftpException(SSH_FX_FAILURE, "Copying multiple files, but destination is missing or a file.");
367       }
368
369       for(int j=0; j<vsize; j++){
370     String JavaDoc _src=(String JavaDoc)(v.elementAt(j));
371     String JavaDoc _dst=null;
372     if(isRemoteDir){
373       int i=_src.lastIndexOf(file_separatorc);
374       if(i==-1) dstsb.append(_src);
375       else dstsb.append(_src.substring(i + 1));
376           _dst=dstsb.toString();
377           dstsb.delete(dst.length(), _dst.length());
378     }
379         else{
380           _dst=dst;
381         }
382         //System.err.println("_dst "+_dst);
383

384     long size_of_dst=0;
385     if(mode==RESUME){
386       try{
387         SftpATTRS attr=_stat(_dst);
388         size_of_dst=attr.getSize();
389       }
390       catch(Exception JavaDoc eee){
391         //System.err.println(eee);
392
}
393       long size_of_src=new File(_src).length();
394       if(size_of_src<size_of_dst){
395         throw new SftpException(SSH_FX_FAILURE, "failed to resume for "+_dst);
396       }
397       if(size_of_src==size_of_dst){
398         return;
399       }
400     }
401
402         if(monitor!=null){
403       monitor.init(SftpProgressMonitor.PUT, _src, _dst,
404                (new File(_src)).length());
405       if(mode==RESUME){
406         monitor.count(size_of_dst);
407       }
408         }
409     FileInputStream fis=null;
410     try{
411       fis=new FileInputStream(_src);
412       _put(fis, _dst, monitor, mode);
413     }
414     finally{
415       if(fis!=null) {
416 // try{
417
fis.close();
418 // }catch(Exception ee){};
419
}
420     }
421       }
422     }
423     catch(Exception JavaDoc e){
424       if(e instanceof SftpException) throw (SftpException)e;
425       if(e instanceof Throwable JavaDoc)
426         throw new SftpException(SSH_FX_FAILURE, e.toString(), (Throwable JavaDoc)e);
427       throw new SftpException(SSH_FX_FAILURE, e.toString());
428     }
429   }
430   public void put(InputStream src, String JavaDoc dst) throws SftpException{
431     put(src, dst, null, OVERWRITE);
432   }
433   public void put(InputStream src, String JavaDoc dst, int mode) throws SftpException{
434     put(src, dst, null, mode);
435   }
436   public void put(InputStream src, String JavaDoc dst,
437           SftpProgressMonitor monitor) throws SftpException{
438     put(src, dst, monitor, OVERWRITE);
439   }
440   public void put(InputStream src, String JavaDoc dst,
441           SftpProgressMonitor monitor, int mode) throws SftpException{
442     try{
443       dst=remoteAbsolutePath(dst);
444       Vector JavaDoc v=glob_remote(dst);
445       int vsize=v.size();
446       if(vsize!=1){
447         if(vsize==0){
448           if(isPattern(dst))
449             throw new SftpException(SSH_FX_FAILURE, dst);
450           else
451             dst=Util.unquote(dst);
452         }
453         throw new SftpException(SSH_FX_FAILURE, v.toString());
454       }
455       else{
456         dst=(String JavaDoc)(v.elementAt(0));
457       }
458       if(isRemoteDir(dst)){
459         throw new SftpException(SSH_FX_FAILURE, dst+" is a directory");
460       }
461       _put(src, dst, monitor, mode);
462     }
463     catch(Exception JavaDoc e){
464       if(e instanceof SftpException) throw (SftpException)e;
465       if(e instanceof Throwable JavaDoc)
466         throw new SftpException(SSH_FX_FAILURE, e.toString(), (Throwable JavaDoc)e);
467       throw new SftpException(SSH_FX_FAILURE, e.toString());
468     }
469   }
470   public void _put(InputStream src, String JavaDoc dst,
471           SftpProgressMonitor monitor, int mode) throws SftpException{
472
473     try{
474       long skip=0;
475       if(mode==RESUME || mode==APPEND){
476     try{
477       SftpATTRS attr=_stat(dst);
478       skip=attr.getSize();
479     }
480     catch(Exception JavaDoc eee){
481       //System.err.println(eee);
482
}
483       }
484       if(mode==RESUME && skip>0){
485     long skipped=src.skip(skip);
486     if(skipped<skip){
487       throw new SftpException(SSH_FX_FAILURE, "failed to resume for "+dst);
488     }
489       }
490       if(mode==OVERWRITE){ sendOPENW(dst.getBytes()); }
491       else{ sendOPENA(dst.getBytes()); }
492
493       Header header=new Header();
494       header=header(buf, header);
495       int length=header.length;
496       int type=header.type;
497       buf.rewind();
498       fill(buf.buffer, 0, length);
499
500       if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
501     throw new SftpException(SSH_FX_FAILURE, "invalid type="+type);
502       }
503       if(type==SSH_FXP_STATUS){
504         int i=buf.getInt();
505         throwStatusError(buf, i);
506       }
507       byte[] handle=buf.getString(); // filename
508
byte[] data=null;
509
510       boolean dontcopy=true;
511
512       if(!dontcopy){
513         data=new byte[buf.buffer.length
514                       -(5+13+21+handle.length
515                         +32 +20 // padding and mac
516
)
517         ];
518       }
519
520       long offset=0;
521       if(mode==RESUME || mode==APPEND){
522     offset+=skip;
523       }
524
525       int startid=seq;
526       int _ackid=seq;
527       int ackcount=0;
528       while(true){
529         int nread=0;
530         int s=0;
531         int datalen=0;
532         int count=0;
533
534         if(!dontcopy){
535           datalen=data.length-s;
536         }
537         else{
538           data=buf.buffer;
539           s=5+13+21+handle.length;
540           datalen=buf.buffer.length -s
541             -32 -20; // padding and mac
542
}
543
544         do{
545           nread=src.read(data, s, datalen);
546           if(nread>0){
547             s+=nread;
548             datalen-=nread;
549             count+=nread;
550           }
551         }
552         while(datalen>0 && nread>0);
553         if(count<=0)break;
554
555         int _i=count;
556         while(_i>0){
557           _i-=sendWRITE(handle, offset, data, 0, _i);
558           if((seq-1)==startid ||
559              io.in.available()>=1024){
560             while(io.in.available()>0){
561               if(checkStatus(ackid, header)){
562                 _ackid=ackid[0];
563                 if(startid>_ackid || _ackid>seq-1){
564                   if(_ackid==seq){
565                     System.err.println("ack error: startid="+startid+" seq="+seq+" _ackid="+_ackid);
566                   }
567                   else{
568                     //throw new SftpException(SSH_FX_FAILURE, "ack error:");
569
throw new SftpException(SSH_FX_FAILURE, "ack error: startid="+startid+" seq="+seq+" _ackid="+_ackid);
570                   }
571                 }
572                 ackcount++;
573               }
574               else{
575                 break;
576               }
577             }
578           }
579         }
580         offset+=count;
581     if(monitor!=null && !monitor.count(count)){
582           break;
583     }
584       }
585       int _ackcount=seq-startid;
586       while(_ackcount>ackcount){
587         if(!checkStatus(null, header)){
588           break;
589         }
590         ackcount++;
591       }
592       if(monitor!=null)monitor.end();
593       _sendCLOSE(handle, header);
594 //System.err.println("start end "+startid+" "+endid);
595
}
596     catch(Exception JavaDoc e){
597       if(e instanceof SftpException) throw (SftpException)e;
598       if(e instanceof Throwable JavaDoc)
599         throw new SftpException(SSH_FX_FAILURE, e.toString(), (Throwable JavaDoc)e);
600       throw new SftpException(SSH_FX_FAILURE, e.toString());
601     }
602   }
603   /**/
604   public OutputStream put(String JavaDoc dst) throws SftpException{
605     return put(dst, (SftpProgressMonitor)null, OVERWRITE);
606   }
607   public OutputStream put(String JavaDoc dst, final int mode) throws SftpException{
608     return put(dst, (SftpProgressMonitor)null, mode);
609   }
610   public OutputStream put(String JavaDoc dst, final SftpProgressMonitor monitor, final int mode) throws SftpException{
611     return put(dst, monitor, mode, 0);
612   }
613   public OutputStream put(String JavaDoc dst, final SftpProgressMonitor monitor, final int mode, long offset) throws SftpException{
614     dst=remoteAbsolutePath(dst);
615     try{
616       Vector JavaDoc v=glob_remote(dst);
617       if(v.size()!=1){
618     throw new SftpException(SSH_FX_FAILURE, v.toString());
619       }
620       dst=(String JavaDoc)(v.elementAt(0));
621       if(isRemoteDir(dst)){
622     throw new SftpException(SSH_FX_FAILURE, dst+" is a directory");
623       }
624
625       long skip=0;
626       if(mode==RESUME || mode==APPEND){
627     try{
628       SftpATTRS attr=_stat(dst);
629       skip=attr.getSize();
630     }
631     catch(Exception JavaDoc eee){
632       //System.err.println(eee);
633
}
634       }
635
636       if(mode==OVERWRITE){ sendOPENW(dst.getBytes()); }
637       else{ sendOPENA(dst.getBytes()); }
638
639       Header header=new Header();
640       header=header(buf, header);
641       int length=header.length;
642       int type=header.type;
643       buf.rewind();
644       fill(buf.buffer, 0, length);
645
646       if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
647     throw new SftpException(SSH_FX_FAILURE, "");
648       }
649       if(type==SSH_FXP_STATUS){
650         int i=buf.getInt();
651         throwStatusError(buf, i);
652       }
653       final byte[] handle=buf.getString(); // filename
654

655       //long offset=0;
656
if(mode==RESUME || mode==APPEND){
657     offset+=skip;
658       }
659
660       final long[] _offset=new long[1];
661       _offset[0]=offset;
662       OutputStream out = new OutputStream(){
663         private boolean init=true;
664         private boolean isClosed=false;
665         private int[] ackid=new int[1];
666         private int startid=0;
667         private int _ackid=0;
668         private int ackcount=0;
669         private int writecount=0;
670         private Header header=new Header();
671
672         public void write(byte[] d) throws java.io.IOException JavaDoc{
673           write(d, 0, d.length);
674         }
675
676         public void write(byte[] d, int s, int len) throws java.io.IOException JavaDoc{
677           if(init){
678             startid=seq;
679             _ackid=seq;
680             init=false;
681           }
682
683           if(isClosed){
684             throw new IOException("stream already closed");
685           }
686
687           try{
688             int _len=len;
689             while(_len>0){
690               int sent=sendWRITE(handle, _offset[0], d, s, _len);
691               writecount++;
692               _offset[0]+=sent;
693               s+=sent;
694               _len-=sent;
695               if((seq-1)==startid ||
696                  io.in.available()>=1024){
697                 while(io.in.available()>0){
698                   if(checkStatus(ackid, header)){
699                     _ackid=ackid[0];
700                     if(startid>_ackid || _ackid>seq-1){
701                       throw new SftpException(SSH_FX_FAILURE, "");
702                     }
703                     ackcount++;
704                   }
705                   else{
706                     break;
707                   }
708                 }
709               }
710             }
711             if(monitor!=null && !monitor.count(len)){
712               close();
713               throw new IOException("canceled");
714         }
715           }
716           catch(IOException e){ throw e; }
717           catch(Exception JavaDoc e){ throw new IOException(e.toString()); }
718         }
719
720         byte[] _data=new byte[1];
721         public void write(int foo) throws java.io.IOException JavaDoc{
722           _data[0]=(byte)foo;
723           write(_data, 0, 1);
724         }
725
726         public void flush() throws java.io.IOException JavaDoc{
727
728           if(isClosed){
729             throw new IOException("stream already closed");
730           }
731
732           if(!init){
733             try{
734               while(writecount>ackcount){
735                 if(!checkStatus(null, header)){
736                   break;
737                 }
738                 ackcount++;
739               }
740             }
741             catch(SftpException e){
742               throw new IOException(e.toString());
743             }
744           }
745         }
746
747         public void close() throws java.io.IOException JavaDoc{
748           if(isClosed){
749             return;
750           }
751           flush();
752           if(monitor!=null)monitor.end();
753           try{ _sendCLOSE(handle, header); }
754           catch(IOException e){ throw e; }
755           catch(Exception JavaDoc e){
756             throw new IOException(e.toString());
757           }
758           isClosed=true;
759         }
760       };
761       return out;
762     }
763     catch(Exception JavaDoc e){
764       if(e instanceof SftpException) throw (SftpException)e;
765       if(e instanceof Throwable JavaDoc)
766         throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
767       throw new SftpException(SSH_FX_FAILURE, "");
768     }
769   }
770
771   /**/
772   public void get(String JavaDoc src, String JavaDoc dst) throws SftpException{
773     get(src, dst, null, OVERWRITE);
774   }
775   public void get(String JavaDoc src, String JavaDoc dst,
776           SftpProgressMonitor monitor) throws SftpException{
777     get(src, dst, monitor, OVERWRITE);
778   }
779   public void get(String JavaDoc src, String JavaDoc dst,
780           SftpProgressMonitor monitor, int mode) throws SftpException{
781     src=remoteAbsolutePath(src);
782     dst=localAbsolutePath(dst);
783     try{
784       Vector JavaDoc v=glob_remote(src);
785       int vsize=v.size();
786       if(vsize==0){
787         throw new SftpException(SSH_FX_NO_SUCH_FILE, "No such file");
788       }
789
790       File dstFile=new File(dst);
791       boolean isDstDir=dstFile.isDirectory();
792       StringBuffer JavaDoc dstsb=null;
793       if(isDstDir){
794         if(!dst.endsWith(file_separator)){
795           dst+=file_separator;
796         }
797         dstsb=new StringBuffer JavaDoc(dst);
798       }
799       else if(vsize>1){
800         throw new SftpException(SSH_FX_FAILURE, "Copying multiple files, but destination is missing or a file.");
801       }
802
803       for(int j=0; j<vsize; j++){
804     String JavaDoc _src=(String JavaDoc)(v.elementAt(j));
805
806     SftpATTRS attr=_stat(_src);
807         if(attr.isDir()){
808           throw new SftpException(SSH_FX_FAILURE, "not supported to get directory "+_src);
809         }
810
811     String JavaDoc _dst=null;
812     if(isDstDir){
813       int i=_src.lastIndexOf('/');
814       if(i==-1) dstsb.append(_src);
815       else dstsb.append(_src.substring(i + 1));
816           _dst=dstsb.toString();
817           dstsb.delete(dst.length(), _dst.length());
818     }
819         else{
820           _dst=dst;
821         }
822
823     if(mode==RESUME){
824       long size_of_src=attr.getSize();
825       long size_of_dst=new File(_dst).length();
826       if(size_of_dst>size_of_src){
827         throw new SftpException(SSH_FX_FAILURE, "failed to resume for "+_dst);
828       }
829       if(size_of_dst==size_of_src){
830         return;
831       }
832     }
833
834     if(monitor!=null){
835       monitor.init(SftpProgressMonitor.GET, _src, _dst, attr.getSize());
836       if(mode==RESUME){
837         monitor.count(new File(_dst).length());
838       }
839     }
840     FileOutputStream fos=null;
841     if(mode==OVERWRITE){
842       fos=new FileOutputStream(_dst);
843     }
844     else{
845       fos=new FileOutputStream(_dst, true); // append
846
}
847
848 //System.err.println("_get: "+_src+", "+_dst);
849
_get(_src, fos, monitor, mode, new File(_dst).length());
850     fos.close();
851       }
852     }
853     catch(Exception JavaDoc e){
854       if(e instanceof SftpException) throw (SftpException)e;
855       if(e instanceof Throwable JavaDoc)
856         throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
857       throw new SftpException(SSH_FX_FAILURE, "");
858     }
859   }
860   public void get(String JavaDoc src, OutputStream dst) throws SftpException{
861     get(src, dst, null, OVERWRITE, 0);
862   }
863   public void get(String JavaDoc src, OutputStream dst,
864           SftpProgressMonitor monitor) throws SftpException{
865     get(src, dst, monitor, OVERWRITE, 0);
866   }
867   public void get(String JavaDoc src, OutputStream dst,
868            SftpProgressMonitor monitor, int mode, long skip) throws SftpException{
869 //System.err.println("get: "+src+", "+dst);
870
try{
871       src=remoteAbsolutePath(src);
872       Vector JavaDoc v=glob_remote(src);
873       if(v.size()!=1){
874         throw new SftpException(SSH_FX_FAILURE, v.toString());
875       }
876       src=(String JavaDoc)(v.elementAt(0));
877
878       if(monitor!=null){
879     SftpATTRS attr=_stat(src);
880         monitor.init(SftpProgressMonitor.GET, src, "??", attr.getSize());
881         if(mode==RESUME){
882           monitor.count(skip);
883         }
884       }
885       _get(src, dst, monitor, mode, skip);
886     }
887     catch(Exception JavaDoc e){
888       if(e instanceof SftpException) throw (SftpException)e;
889       if(e instanceof Throwable JavaDoc)
890         throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
891       throw new SftpException(SSH_FX_FAILURE, "");
892     }
893   }
894   private void _get(String JavaDoc src, OutputStream dst,
895                     SftpProgressMonitor monitor, int mode, long skip) throws SftpException{
896 //System.err.println("_get: "+src+", "+dst);
897
try{
898       sendOPENR(src.getBytes());
899
900       Header header=new Header();
901       header=header(buf, header);
902       int length=header.length;
903       int type=header.type;
904       buf.rewind();
905       fill(buf.buffer, 0, length);
906
907       if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
908     throw new SftpException(SSH_FX_FAILURE, "");
909       }
910       if(type==SSH_FXP_STATUS){
911         int i=buf.getInt();
912         throwStatusError(buf, i);
913       }
914
915       byte[] handle=buf.getString(); // filename
916

917       long offset=0;
918       if(mode==RESUME){
919     offset+=skip;
920       }
921
922       int request_len=0;
923       loop:
924       while(true){
925
926         request_len=buf.buffer.length-13;
927         if(server_version==0){ request_len=1024; }
928         sendREAD(handle, offset, request_len);
929
930         header=header(buf, header);
931         length=header.length;
932         type=header.type;
933
934         if(type==SSH_FXP_STATUS){
935           buf.rewind();
936           fill(buf.buffer, 0, length);
937           int i=buf.getInt();
938           if(i==SSH_FX_EOF){
939             break loop;
940           }
941           throwStatusError(buf, i);
942         }
943
944         if(type!=SSH_FXP_DATA){
945       break loop;
946         }
947
948         buf.rewind();
949         fill(buf.buffer, 0, 4); length-=4;
950         int i=buf.getInt(); // length of data
951
int foo=i;
952
953         while(foo>0){
954           int bar=foo;
955           if(bar>buf.buffer.length){
956             bar=buf.buffer.length;
957           }
958           i=io.in.read(buf.buffer, 0, bar);
959           if(i<0){
960             break loop;
961       }
962           int data_len=i;
963           dst.write(buf.buffer, 0, data_len);
964
965           offset+=data_len;
966           foo-=data_len;
967
968           if(monitor!=null){
969             if(!monitor.count(data_len)){
970               while(foo>0){
971                 i=io.in.read(buf.buffer,
972                              0,
973                              (buf.buffer.length<foo?buf.buffer.length:foo));
974                 if(i<=0) break;
975                 foo-=i;
976               }
977               break loop;
978             }
979           }
980
981         }
982     //System.err.println("length: "+length); // length should be 0
983
}
984       dst.flush();
985
986       if(monitor!=null)monitor.end();
987       _sendCLOSE(handle, header);
988     }
989     catch(Exception JavaDoc e){
990       if(e instanceof SftpException) throw (SftpException)e;
991       if(e instanceof Throwable JavaDoc)
992         throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
993       throw new SftpException(SSH_FX_FAILURE, "");
994     }
995   }
996
997   public InputStream get(String JavaDoc src) throws SftpException{
998     return get(src, null, OVERWRITE);
999   }
1000  public InputStream get(String JavaDoc src, SftpProgressMonitor monitor) throws SftpException{
1001    return get(src, monitor, OVERWRITE);
1002  }
1003  public InputStream get(String JavaDoc src, int mode) throws SftpException{
1004    return get(src, null, mode);
1005  }
1006  public InputStream get(String JavaDoc src, final SftpProgressMonitor monitor, final int mode) throws SftpException{
1007    if(mode==RESUME){
1008      throw new SftpException(SSH_FX_FAILURE, "faile to resume from "+src);
1009    }
1010    src=remoteAbsolutePath(src);
1011    try{
1012      Vector JavaDoc v=glob_remote(src);
1013      if(v.size()!=1){
1014        throw new SftpException(SSH_FX_FAILURE, v.toString());
1015      }
1016      src=(String JavaDoc)(v.elementAt(0));
1017
1018      SftpATTRS attr=_stat(src);
1019      if(monitor!=null){
1020        monitor.init(SftpProgressMonitor.GET, src, "??", attr.getSize());
1021      }
1022
1023      sendOPENR(src.getBytes());
1024
1025      Header header=new Header();
1026      header=header(buf, header);
1027      int length=header.length;
1028      int type=header.type;
1029      buf.rewind();
1030      fill(buf.buffer, 0, length);
1031
1032      if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
1033    throw new SftpException(SSH_FX_FAILURE, "");
1034      }
1035      if(type==SSH_FXP_STATUS){
1036        int i=buf.getInt();
1037        throwStatusError(buf, i);
1038      }
1039
1040      final byte[] handle=buf.getString(); // filename
1041

1042      java.io.InputStream JavaDoc in=new java.io.InputStream JavaDoc(){
1043           long offset=0;
1044           boolean closed=false;
1045           int rest_length=0;
1046           byte[] _data=new byte[1];
1047           byte[] rest_byte=new byte[1024];
1048           Header header=new Header();
1049
1050           public int read() throws java.io.IOException JavaDoc{
1051             if(closed)return -1;
1052             int i=read(_data, 0, 1);
1053             if (i==-1) { return -1; }
1054             else {
1055               return _data[0]&0xff;
1056             }
1057           }
1058           public int read(byte[] d) throws java.io.IOException JavaDoc{
1059             if(closed)return -1;
1060             return read(d, 0, d.length);
1061           }
1062           public int read(byte[] d, int s, int len) throws java.io.IOException JavaDoc{
1063             if(closed)return -1;
1064             if(d==null){throw new NullPointerException JavaDoc();}
1065             if(s<0 || len <0 || s+len>d.length){
1066               throw new IndexOutOfBoundsException JavaDoc();
1067             }
1068             if(len==0){ return 0; }
1069
1070             if(rest_length>0){
1071               int foo=rest_length;
1072               if(foo>len) foo=len;
1073               System.arraycopy(rest_byte, 0, d, s, foo);
1074               if(foo!=rest_length){
1075                 System.arraycopy(rest_byte, foo,
1076                                  rest_byte, 0, rest_length-foo);
1077               }
1078
1079               if(monitor!=null){
1080                 if(!monitor.count(foo)){
1081                   close();
1082                   return -1;
1083                 }
1084               }
1085
1086               rest_length-=foo;
1087               return foo;
1088             }
1089
1090             if(buf.buffer.length-13<len){
1091               len=buf.buffer.length-13;
1092             }
1093             if(server_version==0 && len>1024){
1094               len=1024;
1095             }
1096
1097             try{sendREAD(handle, offset, len);}
1098             catch(Exception JavaDoc e){ throw new IOException("error"); }
1099
1100             header=header(buf, header);
1101             rest_length=header.length;
1102             int type=header.type;
1103             int id=header.rid;
1104
1105             if(type!=SSH_FXP_STATUS && type!=SSH_FXP_DATA){
1106               throw new IOException("error");
1107             }
1108             if(type==SSH_FXP_STATUS){
1109               buf.rewind();
1110               fill(buf.buffer, 0, rest_length);
1111               int i=buf.getInt();
1112               rest_length=0;
1113               if(i==SSH_FX_EOF){
1114                 close();
1115                 return -1;
1116               }
1117               //throwStatusError(buf, i);
1118
throw new IOException("error");
1119             }
1120             buf.rewind();
1121             fill(buf.buffer, 0, 4);
1122             int i=buf.getInt(); rest_length-=4;
1123
1124             offset+=rest_length;
1125             int foo=i;
1126             if(foo>0){
1127               int bar=rest_length;
1128               if(bar>len){
1129                 bar=len;
1130               }
1131               i=io.in.read(d, s, bar);
1132               if(i<0){
1133                 return -1;
1134               }
1135               rest_length-=i;
1136
1137               if(rest_length>0){
1138                 if(rest_byte.length<rest_length){
1139                   rest_byte=new byte[rest_length];
1140                 }
1141                 int _s=0;
1142                 int _len=rest_length;
1143                 int j;
1144                 while(_len>0){
1145                   j=io.in.read(rest_byte, _s, _len);
1146                   if(j<=0)break;
1147                   _s+=j;
1148                   _len-=j;
1149                 }
1150               }
1151
1152               if(monitor!=null){
1153                 if(!monitor.count(i)){
1154                   close();
1155                   return -1;
1156                 }
1157               }
1158
1159               return i;
1160             }
1161             return 0; // ??
1162
}
1163           public void close() throws IOException{
1164             if(closed)return;
1165             closed=true;
1166             /*
1167             while(rest_length>0){
1168               int foo=rest_length;
1169               if(foo>buf.buffer.length){
1170                 foo=buf.buffer.length;
1171               }
1172               io.in.read(buf.buffer, 0, foo);
1173               rest_length-=foo;
1174             }
1175             */

1176             if(monitor!=null)monitor.end();
1177             try{_sendCLOSE(handle, header);}
1178             catch(Exception JavaDoc e){throw new IOException("error");}
1179           }
1180         };
1181       return in;
1182     }
1183     catch(Exception JavaDoc e){
1184       if(e instanceof SftpException) throw (SftpException)e;
1185       if(e instanceof Throwable JavaDoc)
1186         throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1187       throw new SftpException(SSH_FX_FAILURE, "");
1188     }
1189   }
1190
1191   public java.util.Vector JavaDoc ls(String JavaDoc path) throws SftpException{
1192     try{
1193       path=remoteAbsolutePath(path);
1194
1195       String JavaDoc dir=path;
1196       byte[] pattern=null;
1197       SftpATTRS attr=null;
1198       if(isPattern(dir) ||
1199         ((attr=stat(dir))!=null && !attr.isDir())){
1200         int foo=path.lastIndexOf('/');
1201         dir=path.substring(0, ((foo==0)?1:foo));
1202         pattern=path.substring(foo+1).getBytes();
1203       }
1204
1205       sendOPENDIR(dir.getBytes());
1206
1207       Header header=new Header();
1208       header=header(buf, header);
1209       int length=header.length;
1210       int type=header.type;
1211       buf.rewind();
1212       fill(buf.buffer, 0, length);
1213
1214       if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
1215         throw new SftpException(SSH_FX_FAILURE, "");
1216       }
1217       if(type==SSH_FXP_STATUS){
1218         int i=buf.getInt();
1219         throwStatusError(buf, i);
1220       }
1221
1222       byte[] handle=buf.getString(); // filename
1223

1224       java.util.Vector JavaDoc v=new java.util.Vector JavaDoc();
1225       while(true){
1226         sendREADDIR(handle);
1227
1228         header=header(buf, header);
1229         length=header.length;
1230         type=header.type;
1231         if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){
1232           throw new SftpException(SSH_FX_FAILURE, "");
1233         }
1234         if(type==SSH_FXP_STATUS){
1235           buf.rewind();
1236           fill(buf.buffer, 0, length);
1237           int i=buf.getInt();
1238           if(i==SSH_FX_EOF)
1239             break;
1240           throwStatusError(buf, i);
1241         }
1242
1243         buf.rewind();
1244         fill(buf.buffer, 0, 4); length-=4;
1245         int count=buf.getInt();
1246
1247         byte[] str;
1248         int flags;
1249
1250         buf.reset();
1251         while(count>0){
1252           if(length>0){
1253             buf.shift();
1254             int j=(buf.buffer.length>(buf.index+length)) ? length : (buf.buffer.length-buf.index);
1255             int i=fill(buf.buffer, buf.index, j);
1256             buf.index+=i;
1257             length-=i;
1258           }
1259           byte[] filename=buf.getString();
1260           str=buf.getString();
1261           String JavaDoc longname=new String JavaDoc(str);
1262
1263           SftpATTRS attrs=SftpATTRS.getATTR(buf);
1264           if(pattern==null || Util.glob(pattern, filename)){
1265             v.addElement(new LsEntry(new String JavaDoc(filename), longname, attrs));
1266           }
1267
1268           count--;
1269         }
1270       }
1271       _sendCLOSE(handle, header);
1272       return v;
1273     }
1274     catch(Exception JavaDoc e){
1275       if(e instanceof SftpException) throw (SftpException)e;
1276       if(e instanceof Throwable JavaDoc)
1277         throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1278       throw new SftpException(SSH_FX_FAILURE, "");
1279     }
1280   }
1281   public String JavaDoc readlink(String JavaDoc path) throws SftpException{
1282     try{
1283       path=remoteAbsolutePath(path);
1284       Vector JavaDoc v=glob_remote(path);
1285       if(v.size()!=1){
1286         throw new SftpException(SSH_FX_FAILURE, v.toString());
1287       }
1288       path=(String JavaDoc)(v.elementAt(0));
1289
1290       sendREADLINK(path.getBytes());
1291
1292       Header header=new Header();
1293       header=header(buf, header);
1294       int length=header.length;
1295       int type=header.type;
1296       buf.rewind();
1297       fill(buf.buffer, 0, length);
1298
1299       if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){
1300         throw new SftpException(SSH_FX_FAILURE, "");
1301       }
1302       if(type==SSH_FXP_NAME){
1303         int count=buf.getInt(); // count
1304
byte[] filename=null;
1305         byte[] longname=null;
1306         for(int i=0; i<count; i++){
1307           filename=buf.getString();
1308           longname=buf.getString();
1309           SftpATTRS.getATTR(buf);
1310         }
1311         return new String JavaDoc(filename);
1312       }
1313
1314       int i=buf.getInt();
1315       throwStatusError(buf, i);
1316     }
1317     catch(Exception JavaDoc e){
1318       if(e instanceof SftpException) throw (SftpException)e;
1319       if(e instanceof Throwable JavaDoc)
1320         throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1321       throw new SftpException(SSH_FX_FAILURE, "");
1322     }
1323     return null;
1324   }
1325   public void symlink(String JavaDoc oldpath, String JavaDoc newpath) throws SftpException{
1326     if(server_version<3){
1327       throw new SftpException(SSH_FX_FAILURE,
1328                               "The remote sshd is too old to support symlink operation.");
1329     }
1330
1331     try{
1332       oldpath=remoteAbsolutePath(oldpath);
1333       newpath=remoteAbsolutePath(newpath);
1334
1335       Vector JavaDoc v=glob_remote(oldpath);
1336       int vsize=v.size();
1337       if(vsize!=1){
1338         throw new SftpException(SSH_FX_FAILURE, v.toString());
1339       }
1340       oldpath=(String JavaDoc)(v.elementAt(0));
1341
1342       if(isPattern(newpath)){
1343         throw new SftpException(SSH_FX_FAILURE, v.toString());
1344       }
1345
1346       newpath=Util.unquote(newpath);
1347
1348       sendSYMLINK(oldpath.getBytes(), newpath.getBytes());
1349
1350       Header header=new Header();
1351       header=header(buf, header);
1352       int length=header.length;
1353       int type=header.type;
1354       buf.rewind();
1355       fill(buf.buffer, 0, length);
1356
1357       if(type!=SSH_FXP_STATUS){
1358         throw new SftpException(SSH_FX_FAILURE, "");
1359       }
1360
1361       int i=buf.getInt();
1362       if(i==SSH_FX_OK) return;
1363       throwStatusError(buf, i);
1364     }
1365     catch(Exception JavaDoc e){
1366       if(e instanceof SftpException) throw (SftpException)e;
1367       if(e instanceof Throwable JavaDoc)
1368         throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1369       throw new SftpException(SSH_FX_FAILURE, "");
1370     }
1371   }
1372   public void rename(String JavaDoc oldpath, String JavaDoc newpath) throws SftpException{
1373     if(server_version<2){
1374       throw new SftpException(SSH_FX_FAILURE,
1375                               "The remote sshd is too old to support rename operation.");
1376     }
1377     try{
1378       oldpath=remoteAbsolutePath(oldpath);
1379       newpath=remoteAbsolutePath(newpath);
1380
1381       Vector JavaDoc v=glob_remote(oldpath);
1382       int vsize=v.size();
1383       if(vsize!=1){
1384         throw new SftpException(SSH_FX_FAILURE, v.toString());
1385       }
1386       oldpath=(String JavaDoc)(v.elementAt(0));
1387
1388       v=glob_remote(newpath);
1389       vsize=v.size();
1390       if(vsize>=2){
1391         throw new SftpException(SSH_FX_FAILURE, v.toString());
1392       }
1393       if(vsize==1){
1394         newpath=(String JavaDoc)(v.elementAt(0));
1395       }
1396       else{ // vsize==0
1397
if(isPattern(newpath))
1398           throw new SftpException(SSH_FX_FAILURE, newpath);
1399         newpath=Util.unquote(newpath);
1400       }
1401
1402       sendRENAME(oldpath.getBytes(), newpath.getBytes());
1403
1404       Header header=new Header();
1405       header=header(buf, header);
1406       int length=header.length;
1407       int type=header.type;
1408       buf.rewind();
1409       fill(buf.buffer, 0, length);
1410
1411       if(type!=SSH_FXP_STATUS){
1412         throw new SftpException(SSH_FX_FAILURE, "");
1413       }
1414
1415       int i=buf.getInt();
1416       if(i==SSH_FX_OK) return;
1417       throwStatusError(buf, i);
1418    }
1419    catch(Exception JavaDoc e){
1420      if(e instanceof SftpException) throw (SftpException)e;
1421      if(e instanceof Throwable JavaDoc)
1422        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1423      throw new SftpException(SSH_FX_FAILURE, "");
1424    }
1425  }
1426  public void rm(String JavaDoc path) throws SftpException{
1427    try{
1428      path=remoteAbsolutePath(path);
1429      Vector JavaDoc v=glob_remote(path);
1430      int vsize=v.size();
1431      Header header=new Header();
1432
1433      for(int j=0; j<vsize; j++){
1434    path=(String JavaDoc)(v.elementAt(j));
1435        sendREMOVE(path.getBytes());
1436
1437        header=header(buf, header);
1438        int length=header.length;
1439        int type=header.type;
1440        buf.rewind();
1441        fill(buf.buffer, 0, length);
1442
1443        if(type!=SSH_FXP_STATUS){
1444      throw new SftpException(SSH_FX_FAILURE, "");
1445        }
1446        int i=buf.getInt();
1447    if(i!=SSH_FX_OK){
1448      throwStatusError(buf, i);
1449    }
1450      }
1451    }
1452    catch(Exception JavaDoc e){
1453      if(e instanceof SftpException) throw (SftpException)e;
1454      if(e instanceof Throwable JavaDoc)
1455        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1456      throw new SftpException(SSH_FX_FAILURE, "");
1457    }
1458  }
1459  private boolean isRemoteDir(String JavaDoc path){
1460    try{
1461      sendSTAT(path.getBytes());
1462
1463      Header header=new Header();
1464      header=header(buf, header);
1465      int length=header.length;
1466      int type=header.type;
1467      buf.rewind();
1468      fill(buf.buffer, 0, length);
1469
1470      if(type!=SSH_FXP_ATTRS){
1471        return false;
1472      }
1473      SftpATTRS attr=SftpATTRS.getATTR(buf);
1474      return attr.isDir();
1475    }
1476    catch(Exception JavaDoc e){}
1477    return false;
1478  }
1479  /*
1480  boolean isRemoteDir(String path) throws SftpException{
1481    SftpATTRS attr=stat(path);
1482    return attr.isDir();
1483  }
1484  */

1485  public void chgrp(int gid, String JavaDoc path) throws SftpException{
1486    try{
1487      path=remoteAbsolutePath(path);
1488
1489      Vector JavaDoc v=glob_remote(path);
1490      int vsize=v.size();
1491      for(int j=0; j<vsize; j++){
1492    path=(String JavaDoc)(v.elementAt(j));
1493
1494        SftpATTRS attr=_stat(path);
1495
1496    attr.setFLAGS(0);
1497    attr.setUIDGID(attr.uid, gid);
1498    _setStat(path, attr);
1499      }
1500    }
1501    catch(Exception JavaDoc e){
1502      if(e instanceof SftpException) throw (SftpException)e;
1503      if(e instanceof Throwable JavaDoc)
1504        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1505      throw new SftpException(SSH_FX_FAILURE, "");
1506    }
1507  }
1508  public void chown(int uid, String JavaDoc path) throws SftpException{
1509    try{
1510      path=remoteAbsolutePath(path);
1511
1512      Vector JavaDoc v=glob_remote(path);
1513      int vsize=v.size();
1514      for(int j=0; j<vsize; j++){
1515    path=(String JavaDoc)(v.elementAt(j));
1516
1517        SftpATTRS attr=_stat(path);
1518
1519    attr.setFLAGS(0);
1520    attr.setUIDGID(uid, attr.gid);
1521    _setStat(path, attr);
1522      }
1523    }
1524    catch(Exception JavaDoc e){
1525      if(e instanceof SftpException) throw (SftpException)e;
1526      if(e instanceof Throwable JavaDoc)
1527        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1528      throw new SftpException(SSH_FX_FAILURE, "");
1529    }
1530  }
1531  public void chmod(int permissions, String JavaDoc path) throws SftpException{
1532    try{
1533      path=remoteAbsolutePath(path);
1534
1535      Vector JavaDoc v=glob_remote(path);
1536      int vsize=v.size();
1537      for(int j=0; j<vsize; j++){
1538    path=(String JavaDoc)(v.elementAt(j));
1539
1540    SftpATTRS attr=_stat(path);
1541
1542    attr.setFLAGS(0);
1543    attr.setPERMISSIONS(permissions);
1544    _setStat(path, attr);
1545      }
1546    }
1547    catch(Exception JavaDoc e){
1548      if(e instanceof SftpException) throw (SftpException)e;
1549      if(e instanceof Throwable JavaDoc)
1550        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1551      throw new SftpException(SSH_FX_FAILURE, "");
1552    }
1553  }
1554  public void setMtime(String JavaDoc path, int mtime) throws SftpException{
1555    try{
1556      path=remoteAbsolutePath(path);
1557
1558      Vector JavaDoc v=glob_remote(path);
1559      int vsize=v.size();
1560      for(int j=0; j<vsize; j++){
1561    path=(String JavaDoc)(v.elementAt(j));
1562
1563        SftpATTRS attr=_stat(path);
1564
1565    attr.setFLAGS(0);
1566    attr.setACMODTIME(attr.getATime(), mtime);
1567    _setStat(path, attr);
1568      }
1569    }
1570    catch(Exception JavaDoc e){
1571      if(e instanceof SftpException) throw (SftpException)e;
1572      if(e instanceof Throwable JavaDoc)
1573        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1574      throw new SftpException(SSH_FX_FAILURE, "");
1575    }
1576  }
1577  public void rmdir(String JavaDoc path) throws SftpException{
1578    try{
1579      path=remoteAbsolutePath(path);
1580
1581      Vector JavaDoc v=glob_remote(path);
1582      int vsize=v.size();
1583      Header header=new Header();
1584
1585      for(int j=0; j<vsize; j++){
1586    path=(String JavaDoc)(v.elementAt(j));
1587    sendRMDIR(path.getBytes());
1588
1589        header=header(buf, header);
1590        int length=header.length;
1591        int type=header.type;
1592        buf.rewind();
1593        fill(buf.buffer, 0, length);
1594
1595    if(type!=SSH_FXP_STATUS){
1596      throw new SftpException(SSH_FX_FAILURE, "");
1597    }
1598
1599    int i=buf.getInt();
1600    if(i!=SSH_FX_OK){
1601      throwStatusError(buf, i);
1602    }
1603      }
1604    }
1605    catch(Exception JavaDoc e){
1606      if(e instanceof SftpException) throw (SftpException)e;
1607      if(e instanceof Throwable JavaDoc)
1608        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1609      throw new SftpException(SSH_FX_FAILURE, "");
1610    }
1611  }
1612
1613  public void mkdir(String JavaDoc path) throws SftpException{
1614    try{
1615      path=remoteAbsolutePath(path);
1616
1617      sendMKDIR(path.getBytes(), null);
1618
1619      Header header=new Header();
1620      header=header(buf, header);
1621      int length=header.length;
1622      int type=header.type;
1623      buf.rewind();
1624      fill(buf.buffer, 0, length);
1625
1626      if(type!=SSH_FXP_STATUS){
1627    throw new SftpException(SSH_FX_FAILURE, "");
1628      }
1629
1630      int i=buf.getInt();
1631      if(i==SSH_FX_OK) return;
1632      throwStatusError(buf, i);
1633    }
1634    catch(Exception JavaDoc e){
1635      if(e instanceof SftpException) throw (SftpException)e;
1636      if(e instanceof Throwable JavaDoc)
1637        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1638      throw new SftpException(SSH_FX_FAILURE, "");
1639    }
1640  }
1641
1642  public SftpATTRS stat(String JavaDoc path) throws SftpException{
1643    try{
1644      path=remoteAbsolutePath(path);
1645
1646      Vector JavaDoc v=glob_remote(path);
1647      if(v.size()!=1){
1648    throw new SftpException(SSH_FX_FAILURE, v.toString());
1649      }
1650      path=(String JavaDoc)(v.elementAt(0));
1651      return _stat(path);
1652    }
1653    catch(Exception JavaDoc e){
1654      if(e instanceof SftpException) throw (SftpException)e;
1655      if(e instanceof Throwable JavaDoc)
1656        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1657      throw new SftpException(SSH_FX_FAILURE, "");
1658    }
1659    //return null;
1660
}
1661
1662  private SftpATTRS _stat(String JavaDoc path) throws SftpException{
1663    try{
1664      sendSTAT(path.getBytes());
1665
1666      Header header=new Header();
1667      header=header(buf, header);
1668      int length=header.length;
1669      int type=header.type;
1670      buf.rewind();
1671      fill(buf.buffer, 0, length);
1672
1673      if(type!=SSH_FXP_ATTRS){
1674    if(type==SSH_FXP_STATUS){
1675      int i=buf.getInt();
1676      throwStatusError(buf, i);
1677    }
1678    throw new SftpException(SSH_FX_FAILURE, "");
1679      }
1680      SftpATTRS attr=SftpATTRS.getATTR(buf);
1681      return attr;
1682    }
1683    catch(Exception JavaDoc e){
1684      if(e instanceof SftpException) throw (SftpException)e;
1685      if(e instanceof Throwable JavaDoc)
1686        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1687      throw new SftpException(SSH_FX_FAILURE, "");
1688    }
1689    //return null;
1690
}
1691
1692  public SftpATTRS lstat(String JavaDoc path) throws SftpException{
1693    try{
1694      path=remoteAbsolutePath(path);
1695
1696      Vector JavaDoc v=glob_remote(path);
1697      if(v.size()!=1){
1698    throw new SftpException(SSH_FX_FAILURE, v.toString());
1699      }
1700      path=(String JavaDoc)(v.elementAt(0));
1701
1702      return _lstat(path);
1703    }
1704    catch(Exception JavaDoc e){
1705      if(e instanceof SftpException) throw (SftpException)e;
1706      if(e instanceof Throwable JavaDoc)
1707        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1708      throw new SftpException(SSH_FX_FAILURE, "");
1709    }
1710  }
1711
1712  private SftpATTRS _lstat(String JavaDoc path) throws SftpException{
1713    try{
1714      sendLSTAT(path.getBytes());
1715
1716      Header header=new Header();
1717      header=header(buf, header);
1718      int length=header.length;
1719      int type=header.type;
1720      buf.rewind();
1721      fill(buf.buffer, 0, length);
1722
1723      if(type!=SSH_FXP_ATTRS){
1724    if(type==SSH_FXP_STATUS){
1725      int i=buf.getInt();
1726      throwStatusError(buf, i);
1727    }
1728    throw new SftpException(SSH_FX_FAILURE, "");
1729      }
1730      SftpATTRS attr=SftpATTRS.getATTR(buf);
1731      return attr;
1732    }
1733    catch(Exception JavaDoc e){
1734      if(e instanceof SftpException) throw (SftpException)e;
1735      if(e instanceof Throwable JavaDoc)
1736        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1737      throw new SftpException(SSH_FX_FAILURE, "");
1738    }
1739  }
1740
1741  public void setStat(String JavaDoc path, SftpATTRS attr) throws SftpException{
1742    try{
1743      path=remoteAbsolutePath(path);
1744
1745      Vector JavaDoc v=glob_remote(path);
1746      int vsize=v.size();
1747      for(int j=0; j<vsize; j++){
1748    path=(String JavaDoc)(v.elementAt(j));
1749    _setStat(path, attr);
1750      }
1751    }
1752    catch(Exception JavaDoc e){
1753      if(e instanceof SftpException) throw (SftpException)e;
1754      if(e instanceof Throwable JavaDoc)
1755        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1756      throw new SftpException(SSH_FX_FAILURE, "");
1757    }
1758  }
1759  private void _setStat(String JavaDoc path, SftpATTRS attr) throws SftpException{
1760    try{
1761      sendSETSTAT(path.getBytes(), attr);
1762
1763      Header header=new Header();
1764      header=header(buf, header);
1765      int length=header.length;
1766      int type=header.type;
1767      buf.rewind();
1768      fill(buf.buffer, 0, length);
1769
1770      if(type!=SSH_FXP_STATUS){
1771    throw new SftpException(SSH_FX_FAILURE, "");
1772      }
1773      int i=buf.getInt();
1774      if(i!=SSH_FX_OK){
1775    throwStatusError(buf, i);
1776      }
1777    }
1778    catch(Exception JavaDoc e){
1779      if(e instanceof SftpException) throw (SftpException)e;
1780      if(e instanceof Throwable JavaDoc)
1781        throw new SftpException(SSH_FX_FAILURE, "", (Throwable JavaDoc)e);
1782      throw new SftpException(SSH_FX_FAILURE, "");
1783    }
1784  }
1785
1786  public String JavaDoc pwd(){ return cwd; }
1787  public String JavaDoc lpwd(){ return lcwd; }
1788  public String JavaDoc version(){ return version; }
1789  public String JavaDoc getHome(){ return home; }
1790
1791  private void read(byte[] buf, int s, int l) throws IOException, SftpException{
1792    int i=0;
1793    while(l>0){
1794      i=io.in.read(buf, s, l);
1795      if(i<=0){
1796        throw new SftpException(SSH_FX_FAILURE, "");
1797      }
1798      s+=i;
1799      l-=i;
1800    }
1801  }
1802
1803  private boolean checkStatus(int[] ackid, Header header) throws IOException, SftpException{
1804    header=header(buf, header);
1805    int length=header.length;
1806    int type=header.type;
1807    if(ackid!=null)
1808      ackid[0]=header.rid;
1809    buf.rewind();
1810    fill(buf.buffer, 0, length);
1811
1812    if(type!=SSH_FXP_STATUS){
1813      throw new SftpException(SSH_FX_FAILURE, "");
1814    }
1815    int i=buf.getInt();
1816    if(i!=SSH_FX_OK){
1817      throwStatusError(buf, i);
1818    }
1819    return true;
1820  }
1821  private boolean _sendCLOSE(byte[] handle, Header header) throws Exception JavaDoc{
1822    sendCLOSE(handle);
1823    return checkStatus(null, header);
1824  }
1825
1826  private void sendINIT() throws Exception JavaDoc{
1827    packet.reset();
1828    putHEAD(SSH_FXP_INIT, 5);
1829    buf.putInt(3); // version 3
1830
session.write(packet, this, 5+4);
1831  }
1832
1833  private void sendREALPATH(byte[] path) throws Exception JavaDoc{
1834    sendPacketPath(SSH_FXP_REALPATH, path);
1835  }
1836  private void sendSTAT(byte[] path) throws Exception JavaDoc{
1837    sendPacketPath(SSH_FXP_STAT, path);
1838  }
1839  private void sendLSTAT(byte[] path) throws Exception JavaDoc{
1840    sendPacketPath(SSH_FXP_LSTAT, path);
1841  }
1842  private void sendFSTAT(byte[] handle) throws Exception JavaDoc{
1843    sendPacketPath(SSH_FXP_FSTAT, handle);
1844  }
1845  private void sendSETSTAT(byte[] path, SftpATTRS attr) throws Exception JavaDoc{
1846    packet.reset();
1847    putHEAD(SSH_FXP_SETSTAT, 9+path.length+attr.length());
1848    buf.putInt(seq++);
1849    buf.putString(path); // path
1850
attr.dump(buf);
1851    session.write(packet, this, 9+path.length+attr.length()+4);
1852  }
1853  private void sendREMOVE(byte[] path) throws Exception JavaDoc{
1854    sendPacketPath(SSH_FXP_REMOVE, path);
1855  }
1856  private void sendMKDIR(byte[] path, SftpATTRS attr) throws Exception JavaDoc{
1857    packet.reset();
1858    putHEAD(SSH_FXP_MKDIR, 9+path.length+(attr!=null?attr.length():4));
1859    buf.putInt(seq++);
1860    buf.putString(path); // path
1861
if(attr!=null) attr.dump(buf);
1862    else buf.putInt(0);
1863    session.write(packet, this, 9+path.length+(attr!=null?attr.length():4)+4);
1864  }
1865  private void sendRMDIR(byte[] path) throws Exception JavaDoc{
1866    sendPacketPath(SSH_FXP_RMDIR, path);
1867  }
1868  private void sendSYMLINK(byte[] p1, byte[] p2) throws Exception JavaDoc{
1869    sendPacketPath(SSH_FXP_SYMLINK, p1, p2);
1870  }
1871  private void sendREADLINK(byte[] path) throws Exception JavaDoc{
1872    sendPacketPath(SSH_FXP_READLINK, path);
1873  }
1874  private void sendOPENDIR(byte[] path) throws Exception JavaDoc{
1875    sendPacketPath(SSH_FXP_OPENDIR, path);
1876  }
1877  private void sendREADDIR(byte[] path) throws Exception JavaDoc{
1878    sendPacketPath(SSH_FXP_READDIR, path);
1879  }
1880  private void sendRENAME(byte[] p1, byte[] p2) throws Exception JavaDoc{
1881    sendPacketPath(SSH_FXP_RENAME, p1, p2);
1882  }
1883  private void sendCLOSE(byte[] path) throws Exception JavaDoc{
1884    sendPacketPath(SSH_FXP_CLOSE, path);
1885  }
1886  private void sendOPENR(byte[] path) throws Exception JavaDoc{
1887    sendOPEN(path, SSH_FXF_READ);
1888  }
1889  private void sendOPENW(byte[] path) throws Exception JavaDoc{
1890    sendOPEN(path, SSH_FXF_WRITE|SSH_FXF_CREAT|SSH_FXF_TRUNC);
1891  }
1892  private void sendOPENA(byte[] path) throws Exception JavaDoc{
1893    sendOPEN(path, SSH_FXF_WRITE|/*SSH_FXF_APPEND|*/SSH_FXF_CREAT);
1894  }
1895  private void sendOPEN(byte[] path, int mode) throws Exception JavaDoc{
1896    packet.reset();
1897    putHEAD(SSH_FXP_OPEN, 17+path.length);
1898    buf.putInt(seq++);
1899    buf.putString(path);
1900    buf.putInt(mode);
1901    buf.putInt(0); // attrs
1902
session.write(packet, this, 17+path.length+4);
1903  }
1904  private void sendPacketPath(byte fxp, byte[] path) throws Exception JavaDoc{
1905    packet.reset();
1906    putHEAD(fxp, 9+path.length);
1907    buf.putInt(seq++);
1908    buf.putString(path); // path
1909
session.write(packet, this, 9+path.length+4);
1910  }
1911  private void sendPacketPath(byte fxp, byte[] p1, byte[] p2) throws Exception JavaDoc{
1912    packet.reset();
1913    putHEAD(fxp, 13+p1.length+p2.length);
1914    buf.putInt(seq++);
1915    buf.putString(p1);
1916    buf.putString(p2);
1917    session.write(packet, this, 13+p1.length+p2.length+4);
1918  }
1919
1920  private int sendWRITE(byte[] handle, long offset,
1921                        byte[] data, int start, int length) throws Exception JavaDoc{
1922    int _length=length;
1923    packet.reset();
1924    if(buf.buffer.length<buf.index+13+21+handle.length+length
1925       +32 +20 // padding and mac
1926
){
1927      _length=buf.buffer.length-(buf.index+13+21+handle.length
1928                                 +32 +20 // padding and mac
1929
);
1930      //System.err.println("_length="+_length+" length="+length);
1931
}
1932
1933    putHEAD(SSH_FXP_WRITE, 21+handle.length+_length); // 14
1934
buf.putInt(seq++); // 4
1935
buf.putString(handle); // 4+handle.length
1936
buf.putLong(offset); // 8
1937
if(buf.buffer!=data){
1938    buf.putString(data, start, _length); // 4+_length
1939
}
1940    else{
1941      buf.putInt(_length);
1942      buf.skip(_length);
1943    }
1944    session.write(packet, this, 21+handle.length+_length+4);
1945    return _length;
1946  }
1947
1948  private void sendREAD(byte[] handle, long offset, int length) throws Exception JavaDoc{
1949    packet.reset();
1950    putHEAD(SSH_FXP_READ, 21+handle.length);
1951    buf.putInt(seq++);
1952    buf.putString(handle);
1953    buf.putLong(offset);
1954    buf.putInt(length);
1955    session.write(packet, this, 21+handle.length+4);
1956  }
1957
1958  private void putHEAD(byte type, int length) throws Exception JavaDoc{
1959    buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
1960    buf.putInt(recipient);
1961    buf.putInt(length+4);
1962    buf.putInt(length);
1963    buf.putByte(type);
1964  }
1965
1966  private Vector JavaDoc glob_remote(String JavaDoc _path) throws Exception JavaDoc{
1967//System.err.println("glob_remote: "+_path);
1968
Vector JavaDoc v=new Vector JavaDoc();
1969    byte[] path=_path.getBytes();
1970    if(!isPattern(path)){
1971      v.addElement(Util.unquote(_path)); return v;
1972    }
1973    int i=path.length-1;
1974    while(i>=0){if(path[i]=='/')break;i--;}
1975    if(i<0){ v.addElement(Util.unquote(_path)); return v;}
1976    byte[] dir;
1977    if(i==0){dir=new byte[]{(byte)'/'};}
1978    else{
1979      dir=new byte[i];
1980      System.arraycopy(path, 0, dir, 0, i);
1981    }
1982//System.err.println("dir: "+new String(dir));
1983
byte[] pattern=new byte[path.length-i-1];
1984    System.arraycopy(path, i+1, pattern, 0, pattern.length);
1985//System.err.println("file: "+new String(pattern));
1986

1987    sendOPENDIR(dir);
1988
1989    Header header=new Header();
1990    header=header(buf, header);
1991    int length=header.length;
1992    int type=header.type;
1993    buf.rewind();
1994    fill(buf.buffer, 0, length);
1995
1996    if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
1997      throw new SftpException(SSH_FX_FAILURE, "");
1998    }
1999    if(type==SSH_FXP_STATUS){
2000      i=buf.getInt();
2001      throwStatusError(buf, i);
2002    }
2003
2004    byte[] handle=buf.getString(); // filename
2005

2006    while(true){
2007      sendREADDIR(handle);
2008      header=header(buf, header);
2009      length=header.length;
2010      type=header.type;
2011
2012      if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){
2013    throw new SftpException(SSH_FX_FAILURE, "");
2014      }
2015      if(type==SSH_FXP_STATUS){
2016        buf.rewind();
2017        fill(buf.buffer, 0, length);
2018    break;
2019      }
2020
2021      buf.rewind();
2022      fill(buf.buffer, 0, 4); length-=4;
2023      int count=buf.getInt();
2024
2025      byte[] str;
2026      int flags;
2027
2028      buf.reset();
2029      while(count>0){
2030    if(length>0){
2031      buf.shift();
2032          int j=(buf.buffer.length>(buf.index+length)) ? length : (buf.buffer.length-buf.index);
2033      i=io.in.read(buf.buffer, buf.index, j);
2034      if(i<=0)break;
2035      buf.index+=i;
2036      length-=i;
2037    }
2038
2039    byte[] filename=buf.getString();
2040    //System.err.println("filename: "+new String(filename));
2041
str=buf.getString();
2042    SftpATTRS attrs=SftpATTRS.getATTR(buf);
2043
2044    if(Util.glob(pattern, filename)){
2045      v.addElement(new String JavaDoc(dir)+"/"+new String JavaDoc(filename));
2046    }
2047    count--;
2048      }
2049    }
2050    if(_sendCLOSE(handle, header))
2051      return v;
2052    return null;
2053  }
2054
2055  private boolean isPattern(byte[] path){
2056    int i=path.length-1;
2057    while(i>=0){
2058      if(path[i]=='*' || path[i]=='?'){
2059        if(i>0 && path[i-1]=='\\'){
2060          i--;
2061        }
2062        else{
2063          break;
2064        }
2065      }
2066      i--;
2067    }
2068    //System.err.println("isPattern: ["+(new String(path))+"] "+(!(i<0)));
2069
return !(i<0);
2070  }
2071
2072  private Vector JavaDoc glob_local(String JavaDoc _path) throws Exception JavaDoc{
2073//System.err.println("glob_local: "+_path);
2074
Vector JavaDoc v=new Vector JavaDoc();
2075    byte[] path=_path.getBytes();
2076    int i=path.length-1;
2077    while(i>=0){if(path[i]=='*' || path[i]=='?')break;i--;}
2078    if(i<0){ v.addElement(_path); return v;}
2079    while(i>=0){if(path[i]==file_separatorc)break;i--;}
2080    if(i<0){ v.addElement(_path); return v;}
2081    byte[] dir;
2082    if(i==0){dir=new byte[]{(byte)file_separatorc};}
2083    else{
2084      dir=new byte[i];
2085      System.arraycopy(path, 0, dir, 0, i);
2086    }
2087    byte[] pattern=new byte[path.length-i-1];
2088    System.arraycopy(path, i+1, pattern, 0, pattern.length);
2089//System.err.println("dir: "+new String(dir)+" pattern: "+new String(pattern));
2090
try{
2091      String JavaDoc[] children=(new File(new String JavaDoc(dir))).list();
2092      for(int j=0; j<children.length; j++){
2093//System.err.println("children: "+children[j]);
2094
if(Util.glob(pattern, children[j].getBytes())){
2095      v.addElement(new String JavaDoc(dir)+file_separator+children[j]);
2096    }
2097      }
2098    }
2099    catch(Exception JavaDoc e){
2100    }
2101    return v;
2102  }
2103
2104  private void throwStatusError(Buffer buf, int i) throws SftpException{
2105    if(server_version>=3){
2106      byte[] str=buf.getString();
2107      //byte[] tag=buf.getString();
2108
throw new SftpException(i, new String JavaDoc(str));
2109    }
2110    else{
2111      throw new SftpException(i, "Failure");
2112    }
2113  }
2114
2115  private static boolean isLocalAbsolutePath(String JavaDoc path){
2116    return (new File(path)).isAbsolute();
2117  }
2118
2119  /*
2120  public void finalize() throws Throwable{
2121    super.finalize();
2122  }
2123  */

2124
2125  public void disconnect(){
2126    //waitForRunningThreadFinish(10000);
2127
clearRunningThreads();
2128    super.disconnect();
2129  }
2130  private java.util.Vector JavaDoc threadList=null;
2131  protected synchronized void addRunningThread(Thread JavaDoc thread){
2132    if(threadList==null)threadList=new java.util.Vector JavaDoc();
2133    threadList.add(thread);
2134  }
2135  protected synchronized void clearRunningThreads(){
2136    if(threadList==null)return;
2137    for(int t=0;t<threadList.size();t++){
2138      Thread JavaDoc thread=(Thread JavaDoc)threadList.get(t);
2139      if(thread!=null)
2140    if(thread.isAlive())
2141      thread.interrupt();
2142    }
2143    threadList.clear();
2144  }
2145  private boolean isPattern(String JavaDoc path){
2146    return path.indexOf("*")!=-1 || path.indexOf("?")!=-1;
2147  }
2148
2149  private int fill(byte[] buf, int s, int len) throws IOException{
2150    int i=0;
2151    int foo=s;
2152    while(len>0){
2153      i=io.in.read(buf, s, len);
2154      if(i<=0){
2155        throw new IOException("inputstream is closed");
2156        //return (s-foo)==0 ? i : s-foo;
2157
}
2158      s+=i;
2159      len-=i;
2160    }
2161    return s-foo;
2162  }
2163  private void skip(long foo) throws IOException{
2164    while(foo>0){
2165      long bar=io.in.skip(foo);
2166      if(bar<=0)
2167        break;
2168      foo-=bar;
2169    }
2170  }
2171
2172  class Header{
2173    int length;
2174    int type;
2175    int rid;
2176  }
2177  private Header header(Buffer buf, Header header) throws IOException{
2178    buf.rewind();
2179    int i=fill(buf.buffer, 0, 9);
2180    header.length=buf.getInt()-5;
2181    header.type=buf.getByte()&0xff;
2182    header.rid=buf.getInt();
2183    return header;
2184  }
2185  private String JavaDoc remoteAbsolutePath(String JavaDoc path){
2186    if(path.charAt(0)=='/') return path;
2187    if(cwd.endsWith("/")) return cwd+path;
2188    return cwd+"/"+path;
2189  }
2190
2191  private String JavaDoc localAbsolutePath(String JavaDoc path){
2192    if(isLocalAbsolutePath(path)) return path;
2193    if(lcwd.endsWith(file_separator)) return lcwd+path;
2194    return lcwd+file_separator+path;
2195  }
2196
2197  public class LsEntry {
2198    private String JavaDoc filename;
2199    private String JavaDoc longname;
2200    private SftpATTRS attrs;
2201    LsEntry(String JavaDoc filename, String JavaDoc longname, SftpATTRS attrs){
2202      setFilename(filename);
2203      setLongname(longname);
2204      setAttrs(attrs);
2205    }
2206    public String JavaDoc getFilename(){return filename;};
2207    void setFilename(String JavaDoc filename){this.filename = filename;};
2208    public String JavaDoc getLongname(){return longname;};
2209    void setLongname(String JavaDoc longname){this.longname = longname;};
2210    public SftpATTRS getAttrs(){return attrs;};
2211    void setAttrs(SftpATTRS attrs) {this.attrs = attrs;};
2212    public String JavaDoc toString(){ return longname; }
2213  }
2214}
2215
Popular Tags