private void _get(String src, Stream dst, SftpProgressMonitor monitor, int mode, long skip) { //System.out.println("_get: "+src+", "+dst); try { sendOPENR(Util.getBytes(src)); buf.rewind(); int i=io.ins.Read(buf.buffer, 0, buf.buffer.Length); int length=buf.getInt(); int type=buf.getByte(); if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE) { throw new SftpException(SSH_FX_FAILURE, ""); } if(type==SSH_FXP_STATUS) { buf.getInt(); i=buf.getInt(); throwStatusError(buf, i); } buf.getInt(); byte[] handle=buf.getString(); // filename long offset=0; if(mode==RESUME) { offset+=skip; } int request_len=0; loop: while(true) { request_len=buf.buffer.Length-13; if(server_version==0){ request_len=1024; } sendREAD(handle, offset, request_len); buf.rewind(); i=io.ins.Read(buf.buffer, 0, 13); // 4 + 1 + 4 + 4 if(i!=13) { goto BREAK; } length=buf.getInt(); type=buf.getByte(); length--; buf.getInt(); length-=4; if(type!=SSH_FXP_STATUS && type!=SSH_FXP_DATA) { goto BREAK; } if(type==SSH_FXP_STATUS) { i=buf.getInt(); length-=4; io.ins.Read(buf.buffer, 13, length); if(i==SSH_FX_EOF) { goto BREAK; } throwStatusError(buf, i); } i=buf.getInt(); length-=4; int foo=i; while(foo>0) { int bar=length; if(bar>buf.buffer.Length) { bar=buf.buffer.Length; } i=io.ins.Read(buf.buffer, 0, bar); if(i<0) { goto BREAK; } int data_len=i; length-=data_len; dst.Write(buf.buffer, 0, data_len); if(monitor!=null) { if(!monitor.count(data_len)) { goto BREAK; } } offset+=data_len; foo-=data_len; } //System.out.println("length: "+length); // length should be 0 } BREAK: dst.Flush(); if(monitor!=null)monitor.end(); _sendCLOSE(handle); } catch(Exception e) { if(e is SftpException) throw (SftpException)e; throw new SftpException(SSH_FX_FAILURE, ""); } }
public void put(Stream src, String dst, SftpProgressMonitor monitor, int mode) { try { if(!dst.StartsWith("/")){ dst=cwd+"/"+dst; } ArrayList v=glob_remote(dst); if(v.Count!=1) { throw new SftpException(SSH_FX_FAILURE, v.ToString()); } dst=(String)(v[0]); if(isRemoteDir(dst)) { throw new SftpException(SSH_FX_FAILURE, dst+" is a directory"); } long skip=0; if(mode==RESUME || mode==APPEND) { try { SftpATTRS attr=stat(dst); skip=attr.getSize(); } catch(Exception eee) { //System.out.println(eee); } } if(mode==RESUME && skip>0) { long skipped=src.Seek(skip, SeekOrigin.Current); if(skipped<skip) { throw new SftpException(SSH_FX_FAILURE, "failed to resume for "+dst); } } if(mode==OVERWRITE) { sendOPENW(Util.getBytes(dst)); } else { sendOPENA(Util.getBytes(dst)); } buf.rewind(); int i=io.ins.Read(buf.buffer, 0, buf.buffer.Length); int length=buf.getInt(); int type=buf.getByte(); if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE) { throw new SftpException(SSH_FX_FAILURE, ""); } if(type==SSH_FXP_STATUS) { buf.getInt(); i=buf.getInt(); throwStatusError(buf, i); } buf.getInt(); byte[] handle=buf.getString(); // filename byte[] data=new byte[buf.buffer.Length-1024]; long offset=0; if(mode==RESUME || mode==APPEND) { offset+=skip; } while(true) { //i=src.read(data, 0, data.Length); i=0; int nread=0; do { nread=src.Read(data, i, data.Length-i); if(nread>0) { i+=nread; } } while(i<data.Length && nread>0); if(i<=0)break; sendWRITE(handle, offset, data, 0, i); offset+=i; if(!checkStatus()){ break; } if(monitor!=null && !monitor.count(i)) { break; } } if(monitor!=null)monitor.end(); _sendCLOSE(handle); } catch(Exception e) { if(e is SftpException) throw (SftpException)e; throw new SftpException(SSH_FX_FAILURE, ""); } }