Documentation
¶
Index ¶
- Variables
- func CloseIdlePool()
- func DialSSH(host, port, user, pass, keyPath string, timeout int, px netproxy.Settings) (*ssh.Client, error)
- func GetProtocols() []string
- func RegisterProtocol(h ProtocolHandler)
- type FTPVFS
- func (v *FTPVFS) Abs(p string) (string, error)
- func (v *FTPVFS) Base(p string) string
- func (v *FTPVFS) BookmarkPath(string) (string, bool)
- func (v *FTPVFS) Clone() vfs.VFS
- func (v *FTPVFS) Close() error
- func (v *FTPVFS) Create(ctx context.Context, p string) (io.WriteCloser, error)
- func (v *FTPVFS) Dir(p string) string
- func (v *FTPVFS) GetCapabilities() vfs.VFSCapabilities
- func (v *FTPVFS) GetPath() string
- func (v *FTPVFS) GetTitle() string
- func (v *FTPVFS) HistoryEntry() (display, ref string, ok bool)
- func (v *FTPVFS) IsAbs(p string) bool
- func (v *FTPVFS) IsAtRoot() bool
- func (v *FTPVFS) Join(e ...string) string
- func (v *FTPVFS) MkDir(ctx context.Context, p string) error
- func (v *FTPVFS) NavigateHistoryEntry(ref string) bool
- func (v *FTPVFS) Open(ctx context.Context, p string) (vfs.ReadAtCloser, error)
- func (v *FTPVFS) ParentVFS() vfs.VFS
- func (v *FTPVFS) ReadDir(ctx context.Context, p string, onChunk func([]vfs.VFSItem)) error
- func (v *FTPVFS) Remove(ctx context.Context, p string) error
- func (v *FTPVFS) Rename(ctx context.Context, o, n string) error
- func (v *FTPVFS) Search(ctx context.Context, p, pat string) (chan int64, error)
- func (v *FTPVFS) SessionKey() any
- func (v *FTPVFS) SetAttributes(ctx context.Context, path string, item vfs.VFSItem) error
- func (v *FTPVFS) SetPath(p string) error
- func (v *FTPVFS) Stat(ctx context.Context, p string) (vfs.VFSItem, error)
- type FishDialer
- type FishVFS
- func NewFishVFS(parent vfs.VFS, host, port, user, pass, keyPath string, timeout int, ...) (*FishVFS, error)
- func NewFishVFSOnDialer(ctx context.Context, parent vfs.VFS, dial FishDialer, title string) (*FishVFS, error)
- func NewFishVFSOnDialers(ctx context.Context, parent vfs.VFS, dial FishDialer, ...) (*FishVFS, error)
- func NewFishVFSOnStream(ctx context.Context, parent vfs.VFS, stdin io.Writer, stdout io.Reader, ...) (*FishVFS, error)
- func NewFishVFSOnStreamWithOptions(ctx context.Context, parent vfs.VFS, stdin io.Writer, stdout io.Reader, ...) (*FishVFS, error)
- func NewFishVFSWithOptions(parent vfs.VFS, host, port, user, pass, keyPath string, timeout int, ...) (*FishVFS, error)
- func (v *FishVFS) Abs(p string) (string, error)
- func (v *FishVFS) Base(p string) string
- func (v *FishVFS) BookmarkPath(string) (string, bool)
- func (v *FishVFS) CachedPanelInfo(req vfs.PanelInfoRequest) (vfs.PanelInfoSnapshot, bool)
- func (v *FishVFS) CanReconnect() bool
- func (v *FishVFS) Client() *fishplus.Client
- func (v *FishVFS) Clone() vfs.VFS
- func (v *FishVFS) CloneForParent(parent vfs.VFS) *FishVFS
- func (v *FishVFS) Close() error
- func (v *FishVFS) CommandRunnerAvailable() bool
- func (v *FishVFS) CommandRunnerInfo() vfs.CommandRunnerInfo
- func (v *FishVFS) ConnectionInfo() (host, port, user string, ok bool)
- func (v *FishVFS) Copy(ctx context.Context, o, n string) error
- func (v *FishVFS) Create(ctx context.Context, p string) (io.WriteCloser, error)
- func (v *FishVFS) Dir(p string) string
- func (v *FishVFS) FindDuplicates(ctx context.Context, dir string, cb func(vfs.DuplicateProgress)) ([][]string, error)
- func (v *FishVFS) FindFiles(ctx context.Context, dir string, q vfs.FindQuery) ([]vfs.FoundEntry, error)
- func (v *FishVFS) FindFilesStream(ctx context.Context, dir string, q vfs.FindQuery, onFound func(vfs.FoundEntry)) error
- func (v *FishVFS) GetCapabilities() vfs.VFSCapabilities
- func (v *FishVFS) GetPath() string
- func (v *FishVFS) GetTitle() string
- func (v *FishVFS) HistoryEntry() (display, ref string, ok bool)
- func (v *FishVFS) IsAbs(p string) bool
- func (v *FishVFS) IsAtRoot() bool
- func (v *FishVFS) Join(e ...string) string
- func (v *FishVFS) LineIndex(ctx context.Context, p string, first, count int64) (vfs.LineIndexResult, error)
- func (v *FishVFS) MkDir(ctx context.Context, p string) error
- func (v *FishVFS) NavigateHistoryEntry(ref string) bool
- func (v *FishVFS) Open(ctx context.Context, p string) (vfs.ReadAtCloser, error)
- func (v *FishVFS) OpenPty(cols, rows int) (any, error)
- func (v *FishVFS) PanelInfoKey(req vfs.PanelInfoRequest) string
- func (v *FishVFS) PanelTitle(path string) string
- func (v *FishVFS) ParentVFS() vfs.VFS
- func (v *FishVFS) PatchFile(ctx context.Context, src, dst string, pieces []vfs.PatchPiece) error
- func (v *FishVFS) PtyAvailable() bool
- func (v *FishVFS) PtyChangeDirCommand(dir string) []byte
- func (v *FishVFS) PtyInitSequence() []byte
- func (v *FishVFS) PtyInterrupt() []byte
- func (v *FishVFS) PtyRunCommand(dir, command string) []byte
- func (v *FishVFS) ReadDir(ctx context.Context, p string, onChunk func([]vfs.VFSItem)) error
- func (v *FishVFS) Reconnect(ctx context.Context) error
- func (v *FishVFS) RefreshPanelInfo(ctx context.Context, req vfs.PanelInfoRequest) (vfs.PanelInfoSnapshot, error)
- func (v *FishVFS) Remove(ctx context.Context, p string) error
- func (v *FishVFS) Rename(ctx context.Context, o, n string) error
- func (v *FishVFS) RunCommand(ctx context.Context, dir, command string, cb func(line string)) (int, error)
- func (v *FishVFS) Scan(ctx context.Context, basePath string, names []string, cb vfs.ScanCallback) (vfs.OpStats, error)
- func (v *FishVFS) Search(ctx context.Context, p, pattern string) (chan int64, error)
- func (v *FishVFS) SecondHopPassword() (string, bool)
- func (v *FishVFS) SessionKey() any
- func (v *FishVFS) SessionLost(err error) bool
- func (v *FishVFS) SetAttributes(ctx context.Context, p string, item vfs.VFSItem) error
- func (v *FishVFS) SetPanelInfoProvider(provider vfs.PanelInfoProvider)
- func (v *FishVFS) SetPanelTitleFormatter(formatter func(title, path string) string)
- func (v *FishVFS) SetPath(p string) error
- func (v *FishVFS) SetPathOptimistic(p string) error
- func (v *FishVFS) StageSecret(ctx context.Context, password string) (string, func(context.Context), error)
- func (v *FishVFS) Stat(ctx context.Context, p string) (vfs.VFSItem, error)
- type NetFoxConfig
- type NetFoxPlugin
- type NetFoxVFS
- func (v *NetFoxVFS) Abs(p string) (string, error)
- func (v *NetFoxVFS) Base(p string) string
- func (v *NetFoxVFS) BookmarkPath(cursor string) (string, bool)
- func (v *NetFoxVFS) Clone() vfs.VFS
- func (v *NetFoxVFS) Close() error
- func (v *NetFoxVFS) Create(ctx context.Context, p string) (io.WriteCloser, error)
- func (v *NetFoxVFS) Dir(p string) string
- func (v *NetFoxVFS) GetCapabilities() vfs.VFSCapabilities
- func (v *NetFoxVFS) GetPath() string
- func (v *NetFoxVFS) HistoryEntry() (display, ref string, ok bool)
- func (v *NetFoxVFS) IsAbs(p string) bool
- func (v *NetFoxVFS) IsAtRoot() bool
- func (v *NetFoxVFS) IsReadOnly() bool
- func (v *NetFoxVFS) Join(e ...string) string
- func (v *NetFoxVFS) MkDir(ctx context.Context, p string) error
- func (v *NetFoxVFS) NavigateHistoryEntry(ref string) bool
- func (v *NetFoxVFS) Open(ctx context.Context, p string) (vfs.ReadAtCloser, error)
- func (v *NetFoxVFS) ParentVFS() vfs.VFS
- func (v *NetFoxVFS) ReadDir(ctx context.Context, p string, onChunk func([]vfs.VFSItem)) error
- func (v *NetFoxVFS) Remove(ctx context.Context, p string) error
- func (v *NetFoxVFS) Rename(ctx context.Context, old, new string) error
- func (v *NetFoxVFS) SaveConfig(name string, cfg NetFoxConfig) error
- func (v *NetFoxVFS) Search(ctx context.Context, p, pat string) (chan int64, error)
- func (v *NetFoxVFS) SetAttributes(ctx context.Context, path string, item vfs.VFSItem) error
- func (v *NetFoxVFS) SetPath(p string) error
- func (v *NetFoxVFS) Stat(ctx context.Context, p string) (vfs.VFSItem, error)
- type ProtocolHandler
- type SFTPVFS
- func (v *SFTPVFS) Abs(p string) (string, error)
- func (v *SFTPVFS) Base(p string) string
- func (v *SFTPVFS) BookmarkPath(string) (string, bool)
- func (v *SFTPVFS) Clone() vfs.VFS
- func (v *SFTPVFS) Close() error
- func (*SFTPVFS) CommandRunnerInfo() vfs.CommandRunnerInfo
- func (v *SFTPVFS) Create(ctx context.Context, p string) (io.WriteCloser, error)
- func (v *SFTPVFS) Dir(p string) string
- func (v *SFTPVFS) EncodeCommandListANSI(text []byte) ([]byte, error)
- func (v *SFTPVFS) GetCapabilities() vfs.VFSCapabilities
- func (v *SFTPVFS) GetPath() string
- func (v *SFTPVFS) GetTitle() string
- func (v *SFTPVFS) HistoryEntry() (display, ref string, ok bool)
- func (v *SFTPVFS) IsAbs(p string) bool
- func (v *SFTPVFS) IsAtRoot() bool
- func (v *SFTPVFS) Join(e ...string) string
- func (v *SFTPVFS) MkDir(ctx context.Context, p string) error
- func (v *SFTPVFS) NavigateHistoryEntry(ref string) bool
- func (v *SFTPVFS) Open(ctx context.Context, p string) (vfs.ReadAtCloser, error)
- func (v *SFTPVFS) OpenPty(cols, rows int) (any, error)
- func (v *SFTPVFS) OpenWriteAt(ctx context.Context, p string) (vfs.WriterAtCloser, error)
- func (v *SFTPVFS) ParentVFS() vfs.VFS
- func (v *SFTPVFS) ReadDir(ctx context.Context, p string, onChunk func([]vfs.VFSItem)) error
- func (v *SFTPVFS) Readlink(ctx context.Context, p string) (string, error)
- func (v *SFTPVFS) Remove(ctx context.Context, p string) error
- func (v *SFTPVFS) Rename(ctx context.Context, o, n string) error
- func (v *SFTPVFS) RunCommand(ctx context.Context, dir, command string, cb func(line string)) (int, error)
- func (v *SFTPVFS) Search(ctx context.Context, p, pat string) (chan int64, error)
- func (v *SFTPVFS) SessionKey() any
- func (v *SFTPVFS) SetAttributes(ctx context.Context, path string, item vfs.VFSItem) error
- func (v *SFTPVFS) SetPath(p string) error
- func (v *SFTPVFS) Stat(ctx context.Context, p string) (vfs.VFSItem, error)
- func (*SFTPVFS) SupportsConcurrentCalls() bool
- func (v *SFTPVFS) Symlink(ctx context.Context, target, linkPath string) error
- type SSHPty
Constants ¶
This section is empty.
Variables ¶
var ErrNoDialer = errors.New("fishplus: this session cannot be reconnected")
ErrNoDialer is what a reconnect answers when nobody told the connection how to rebuild itself.
var FishPoolIdleTimeout = 15 * time.Minute
FishPoolIdleTimeout is how long a session is kept alive with nothing attached to it before it is finally closed. Reopening the same site within this window hands back the still-live connection instead of dialling and shaking hands again, so stepping out of a panel and back into it — the "other panel" swap, a quick trip to a local directory and back — costs nothing over a remote link that a fresh connection would have made the user wait for.
var FishPreferRemoteF4 atomic.Bool
FishPreferRemoteF4 makes a FISH+ connection over SSH try f4 itself as the server first (nativeRemoteCommand, fishplus.Server), falling back to the shell helper on a host without f4 (unxed/f4#1680). Off by default: on a host without f4 it costs one extra connection attempt before the fallback.
Functions ¶
func CloseIdlePool ¶
func CloseIdlePool()
CloseIdlePool closes every FISH+ session the pool is holding onto. f4 calls it once, during application shutdown.
func DialSSH ¶
func DialSSH(host, port, user, pass, keyPath string, timeout int, px netproxy.Settings) (*ssh.Client, error)
DialSSH opens an SSH connection the way every SSH based NetFox backend needs it. When keyPath is set, that key is the only key file offered, and it goes ahead of whatever the ssh-agent carries — this avoids servers that cut the handshake short after a handful of failed public-key attempts (MaxAuthTries) before ever reaching the right key. When keyPath is empty, it is the agent, then the usual private keys from ~/.ssh, then the password. It is shared by the SFTP and the FISH+ backends so that a site behaves identically whichever of them opens it.
func GetProtocols ¶
func GetProtocols() []string
func RegisterProtocol ¶
func RegisterProtocol(h ProtocolHandler)
Types ¶
type FTPVFS ¶
type FTPVFS struct {
// contains filtered or unexported fields
}
func (*FTPVFS) BookmarkPath ¶
BookmarkPath implements vfs.BookmarkPathProvider: the folder on the server under the address the session was opened from (bookmark_path.go).
func (*FTPVFS) GetCapabilities ¶
func (v *FTPVFS) GetCapabilities() vfs.VFSCapabilities
func (*FTPVFS) HistoryEntry ¶
HistoryEntry and NavigateHistoryEntry implement vfs.HistoryPathProvider (f4#262): an FTP session owns its own folder-history entries instead of its raw remote path (e.g. /root/foo) being recorded as if it were local.
func (*FTPVFS) NavigateHistoryEntry ¶
func (*FTPVFS) SessionKey ¶
func (*FTPVFS) SetAttributes ¶
type FishDialer ¶
fishConn keeps one FISH+ session alive for as long as any of the VFS instances built on it is still in use. f4 clones a panel's file system in several places — the "other panel" menu item and the frame snapshot taken for a background task — and every panel closes its own file system when it leaves it. Handing back the same instance, the way the SFTP backend does, would therefore let one panel tear the session down under another, and would make both panels share a single current directory.
Requests from the clones interleave freely: the session serializes them with its own mutex, so each request stays atomic. They do not run in parallel, which for a shell that answers one command at a time is what a second connection could not fix anyway. FishDialer opens a new transport for a session that has to be rebuilt. It returns the two halves of the stream and the closer that ties the remote shell and its connection to the session speaking through them — the same three things NewFishVFSOnStream is handed. Whoever built the connection supplies it, which is what keeps SSH out of this file and lets the tests reconnect to a local shell instead.
A nil dialer means the connection cannot be rebuilt, which is the honest answer for a caller that handed over a pair of streams it has no second copy of.
type FishVFS ¶
type FishVFS struct {
// contains filtered or unexported fields
}
FishVFS exposes a FISH+ session as an f4 file system. It owns the session and closes it with itself; the transport underneath is whatever stream the caller handed over, which is what lets the tests run it on a local shell instead of on ssh.
func NewFishVFS ¶
func NewFishVFS(parent vfs.VFS, host, port, user, pass, keyPath string, timeout int, px netproxy.Settings) (*FishVFS, error)
NewFishVFS opens a site over SSH. It goes through a dialer rather than through a pair of streams, so the session it hands back is one that can be rebuilt after the connection drops; a site opened any other way would have to be reopened by hand.
func NewFishVFSOnDialer ¶
func NewFishVFSOnDialer(ctx context.Context, parent vfs.VFS, dial FishDialer, title string) (*FishVFS, error)
NewFishVFSOnDialer builds a session the same way and remembers how to build it again, which is what a reconnect needs. The dialer is called once here so that a site that cannot be reached fails at open time rather than at the first request.
func NewFishVFSOnDialers ¶
func NewFishVFSOnDialers(ctx context.Context, parent vfs.VFS, dial FishDialer, opts fishplus.HandshakeOptions, dialAlt FishDialer, optsAlt fishplus.HandshakeOptions, title string) (*FishVFS, error)
NewFishVFSOnDialers is NewFishVFSOnDialer with a fallback: a peer the first (dial, opts) pair cannot bring a helper up on is retried with the second pair. Meant for sites where the shell flavor is not known at open time — a POSIX login shell wins the common case, and a PowerShell peer answers only after the retry. Once the fallback succeeds it is promoted to primary, so every reconnect after the first goes straight to the flavor that actually works. A nil dialAlt means no fallback.
func NewFishVFSOnStream ¶
func NewFishVFSOnStream(ctx context.Context, parent vfs.VFS, stdin io.Writer, stdout io.Reader, closer io.Closer, title string) (*FishVFS, error)
NewFishVFSOnStream completes the handshake on an already established pair of streams and opens the panel in whatever directory the remote shell started in. closer may be nil; when set it is closed together with the session, which is also what makes the remote helper exit.
func NewFishVFSOnStreamWithOptions ¶
func NewFishVFSOnStreamWithOptions(ctx context.Context, parent vfs.VFS, stdin io.Writer, stdout io.Reader, closer io.Closer, title string, opts fishplus.HandshakeOptions) (*FishVFS, error)
NewFishVFSOnStreamWithOptions is the transport-specific variant of NewFishVFSOnStream. Most callers should keep the default line bootstrap; transports such as Android shell_v2 can select the single-line base64 bootstrap without changing the FISH+ filesystem implementation.
func NewFishVFSWithOptions ¶
func NewFishVFSWithOptions(parent vfs.VFS, host, port, user, pass, keyPath string, timeout int, px netproxy.Settings, remoteF4 bool) (*FishVFS, error)
NewFishVFSWithOptions is NewFishVFS with the choice of server made by the caller: with remoteF4 set the peer's f4 (--fish-server) is tried before the shell helper (see FishPreferRemoteF4).
func (*FishVFS) BookmarkPath ¶
BookmarkPath implements vfs.BookmarkPathProvider: the folder on the server under the address the session was opened from (bookmark_path.go).
func (*FishVFS) CachedPanelInfo ¶
func (v *FishVFS) CachedPanelInfo(req vfs.PanelInfoRequest) (vfs.PanelInfoSnapshot, bool)
func (*FishVFS) CanReconnect ¶
CanReconnect reports whether this file system can rebuild its session. A site opened from a configuration can; one handed a pair of streams cannot, because there is no second pair. A caller offering the user a choice has to know which it is before it offers one.
func (*FishVFS) Client ¶
Client exposes the underlying protocol client, mostly so a caller can ask what the remote host turned out to be capable of.
func (*FishVFS) Clone ¶
Clone returns a second view of the same session, with its own current directory. A second login would cost another authentication and another password prompt, and would buy nothing: the remote shell answers one command at a time either way.
func (*FishVFS) CloneForParent ¶
CloneForParent returns another view of the same live session attached to a different mount parent. Session pools use it to retain a parentless anchor while every panel still gets the manager instance it was opened from.
func (*FishVFS) Close ¶
Close releases this view. The session itself goes away with its last user, and closing the same view twice is harmless: a panel may well be closed by both its own teardown and the frame that owned it.
func (*FishVFS) CommandRunnerAvailable ¶
func (*FishVFS) CommandRunnerInfo ¶
func (v *FishVFS) CommandRunnerInfo() vfs.CommandRunnerInfo
CommandRunnerInfo reports the remote shell syntax and the transport's real concurrency limit. A FISH+ connection serializes protocol requests, so advertising more workers would only reorder queued requests locally.
func (*FishVFS) ConnectionInfo ¶
ConnectionInfo implements vfs.ConnectionInfoProvider. A session with no host of its own -- the WSL "wsl" site type (wsl_vfs_windows.go) reaches its distribution through a locally spawned wsl.exe, not a network address -- reports ok=false: it is not a second hop any scp-based server-to-server transfer (internal/fileops/ops.go) could ever reach.
func (*FishVFS) Create ¶
Create truncates the file, or creates it, and hands back a handle that streams from the beginning. The handle buffers up to one transfer chunk, so the copier's small writes do not each become a round trip.
func (*FishVFS) FindDuplicates ¶
func (v *FishVFS) FindDuplicates(ctx context.Context, dir string, cb func(vfs.DuplicateProgress)) ([][]string, error)
FindDuplicates implements vfs.DuplicateFinder. Only the paths of the files that turned out to be identical cross the network; the reading and the hashing happen where the disk is.
func (*FishVFS) FindFiles ¶
func (v *FishVFS) FindFiles(ctx context.Context, dir string, q vfs.FindQuery) ([]vfs.FoundEntry, error)
FindFiles implements vfs.FileFinder. The remote host walks the tree and, when a content pattern is given, greps the candidates in the same pass, so what crosses the network is one request and one line per hit.
A symlink is reported as found without resolving it: the alternative is a round trip per hit, which would give back what the whole command saves.
func (*FishVFS) FindFilesStream ¶
func (v *FishVFS) FindFilesStream(ctx context.Context, dir string, q vfs.FindQuery, onFound func(vfs.FoundEntry)) error
FindFilesStream keeps the panel session free while a synchronous ffind owns its protocol lock. Job searches already release that lock between polls.
func (*FishVFS) GetCapabilities ¶
func (v *FishVFS) GetCapabilities() vfs.VFSCapabilities
func (*FishVFS) HistoryEntry ¶
HistoryEntry and NavigateHistoryEntry implement vfs.HistoryPathProvider (f4#262): a FISH+ session owns its own folder-history entries instead of its raw remote path (e.g. /root/foo) being recorded as if it were local.
func (*FishVFS) LineIndex ¶
func (v *FishVFS) LineIndex(ctx context.Context, p string, first, count int64) (vfs.LineIndexResult, error)
LineIndex implements vfs.LineIndexer. A count of zero asks for nothing but the total, which is one remote pass and three numbers on the wire.
func (*FishVFS) NavigateHistoryEntry ¶
func (*FishVFS) PanelInfoKey ¶
func (v *FishVFS) PanelInfoKey(req vfs.PanelInfoRequest) string
func (*FishVFS) PanelTitle ¶
func (*FishVFS) PatchFile ¶
PatchFile implements vfs.DeltaWriter. The copying happens on the remote host at local disk speed; only the new bytes cross the network.
func (*FishVFS) PtyAvailable ¶
PtyAvailable distinguishes SSH-backed FISH+ from transports such as Android shell_v2. The concrete FishVFS type has OpenPty for the SSH case, but treating every instance as a remote PTY makes Android navigation send Unix cd commands into f4's local terminal on every path change.
func (*FishVFS) PtyChangeDirCommand ¶
PtyChangeDirCommand implements vfs.PtyShellIntegration. The panel's PTY channel runs the peer's DefaultShell — cmd.exe on a stock OpenSSH-Server-Windows host, whatever the login shell is on a POSIX host. Send syntax the actual PTY shell understands, converting the path from the wire's Cygwin shape (/c/Users/foo) to what the shell wants (C:\Users\foo for cmd, /c/Users/foo unchanged for POSIX).
f4_sync is a stray marker helper.sh's own log filter can strip: cmd keeps it as a rem comment, POSIX carries it as "&& true f4_sync" — not a "#" comment, because stock zsh ships with interactive_comments off and would feed the tail to cd as extra arguments.
func (*FishVFS) PtyInitSequence ¶
PtyInitSequence implements vfs.PtyShellIntegration. On a Windows peer it sets cmd's PROMPT so that every prompt cmd draws — every time a command finishes — embeds an OSC 133 D marker. The ANSI parser in terminal_view.go then fires OnBusyChange(false), which is what makes panels_frame return to panels after a cmdline command completes. This is the same trick panels_frame.go uses for the local Windows PTY (see the os.Setenv("PROMPT", ...) around initPTY).
$E is cmd's PROMPT syntax for ESC; $E\ is the OSC ST terminator (\x1b\); $P and $G are the standard current-path-and-'>' pieces. The leading @ suppresses cmd's echo of the prompt-setup line in batch contexts; interactive cmd on ConPTY still echoes it, so the second half of the line is a cls that wipes the cmd banner + copyright + the echoed setup line, leaving the panel-terminal view starting on the first marker-embedded prompt with no visible init noise.
func (*FishVFS) PtyInterrupt ¶
PtyInterrupt implements vfs.PtyShellIntegration. cmd.exe over ConPTY and every POSIX shell treat a raw ETX (0x03) as SIGINT / Ctrl+C; no flavor-specific wrapping is needed.
func (*FishVFS) PtyRunCommand ¶
PtyRunCommand implements vfs.PtyShellIntegration. Same shell-flavor split as PtyChangeDirCommand: cmd wants "cd /d \"path\" & command", POSIX wants "cd 'path' && command". An empty dir skips the cd.
func (*FishVFS) Reconnect ¶
Reconnect rebuilds the session behind this file system and points this view at the result. The new shell knows nothing of what the old one was doing: background jobs are gone, and a write or a patch that was in flight cannot be resumed, only reported. What survives is what lives on this side — the path this panel stands in, a read handle, and the credentials the dialer holds.
It is deliberately not called from inside a request. A request that reconnected on its own would turn one failure into a delay of unknown length in the middle of a copy, with no way for the user to say no; the choice belongs to whoever meets ErrBroken and can ask.
Every view of the connection is repointed, not just this one: they all reach the session through the connection, so the panel that asked and the panel next to it are on the same shell afterwards. What each of them keeps is its own current directory, which never depended on the shell that died.
func (*FishVFS) RefreshPanelInfo ¶
func (v *FishVFS) RefreshPanelInfo(ctx context.Context, req vfs.PanelInfoRequest) (vfs.PanelInfoSnapshot, error)
func (*FishVFS) Remove ¶
Remove deletes whatever is at the path. A directory is removed with everything below it by the remote host itself, in one round trip instead of one per entry, which is the main reason a shell based file system is worth having at all.
func (*FishVFS) RunCommand ¶
func (v *FishVFS) RunCommand(ctx context.Context, dir, command string, cb func(line string)) (int, error)
RunCommand implements vfs.CommandRunner. The command runs as a job, so it can read stdin, print for an hour or never end without any of that reaching the request stream the panel is using.
func (*FishVFS) Scan ¶
func (v *FishVFS) Scan(ctx context.Context, basePath string, names []string, cb vfs.ScanCallback) (vfs.OpStats, error)
Scan implements vfs.FastScanner. Counting a tree is one remote job instead of a listing round trip per directory, which is the difference between a directory size dialog that answers and one the user gives up on.
Anything the remote host cannot do falls back to the generic walk, because the caller takes this answer as final: vfs.CalculateStats does not retry a FastScanner that failed.
func (*FishVFS) Search ¶
Search hands the pattern to the remote host's own grep and returns the byte offset of every match. Only the offsets cross the network, which is what lets a panel search a log it would take an hour to download. A host without the tools answers nil, and the caller falls back to reading the file, exactly as it does with SFTP.
func (*FishVFS) SecondHopPassword ¶
SecondHopPassword implements vfs.SecondHopPasswordProvider. It answers on this site's own behalf: a server-to-server transfer that wants to authenticate to this exact host, port and user with a password asks here, and gets one back only when NetFox's "password auth for server-to-server transfers" setting is on and a saved connection matches (see secondHopPassword in s2s_password.go).
func (*FishVFS) SessionKey ¶
SessionKey implements vfs.SessionIdentity. The connection is the identity: a clone shares it, which is exactly the property a caller looking for everything that died with one session needs.
func (*FishVFS) SessionLost ¶
SessionLost implements vfs.SessionReconnector. Only a session that stopped speaking counts: a file that is not there, a permission that was refused or a cancelled request are failures of the request, and offering to reconnect over any of them would be noise in front of the real message.
func (*FishVFS) SetAttributes ¶
SetAttributes applies the permission bits, then the ownership, then the timestamps. A Uid or Gid below zero means "leave that half alone", which is what the copier passes; a zero timestamp is filled in from the other one, the same way the SFTP backend does it, so a file copied onto a FISH+ panel keeps the times it had.
func (*FishVFS) SetPanelInfoProvider ¶
func (v *FishVFS) SetPanelInfoProvider(provider vfs.PanelInfoProvider)
SetPanelInfoProvider attaches transport-specific facts without wrapping the filesystem. Keeping *FishVFS as the mounted concrete type is important to the Android session pool and to callers that inspect protocol features.
func (*FishVFS) SetPanelTitleFormatter ¶
SetPanelTitleFormatter customizes only the path rendered in the panel border. The canonical POSIX path and the session title remain untouched.
func (*FishVFS) SetPathOptimistic ¶
SetPathOptimistic only changes this view's client-side path. A panel calls it for a row already known to be a directory, including a cached row, then validates that possibly stale knowledge with its asynchronous ReadDir. FISH+ sends absolute paths with every command and has no server-side cwd, so no protocol request is needed here.
func (*FishVFS) StageSecret ¶
func (v *FishVFS) StageSecret(ctx context.Context, password string) (string, func(context.Context), error)
StageSecret implements vfs.SecondHopSecretStager. The secret travels to this host over the same encrypted FISH+ write channel every ordinary file transfer already uses (Client.Write) -- never as part of a command's own text, never through an environment variable a sibling process could read out of /proc, and never logged -- and lands in a file mktemp created for this call alone, which cleanup removes again once the caller is done.
type NetFoxConfig ¶
type NetFoxConfig struct {
Type string `json:"Type"`
Host string `json:"Host"`
Port string `json:"Port"`
User string `json:"User"`
Pass string `json:"Pass"`
KeyPath string `json:"KeyPath,omitempty"`
Timeout string `json:"Timeout,omitempty"`
Codepage string `json:"Codepage,omitempty"`
Options map[string]string `json:"Options,omitempty"`
// Path is the folder the connection opens in, like the path of a Far
// connection (nz256, f4#1894); empty opens where the server puts a new
// session, the home folder of the user as a rule.
Path string `json:"Path,omitempty"`
// Proxy overrides f4's app-wide proxy for this site alone. ProxyMode 0
// is netproxy.ModeGlobal, so connections saved before this existed —
// and new ones the user never touched — simply follow the app setting.
ProxyMode int `json:"ProxyMode,omitempty"`
ProxyHost string `json:"ProxyHost,omitempty"`
ProxyPort string `json:"ProxyPort,omitempty"`
ProxyUser string `json:"ProxyUser,omitempty"`
ProxyPass string `json:"ProxyPass,omitempty"`
}
func (NetFoxConfig) Proxy ¶
func (c NetFoxConfig) Proxy() netproxy.Settings
Proxy is the settings this connection dials through: its own when it overrides, the app-wide ones otherwise.
type NetFoxPlugin ¶
type NetFoxPlugin struct {
// contains filtered or unexported fields
}
func (*NetFoxPlugin) Close ¶
func (p *NetFoxPlugin) Close() error
func (*NetFoxPlugin) GetName ¶
func (p *NetFoxPlugin) GetName() string
type NetFoxVFS ¶
type NetFoxVFS struct {
// contains filtered or unexported fields
}
func NewNetFoxVFS ¶
func (*NetFoxVFS) BookmarkPath ¶
BookmarkPath implements vfs.BookmarkPathProvider for the connection manager: a bookmark made with the cursor on a saved connection is the address of that connection, so a connection is bookmarked without being opened; anywhere else in the list it is the manager itself.
func (*NetFoxVFS) GetCapabilities ¶
func (v *NetFoxVFS) GetCapabilities() vfs.VFSCapabilities
func (*NetFoxVFS) HistoryEntry ¶
HistoryEntry implements vfs.HistoryPathProvider. The root screen is a list of saved connections, not a folder, so it never has anything worth remembering in folder history (f4#262): without this, the bare "net://" GetPath() above fell through to ShouldRecordFolderHistory's "no parent VFS, trust it as a local path" rule and was recorded as a useless entry point with no navigational value.
func (*NetFoxVFS) IsReadOnly ¶
func (*NetFoxVFS) NavigateHistoryEntry ¶
NavigateHistoryEntry implements vfs.HistoryPathProvider. HistoryEntry above never produces an entry for the root screen, so this is never reached through the normal folder-history flow; it exists only to satisfy the interface and always declines.
func (*NetFoxVFS) SaveConfig ¶
func (v *NetFoxVFS) SaveConfig(name string, cfg NetFoxConfig) error
func (*NetFoxVFS) SetAttributes ¶
func (*NetFoxVFS) SetPath ¶
SetPath accepts the spellings of the manager's own root and nothing else. The list has no folders, and a net://<name> address (net_uri.go) must reach the URI provider rather than be swallowed here as a folder the manager is "already in": the panel tries the current file system first.
type ProtocolHandler ¶
type SFTPVFS ¶
type SFTPVFS struct {
// contains filtered or unexported fields
}
func NewSFTPVFS ¶
func (*SFTPVFS) BookmarkPath ¶
BookmarkPath implements vfs.BookmarkPathProvider: the folder on the server under the address the session was opened from (bookmark_path.go).
func (*SFTPVFS) CommandRunnerInfo ¶
func (*SFTPVFS) CommandRunnerInfo() vfs.CommandRunnerInfo
CommandRunnerInfo describes commands executed in independent SSH sessions. A modest cap avoids opening an unbounded number of channels on servers with conservative MaxSessions settings while still permitting useful parallelism.
func (*SFTPVFS) EncodeCommandListANSI ¶
EncodeCommandListANSI applies the same configured filename codepage used by this panel. A fresh encoder keeps parallel Apply workers independent.
func (*SFTPVFS) GetCapabilities ¶
func (v *SFTPVFS) GetCapabilities() vfs.VFSCapabilities
func (*SFTPVFS) HistoryEntry ¶
HistoryEntry and NavigateHistoryEntry implement vfs.HistoryPathProvider (f4#262): an SFTP session owns its own folder-history entries instead of its raw remote path (e.g. /root/foo) being recorded as if it were local.
func (*SFTPVFS) NavigateHistoryEntry ¶
func (*SFTPVFS) OpenWriteAt ¶
OpenWriteAt makes SFTPVFS a vfs.RandomWriteVFS. This is the backend the interface was written for: a remote file is exactly where re-uploading everything to change ten bytes hurts.
func (*SFTPVFS) RunCommand ¶
func (v *SFTPVFS) RunCommand(ctx context.Context, dir, command string, cb func(line string)) (int, error)
RunCommand starts a new SSH session rather than borrowing either the SFTP subsystem's channel or the panel's interactive PTY. The current directory is resolved before opening that session, so later panel navigation cannot move a command that is already being dispatched.
func (*SFTPVFS) SessionKey ¶
func (*SFTPVFS) SetAttributes ¶
func (*SFTPVFS) SupportsConcurrentCalls ¶
The upstream SFTP client multiplexes independent requests safely over one SSH connection. This lets FUSE serve directory listings, stats, and reads concurrently instead of making a remote mount wait behind one operation.
Source Files
¶
- bookmark_path.go
- crypto.go
- dialog.go
- fish_native.go
- fish_pool.go
- fish_search.go
- fish_vfs.go
- ftp_vfs.go
- history.go
- net_uri.go
- netfox.go
- netfox_uri_full.go
- proxy_dialog.go
- registry.go
- s2s_password.go
- settings_center.go
- sftp_uri.go
- sftp_vfs.go
- smb_backend.go
- smb_provider.go
- smb_uri.go
- smb_vfs.go
- ssh_agent_unix.go
- ssh_dial.go
- ssh_fish_dialer.go
- ssh_known_hosts.go
- ssh_pty.go
- vfs.go