now displays shell on screen!!
currently view only :cry but still
This commit is contained in:
neon443
2025-06-07 21:18:30 +01:00
parent b395876156
commit e786d31da9
3 changed files with 35 additions and 24 deletions

View File

@@ -14,6 +14,7 @@
A92538CD2DEE0744007E0A18 /* ShhShellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CB2DEE0744007E0A18 /* ShhShellTests.swift */; }; A92538CD2DEE0744007E0A18 /* ShhShellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CB2DEE0744007E0A18 /* ShhShellTests.swift */; };
A92538D12DEE0745007E0A18 /* ShhShellUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CE2DEE0745007E0A18 /* ShhShellUITests.swift */; }; A92538D12DEE0745007E0A18 /* ShhShellUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CE2DEE0745007E0A18 /* ShhShellUITests.swift */; };
A92538D22DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CF2DEE0745007E0A18 /* ShhShellUITestsLaunchTests.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 */; }; A95FAA472DF3884B00DE2F5A /* Config.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = A95FAA462DF3884B00DE2F5A /* Config.xcconfig */; };
A95FAA542DF4B62900DE2F5A /* LibSSH.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */; }; 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, ); }; }; 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 = "<group>"; }; A92538CB2DEE0744007E0A18 /* ShhShellTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellTests.swift; sourceTree = "<group>"; };
A92538CE2DEE0745007E0A18 /* ShhShellUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellUITests.swift; sourceTree = "<group>"; }; A92538CE2DEE0745007E0A18 /* ShhShellUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellUITests.swift; sourceTree = "<group>"; };
A92538CF2DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellUITestsLaunchTests.swift; sourceTree = "<group>"; }; A92538CF2DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellUITestsLaunchTests.swift; sourceTree = "<group>"; };
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; }; 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 = "<group>"; }; A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = LibSSH.xcframework; path = Frameworks/LibSSH.xcframework; sourceTree = "<group>"; };
A95FAA512DF4B62100DE2F5A /* openssl.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = openssl.xcframework; path = Frameworks/openssl.xcframework; sourceTree = "<group>"; }; A95FAA512DF4B62100DE2F5A /* openssl.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = openssl.xcframework; path = Frameworks/openssl.xcframework; sourceTree = "<group>"; };
@@ -82,6 +84,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A95FAA542DF4B62900DE2F5A /* LibSSH.xcframework in Frameworks */, A95FAA542DF4B62900DE2F5A /* LibSSH.xcframework in Frameworks */,
A93143BE2DF4D0B300FCD5DB /* libpthread.tbd in Frameworks */,
A9083E402DF2226F0042906E /* libz.tbd in Frameworks */, A9083E402DF2226F0042906E /* libz.tbd in Frameworks */,
A95FAA562DF4B62A00DE2F5A /* openssl.xcframework in Frameworks */, A95FAA562DF4B62A00DE2F5A /* openssl.xcframework in Frameworks */,
); );
@@ -185,6 +188,7 @@
A9C8976F2DF1980900EF9A5F /* Frameworks */ = { A9C8976F2DF1980900EF9A5F /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A93143BD2DF4D0A700FCD5DB /* libpthread.tbd */,
A9083E3F2DF2225A0042906E /* libz.tbd */, A9083E3F2DF2225A0042906E /* libz.tbd */,
A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */, A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */,
A95FAA512DF4B62100DE2F5A /* openssl.xcframework */, A95FAA512DF4B62100DE2F5A /* openssl.xcframework */,

View File

@@ -11,6 +11,7 @@ import OSLog
class SSHHandler: ObservableObject { class SSHHandler: ObservableObject {
private var session: ssh_session? private var session: ssh_session?
private var channel: ssh_channel?
@Published var authorized: Bool = false @Published var authorized: Bool = false
@Published var username: String @Published var username: String
@@ -250,7 +251,7 @@ class SSHHandler: ObservableObject {
func openShell() { func openShell() {
var status: CInt var status: CInt
let channel = ssh_channel_new(session) channel = ssh_channel_new(session)
guard let channel = channel else { return } guard let channel = channel else { return }
status = ssh_channel_open_session(channel) status = ssh_channel_open_session(channel)
@@ -259,19 +260,15 @@ class SSHHandler: ObservableObject {
return return
} }
interactiveShellSession(channel: channel) interactiveShellSession()
// ssh_channel_close(channel) // ssh_channel_close(channel)
// ssh_channel_send_eof(channel) // ssh_channel_send_eof(channel)
// ssh_channel_free(channel) // ssh_channel_free(channel)
} }
private func interactiveShellSession(channel: ssh_channel) { private func interactiveShellSession() {
var status: CInt var status: CInt
var buffer: [CChar] = Array(repeating: 0, count: 256)
var nbytes: CInt = 0
let timer: Timer?
status = ssh_channel_request_pty(channel) status = ssh_channel_request_pty(channel)
guard status == SSH_OK else { return } guard status == SSH_OK else { return }
@@ -282,29 +279,30 @@ class SSHHandler: ObservableObject {
status = ssh_channel_request_shell(channel) status = ssh_channel_request_shell(channel)
guard status == SSH_OK else { return } guard status == SSH_OK else { return }
timer = Timer(timeInterval: 0.01, repeats: true) { _ in while ssh_channel_is_open(channel) != 0 && ssh_channel_is_eof(channel) == 0 {
// guard let self = self else { var buffer: [CChar] = Array(repeating: 0, count: 256)
// timer?.invalidate() let nbytes = ssh_channel_read_nonblocking(channel, &buffer, UInt32(buffer.count), 0)
// return
// }
guard ssh_channel_is_open(channel) != 0 else { return }
guard ssh_channel_is_eof(channel) == 0 else { return }
nbytes = ssh_channel_read(channel, &buffer, UInt32(buffer.count), 0)
guard nbytes > 0 else { return } guard nbytes > 0 else { return }
write(1, buffer, Int(nbytes))
if nbytes > 0 { let data = Data(bytes: buffer, count: buffer.count)
write(1, buffer, Int(nbytes)) print(String(data: data, encoding: .utf8))
}
print(String(cString: buffer))
} }
}
DispatchQueue.global().async { func readFromChannel() -> String? {
RunLoop.current.add(timer!, forMode: .common) guard ssh_channel_is_open(channel) != 0 else { return nil }
} guard ssh_channel_is_eof(channel) == 0 else { return nil }
// ssh_channel_close(channel) var buffer: [CChar] = Array(repeating: 0, count: 256)
// ssh_channel_free(channel) let nbytes = ssh_channel_read_nonblocking(channel, &buffer, UInt32(buffer.count), 0)
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() { private func logSshGetError() {

View File

@@ -12,6 +12,8 @@ struct ContentView: View {
@State var connected: Bool = false @State var connected: Bool = false
@State var testSucceded: Bool? @State var testSucceded: Bool?
@State var terminal: String = ""
var body: some View { var body: some View {
VStack { VStack {
Text(connected ? "connected" : "not connected") Text(connected ? "connected" : "not connected")
@@ -74,7 +76,14 @@ struct ContentView: View {
Button("request a shell") { Button("request a shell") {
handler.openShell() handler.openShell()
terminal.append(handler.readFromChannel() ?? "")
} }
Button("read from server") {
terminal.append(handler.readFromChannel() ?? "")
}
Text(terminal)
} }
} }
} }