/// <summary> /// Get intermediate results as ASCII strings. Only the /// "standard output" stream will be checked, not the "error" stream. /// Results will be collected until the separator byte is seen, /// at which time a string will be yielded. The separator /// byte will be included at the end of each string (except possibly /// the last). /// </summary> /// <param name="sep">A value to separate strings by (e.g., 0x10 for newline). </param> /// <param name="chan">SSH Channel to use. Should NOT be connected yet. Will be disconnected /// when streaming finishes.</param> /// <returns></returns> protected IEnumerator<string> StreamASCII(byte sep, Channel chan) { if (chan == null) throw new ArgumentNullException("chan"); if (chan.connected) throw new InvalidOperationException("The channel must not be connected when StreamASCII is called."); Stream s = null; try { s = chan.getInputStream(); chan.connect(); var res = new StringBuilder(); var fn = StreamResults(s); byte[] buff; while ((buff = fn()) != null) { int upTo; if ((upTo = Array.IndexOf(buff, sep) + 1) != 0) { if (res.Length > 0) { res.Append(Encoding.ASCII.GetString(buff, 0, upTo)); yield return res.ToString(); res.Length = 0; } else yield return Encoding.ASCII.GetString(buff, 0, upTo); if (upTo < buff.Length) { int currUpTo = 0; while ((currUpTo = Array.IndexOf(buff, sep, upTo) + 1) != 0) { yield return Encoding.ASCII.GetString(buff, upTo, currUpTo - upTo); upTo = currUpTo; } if (upTo < buff.Length) res.Append(Encoding.ASCII.GetString(buff, upTo, buff.Length - upTo)); } } else res.Append(Encoding.ASCII.GetString(buff, 0, buff.Length)); } if (res.Length > 0) yield return res.ToString(); } finally { chan.disconnect(); } }
/// <summary> /// Connect a channel to the remote server using the 'SCP From' command ('scp -f') /// </summary> /// <param name="channel">Will contain the new connected channel</param> /// <param name="server">Will contaun the new connected server I/O stream</param> /// <param name="rfile">The remote path on the server</param> /// <param name="recursive">Idicate a recursive scp transfer</param> protected void SCP_ConnectFrom(out Channel channel, out Stream server, string rfile, bool recursive) { string scpCommand = "scp -f "; if(recursive) scpCommand += "-r "; scpCommand += "\""+rfile+"\""; channel = (ChannelExec)m_session.openChannel(ChannelType); ((ChannelExec)channel).setCommand(scpCommand); server = new Tamir.Streams.CombinedStream (channel.getInputStream(), channel.getOutputStream()); channel.connect(); //SCP_CheckAck(server); }
/// <summary> /// Stream results from the channel as ASCII strings. Only the /// "standard output" stream will be checked, not the "error" stream. /// Results will be streamed in approximately 1K chunks. /// </summary> /// <param name="chan">SSH Channel to use. Should NOT be connected yet. Will be disconnected /// when streaming finishes.</param> /// <returns></returns> protected IEnumerator<string> StreamASCII(Channel chan) { if (chan == null) throw new ArgumentNullException("chan"); if (chan.connected) throw new InvalidOperationException("The channel must not be connected when StreamASCII is called."); Stream s = chan.getInputStream(); chan.connect(); try { var fn = StreamResults(s); byte[] buff; while ((buff = fn()) != null) yield return Encoding.ASCII.GetString(buff); } finally { chan.disconnect(); } }