diff --git a/build.gradle.kts b/build.gradle.kts index 43c6c67..a3b4f91 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -205,7 +205,7 @@ fun generateKotlinFromUdl() { workingDir = File(project.projectDir, "rs") commandLine = listOf( "cargo", "run", "--features=uniffi/cli", - "--bin", "uniffi-bindgen", "generate", "src/repository_watcher.udl", + "--bin", "uniffi-bindgen", "generate", "src/gitnuro.udl", "--language", "kotlin", "--out-dir", rustGeneratedSource ) diff --git a/rs/Cargo.toml b/rs/Cargo.toml index b72fb94..4f12390 100644 --- a/rs/Cargo.toml +++ b/rs/Cargo.toml @@ -13,6 +13,7 @@ name = "gitnuro_rs" uniffi = { version = "0.24.1" } notify = "6.0.1" thiserror = "1.0.43" +libssh-rs = "0.2.1" [build-dependencies] uniffi = { version = "0.24.1", features = [ "build" ] } diff --git a/rs/build.rs b/rs/build.rs index b76debf..f5c593b 100644 --- a/rs/build.rs +++ b/rs/build.rs @@ -1,3 +1,3 @@ fn main() { - uniffi::generate_scaffolding("src/repository_watcher.udl").unwrap(); + uniffi::generate_scaffolding("src/gitnuro.udl").unwrap(); } diff --git a/rs/src/gitnuro.udl b/rs/src/gitnuro.udl new file mode 100644 index 0000000..3f29928 --- /dev/null +++ b/rs/src/gitnuro.udl @@ -0,0 +1,46 @@ +namespace gitnuro { + [Throws=WatcherInitError] + void watch_directory(string path, WatchDirectoryNotifier checker); +}; + +callback interface WatchDirectoryNotifier { + boolean should_keep_looping(); + + void detected_change(sequence paths); +}; + +[Error] +interface WatcherInitError { + Generic(string error); + Io(string error); + PathNotFound(); + WatchNotFound(); + InvalidConfig(); + MaxFilesWatch(); +}; + + +interface Session { + constructor(); + void setup(string host, string? user, i32 port); + void public_key_auth(); + void password_auth(string password); + void disconnect(); +}; + +interface Channel { + constructor(Session session); + void open_session(); + boolean is_open(); + void close(); + void request_exec(string command); + boolean poll_has_bytes(boolean is_stderr); + ReadResult read(boolean is_stderr, u64 len); + void write_byte(i32 byte); + void write_bytes(bytes data); +}; + +dictionary ReadResult { + u64 read_count; + bytes data; +}; \ No newline at end of file diff --git a/rs/src/lib.rs b/rs/src/lib.rs index 1a7e182..9a93859 100644 --- a/rs/src/lib.rs +++ b/rs/src/lib.rs @@ -1,13 +1,18 @@ extern crate notify; use std::fmt::Debug; +use std::io::{Write}; use std::path::Path; use std::sync::mpsc::{channel, RecvTimeoutError}; +use std::sync::{Arc, RwLock}; use std::time::Duration; +use libssh_rs::{PollStatus, SshOption}; use notify::{Config, Error, ErrorKind, Event, RecommendedWatcher, RecursiveMode, Watcher}; -uniffi::include_scaffolding!("repository_watcher"); +uniffi::include_scaffolding!("gitnuro"); + +const ACCEPTED_SSH_TYPES: &str = "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,rsa-sha2-512,rsa-sha2-256,ssh-dss"; fn watch_directory( path: String, @@ -114,3 +119,125 @@ impl WatcherInitErrorConverter for ErrorKind { } } } + +struct Session { + pub session: RwLock, +} + +impl Session { + fn new() -> Self { + let session = libssh_rs::Session::new().unwrap(); + + Session { + session: RwLock::new(session) + } + } + + fn setup(&self, host: String, user: Option, port: i32) { + let session = self.session.write().unwrap(); + session.set_option(SshOption::Hostname(host)).unwrap(); + + if let Some(user) = user { + session.set_option(SshOption::User(Some(user))).unwrap(); + } + + if let Ok(port) = port.try_into() { + session.set_option(SshOption::Port(port)).unwrap(); + } + + session.set_option(SshOption::PublicKeyAcceptedTypes(ACCEPTED_SSH_TYPES.to_string())).unwrap(); + session.options_parse_config(None).unwrap(); + session.connect().unwrap(); + } + + fn public_key_auth(&self) { + let session = self.session.write().unwrap(); + session.userauth_public_key_auto(None, Some("")).unwrap(); + } + + fn password_auth(&self, password: String) { + let session = self.session.write().unwrap(); + session.userauth_password(None, Some(&password)).unwrap(); + } + + fn disconnect(&self) { + let session = self.session.write().unwrap(); + session.disconnect() + } +} + + +struct Channel { + channel: RwLock, +} + +unsafe impl Send for Channel {} +unsafe impl Sync for Channel {} + +impl Channel { + fn new(session: Arc) -> Self { + let session = session.session.write().unwrap(); + let channel = session.new_channel().unwrap(); + + Channel { + channel: RwLock::new(channel) + } + } + fn open_session(&self) { + let channel = self.channel.write().unwrap(); + channel.open_session().unwrap(); + } + fn is_open(&self) -> bool { + let channel = self.channel.write().unwrap(); + channel.is_open() + } + + fn close(&self) { + let channel = self.channel.write().unwrap(); + channel.close().unwrap(); + } + + fn request_exec(&self, command: String) { + let channel = self.channel.write().unwrap(); + channel.request_exec(&command).unwrap(); + } + + fn poll_has_bytes(&self, is_stderr: bool) -> bool { + let channel = self.channel.write().unwrap(); + let poll_timeout = channel.poll_timeout(is_stderr, None).unwrap(); + + match poll_timeout { + PollStatus::AvailableBytes(count) => count > 0, + PollStatus::EndOfFile => false + } + } + + fn read(&self, is_stderr: bool, len: u64) -> ReadResult { + let ulen = len as usize; + + let channel = self.channel.write().unwrap(); + + let mut buffer = vec![0; ulen]; + let read = channel.read_timeout(&mut buffer, is_stderr, None).unwrap(); + + ReadResult { + read_count: read as u64, + data: buffer, + } + } + + fn write_byte(&self, byte: i32) { + let channel = self.channel.write().unwrap(); + channel.stdin().write_all(&byte.to_ne_bytes()).unwrap(); + } + + fn write_bytes(&self, data: Vec) { + let channel = self.channel.write().unwrap(); + channel.stdin().write_all(&data).unwrap(); + } +} + +pub struct ReadResult { + read_count: u64, + data: Vec, +} \ No newline at end of file diff --git a/rs/src/repository_watcher.udl b/rs/src/repository_watcher.udl deleted file mode 100644 index 163bab0..0000000 --- a/rs/src/repository_watcher.udl +++ /dev/null @@ -1,20 +0,0 @@ -namespace gitnuro { - [Throws=WatcherInitError] - void watch_directory(string path, WatchDirectoryNotifier checker); -}; - -callback interface WatchDirectoryNotifier { - boolean should_keep_looping(); - - void detected_change(sequence paths); -}; - -[Error] -interface WatcherInitError { - Generic(string error); - Io(string error); - PathNotFound(); - WatchNotFound(); - InvalidConfig(); - MaxFilesWatch(); -}; diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GProcessLibSsh.kt b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GProcessLibSsh.kt index ecc681b..80dba1c 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GProcessLibSsh.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GProcessLibSsh.kt @@ -1,13 +1,14 @@ package com.jetpackduba.gitnuro.credentials import com.jetpackduba.gitnuro.ssh.libssh.LibSshChannel -import com.jetpackduba.gitnuro.ssh.libssh.LibSshSession +import uniffi.gitnuro.Channel +import uniffi.gitnuro.Session import java.io.InputStream import java.io.OutputStream class GProcessLibSsh : Process() { private lateinit var channel: LibSshChannel - private lateinit var session: LibSshSession + private lateinit var session: Session private val outputStream by lazy { channel.outputStream @@ -42,7 +43,9 @@ class GProcessLibSsh : Process() { check(!isRunning()) println("exitValue called") - return channel.close() + channel.close() + + return 0 } override fun destroy() { @@ -57,8 +60,8 @@ class GProcessLibSsh : Process() { return channel.isOpen() } - fun setup(session: LibSshSession, commandName: String) { - val channel = session.createChannel() + fun setup(session: Session, commandName: String) { + val channel = LibSshChannel(session) channel.openSession() channel.requestExec(commandName) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt index 4d77843..292fc9b 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt @@ -1,21 +1,17 @@ package com.jetpackduba.gitnuro.credentials -import com.jetpackduba.gitnuro.ssh.libssh.LibSshOptions -import com.jetpackduba.gitnuro.ssh.libssh.LibSshSession -import kotlinx.coroutines.CancellationException import org.eclipse.jgit.transport.RemoteSession import org.eclipse.jgit.transport.URIish +import uniffi.gitnuro.Session import javax.inject.Inject -import javax.inject.Provider private const val DEFAULT_SSH_PORT = 22 class GRemoteSession @Inject constructor( - private val processSession: Provider, private val credentialsStateManager: CredentialsStateManager, ) : RemoteSession { - private var session: LibSshSession? = null + private var session: Session? = null override fun exec(commandName: String, timeout: Int): Process { println("Running command $commandName") @@ -32,44 +28,33 @@ class GRemoteSession @Inject constructor( } fun setup(uri: URIish) { - val session = processSession.get() - session.setOptions(LibSshOptions.SSH_OPTIONS_HOST, uri.host) + val session = Session() + session.setup(uri.host, uri.user, uri.port) - uri.user?.let { - session.setOptions(LibSshOptions.SSH_OPTIONS_USER, uri.user) - } + var result = session.publicKeyAuth() - session.setOptions( - LibSshOptions.SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES, - "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,rsa-sha2-512,rsa-sha2-256,ssh-dss" - ) - session.loadOptionsFromConfig() - - session.connect() - var result = session.userAuthPublicKeyAuto(null, "") - - if (result == 1) { - credentialsStateManager.updateState(CredentialsRequested.SshCredentialsRequested) - - var credentials = credentialsStateManager.currentCredentialsState - while (credentials is CredentialsRequested) { - credentials = credentialsStateManager.currentCredentialsState - } - - val password = if (credentials !is CredentialsAccepted.SshCredentialsAccepted) - throw CancellationException("Credentials cancelled") - else - credentials.password - - result = session.userAuthPublicKeyAuto(null, password) - - if (result != 0) { - result = session.userAuthPassword(password) - } - } - - if (result != 0) - throw Exception("Something went wrong with authentication. Code $result") +// if (result == 1) { +// credentialsStateManager.updateState(CredentialsRequested.SshCredentialsRequested) +// +// var credentials = credentialsStateManager.currentCredentialsState +// while (credentials is CredentialsRequested) { +// credentials = credentialsStateManager.currentCredentialsState +// } +// +// val password = if (credentials !is CredentialsAccepted.SshCredentialsAccepted) +// throw CancellationException("Credentials cancelled") +// else +// credentials.password +// +// result = session.userAuthPublicKeyAuto(null, password) +// +// if (result != 0) { +// result = session.userAuthPassword(password) +// } +// } +// +// if (result != 0) +// throw Exception("Something went wrong with authentication. Code $result") this.session = session } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshChannel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshChannel.kt index 97c6a94..cf60b67 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshChannel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshChannel.kt @@ -3,30 +3,29 @@ package com.jetpackduba.gitnuro.ssh.libssh import com.jetpackduba.gitnuro.ssh.libssh.streams.LibSshChannelInputErrStream import com.jetpackduba.gitnuro.ssh.libssh.streams.LibSshChannelInputStream import com.jetpackduba.gitnuro.ssh.libssh.streams.LibSshChannelOutputStream +import uniffi.gitnuro.Channel +import uniffi.gitnuro.Session -class LibSshChannel internal constructor(sshSession: ssh_session) { - private val sshLib = SSHLibrary.INSTANCE - private var channel: ssh_channel = sshLib.ssh_channel_new(sshSession) +class LibSshChannel internal constructor(sshSession: Session) { + private var channel = Channel(sshSession) val outputStream = LibSshChannelOutputStream(channel) val inputStream = LibSshChannelInputStream(channel) val errorOutputStream = LibSshChannelInputErrStream(channel) - fun openSession() { - sshLib.ssh_channel_open_session(channel) + channel.openSession() } fun requestExec(commandName: String) { - sshLib.ssh_channel_request_exec(channel, commandName) + channel.requestExec(commandName) } fun isOpen(): Boolean { - return sshLib.ssh_channel_is_open(channel) == 1 + return channel.isOpen() } - fun close(): Int { - return sshLib.ssh_channel_close(channel) + fun close() { + channel.close() } - } \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshOptions.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshOptions.kt deleted file mode 100644 index f98ed13..0000000 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshOptions.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.jetpackduba.gitnuro.ssh.libssh - -/** - * Enum based on the enum "ssh_options_e" of libssh/libssh.h - */ -enum class LibSshOptions { - SSH_OPTIONS_HOST, - SSH_OPTIONS_PORT, - SSH_OPTIONS_PORT_STR, - SSH_OPTIONS_FD, - SSH_OPTIONS_USER, - SSH_OPTIONS_SSH_DIR, - SSH_OPTIONS_IDENTITY, - SSH_OPTIONS_ADD_IDENTITY, - SSH_OPTIONS_KNOWNHOSTS, - SSH_OPTIONS_TIMEOUT, - SSH_OPTIONS_TIMEOUT_USEC, - SSH_OPTIONS_SSH1, - SSH_OPTIONS_SSH2, - SSH_OPTIONS_LOG_VERBOSITY, - SSH_OPTIONS_LOG_VERBOSITY_STR, - SSH_OPTIONS_CIPHERS_C_S, - SSH_OPTIONS_CIPHERS_S_C, - SSH_OPTIONS_COMPRESSION_C_S, - SSH_OPTIONS_COMPRESSION_S_C, - SSH_OPTIONS_PROXYCOMMAND, - SSH_OPTIONS_BINDADDR, - SSH_OPTIONS_STRICTHOSTKEYCHECK, - SSH_OPTIONS_COMPRESSION, - SSH_OPTIONS_COMPRESSION_LEVEL, - SSH_OPTIONS_KEY_EXCHANGE, - SSH_OPTIONS_HOSTKEYS, - SSH_OPTIONS_GSSAPI_SERVER_IDENTITY, - SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY, - SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS, - SSH_OPTIONS_HMAC_C_S, - SSH_OPTIONS_HMAC_S_C, - SSH_OPTIONS_PASSWORD_AUTH, - SSH_OPTIONS_PUBKEY_AUTH, - SSH_OPTIONS_KBDINT_AUTH, - SSH_OPTIONS_GSSAPI_AUTH, - SSH_OPTIONS_GLOBAL_KNOWNHOSTS, - SSH_OPTIONS_NODELAY, - SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES, - SSH_OPTIONS_PROCESS_CONFIG, - SSH_OPTIONS_REKEY_DATA, - SSH_OPTIONS_REKEY_TIME, - SSH_OPTIONS_RSA_MIN_SIZE, - SSH_OPTIONS_IDENTITY_AGENT -} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshSession.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshSession.kt deleted file mode 100644 index 7720540..0000000 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshSession.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.jetpackduba.gitnuro.ssh.libssh - -import com.jetpackduba.gitnuro.logging.printError -import com.jetpackduba.gitnuro.ssh.libssh.streams.checkValidResult -import javax.inject.Inject - -private const val TAG = "LibSshSession" - -class LibSshSession @Inject constructor() { - private val sshLib = SSHLibrary.INSTANCE - - private var session: ssh_session = sshLib.ssh_new() - private var channel: LibSshChannel? = null - - fun setOptions(option: LibSshOptions, value: String) { - sshLib.ssh_options_set(session, option.ordinal, value) - } - - fun loadOptionsFromConfig() { - checkValidResult("loadOptionsFromConfig", sshLib.ssh_options_parse_config(session, null)) - } - - fun connect() { - sshLib.ssh_connect(session) - } - - fun userAuthPublicKeyAuto(username: String?, password: String?): Int { - val result = sshLib.ssh_userauth_publickey_auto(session, username, password) - - if (result != 0) - printError(TAG, "Result is: $result.\nError is: ${getError()}") - - return result - } - - fun userAuthPassword(password: String): Int { - val result = sshLib.ssh_userauth_password(session, null, password) - - if (result != 0) - printError(TAG, "Result is: $result.\nError is: ${getError()}") - - return result - } - - fun createChannel(): LibSshChannel { - val newChannel = LibSshChannel(session) - - this.channel = newChannel - - return newChannel - } - - private fun getError(): String { - return sshLib.ssh_get_error(session) - } - - fun disconnect() { - sshLib.ssh_disconnect(session) - } -} - - diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshWrapper.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshWrapper.kt deleted file mode 100644 index eafc8d3..0000000 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshWrapper.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.jetpackduba.gitnuro.ssh.libssh - -import com.sun.jna.Library -import com.sun.jna.Native -import com.sun.jna.PointerType - -class ssh_session : PointerType() -class ssh_channel : PointerType() - -@Suppress("FunctionName") -interface SSHLibrary : Library { - fun ssh_new(): ssh_session - fun ssh_disconnect(session: ssh_session): ssh_session - fun ssh_options_set(session: ssh_session, enumValue: Int, value: String) - - fun ssh_options_parse_config(session: ssh_session, fileName: String?): Int - - fun ssh_connect(session: ssh_session): Int - - fun ssh_userauth_publickey_auto(session: ssh_session, username: String?, password: String?): Int - fun ssh_userauth_password(session: ssh_session, username: String?, password: String?): Int - fun ssh_get_error(session: ssh_session): String - - fun ssh_channel_new(sshSession: ssh_session): ssh_channel - - fun ssh_channel_open_session(sshChannel: ssh_channel): Int - - fun ssh_channel_request_exec(sshChannel: ssh_channel, command: String): Int - - fun ssh_channel_read(sshChannel: ssh_channel, buffer: ByteArray, count: Int, isStderr: Int): Int - - fun ssh_channel_poll(sshChannel: ssh_channel, isStderr: Int): Int - - fun ssh_channel_write(sshChannel: ssh_channel, data: ByteArray, len: Int): Int - - fun ssh_channel_close(sshChannel: ssh_channel): Int - - fun ssh_channel_is_open(sshChannel: ssh_channel): Int - - - companion object { - val INSTANCE = Native.load("ssh", SSHLibrary::class.java) as SSHLibrary - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputErrStream.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputErrStream.kt index 4faaed4..49b4ebb 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputErrStream.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputErrStream.kt @@ -1,20 +1,17 @@ package com.jetpackduba.gitnuro.ssh.libssh.streams -import com.jetpackduba.gitnuro.ssh.libssh.SSHLibrary -import com.jetpackduba.gitnuro.ssh.libssh.ssh_channel +import uniffi.gitnuro.Channel import java.io.InputStream -class LibSshChannelInputErrStream(private val sshChannel: ssh_channel) : InputStream() { +class LibSshChannelInputErrStream(private val sshChannel: Channel) : InputStream() { private var cancelled = false - private val sshLib = SSHLibrary.INSTANCE override fun read(): Int { - val buffer = ByteArray(1) + return if (sshChannel.pollHasBytes(true)) { + val read = sshChannel.read(true, 1u) + val byteArray = read.data - return if (sshLib.ssh_channel_poll(sshChannel, 1) > 0) { - sshLib.ssh_channel_read(sshChannel, buffer, 1, 1) - - val first = buffer.first() + val first = byteArray.first() first.toInt() } else diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputStream.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputStream.kt index 34389ad..5af2833 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputStream.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputStream.kt @@ -1,28 +1,26 @@ package com.jetpackduba.gitnuro.ssh.libssh.streams -import com.jetpackduba.gitnuro.ssh.libssh.SSHLibrary -import com.jetpackduba.gitnuro.ssh.libssh.ssh_channel +import uniffi.gitnuro.Channel import java.io.InputStream -class LibSshChannelInputStream(private val sshChannel: ssh_channel) : InputStream() { - private val sshLib = SSHLibrary.INSTANCE - +class LibSshChannelInputStream(private val sshChannel: Channel) : InputStream() { override fun read(b: ByteArray, off: Int, len: Int): Int { - val byteArray = ByteArray(len) - val result = sshLib.ssh_channel_read(sshChannel, byteArray, len, 0) + val result = sshChannel.read(false, len.toULong()) + val byteArray = result.data + val read = result.readCount + for (i in 0 until len) { b[off + i] = byteArray[i] } - return result + return read.toInt() } override fun read(): Int { - val buffer = ByteArray(1) - sshLib.ssh_channel_read(sshChannel, buffer, 1, 0) + val result = sshChannel.read(false, 1u) - val first = buffer.first() + val first = result.data.first() return first.toInt() } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelOutputStream.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelOutputStream.kt index fed94e9..9293c9c 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelOutputStream.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelOutputStream.kt @@ -1,26 +1,18 @@ package com.jetpackduba.gitnuro.ssh.libssh.streams -import com.jetpackduba.gitnuro.ssh.libssh.SSHLibrary -import com.jetpackduba.gitnuro.ssh.libssh.ssh_channel +import uniffi.gitnuro.Channel import java.io.OutputStream -class LibSshChannelOutputStream(private val sshChannel: ssh_channel) : OutputStream() { - private val sshLib = SSHLibrary.INSTANCE - +class LibSshChannelOutputStream(private val sshChannel: Channel) : OutputStream() { override fun write(b: Int) { val byteArrayData = byteArrayOf(b.toByte()) write(byteArrayData) } override fun write(b: ByteArray) { - sshLib.ssh_channel_write(sshChannel, b, b.size) + sshChannel.writeBytes(b) } override fun close() { } } - -fun checkValidResult(tag: String, result: Int) { - if (result != 0) - throw Exception("$tag - Result is $result") -} \ No newline at end of file