109 val session: Session, val kind: String, val channel: C) |
109 val session: Session, val kind: String, val channel: C) |
110 { |
110 { |
111 override def toString: String = kind + " " + session.toString |
111 override def toString: String = kind + " " + session.toString |
112 |
112 |
113 def close() { channel.disconnect } |
113 def close() { channel.disconnect } |
|
114 } |
|
115 |
|
116 |
|
117 /* Sftp channel */ |
|
118 |
|
119 type Attrs = SftpATTRS |
|
120 |
|
121 sealed case class Dir_Entry(name: String, attrs: Attrs) |
|
122 { |
|
123 def is_file: Boolean = attrs.isReg |
|
124 def is_dir: Boolean = attrs.isDir |
|
125 } |
|
126 |
|
127 class Sftp private[SSH](session: Session, kind: String, channel: ChannelSftp) |
|
128 extends Channel[ChannelSftp](session, kind, channel) |
|
129 { |
|
130 channel.connect(connect_timeout(session.options)) |
|
131 |
|
132 def home: String = channel.getHome() |
|
133 |
|
134 def chmod(permissions: Int, remote_path: String) { channel.chmod(permissions, remote_path) } |
|
135 def mv(remote_path1: String, remote_path2: String): Unit = |
|
136 channel.rename(remote_path1, remote_path2) |
|
137 def rm(remote_path: String) { channel.rm(remote_path) } |
|
138 def mkdir(remote_path: String) { channel.mkdir(remote_path) } |
|
139 def rmdir(remote_path: String) { channel.rmdir(remote_path) } |
|
140 |
|
141 def stat(remote_path: String): Dir_Entry = |
|
142 Dir_Entry(remote_path, channel.stat(remote_path)) |
|
143 |
|
144 def read_dir(remote_path: String): List[Dir_Entry] = |
|
145 { |
|
146 val dir = channel.ls(remote_path) |
|
147 (for { |
|
148 i <- (0 until dir.size).iterator |
|
149 a = dir.get(i).asInstanceOf[AnyRef] |
|
150 name = Untyped.get[String](a, "filename") |
|
151 attrs = Untyped.get[Attrs](a, "attrs") |
|
152 if name != "." && name != ".." |
|
153 } yield Dir_Entry(name, attrs)).toList |
|
154 } |
|
155 |
|
156 def find_files(remote_path: String, pred: Dir_Entry => Boolean = _ => true): List[Dir_Entry] = |
|
157 { |
|
158 def find(dir: String): List[Dir_Entry] = |
|
159 read_dir(dir).flatMap(entry => |
|
160 { |
|
161 val file = dir + "/" + entry.name |
|
162 if (entry.is_dir) find(file) |
|
163 else if (pred(entry)) List(entry.copy(name = file)) |
|
164 else Nil |
|
165 }) |
|
166 find(remote_path) |
|
167 } |
|
168 |
|
169 def open_input(remote_path: String): InputStream = channel.get(remote_path) |
|
170 def open_output(remote_path: String): OutputStream = channel.put(remote_path) |
|
171 |
|
172 def read_file(remote_path: String, local_path: Path): Unit = |
|
173 channel.get(remote_path, File.platform_path(local_path)) |
|
174 def read_bytes(remote_path: String): Bytes = |
|
175 using(open_input(remote_path))(Bytes.read_stream(_)) |
|
176 def read(remote_path: String): String = |
|
177 using(open_input(remote_path))(File.read_stream(_)) |
|
178 |
|
179 def write_file(remote_path: String, local_path: Path): Unit = |
|
180 channel.put(File.platform_path(local_path), remote_path) |
|
181 def write_bytes(remote_path: String, bytes: Bytes): Unit = |
|
182 using(open_output(remote_path))(bytes.write_stream(_)) |
|
183 def write(remote_path: String, text: String): Unit = |
|
184 using(open_output(remote_path))(stream => Bytes(text).write_stream(stream)) |
114 } |
185 } |
115 |
186 |
116 |
187 |
117 /* exec channel */ |
188 /* exec channel */ |
118 |
189 |
191 Process_Result(rc, out_lines.join, err_lines.join) |
262 Process_Result(rc, out_lines.join, err_lines.join) |
192 } |
263 } |
193 } |
264 } |
194 |
265 |
195 |
266 |
196 /* Sftp channel */ |
|
197 |
|
198 type Attrs = SftpATTRS |
|
199 |
|
200 sealed case class Dir_Entry(name: String, attrs: Attrs) |
|
201 { |
|
202 def is_file: Boolean = attrs.isReg |
|
203 def is_dir: Boolean = attrs.isDir |
|
204 } |
|
205 |
|
206 class Sftp private[SSH](session: Session, kind: String, channel: ChannelSftp) |
|
207 extends Channel[ChannelSftp](session, kind, channel) |
|
208 { |
|
209 channel.connect(connect_timeout(session.options)) |
|
210 |
|
211 def home: String = channel.getHome() |
|
212 |
|
213 def chmod(permissions: Int, remote_path: String) { channel.chmod(permissions, remote_path) } |
|
214 def mv(remote_path1: String, remote_path2: String): Unit = |
|
215 channel.rename(remote_path1, remote_path2) |
|
216 def rm(remote_path: String) { channel.rm(remote_path) } |
|
217 def mkdir(remote_path: String) { channel.mkdir(remote_path) } |
|
218 def rmdir(remote_path: String) { channel.rmdir(remote_path) } |
|
219 |
|
220 def stat(remote_path: String): Dir_Entry = |
|
221 Dir_Entry(remote_path, channel.stat(remote_path)) |
|
222 |
|
223 def read_dir(remote_path: String): List[Dir_Entry] = |
|
224 { |
|
225 val dir = channel.ls(remote_path) |
|
226 (for { |
|
227 i <- (0 until dir.size).iterator |
|
228 a = dir.get(i).asInstanceOf[AnyRef] |
|
229 name = Untyped.get[String](a, "filename") |
|
230 attrs = Untyped.get[Attrs](a, "attrs") |
|
231 if name != "." && name != ".." |
|
232 } yield Dir_Entry(name, attrs)).toList |
|
233 } |
|
234 |
|
235 def find_files(remote_path: String, pred: Dir_Entry => Boolean = _ => true): List[Dir_Entry] = |
|
236 { |
|
237 def find(dir: String): List[Dir_Entry] = |
|
238 read_dir(dir).flatMap(entry => |
|
239 { |
|
240 val file = dir + "/" + entry.name |
|
241 if (entry.is_dir) find(file) |
|
242 else if (pred(entry)) List(entry.copy(name = file)) |
|
243 else Nil |
|
244 }) |
|
245 find(remote_path) |
|
246 } |
|
247 |
|
248 def open_input(remote_path: String): InputStream = channel.get(remote_path) |
|
249 def open_output(remote_path: String): OutputStream = channel.put(remote_path) |
|
250 |
|
251 def read_file(remote_path: String, local_path: Path): Unit = |
|
252 channel.get(remote_path, File.platform_path(local_path)) |
|
253 def read_bytes(remote_path: String): Bytes = |
|
254 using(open_input(remote_path))(Bytes.read_stream(_)) |
|
255 def read(remote_path: String): String = |
|
256 using(open_input(remote_path))(File.read_stream(_)) |
|
257 |
|
258 def write_file(remote_path: String, local_path: Path): Unit = |
|
259 channel.put(File.platform_path(local_path), remote_path) |
|
260 def write_bytes(remote_path: String, bytes: Bytes): Unit = |
|
261 using(open_output(remote_path))(bytes.write_stream(_)) |
|
262 def write(remote_path: String, text: String): Unit = |
|
263 using(open_output(remote_path))(stream => Bytes(text).write_stream(stream)) |
|
264 } |
|
265 |
|
266 |
|
267 /* session */ |
267 /* session */ |
268 |
268 |
269 class Session private[SSH](val options: Options, val session: JSch_Session) |
269 class Session private[SSH](val options: Options, val session: JSch_Session) |
270 { |
270 { |
271 def update_options(new_options: Options): Session = new Session(new_options, session) |
271 def update_options(new_options: Options): Session = new Session(new_options, session) |
276 (if (session.getPort == default_port) "" else ":" + session.getPort) + |
276 (if (session.getPort == default_port) "" else ":" + session.getPort) + |
277 (if (session.isConnected) "" else " (disconnected)") |
277 (if (session.isConnected) "" else " (disconnected)") |
278 |
278 |
279 def close() { session.disconnect } |
279 def close() { session.disconnect } |
280 |
280 |
|
281 def sftp(): Sftp = |
|
282 { |
|
283 val kind = "sftp" |
|
284 val channel = session.openChannel(kind).asInstanceOf[ChannelSftp] |
|
285 new Sftp(this, kind, channel) |
|
286 } |
|
287 |
|
288 def exec(command: String): Exec = |
|
289 { |
|
290 val kind = "exec" |
|
291 val channel = session.openChannel(kind).asInstanceOf[ChannelExec] |
|
292 channel.setCommand("export USER_HOME=\"$HOME\"\n" + command) |
|
293 new Exec(this, kind, channel) |
|
294 } |
|
295 |
281 def execute(command: String, |
296 def execute(command: String, |
282 progress_stdout: String => Unit = (_: String) => (), |
297 progress_stdout: String => Unit = (_: String) => (), |
283 progress_stderr: String => Unit = (_: String) => (), |
298 progress_stderr: String => Unit = (_: String) => (), |
284 strict: Boolean = true): Process_Result = |
299 strict: Boolean = true): Process_Result = |
285 exec(command).result(progress_stdout, progress_stderr, strict) |
300 exec(command).result(progress_stdout, progress_stderr, strict) |
286 |
301 |
287 def exec(command: String): Exec = |
|
288 { |
|
289 val kind = "exec" |
|
290 val channel = session.openChannel(kind).asInstanceOf[ChannelExec] |
|
291 channel.setCommand("export USER_HOME=\"$HOME\"\n" + command) |
|
292 new Exec(this, kind, channel) |
|
293 } |
|
294 |
|
295 def sftp(): Sftp = |
|
296 { |
|
297 val kind = "sftp" |
|
298 val channel = session.openChannel(kind).asInstanceOf[ChannelSftp] |
|
299 new Sftp(this, kind, channel) |
|
300 } |
|
301 |
|
302 |
302 |
303 /* tmp dirs */ |
303 /* tmp dirs */ |
304 |
304 |
305 def rm_tree(remote_dir: String): Unit = |
305 def rm_tree(remote_dir: String): Unit = |
306 execute("rm -r -f " + File.bash_string(remote_dir)).check |
306 execute("rm -r -f " + File.bash_string(remote_dir)).check |