sftpgo: fix compatibility issues with rclone
This commit is contained in:
@@ -65,9 +65,17 @@ in
|
|||||||
# ftp LIST operation returns entries over-the-wire like:
|
# ftp LIST operation returns entries over-the-wire like:
|
||||||
# - dgrwxrwxr-x 1 ftp ftp 9 Apr 9 15:05 Videos
|
# - dgrwxrwxr-x 1 ftp ftp 9 Apr 9 15:05 Videos
|
||||||
# however not all clients understand all mode bits (like that `g`, indicating SGID / group sticky bit).
|
# however not all clients understand all mode bits (like that `g`, indicating SGID / group sticky bit).
|
||||||
|
# - e.g. Kodi will sliently not display entries with `g`.
|
||||||
# instead, only send mode bits which are well-understood.
|
# instead, only send mode bits which are well-understood.
|
||||||
# the full set of bits, from which i filter, is found here: <https://pkg.go.dev/io/fs#FileMode>
|
# the full set of bits, from which i filter, is found here: <https://pkg.go.dev/io/fs#FileMode>
|
||||||
./safe_fileinfo.patch
|
#
|
||||||
|
# PATCH NOTES:
|
||||||
|
# - i *think* os.FileInfo contains the bad mode bits, and anything that goes through `vfs.NewFileInfo` gets those bits stripped (good).
|
||||||
|
# - for readdir, `patternDirLister` is just an easily accessible interface which causes the os.FileInfo's to be converted through `vfs.NewFileInfo`.
|
||||||
|
# - if patched incorrectly, sftpgo may return absolute paths for operations like `ls foo/bar/` (breaks rclone)
|
||||||
|
./safe_fileinfo_readdir.patch
|
||||||
|
# XXX(2025-09-20): nothing seems to break in Kodi when i leave `Stat` unpatched
|
||||||
|
# ./safe_fileinfo_stat.patch
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -2,29 +2,21 @@ diff --git a/internal/ftpd/handler.go b/internal/ftpd/handler.go
|
|||||||
index 036c3977..33211261 100644
|
index 036c3977..33211261 100644
|
||||||
--- a/internal/ftpd/handler.go
|
--- a/internal/ftpd/handler.go
|
||||||
+++ b/internal/ftpd/handler.go
|
+++ b/internal/ftpd/handler.go
|
||||||
@@ -169,7 +169,7 @@ func (c *Connection) Stat(name string) (os.FileInfo, error) {
|
@@ -315,7 +315,18 @@ func (c *Connection) ReadDir(name string) (ftpserver.DirLister, error) {
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
- return fi, nil
|
|
||||||
+ return vfs.NewFileInfo(name, fi.IsDir(), fi.Size(), fi.ModTime(), false), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name returns the name of this connection
|
|
||||||
@@ -315,7 +315,17 @@ func (c *Connection) ReadDir(name string) (ftpserver.DirLister, error) {
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
- return c.ListDir(name)
|
- return c.ListDir(name)
|
||||||
|
+ c.clientContext.SetListPath(name) //< MIGHT not be required
|
||||||
+ lister, err := c.ListDir(name)
|
+ lister, err := c.ListDir(name)
|
||||||
+ if err != nil {
|
+ if err != nil {
|
||||||
+ return nil, err
|
+ return nil, err
|
||||||
+ }
|
+ }
|
||||||
+ return &patternDirLister{
|
+ return &patternDirLister{ // this idiom is copied from 10 lines up ^
|
||||||
+ DirLister: lister,
|
+ DirLister: lister,
|
||||||
+ pattern: "*",
|
+ pattern: "*",
|
||||||
+ lastCommand: c.clientContext.GetLastCommand(),
|
+ lastCommand: c.clientContext.GetLastCommand(),
|
||||||
+ dirName: name,
|
+ dirName: "", //< or set to `c.clientContext.Path()`? returned paths are relative to this dirName.
|
||||||
+ connectionPath: c.clientContext.Path(),
|
+ connectionPath: c.clientContext.Path(),
|
||||||
+ }, nil
|
+ }, nil
|
||||||
}
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/internal/ftpd/handler.go b/internal/ftpd/handler.go
|
||||||
|
index 036c3977..33211261 100644
|
||||||
|
--- a/internal/ftpd/handler.go
|
||||||
|
+++ b/internal/ftpd/handler.go
|
||||||
|
@@ -169,7 +169,7 @@ func (c *Connection) Stat(name string) (os.FileInfo, error) {
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
- return fi, nil
|
||||||
|
+ return vfs.NewFileInfo(name, fi.IsDir(), fi.Size(), fi.ModTime(), false), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the name of this connection
|
Reference in New Issue
Block a user