From e786d31da969616284be36d1ceec525b49d612b7 Mon Sep 17 00:00:00 2001 From: neon443 <69979447+neon443@users.noreply.github.com> Date: Sat, 7 Jun 2025 21:18:30 +0100 Subject: [PATCH] YESS now displays shell on screen!! currently view only :cry but still --- ShhShell.xcodeproj/project.pbxproj | 4 +++ ShhShell/SSHHandler.swift | 46 ++++++++++++++---------------- ShhShell/Views/ContentView.swift | 9 ++++++ 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/ShhShell.xcodeproj/project.pbxproj b/ShhShell.xcodeproj/project.pbxproj index 2ced66a..d47465b 100644 --- a/ShhShell.xcodeproj/project.pbxproj +++ b/ShhShell.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ A92538CD2DEE0744007E0A18 /* ShhShellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CB2DEE0744007E0A18 /* ShhShellTests.swift */; }; A92538D12DEE0745007E0A18 /* ShhShellUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CE2DEE0745007E0A18 /* ShhShellUITests.swift */; }; A92538D22DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CF2DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift */; }; + A93143BE2DF4D0B300FCD5DB /* libpthread.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = A93143BD2DF4D0A700FCD5DB /* libpthread.tbd */; }; A95FAA472DF3884B00DE2F5A /* Config.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = A95FAA462DF3884B00DE2F5A /* Config.xcconfig */; }; A95FAA542DF4B62900DE2F5A /* LibSSH.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */; }; A95FAA552DF4B62900DE2F5A /* LibSSH.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -66,6 +67,7 @@ A92538CB2DEE0744007E0A18 /* ShhShellTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellTests.swift; sourceTree = ""; }; A92538CE2DEE0745007E0A18 /* ShhShellUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellUITests.swift; sourceTree = ""; }; A92538CF2DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellUITestsLaunchTests.swift; sourceTree = ""; }; + A93143BD2DF4D0A700FCD5DB /* libpthread.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libpthread.tbd; path = usr/lib/libpthread.tbd; sourceTree = SDKROOT; }; A95FAA462DF3884B00DE2F5A /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = SOURCE_ROOT; }; A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = LibSSH.xcframework; path = Frameworks/LibSSH.xcframework; sourceTree = ""; }; A95FAA512DF4B62100DE2F5A /* openssl.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = openssl.xcframework; path = Frameworks/openssl.xcframework; sourceTree = ""; }; @@ -82,6 +84,7 @@ buildActionMask = 2147483647; files = ( A95FAA542DF4B62900DE2F5A /* LibSSH.xcframework in Frameworks */, + A93143BE2DF4D0B300FCD5DB /* libpthread.tbd in Frameworks */, A9083E402DF2226F0042906E /* libz.tbd in Frameworks */, A95FAA562DF4B62A00DE2F5A /* openssl.xcframework in Frameworks */, ); @@ -185,6 +188,7 @@ A9C8976F2DF1980900EF9A5F /* Frameworks */ = { isa = PBXGroup; children = ( + A93143BD2DF4D0A700FCD5DB /* libpthread.tbd */, A9083E3F2DF2225A0042906E /* libz.tbd */, A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */, A95FAA512DF4B62100DE2F5A /* openssl.xcframework */, diff --git a/ShhShell/SSHHandler.swift b/ShhShell/SSHHandler.swift index 7dcbd6c..3afbde8 100644 --- a/ShhShell/SSHHandler.swift +++ b/ShhShell/SSHHandler.swift @@ -11,6 +11,7 @@ import OSLog class SSHHandler: ObservableObject { private var session: ssh_session? + private var channel: ssh_channel? @Published var authorized: Bool = false @Published var username: String @@ -250,7 +251,7 @@ class SSHHandler: ObservableObject { func openShell() { var status: CInt - let channel = ssh_channel_new(session) + channel = ssh_channel_new(session) guard let channel = channel else { return } status = ssh_channel_open_session(channel) @@ -259,19 +260,15 @@ class SSHHandler: ObservableObject { return } - interactiveShellSession(channel: channel) + interactiveShellSession() // ssh_channel_close(channel) // ssh_channel_send_eof(channel) // ssh_channel_free(channel) } - private func interactiveShellSession(channel: ssh_channel) { + private func interactiveShellSession() { var status: CInt - var buffer: [CChar] = Array(repeating: 0, count: 256) - var nbytes: CInt = 0 - - let timer: Timer? status = ssh_channel_request_pty(channel) guard status == SSH_OK else { return } @@ -282,29 +279,30 @@ class SSHHandler: ObservableObject { status = ssh_channel_request_shell(channel) guard status == SSH_OK else { return } - timer = Timer(timeInterval: 0.01, repeats: true) { _ in -// guard let self = self else { -// timer?.invalidate() -// return -// } - guard ssh_channel_is_open(channel) != 0 else { return } - guard ssh_channel_is_eof(channel) == 0 else { return } + while ssh_channel_is_open(channel) != 0 && ssh_channel_is_eof(channel) == 0 { + var buffer: [CChar] = Array(repeating: 0, count: 256) + let nbytes = ssh_channel_read_nonblocking(channel, &buffer, UInt32(buffer.count), 0) - nbytes = ssh_channel_read(channel, &buffer, UInt32(buffer.count), 0) guard nbytes > 0 else { return } + write(1, buffer, Int(nbytes)) - if nbytes > 0 { - write(1, buffer, Int(nbytes)) - } - print(String(cString: buffer)) + let data = Data(bytes: buffer, count: buffer.count) + print(String(data: data, encoding: .utf8)) } + } + + func readFromChannel() -> String? { + guard ssh_channel_is_open(channel) != 0 else { return nil } + guard ssh_channel_is_eof(channel) == 0 else { return nil } - DispatchQueue.global().async { - RunLoop.current.add(timer!, forMode: .common) - } + var buffer: [CChar] = Array(repeating: 0, count: 256) + let nbytes = ssh_channel_read_nonblocking(channel, &buffer, UInt32(buffer.count), 0) -// ssh_channel_close(channel) -// ssh_channel_free(channel) + guard nbytes > 0 else { return nil } + write(1, buffer, Int(nbytes)) + + let data = Data(bytes: buffer, count: buffer.count) + return String(data: data, encoding: .utf8)! } private func logSshGetError() { diff --git a/ShhShell/Views/ContentView.swift b/ShhShell/Views/ContentView.swift index a0ff550..223c2cd 100644 --- a/ShhShell/Views/ContentView.swift +++ b/ShhShell/Views/ContentView.swift @@ -12,6 +12,8 @@ struct ContentView: View { @State var connected: Bool = false @State var testSucceded: Bool? + @State var terminal: String = "" + var body: some View { VStack { Text(connected ? "connected" : "not connected") @@ -74,7 +76,14 @@ struct ContentView: View { Button("request a shell") { handler.openShell() + terminal.append(handler.readFromChannel() ?? "") } + + Button("read from server") { + terminal.append(handler.readFromChannel() ?? "") + } + + Text(terminal) } } }