From d29bd1d8067daebb61b3fdefcc5e3b51ba718856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lollipopkit=F0=9F=8F=B3=EF=B8=8F=E2=80=8D=E2=9A=A7?= =?UTF-8?q?=EF=B8=8F?= <10864310+lollipopkit@users.noreply.github.com> Date: Thu, 15 May 2025 21:01:10 +0800 Subject: [PATCH] opt.: ssh page sftp path checking (#763) --- lib/view/page/ssh/page/page.dart | 2 - lib/view/page/ssh/page/virt_key.dart | 56 +++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/lib/view/page/ssh/page/page.dart b/lib/view/page/ssh/page/page.dart index a80c2ca8..084a45cf 100644 --- a/lib/view/page/ssh/page/page.dart +++ b/lib/view/page/ssh/page/page.dart @@ -27,8 +27,6 @@ part 'init.dart'; part 'keyboard.dart'; part 'virt_key.dart'; -const _echoPWD = 'echo \$PWD'; - final class SshPageArgs { final Spi spi; final String? initCmd; diff --git a/lib/view/page/ssh/page/virt_key.dart b/lib/view/page/ssh/page/virt_key.dart index 062df402..3b3bb53d 100644 --- a/lib/view/page/ssh/page/virt_key.dart +++ b/lib/view/page/ssh/page/virt_key.dart @@ -69,22 +69,60 @@ extension _VirtKey on SSHPageState { snippet.runInTerm(_terminal, widget.args.spi); break; case VirtualKeyFunc.file: - // get $PWD from SSH session - _terminal.textInput(_echoPWD); + // get $PWD from SSH session with unique markers + const marker = 'ServerBoxOutput'; + const markerEnd = 'ServerBoxEnd'; + const pwdCommand = 'echo "$marker:\$PWD:$markerEnd"'; + _terminal.textInput(pwdCommand); _terminal.keyInput(TerminalKey.enter); - final cmds = _terminal.buffer.lines.toList(); - // wait for the command to finish - await Future.delayed(const Duration(milliseconds: 777)); - // the line below `echo $PWD` is the current path - final idx = cmds.lastIndexWhere((e) => e.toString().contains(_echoPWD)); - final initPath = cmds.elementAtOrNull(idx + 1)?.toString(); - if (initPath == null || !initPath.startsWith('/')) { + + // Wait for output with timeout + String? initPath; + await Future.delayed(const Duration(milliseconds: 700)); + final startTime = DateTime.now(); + final timeout = const Duration(seconds: 3); + + while (initPath == null) { + // Check if we've exceeded timeout + if (DateTime.now().difference(startTime) > timeout) { + contextSafe?.showRoundDialog( + title: libL10n.error, + child: Text(libL10n.empty), + ); + return; + } + + // Search for marked output in terminal buffer + final cmds = _terminal.buffer.lines.toList(); + for (final line in cmds.reversed) { + final lineStr = line.toString(); + if (lineStr.contains(marker) && lineStr.contains(markerEnd)) { + // Extract path between markers + final start = lineStr.indexOf(marker) + marker.length + 1; // +1 for ':' + final end = lineStr.indexOf(markerEnd) - 1; // -1 for ':' + if (start < end) { + initPath = lineStr.substring(start, end); + if (initPath.isEmpty || initPath == '\$PWD') { + initPath = null; + } else { + break; + } + } + } + } + + // Short wait before checking again + await Future.delayed(const Duration(milliseconds: 100)); + } + + if (!initPath.startsWith('/')) { context.showRoundDialog( title: libL10n.error, child: Text('${l10n.remotePath}: $initPath'), ); return; } + final args = SftpPageArgs(spi: widget.args.spi, initPath: initPath); SftpPage.route.go(context, args); break;