/// <summary> /// Instructs the remote server to go up one level /// </summary> /// <param name="server">A connected server I/O stream</param> protected void SCP_EnterIntoParent(Stream server) { try { byte[] tmp = new byte[1]; // send "C0644 filesize filename", where filename should not include '/' string command = "E\n"; if (Verbos) { Console.WriteLine(command); } byte[] buff = StringAux.getBytes(command); server.Write(buff, 0, buff.Length); server.Flush(); if (SCP_CheckAck(server) != 0) { throw new SshTransferException("Error openning communication channel."); } } catch { } }
internal static string unquote(string _path) { byte[] path = StringAux.getBytesUTF8(_path); int pathlen = path.Length; int i = 0; while (i < pathlen) { if (path[i] == '\\') { if (i + 1 == pathlen) { break; } System.Array.Copy(path, i + 1, path, i, path.Length - (i + 1)); pathlen--; continue; } i++; } if (pathlen == path.Length) { return(_path); } byte[] foo = new byte[pathlen]; System.Array.Copy(path, 0, foo, 0, pathlen); return(StringAux.getString(foo)); }
internal static string[] split(string foo, string split) { byte[] buf = StringAux.getBytes(foo); System.Collections.ArrayList bar = new System.Collections.ArrayList(); int start = 0; int index; while (true) { index = foo.IndexOf(split, start); if (index >= 0) { bar.Add(StringAux.getString(buf, start, index - start)); start = index + 1; continue; } bar.Add(StringAux.getString(buf, start, buf.Length - start)); break; } string[] result = new string[bar.Count]; for (int i = 0; i < result.Length; i++) { result[i] = (string)(bar[i]); } return(result); }
/// <summary> /// Transfer a file to the remote server /// </summary> /// <param name="server">A connected server I/O stream</param> /// <param name="src">The source file to copy</param> /// <param name="dst">The remote destination path</param> protected void SCP_SendFile(Stream server, string src, string dst) { int filesize = 0; int copied = 0; filesize = (int)(new FileInfo(src)).Length; byte[] tmp = new byte[1]; // send "C0644 filesize filename", where filename should not include '/' string command = "C0644 " + filesize + " " + Path.GetFileName(dst) + "\n"; if (Verbos) { Console.WriteLine("Sending file modes: " + command); } SendStartMessage(src, dst, filesize, "Starting transfer."); byte[] buff = StringAux.getBytes(command); server.Write(buff, 0, buff.Length); server.Flush(); if (SCP_CheckAck(server) != 0) { throw new SshTransferException("Error openning communication channel."); } // send a content of lfile SendProgressMessage(src, dst, copied, filesize, "Transferring..."); FileStream fis = File.OpenRead(src); byte[] buf = new byte[1024 * 10 * 2]; while (!m_cancelled) { int len = fis.Read(buf, 0, buf.Length); if (len <= 0) { break; } server.Write(buf, 0, len); server.Flush(); copied += len; SendProgressMessage(src, dst, copied, filesize, "Transferring..."); } fis.Close(); if (m_cancelled) { return; } // send '\0' buf[0] = 0; server.Write(buf, 0, 1); server.Flush(); SendProgressMessage(src, dst, copied, filesize, "Verifying transfer..."); if (SCP_CheckAck(server) != 0) { SendEndMessage(src, dst, copied, filesize, "Transfer ended with an error."); throw new SshTransferException("Unknow error during file transfer."); } SendEndMessage(src, dst, copied, filesize, "Transfer completed successfuly (" + copied + " bytes)."); }
/// <summary> /// Copies a file from a remote SSH machine to the local machine using SCP. /// </summary> /// <param name="remoteFile">The remmote file name</param> /// <param name="localPath">The local destination path</param> /// <param name="recursive">Value indicating whether a recursive transfer should take place</param> public void From(string remoteFile, string localPath, bool _recursive) { SCP_CheckConnectivity(); AChannel channel = null; Stream server = null; m_cancelled = false; int filesize = 0; String filename = null; string cmd = null; try { String dir = null; if (Directory.Exists(localPath)) { dir = Path.GetFullPath(localPath); } SCP_ConnectFrom(out channel, out server, remoteFile, _recursive); byte[] buf = new byte[1024]; // send '\0' SCP_SendAck(server); int c = SCP_CheckAck(server); //parse scp commands while ((c == 'D') || (c == 'C') || (c == 'E')) { if (m_cancelled) { break; } cmd = "" + (char)c; if (c == 'E') { c = SCP_CheckAck(server); dir = Path.GetDirectoryName(dir); if (Verbos) { Console.WriteLine("E"); } //send '\0' SCP_SendAck(server); c = (char)SCP_CheckAck(server); continue; } // read '0644 ' or '0755 ' server.Read(buf, 0, 5); for (int i = 0; i < 5; i++) { cmd += (char)buf[i]; } //reading file size filesize = 0; while (true) { server.Read(buf, 0, 1); if (buf[0] == ' ') { break; } filesize = filesize * 10 + (buf[0] - '0'); } //reading file name for (int i = 0; ; i++) { server.Read(buf, i, 1); if (buf[i] == (byte)0x0a) { filename = StringAux.getString(buf, 0, i); break; } } cmd += " " + filesize + " " + filename; // send '\0' SCP_SendAck(server); //Receive file if (c == 'C') { if (Verbos) { Console.WriteLine("Sending file modes: " + cmd); } SCP_ReceiveFile(server, remoteFile, dir == null ? localPath : dir + "/" + filename, filesize); if (m_cancelled) { break; } // send '\0' SCP_SendAck(server); } //Enter directory else if (c == 'D') { if (dir == null) { if (File.Exists(localPath)) { throw new SshTransferException("'" + localPath + "' is not a directory"); } dir = localPath; Directory.CreateDirectory(dir); } if (Verbos) { Console.WriteLine("Entering directory: " + cmd); } dir += "/" + filename; Directory.CreateDirectory(dir); } c = SCP_CheckAck(server); } channel.disconnect(); } catch (Exception e) { if (Verbos) { Console.WriteLine("Error: " + e.Message); } try { channel.disconnect(); } catch { } throw e; } }