示例#1
0
			public _OutputStream_639(ChannelSftp _enclosing, byte[] handle, long[] _offset, SftpProgressMonitor
				 monitor)
			{
				this._enclosing = _enclosing;
				this.handle = handle;
				this._offset = _offset;
				this.monitor = monitor;
				this.init = true;
				this.isClosed = false;
				this.ackid = new int[1];
				this.startid = 0;
				this._ackid = 0;
				this.ackcount = 0;
				this.writecount = 0;
				this.header = new ChannelHeader(_enclosing);
				this._data = new byte[1];
			}
示例#2
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual OutputStream Put(string dst, SftpProgressMonitor monitor, int mode
			)
		{
			return Put(dst, monitor, mode, 0);
		}
示例#3
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual OutputStream Put(string dst, SftpProgressMonitor monitor, int mode
			, long offset)
		{
			dst = RemoteAbsolutePath(dst);
			try
			{
				dst = IsUnique(dst);
				if (IsRemoteDir(dst))
				{
					throw new SftpException(SSH_FX_FAILURE, dst + " is a directory");
				}
				byte[] dstb = Util.Str2byte(dst, fEncoding);
				long skip = 0;
				if (mode == RESUME || mode == APPEND)
				{
					try
					{
						SftpATTRS attr = _stat(dstb);
						skip = attr.GetSize();
					}
					catch (Exception)
					{
					}
				}
				//System.err.println(eee);
				if (mode == OVERWRITE)
				{
					SendOPENW(dstb);
				}
				else
				{
					SendOPENA(dstb);
				}
				ChannelHeader header = new ChannelHeader(this);
				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, string.Empty);
				}
				if (type == SSH_FXP_STATUS)
				{
					int i = buf.GetInt();
					ThrowStatusError(buf, i);
				}
				byte[] handle = buf.GetString();
				// handle
				if (mode == RESUME || mode == APPEND)
				{
					offset += skip;
				}
				long[] _offset = new long[1];
				_offset[0] = offset;
				OutputStream @out = new _OutputStream_639(this, handle, _offset, monitor);
				return @out;
			}
			catch (Exception e)
			{
				if (e is SftpException)
				{
					throw (SftpException)e;
				}
				if (e is Exception)
				{
					throw new SftpException(SSH_FX_FAILURE, string.Empty, (Exception)e);
				}
				throw new SftpException(SSH_FX_FAILURE, string.Empty);
			}
		}
示例#4
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual void Put(InputStream src, string dst, SftpProgressMonitor monitor, 
			int mode)
		{
			try
			{
				dst = RemoteAbsolutePath(dst);
				ArrayList v = Glob_remote(dst);
				int vsize = v.Count;
				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[0]);
				}
				if (IsRemoteDir(dst))
				{
					throw new SftpException(SSH_FX_FAILURE, dst + " is a directory");
				}
				_put(src, dst, monitor, mode);
			}
			catch (Exception e)
			{
				if (e is SftpException)
				{
					throw (SftpException)e;
				}
				if (e is Exception)
				{
					throw new SftpException(SSH_FX_FAILURE, e.ToString(), (Exception)e);
				}
				throw new SftpException(SSH_FX_FAILURE, e.ToString());
			}
		}
示例#5
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual void _put(InputStream src, string dst, SftpProgressMonitor monitor
			, int mode)
		{
			try
			{
				byte[] dstb = Util.Str2byte(dst, fEncoding);
				long skip = 0;
				if (mode == RESUME || mode == APPEND)
				{
					try
					{
						SftpATTRS attr = _stat(dstb);
						skip = attr.GetSize();
					}
					catch (Exception)
					{
					}
				}
				//System.err.println(eee);
				if (mode == RESUME && skip > 0)
				{
					long skipped = src.Skip(skip);
					if (skipped < skip)
					{
						throw new SftpException(SSH_FX_FAILURE, "failed to resume for " + dst);
					}
				}
				if (mode == OVERWRITE)
				{
					SendOPENW(dstb);
				}
				else
				{
					SendOPENA(dstb);
				}
				ChannelHeader header = new ChannelHeader(this);
				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, "invalid type=" + type);
				}
				if (type == SSH_FXP_STATUS)
				{
					int i = buf.GetInt();
					ThrowStatusError(buf, i);
				}
				byte[] handle = buf.GetString();
				// handle
				byte[] data = null;
				bool dontcopy = true;
				if (!dontcopy)
				{
					data = new byte[buf.buffer.Length - (5 + 13 + 21 + handle.Length + 32 + 20)];
				}
				// padding and mac
				long offset = 0;
				if (mode == RESUME || mode == APPEND)
				{
					offset += skip;
				}
				int startid = seq;
				int _ackid = seq;
				int ackcount = 0;
				while (true)
				{
					int nread = 0;
					int s = 0;
					int datalen = 0;
					int count = 0;
					if (!dontcopy)
					{
						datalen = data.Length - s;
					}
					else
					{
						data = buf.buffer;
						s = 5 + 13 + 21 + handle.Length;
						datalen = buf.buffer.Length - s - 32 - 20;
					}
					do
					{
						// padding and mac
						nread = src.Read(data, s, datalen);
						if (nread > 0)
						{
							s += nread;
							datalen -= nread;
							count += nread;
						}
					}
					while (datalen > 0 && nread > 0);
					if (count <= 0)
					{
						break;
					}
					int _i = count;
					while (_i > 0)
					{
						_i -= SendWRITE(handle, offset, data, 0, _i);
						if ((seq - 1) == startid || io_in.Available() >= 1024)
						{
							while (io_in.Available() > 0)
							{
								if (CheckStatus(ackid, header))
								{
									_ackid = ackid[0];
									if (startid > _ackid || _ackid > seq - 1)
									{
										if (_ackid == seq)
										{
											System.Console.Error.WriteLine("ack error: startid=" + startid + " seq=" + seq + 
												" _ackid=" + _ackid);
										}
										else
										{
											//throw new SftpException(SSH_FX_FAILURE, "ack error:");
											throw new SftpException(SSH_FX_FAILURE, "ack error: startid=" + startid + " seq="
												 + seq + " _ackid=" + _ackid);
										}
									}
									ackcount++;
								}
								else
								{
									break;
								}
							}
						}
					}
					offset += count;
					if (monitor != null && !monitor.Count(count))
					{
						break;
					}
				}
				int _ackcount = seq - startid;
				while (_ackcount > ackcount)
				{
					if (!CheckStatus(null, header))
					{
						break;
					}
					ackcount++;
				}
				if (monitor != null)
				{
					monitor.End();
				}
				_sendCLOSE(handle, header);
			}
			catch (Exception e)
			{
				if (e is SftpException)
				{
					throw (SftpException)e;
				}
				if (e is Exception)
				{
					throw new SftpException(SSH_FX_FAILURE, e.ToString(), (Exception)e);
				}
				throw new SftpException(SSH_FX_FAILURE, e.ToString());
			}
		}
示例#6
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual void Put(InputStream src, string dst, SftpProgressMonitor monitor, 
			int mode)
		{
			try
			{
				((Channel.MyPipedInputStream)io_in).UpdateReadSide();
				dst = RemoteAbsolutePath(dst);
				ArrayList v = Glob_remote(dst);
				int vsize = v.Count;
				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[0]);
				}
				if (IsRemoteDir(dst))
				{
					throw new SftpException(SSH_FX_FAILURE, dst + " is a directory");
				}
				if (monitor != null)
				{
					monitor.Init(SftpProgressMonitor.PUT, "-", dst, SftpProgressMonitor.UNKNOWN_SIZE);
				}
				_put(src, dst, monitor, mode);
			}
			catch (Exception e)
			{
				if (e is SftpException)
				{
					throw (SftpException)e;
				}
				if (e is Exception)
				{
					throw new SftpException(SSH_FX_FAILURE, e.ToString(), (Exception)e);
				}
				throw new SftpException(SSH_FX_FAILURE, e.ToString());
			}
		}
示例#7
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual void Put(InputStream src, string dst, SftpProgressMonitor monitor)
		{
			Put(src, dst, monitor, OVERWRITE);
		}
示例#8
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual InputStream Get(string src, SftpProgressMonitor monitor, long skip
			)
		{
			src = RemoteAbsolutePath(src);
			try
			{
				src = IsUnique(src);
				byte[] srcb = Util.Str2byte(src, fEncoding);
				SftpATTRS attr = _stat(srcb);
				if (monitor != null)
				{
					monitor.Init(SftpProgressMonitor.GET, src, "??", attr.GetSize());
				}
				SendOPENR(srcb);
				ChannelHeader header = new ChannelHeader(this);
				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, string.Empty);
				}
				if (type == SSH_FXP_STATUS)
				{
					int i = buf.GetInt();
					ThrowStatusError(buf, i);
				}
				byte[] handle = buf.GetString();
				// handle
				InputStream @in = new _InputStream_1034(this, skip, monitor, handle);
				//throwStatusError(buf, i);
				// ??
				return @in;
			}
			catch (Exception e)
			{
				if (e is SftpException)
				{
					throw (SftpException)e;
				}
				if (e is Exception)
				{
					throw new SftpException(SSH_FX_FAILURE, string.Empty, (Exception)e);
				}
				throw new SftpException(SSH_FX_FAILURE, string.Empty);
			}
		}
示例#9
0
			public _InputStream_1034(ChannelSftp _enclosing, long skip, SftpProgressMonitor monitor
				, byte[] handle)
			{
				this._enclosing = _enclosing;
				this.skip = skip;
				this.monitor = monitor;
				this.handle = handle;
				this.offset = skip;
				this.closed = false;
				this.rest_length = 0;
				this._data = new byte[1];
				this.rest_byte = new byte[1024];
				this.header = new ChannelHeader(_enclosing);
			}
示例#10
0
		/// <exception cref="NSch.SftpException"></exception>
		private void _get(string src, OutputStream dst, SftpProgressMonitor monitor, int 
			mode, long skip)
		{
			//System.err.println("_get: "+src+", "+dst);
			byte[] srcb = Util.Str2byte(src, fEncoding);
			try
			{
				SendOPENR(srcb);
				ChannelHeader header = new ChannelHeader(this);
				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, string.Empty);
				}
				if (type == SSH_FXP_STATUS)
				{
					int i = buf.GetInt();
					ThrowStatusError(buf, i);
				}
				byte[] handle = buf.GetString();
				// filename
				long offset = 0;
				if (mode == RESUME)
				{
					offset += skip;
				}
				int request_len = 0;
				while (true)
				{
					request_len = buf.buffer.Length - 13;
					if (server_version == 0)
					{
						request_len = 1024;
					}
					SendREAD(handle, offset, request_len);
					header = Header(buf, header);
					length = header.length;
					type = header.type;
					if (type == SSH_FXP_STATUS)
					{
						Fill(buf, length);
						int i = buf.GetInt();
						if (i == SSH_FX_EOF)
						{
							goto loop_break;
						}
						ThrowStatusError(buf, i);
					}
					if (type != SSH_FXP_DATA)
					{
						goto loop_break;
					}
					buf.Rewind();
					Fill(buf.buffer, 0, 4);
					length -= 4;
					int i_1 = buf.GetInt();
					// length of data 
					int foo = i_1;
					while (foo > 0)
					{
						int bar = foo;
						if (bar > buf.buffer.Length)
						{
							bar = buf.buffer.Length;
						}
						i_1 = io_in.Read(buf.buffer, 0, bar);
						if (i_1 < 0)
						{
							goto loop_break;
						}
						int data_len = i_1;
						dst.Write(buf.buffer, 0, data_len);
						offset += data_len;
						foo -= data_len;
						if (monitor != null)
						{
							if (!monitor.Count(data_len))
							{
								while (foo > 0)
								{
									i_1 = io_in.Read(buf.buffer, 0, (buf.buffer.Length < foo ? buf.buffer.Length : foo
										));
									if (i_1 <= 0)
									{
										break;
									}
									foo -= i_1;
								}
								goto loop_break;
							}
						}
					}
loop_continue: ;
				}
loop_break: ;
				//System.err.println("length: "+length);  // length should be 0
				dst.Flush();
				if (monitor != null)
				{
					monitor.End();
				}
				_sendCLOSE(handle, header);
			}
			catch (Exception e)
			{
				if (e is SftpException)
				{
					throw (SftpException)e;
				}
				if (e is Exception)
				{
					throw new SftpException(SSH_FX_FAILURE, string.Empty, (Exception)e);
				}
				throw new SftpException(SSH_FX_FAILURE, string.Empty);
			}
		}
示例#11
0
		public virtual InputStream Get(string src, SftpProgressMonitor monitor, int mode)
		{
			return Get(src, monitor, 0L);
		}
示例#12
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual void Get(string src, OutputStream dst, SftpProgressMonitor monitor
			, int mode, long skip)
		{
			//System.err.println("get: "+src+", "+dst);
			try
			{
				src = RemoteAbsolutePath(src);
				src = IsUnique(src);
				if (monitor != null)
				{
					SftpATTRS attr = _stat(src);
					monitor.Init(SftpProgressMonitor.GET, src, "??", attr.GetSize());
					if (mode == RESUME)
					{
						monitor.Count(skip);
					}
				}
				_get(src, dst, monitor, mode, skip);
			}
			catch (Exception e)
			{
				if (e is SftpException)
				{
					throw (SftpException)e;
				}
				if (e is Exception)
				{
					throw new SftpException(SSH_FX_FAILURE, string.Empty, (Exception)e);
				}
				throw new SftpException(SSH_FX_FAILURE, string.Empty);
			}
		}
示例#13
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual void Get(string src, OutputStream dst, SftpProgressMonitor monitor
			)
		{
			Get(src, dst, monitor, OVERWRITE, 0);
		}
示例#14
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual void _put(InputStream src, string dst, SftpProgressMonitor monitor
			, int mode)
		{
			try
			{
				((Channel.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)
					{
					}
				}
				//System.err.println(eee);
				if (mode == RESUME && skip > 0)
				{
					long skipped = src.Skip(skip);
					if (skipped < skip)
					{
						throw new SftpException(SSH_FX_FAILURE, "failed to resume for " + dst);
					}
				}
				if (mode == OVERWRITE)
				{
					SendOPENW(dstb);
				}
				else
				{
					SendOPENA(dstb);
				}
				ChannelHeader header = new ChannelHeader(this);
				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, "invalid type=" + type);
				}
				if (type == SSH_FXP_STATUS)
				{
					int i = buf.GetInt();
					ThrowStatusError(buf, i);
				}
				byte[] handle = buf.GetString();
				// handle
				byte[] data = null;
				bool dontcopy = true;
				if (!dontcopy)
				{
					// This case will not work anymore.
					data = new byte[obuf.buffer.Length - (5 + 13 + 21 + handle.Length + Session.buffer_margin
						)];
				}
				long offset = 0;
				if (mode == RESUME || mode == APPEND)
				{
					offset += skip;
				}
				int startid = seq;
				int ackcount = 0;
				int _s = 0;
				int _datalen = 0;
				if (!dontcopy)
				{
					// This case will not work anymore.
					_datalen = data.Length;
				}
				else
				{
					data = obuf.buffer;
					_s = 5 + 13 + 21 + handle.Length;
					_datalen = obuf.buffer.Length - _s - Session.buffer_margin;
				}
				int bulk_requests = rq.Size();
				while (true)
				{
					int nread = 0;
					int count = 0;
					int s = _s;
					int datalen = _datalen;
					do
					{
						nread = src.Read(data, s, datalen);
						if (nread > 0)
						{
							s += nread;
							datalen -= nread;
							count += nread;
						}
					}
					while (datalen > 0 && nread > 0);
					if (count <= 0)
					{
						break;
					}
					int foo = count;
					while (foo > 0)
					{
						if ((seq - 1) == startid || ((seq - startid) - ackcount) >= bulk_requests)
						{
							while (((seq - startid) - ackcount) >= bulk_requests)
							{
								if (this.rwsize >= foo)
								{
									break;
								}
								if (CheckStatus(ackid, header))
								{
									int _ackid = ackid[0];
									if (startid > _ackid || _ackid > seq - 1)
									{
										if (_ackid == seq)
										{
											System.Console.Error.WriteLine("ack error: startid=" + startid + " seq=" + seq + 
												" _ackid=" + _ackid);
										}
										else
										{
											throw new SftpException(SSH_FX_FAILURE, "ack error: startid=" + startid + " seq="
												 + seq + " _ackid=" + _ackid);
										}
									}
									ackcount++;
								}
								else
								{
									break;
								}
							}
						}
						foo -= SendWRITE(handle, offset, data, 0, foo);
					}
					offset += count;
					if (monitor != null && !monitor.Count(count))
					{
						break;
					}
				}
				int _ackcount = seq - startid;
				while (_ackcount > ackcount)
				{
					if (!CheckStatus(null, header))
					{
						break;
					}
					ackcount++;
				}
				if (monitor != null)
				{
					monitor.End();
				}
				_sendCLOSE(handle, header);
			}
			catch (Exception e)
			{
				if (e is SftpException)
				{
					throw (SftpException)e;
				}
				if (e is Exception)
				{
					throw new SftpException(SSH_FX_FAILURE, e.ToString(), (Exception)e);
				}
				throw new SftpException(SSH_FX_FAILURE, e.ToString());
			}
		}
示例#15
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual void Get(string src, string dst, SftpProgressMonitor monitor)
		{
			Get(src, dst, monitor, OVERWRITE);
		}
示例#16
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual void Put(string src, string dst, SftpProgressMonitor monitor, int 
			mode)
		{
			src = LocalAbsolutePath(src);
			dst = RemoteAbsolutePath(dst);
			try
			{
				ArrayList v = Glob_remote(dst);
				int vsize = v.Count;
				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[0]);
				}
				bool isRemoteDir = IsRemoteDir(dst);
				v = Glob_local(src);
				vsize = v.Count;
				StringBuilder dstsb = null;
				if (isRemoteDir)
				{
					if (!dst.EndsWith("/"))
					{
						dst += "/";
					}
					dstsb = new StringBuilder(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; j < vsize; j++)
				{
					string _src = (string)(v[j]);
					string _dst = null;
					if (isRemoteDir)
					{
						int i = _src.LastIndexOf(file_separatorc);
						if (fs_is_bs)
						{
							int ii = _src.LastIndexOf('/');
							if (ii != -1 && ii > i)
							{
								i = ii;
							}
						}
						if (i == -1)
						{
							dstsb.Append(_src);
						}
						else
						{
							dstsb.Append(Sharpen.Runtime.Substring(_src, i + 1));
						}
						_dst = dstsb.ToString();
						dstsb.Delete(dst.Length, _dst.Length);
					}
					else
					{
						_dst = dst;
					}
					//System.err.println("_dst "+_dst);
					long size_of_dst = 0;
					if (mode == RESUME)
					{
						try
						{
							SftpATTRS attr = _stat(_dst);
							size_of_dst = attr.GetSize();
						}
						catch (Exception)
						{
						}
						//System.err.println(eee);
						long size_of_src = new FilePath(_src).Length();
						if (size_of_src < size_of_dst)
						{
							throw new SftpException(SSH_FX_FAILURE, "failed to resume for " + _dst);
						}
						if (size_of_src == size_of_dst)
						{
							return;
						}
					}
					if (monitor != null)
					{
						monitor.Init(SftpProgressMonitor.PUT, _src, _dst, (new FilePath(_src)).Length());
						if (mode == RESUME)
						{
							monitor.Count(size_of_dst);
						}
					}
					FileInputStream fis = null;
					try
					{
						fis = new FileInputStream(_src);
						_put(fis, _dst, monitor, mode);
					}
					finally
					{
						if (fis != null)
						{
							fis.Close();
						}
					}
				}
			}
			catch (Exception e)
			{
				if (e is SftpException)
				{
					throw (SftpException)e;
				}
				if (e is Exception)
				{
					throw new SftpException(SSH_FX_FAILURE, e.ToString(), (Exception)e);
				}
				throw new SftpException(SSH_FX_FAILURE, e.ToString());
			}
		}
示例#17
0
		/// <exception cref="NSch.SftpException"></exception>
		public virtual void Get(string src, string dst, SftpProgressMonitor monitor, int 
			mode)
		{
			// System.out.println("get: "+src+" "+dst);
			src = RemoteAbsolutePath(src);
			dst = LocalAbsolutePath(dst);
			try
			{
				ArrayList v = Glob_remote(src);
				int vsize = v.Count;
				if (vsize == 0)
				{
					throw new SftpException(SSH_FX_NO_SUCH_FILE, "No such file");
				}
				FilePath dstFile = new FilePath(dst);
				bool isDstDir = dstFile.IsDirectory();
				StringBuilder dstsb = null;
				if (isDstDir)
				{
					if (!dst.EndsWith(file_separator))
					{
						dst += file_separator;
					}
					dstsb = new StringBuilder(dst);
				}
				else
				{
					if (vsize > 1)
					{
						throw new SftpException(SSH_FX_FAILURE, "Copying multiple files, but destination is missing or a file."
							);
					}
				}
				for (int j = 0; j < vsize; j++)
				{
					string _src = (string)(v[j]);
					SftpATTRS attr = _stat(_src);
					if (attr.IsDir())
					{
						throw new SftpException(SSH_FX_FAILURE, "not supported to get directory " + _src);
					}
					string _dst = null;
					if (isDstDir)
					{
						int i = _src.LastIndexOf('/');
						if (i == -1)
						{
							dstsb.Append(_src);
						}
						else
						{
							dstsb.Append(Sharpen.Runtime.Substring(_src, i + 1));
						}
						_dst = dstsb.ToString();
						dstsb.Delete(dst.Length, _dst.Length);
					}
					else
					{
						_dst = dst;
					}
					if (mode == RESUME)
					{
						long size_of_src = attr.GetSize();
						long size_of_dst = new FilePath(_dst).Length();
						if (size_of_dst > size_of_src)
						{
							throw new SftpException(SSH_FX_FAILURE, "failed to resume for " + _dst);
						}
						if (size_of_dst == size_of_src)
						{
							return;
						}
					}
					if (monitor != null)
					{
						monitor.Init(SftpProgressMonitor.GET, _src, _dst, attr.GetSize());
						if (mode == RESUME)
						{
							monitor.Count(new FilePath(_dst).Length());
						}
					}
					FileOutputStream fos = null;
					try
					{
						if (mode == OVERWRITE)
						{
							fos = new FileOutputStream(_dst);
						}
						else
						{
							fos = new FileOutputStream(_dst, true);
						}
						// append
						// System.err.println("_get: "+_src+", "+_dst);
						_get(_src, fos, monitor, mode, new FilePath(_dst).Length());
					}
					finally
					{
						if (fos != null)
						{
							fos.Close();
						}
					}
				}
			}
			catch (Exception e)
			{
				if (e is SftpException)
				{
					throw (SftpException)e;
				}
				if (e is Exception)
				{
					throw new SftpException(SSH_FX_FAILURE, string.Empty, (Exception)e);
				}
				throw new SftpException(SSH_FX_FAILURE, string.Empty);
			}
		}
示例#18
0
		/// <exception cref="NSch.SftpException"></exception>
		private void _get(string src, OutputStream dst, SftpProgressMonitor monitor, int 
			mode, long skip)
		{
			//System.err.println("_get: "+src+", "+dst);
			byte[] srcb = Util.Str2byte(src, fEncoding);
			try
			{
				SendOPENR(srcb);
				ChannelHeader header = new ChannelHeader(this);
				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, string.Empty);
				}
				if (type == SSH_FXP_STATUS)
				{
					int i = buf.GetInt();
					ThrowStatusError(buf, i);
				}
				byte[] handle = buf.GetString();
				// filename
				long offset = 0;
				if (mode == RESUME)
				{
					offset += skip;
				}
				int request_max = 1;
				rq.Init();
				long request_offset = offset;
				int request_len = buf.buffer.Length - 13;
				if (server_version == 0)
				{
					request_len = 1024;
				}
				while (true)
				{
					while (rq.Count() < request_max)
					{
						SendREAD(handle, request_offset, request_len, rq);
						request_offset += request_len;
					}
					header = Header(buf, header);
					length = header.length;
					type = header.type;
					ChannelSftp.RequestQueue.Request rr = rq.Get(header.rid);
					if (type == SSH_FXP_STATUS)
					{
						Fill(buf, length);
						int i = buf.GetInt();
						if (i == SSH_FX_EOF)
						{
							goto loop_break;
						}
						ThrowStatusError(buf, i);
					}
					if (type != SSH_FXP_DATA)
					{
						goto loop_break;
					}
					buf.Rewind();
					Fill(buf.buffer, 0, 4);
					length -= 4;
					int length_of_data = buf.GetInt();
					// length of data 
					int optional_data = length - length_of_data;
					int foo = length_of_data;
					while (foo > 0)
					{
						int bar = foo;
						if (bar > buf.buffer.Length)
						{
							bar = buf.buffer.Length;
						}
						int data_len = io_in.Read(buf.buffer, 0, bar);
						if (data_len < 0)
						{
							goto loop_break;
						}
						dst.Write(buf.buffer, 0, data_len);
						offset += data_len;
						foo -= data_len;
						if (monitor != null)
						{
							if (!monitor.Count(data_len))
							{
								Skip(foo);
								if (optional_data > 0)
								{
									Skip(optional_data);
								}
								goto loop_break;
							}
						}
					}
					//System.err.println("length: "+length);  // length should be 0
					if (optional_data > 0)
					{
						Skip(optional_data);
					}
					if (length_of_data < rr.length)
					{
						//
						rq.Cancel(header, buf);
						SendREAD(handle, rr.offset + length_of_data, (int)(rr.length - length_of_data), rq
							);
						request_offset = rr.offset + rr.length;
					}
					if (request_max < rq.Size())
					{
						request_max++;
					}
loop_continue: ;
				}
loop_break: ;
				dst.Flush();
				if (monitor != null)
				{
					monitor.End();
				}
				rq.Cancel(header, buf);
				_sendCLOSE(handle, header);
			}
			catch (Exception e)
			{
				if (e is SftpException)
				{
					throw (SftpException)e;
				}
				if (e is Exception)
				{
					throw new SftpException(SSH_FX_FAILURE, string.Empty, (Exception)e);
				}
				throw new SftpException(SSH_FX_FAILURE, string.Empty);
			}
		}