From 7b68f5e7ec1cdf730ab8a5fc723eb9a7e7776a65 Mon Sep 17 00:00:00 2001 From: Son Roy Almerol Date: Tue, 12 Nov 2024 12:29:03 -0500 Subject: [PATCH] add unexpected eof handler --- internal/agent/sftp/config.go | 3 --- internal/agent/sftp/eof.go | 28 ++++++++++++++++++++++++++++ internal/agent/sftp/filelister.go | 12 ++---------- internal/agent/sftp/handler.go | 11 +++++++++-- internal/backend/mount/mount.go | 2 +- 5 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 internal/agent/sftp/eof.go diff --git a/internal/agent/sftp/config.go b/internal/agent/sftp/config.go index f6dcc74..1f15067 100644 --- a/internal/agent/sftp/config.go +++ b/internal/agent/sftp/config.go @@ -37,9 +37,6 @@ func (s *SFTPConfig) GetRegistryKey() string { func InitializeSFTPConfig(svc service.Service, driveLetter string) (*SFTPConfig, error) { var err error - if err != nil { - return nil, fmt.Errorf("InitializeLogger: failed to initialize logger -> %w", err) - } baseKey, _, err := registry.CreateKey(registry.LOCAL_MACHINE, "Software\\PBSPlus\\Config", registry.QUERY_VALUE) if err != nil { diff --git a/internal/agent/sftp/eof.go b/internal/agent/sftp/eof.go new file mode 100644 index 0000000..5b8b0f7 --- /dev/null +++ b/internal/agent/sftp/eof.go @@ -0,0 +1,28 @@ +package sftp + +import "io" + +type eofInjectingReaderAt struct { + file io.ReaderAt + length int64 +} + +func NewEOFInjectingReaderAt(file io.ReaderAt, length int64) io.ReaderAt { + return &eofInjectingReaderAt{file: file, length: length} +} + +func (r *eofInjectingReaderAt) ReadAt(p []byte, off int64) (n int, err error) { + if off >= r.length { + // If reading beyond the file length, return EOF to simulate a proper end. + return 0, io.EOF + } + + // Attempt to read as usual. + n, err = r.file.ReadAt(p, off) + if err == io.ErrUnexpectedEOF || n < len(p) { + // If an unexpected EOF or partial read, return what we have and inject EOF. + return n, io.EOF + } + + return n, err +} diff --git a/internal/agent/sftp/filelister.go b/internal/agent/sftp/filelister.go index ac56bd4..0176f9e 100644 --- a/internal/agent/sftp/filelister.go +++ b/internal/agent/sftp/filelister.go @@ -88,8 +88,8 @@ func (h *SftpHandler) setFilePath(r *sftp.Request) { r.Filepath = filepath.Join(h.Snapshot.SnapshotPath, filepath.Clean(r.Filepath)) } -func (h *SftpHandler) fetch(path string, mode int) (*os.File, error) { - return os.OpenFile(path, mode, 0777) +func (h *SftpHandler) fetch(path string) (*os.File, error) { + return os.Open(path) } func wildcardToRegex(pattern string) string { @@ -175,13 +175,5 @@ func skipFile(path string, fileInfo os.FileInfo) bool { } } - if !fileInfo.IsDir() { - f, err := os.Open(path) - if err != nil { - return true - } - f.Close() - } - return false } diff --git a/internal/agent/sftp/handler.go b/internal/agent/sftp/handler.go index 0ed8455..59604f9 100644 --- a/internal/agent/sftp/handler.go +++ b/internal/agent/sftp/handler.go @@ -40,12 +40,19 @@ func (h *SftpHandler) Fileread(r *sftp.Request) (io.ReaderAt, error) { h.Snapshot.UpdateTimestamp() h.setFilePath(r) - file, err := h.fetch(r.Filepath, os.O_RDONLY) + file, err := h.fetch(r.Filepath) if err != nil { log.Printf("error reading file: %v", err) return nil, err } - return file, nil + + stat, err := os.Lstat(r.Filepath) + if err != nil { + log.Printf("error getting file stats: %v", err) + return nil, err + } + + return NewEOFInjectingReaderAt(file, stat.Size()), nil } func (h *SftpHandler) Filewrite(r *sftp.Request) (io.WriterAt, error) { diff --git a/internal/backend/mount/mount.go b/internal/backend/mount/mount.go index 352afde..265d8cc 100644 --- a/internal/backend/mount/mount.go +++ b/internal/backend/mount/mount.go @@ -60,7 +60,7 @@ func Mount(target *store.Target) (*AgentMount, error) { "--sftp-user", "proxmox", "--sftp-host", agentHost, "--allow-other", - "--sftp-shell-type", "unix", + "--sftp-shell-type", "none", ":sftp:/", agentMount.Path, }