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 */; };
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 = "<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>"; };
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 = "<group>"; };
A95FAA512DF4B62100DE2F5A /* openssl.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = openssl.xcframework; path = Frameworks/openssl.xcframework; sourceTree = "<group>"; };
@@ -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 */,

View File

@@ -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))
}
}
DispatchQueue.global().async {
RunLoop.current.add(timer!, forMode: .common)
}
func readFromChannel() -> String? {
guard ssh_channel_is_open(channel) != 0 else { return nil }
guard ssh_channel_is_eof(channel) == 0 else { return nil }
// ssh_channel_close(channel)
// ssh_channel_free(channel)
var buffer: [CChar] = Array(repeating: 0, count: 256)
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() {

View File

@@ -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)
}
}
}