src/Pure/General/ssh.scala
changeset 64131 f01fca58e0a5
parent 64130 e17c211a0bb6
child 64132 c2594513687b
equal deleted inserted replaced
64130:e17c211a0bb6 64131:f01fca58e0a5
     4 SSH client based on JSch (see also http://www.jcraft.com/jsch/examples).
     4 SSH client based on JSch (see also http://www.jcraft.com/jsch/examples).
     5 */
     5 */
     6 
     6 
     7 package isabelle
     7 package isabelle
     8 
     8 
       
     9 
       
    10 import java.io.{InputStream, OutputStream}
       
    11 
       
    12 import scala.collection.JavaConversions
     9 
    13 
    10 import com.jcraft.jsch.{JSch, Logger => JSch_Logger, Session => JSch_Session,
    14 import com.jcraft.jsch.{JSch, Logger => JSch_Logger, Session => JSch_Session,
    11   OpenSSHConfig, UserInfo, Channel => JSch_Channel, ChannelExec, ChannelSftp}
    15   OpenSSHConfig, UserInfo, Channel => JSch_Channel, ChannelExec, ChannelSftp}
    12 
    16 
    13 
    17 
    85     override def toString: String = kind + " " + session.toString
    89     override def toString: String = kind + " " + session.toString
    86 
    90 
    87     def close { channel.disconnect }
    91     def close { channel.disconnect }
    88   }
    92   }
    89 
    93 
       
    94   class Exec private[SSH](
       
    95     session: Session, kind: String, channel_options: Options, channel: ChannelExec)
       
    96     extends Channel[ChannelExec](session, kind, channel_options, channel)
       
    97   {
       
    98     def kill(signal: String) { channel.sendSignal(signal) }
       
    99   }
       
   100 
       
   101 
       
   102   class Sftp private[SSH](
       
   103     session: Session, kind: String, channel_options: Options, channel: ChannelSftp)
       
   104     extends Channel[ChannelSftp](session, kind, channel_options, channel)
       
   105   {
       
   106     def home: String = channel.getHome()
       
   107 
       
   108     def chmod(permissions: Int, remote_path: String) { channel.chmod(permissions, remote_path) }
       
   109     def mv(remote_path1: String, remote_path2: String): Unit =
       
   110       channel.rename(remote_path1, remote_path2)
       
   111     def rm(remote_path: String) { channel.rm(remote_path) }
       
   112     def mkdir(remote_path: String) { channel.mkdir(remote_path) }
       
   113     def rmdir(remote_path: String) { channel.rmdir(remote_path) }
       
   114 
       
   115     def open_input(remote_path: String): InputStream = channel.get(remote_path)
       
   116     def open_output(remote_path: String): OutputStream = channel.put(remote_path)
       
   117 
       
   118     def read_file(remote_path: String, local_path: Path): Unit =
       
   119       channel.get(remote_path, File.platform_path(local_path))
       
   120     def read_bytes(remote_path: String): Bytes =
       
   121       using(open_input(remote_path))(Bytes.read_stream(_))
       
   122     def read(remote_path: String): String =
       
   123       using(open_input(remote_path))(File.read_stream(_))
       
   124 
       
   125     def write_file(remote_path: String, local_path: Path): Unit =
       
   126       channel.put(File.platform_path(local_path), remote_path)
       
   127     def write_bytes(remote_path: String, bytes: Bytes): Unit =
       
   128       using(open_output(remote_path))(bytes.write_stream(_))
       
   129     def write(remote_path: String, text: String): Unit =
       
   130       using(open_output(remote_path))(stream => Bytes(text).write_stream(stream))
       
   131   }
       
   132 
    90 
   133 
    91   /* session */
   134   /* session */
    92 
   135 
    93   class Session private[SSH](val session_options: Options, val session: JSch_Session)
   136   class Session private[SSH](val session_options: Options, val session: JSch_Session)
    94   {
   137   {
    98       (if (session.getPort == 22) "" else ":" + session.getPort) +
   141       (if (session.getPort == 22) "" else ":" + session.getPort) +
    99       (if (session.isConnected) "" else " (disconnected)")
   142       (if (session.isConnected) "" else " (disconnected)")
   100 
   143 
   101     def close { session.disconnect }
   144     def close { session.disconnect }
   102 
   145 
   103     def exec(command: String, options: Options = session_options): Channel[ChannelExec] =
   146     def exec(command: String, options: Options = session_options): Exec =
   104     {
   147     {
   105       val kind = "exec"
   148       val kind = "exec"
   106       val channel = session.openChannel(kind).asInstanceOf[ChannelExec]
   149       val channel = session.openChannel(kind).asInstanceOf[ChannelExec]
   107       channel.setCommand(command)
   150       channel.setCommand(command)
   108 
   151 
   109       channel.connect(connect_timeout(options))
   152       channel.connect(connect_timeout(options))
   110       new Channel(this, kind, options, channel)
   153       new Exec(this, kind, options, channel)
   111     }
   154     }
   112 
   155 
   113     def sftp(options: Options = session_options): Channel[ChannelSftp] =
   156     def sftp(options: Options = session_options): Sftp =
   114     {
   157     {
   115       val kind = "sftp"
   158       val kind = "sftp"
   116       val channel = session.openChannel(kind).asInstanceOf[ChannelSftp]
   159       val channel = session.openChannel(kind).asInstanceOf[ChannelSftp]
   117 
   160 
   118       channel.connect(connect_timeout(options))
   161       channel.connect(connect_timeout(options))
   119       new Channel(this, kind, options, channel)
   162       new Sftp(this, kind, options, channel)
   120     }
   163     }
   121   }
   164   }
   122 }
   165 }
   123 
   166 
   124 class SSH private(val options: Options, val jsch: JSch)
   167 class SSH private(val options: Options, val jsch: JSch)