src
file to dst
file.
* The mode
should be OVERWRITE
,
* RESUME
or APPEND
.
*
* @param src source file
* @param dst destination file
* @param monitor progress monitor
* @param mode how data should be added to dst
*/
public void put(String src, String dst,
SftpProgressMonitor monitor, int mode) throws SftpException{
try{
((MyPipedInputStream)io_in).updateReadSide();
src=localAbsolutePath(src);
dst=remoteAbsolutePath(dst);
Vector v=glob_remote(dst);
int vsize=v.size();
if(vsize!=1){
if(vsize==0){
if(isPattern(dst))
throw new SftpException(SSH_FX_FAILURE, dst);
else
dst=Util.unquote(dst);
}
throw new SftpException(SSH_FX_FAILURE, v.toString());
}
else{
dst=(String)(v.elementAt(0));
}
boolean isRemoteDir=isRemoteDir(dst);
v=glob_local(src);
vsize=v.size();
StringBuffer dstsb=null;
if(isRemoteDir){
if(!dst.endsWith("/")){
dst+="/";
}
dstsb=new StringBuffer(dst);
}
else if(vsize>1){
throw new SftpException(SSH_FX_FAILURE,
"Copying multiple files, but the destination is missing or a file.");
}
for(int j=0; jdst
file.
* The mode
should be OVERWRITE
,
* RESUME
or APPEND
.
*
* @param src input stream
* @param dst destination file
* @param monitor progress monitor
* @param mode how data should be added to dst
*/
public void put(InputStream src, String dst,
SftpProgressMonitor monitor, int mode) throws SftpException{
try{
((MyPipedInputStream)io_in).updateReadSide();
dst=remoteAbsolutePath(dst);
Vector v=glob_remote(dst);
int vsize=v.size();
if(vsize!=1){
if(vsize==0){
if(isPattern(dst))
throw new SftpException(SSH_FX_FAILURE, dst);
else
dst=Util.unquote(dst);
}
throw new SftpException(SSH_FX_FAILURE, v.toString());
}
else{
dst=(String)(v.elementAt(0));
}
if(monitor!=null){
monitor.init(SftpProgressMonitor.PUT,
"-", dst,
SftpProgressMonitor.UNKNOWN_SIZE);
}
_put(src, dst, monitor, mode);
}
catch(Exception e){
if(e instanceof SftpException) {
if(((SftpException)e).id == SSH_FX_FAILURE &&
isRemoteDir(dst)) {
throw new SftpException(SSH_FX_FAILURE, dst+" is a directory");
}
throw (SftpException)e;
}
if(e instanceof Throwable)
throw new SftpException(SSH_FX_FAILURE, e.toString(), (Throwable)e);
throw new SftpException(SSH_FX_FAILURE, e.toString());
}
}
public void _put(InputStream src, String dst,
SftpProgressMonitor monitor, int mode) throws SftpException{
try{
((MyPipedInputStream)io_in).updateReadSide();
byte[] dstb=Util.str2byte(dst, fEncoding);
long skip=0;
if(mode==RESUME || mode==APPEND){
try{
SftpATTRS attr=_stat(dstb);
skip=attr.getSize();
}
catch(Exception eee){
//System.err.println(eee);
}
}
if(mode==RESUME && skip>0){
long skipped=src.skip(skip);
if(skippedLsEntrySelector#select(LsEntry)
method, and if that method
* returns LsEntrySelector#BREAK
, the operation will be
* canceled immediately.
*
* @see ChannelSftp.LsEntrySelector
* @since 0.1.47
*/
public void ls(String path, LsEntrySelector selector) throws SftpException{
//System.out.println("ls: "+path);
try{
((MyPipedInputStream)io_in).updateReadSide();
path=remoteAbsolutePath(path);
byte[] pattern=null;
java.util.Vector v=new java.util.Vector();
int foo=path.lastIndexOf('/');
String dir=path.substring(0, ((foo==0)?1:foo));
String _pattern=path.substring(foo+1);
dir=Util.unquote(dir);
// If pattern has included '*' or '?', we need to convert
// to UTF-8 string before globbing.
byte[][] _pattern_utf8=new byte[1][];
boolean pattern_has_wildcard=isPattern(_pattern, _pattern_utf8);
if(pattern_has_wildcard){
pattern=_pattern_utf8[0];
}
else{
String upath=Util.unquote(path);
//SftpATTRS attr=_lstat(upath);
SftpATTRS attr=_stat(upath);
if(attr.isDir()){
pattern=null;
dir=upath;
}
else{
/*
// If we can generage longname by ourself,
// we don't have to use openDIR.
String filename=Util.unquote(_pattern);
String longname=...
v.addElement(new LsEntry(filename, longname, attr));
return v;
*/
if(fEncoding_is_utf8){
pattern=_pattern_utf8[0];
pattern=Util.unquote(pattern);
}
else{
_pattern=Util.unquote(_pattern);
pattern=Util.str2byte(_pattern, fEncoding);
}
}
}
sendOPENDIR(Util.str2byte(dir, fEncoding));
Header header=new Header();
header=header(buf, header);
int length=header.length;
int type=header.type;
fill(buf, length);
if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
throw new SftpException(SSH_FX_FAILURE, "");
}
if(type==SSH_FXP_STATUS){
int i=buf.getInt();
throwStatusError(buf, i);
}
int cancel = LsEntrySelector.CONTINUE;
byte[] handle=buf.getString(); // handle
while(cancel==LsEntrySelector.CONTINUE){
sendREADDIR(handle);
header=header(buf, header);
length=header.length;
type=header.type;
if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){
throw new SftpException(SSH_FX_FAILURE, "");
}
if(type==SSH_FXP_STATUS){
fill(buf, length);
int i=buf.getInt();
if(i==SSH_FX_EOF)
break;
throwStatusError(buf, i);
}
buf.rewind();
fill(buf.buffer, 0, 4); length-=4;
int count=buf.getInt();
byte[] str;
int flags;
buf.reset();
while(count>0){
if(length>0){
buf.shift();
int j=(buf.buffer.length>(buf.index+length)) ?
length :
(buf.buffer.length-buf.index);
int i=fill(buf.buffer, buf.index, j);
buf.index+=i;
length-=i;
}
byte[] filename=buf.getString();
byte[] longname=null;
if(server_version<=3){
longname=buf.getString();
}
SftpATTRS attrs=SftpATTRS.getATTR(buf);
if(cancel==LsEntrySelector.BREAK){
count--;
continue;
}
boolean find=false;
String f=null;
if(pattern==null){
find=true;
}
else if(!pattern_has_wildcard){
find=Util.array_equals(pattern, filename);
}
else{
byte[] _filename=filename;
if(!fEncoding_is_utf8){
f=Util.byte2str(_filename, fEncoding);
_filename=Util.str2byte(f, UTF8);
}
find=Util.glob(pattern, _filename);
}
if(find){
if(f==null){
f=Util.byte2str(filename, fEncoding);
}
String l=null;
if(longname==null){
// TODO: we need to generate long name from attrs
// for the sftp protocol 4(and later).
l=attrs.toString()+" "+f;
}
else{
l=Util.byte2str(longname, fEncoding);
}
cancel = selector.select(new LsEntry(f, l, attrs));
}
count--;
}
}
_sendCLOSE(handle, header);
/*
if(v.size()==1 && pattern_has_wildcard){
LsEntry le=(LsEntry)v.elementAt(0);
if(le.getAttrs().isDir()){
String f=le.getFilename();
if(isPattern(f)){
f=Util.quote(f);
}
if(!dir.endsWith("/")){
dir+="/";
}
v=null;
return ls(dir+f);
}
}
*/
}
catch(Exception e){
if(e instanceof SftpException) throw (SftpException)e;
if(e instanceof Throwable)
throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
throw new SftpException(SSH_FX_FAILURE, "");
}
}
public String readlink(String path) throws SftpException{
try{
if(server_version<3){
throw new SftpException(SSH_FX_OP_UNSUPPORTED,
"The remote sshd is too old to support symlink operation.");
}
((MyPipedInputStream)io_in).updateReadSide();
path=remoteAbsolutePath(path);
path=isUnique(path);
sendREADLINK(Util.str2byte(path, fEncoding));
Header header=new Header();
header=header(buf, header);
int length=header.length;
int type=header.type;
fill(buf, length);
if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){
throw new SftpException(SSH_FX_FAILURE, "");
}
if(type==SSH_FXP_NAME){
int count=buf.getInt(); // count
byte[] filename=null;
for(int i=0; ils
method.
*
* @see ChannelSftp.LsEntry
* @see #ls(String, ChannelSftp.LsEntrySelector)
* @since 0.1.47
*/
public interface LsEntrySelector {
public final int CONTINUE = 0;
public final int BREAK = 1;
/**
* The select
method will be invoked in ls
* method for each file entry. If this method returns BREAK,
* ls
will be canceled.
*
* @param entry one of entry from ls
* @return if BREAK is returned, the 'ls' operation will be canceled.
*/
public int select(LsEntry entry);
}
}