Documentation
¶
Overview ¶
Package vfs is a filesystem a browser pane works on.
One interface with two implementations: this machine, and a machine on the far end of an SSH connection. A pane holds one of them and does not know which it has, which is what lets a copy run between any two of them.
Every failure is returned. Nothing here reports a partial listing, an empty directory where a read failed, or a file that is shorter than what was asked for: a browser that showed any of those would be telling the user something untrue about their own disk.
Index ¶
- func Base(f FS, path string) string
- func Dir(f FS, path string) string
- func Failed(err error) bool
- func IsTop(f FS, path string) bool
- func Join(f FS, parts ...string) string
- func NameFree(f FS, at, name string) error
- func NameProblem(sep, name string) error
- func OnWindows(f FS, path string) bool
- func OneVolume(f FS, a, b string) bool
- func PlainName(f FS, name string) error
- func Same(a, b FS) bool
- func Spelled(f FS, p string) string
- func VolumeOf(f FS, at string) string
- func WinAttrs(info fs.FileInfo) uint32
- type Entry
- type FS
- type Local
- func (l *Local) Chmod(path string, mode fs.FileMode) error
- func (l *Local) Close() error
- func (l *Local) Create(path string, mode fs.FileMode) (io.WriteCloser, error)
- func (l *Local) Home() (string, error)
- func (l *Local) Mkdir(path string, mode fs.FileMode) error
- func (l *Local) Name() string
- func (l *Local) Open(path string) (io.ReadCloser, error)
- func (l *Local) Place() any
- func (l *Local) ReadDir(path string) ([]Entry, error)
- func (l *Local) Remove(path string) error
- func (l *Local) Rename(from, to string) error
- func (l *Local) Roots() []string
- func (l *Local) Sep() byte
- func (l *Local) Stat(path string) (Entry, error)
- func (l *Local) Symlink(target, path string) error
- func (l *Local) VolumeOf(at string) string
- type SFTP
- func (s *SFTP) CanKeepOnDevice() bool
- func (s *SFTP) Chmod(path string, mode fs.FileMode) error
- func (s *SFTP) Chtimes(path string, mod time.Time) error
- func (s *SFTP) Close() error
- func (s *SFTP) Create(path string, mode fs.FileMode) (io.WriteCloser, error)
- func (s *SFTP) CreateNew(path string, mode fs.FileMode) (io.WriteCloser, error)
- func (s *SFTP) Follow(path string) (fs.FileInfo, error)
- func (s *SFTP) Home() (string, error)
- func (s *SFTP) KeepOnDevice(path string, keep bool) error
- func (s *SFTP) Mkdir(path string, mode fs.FileMode) error
- func (s *SFTP) Name() string
- func (s *SFTP) Open(path string) (io.ReadCloser, error)
- func (s *SFTP) Place() any
- func (s *SFTP) ReadDir(path string) ([]Entry, error)
- func (s *SFTP) Readlink(path string) (string, error)
- func (s *SFTP) RealPath(path string) (string, error)
- func (s *SFTP) Remove(path string) error
- func (s *SFTP) Rename(from, to string) error
- func (s *SFTP) Renamed(name string)
- func (s *SFTP) Roots() []string
- func (s *SFTP) Sep() byte
- func (s *SFTP) Space(path string) (free, total uint64, err error)
- func (s *SFTP) Stat(path string) (Entry, error)
- func (s *SFTP) Symlink(target, path string) error
- type Volumes
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Base ¶
Base returns the last part of a path. The root is its own name, because a pane sitting there has to have something to show.
func Dir ¶
Dir returns the directory a path is in, or the path itself when it is already the top of the filesystem.
func Failed ¶ added in v0.4.0
Failed reports whether err is SFTP's plain failure, which says nothing of why: a rename across volumes fails so, as does a statvfs a server can't answer.
func IsTop ¶
IsTop reports whether a path has nothing above it: the root of a POSIX filesystem, or a drive on this one.
func Join ¶
Join puts the parts of a path together with the filesystem's own separator.
Nothing is cleaned away: ".." is a name the far end resolves, and resolving it here would mean guessing what the far end does with a symbolic link.
func NameProblem ¶
NameProblem is PlainName for a filesystem whose separator is sep, for a dialog that has no filesystem to ask, only the separator it was told of.
func OnWindows ¶ added in v0.5.0
OnWindows reports whether path on f is on a Windows machine: f is this computer's file system on Windows, or the path is on a drive, as a Windows machine's SFTP server writes it, /C:/Users.
func OneVolume ¶
OneVolume reports whether folders a and b of f are on one volume, so a move between them is a rename rather than a copy and a delete.
func PlainName ¶
PlainName refuses, saying why, a name that is not a name in a folder: none, a path, or one of the two that name folders themselves.
func Same ¶
Same reports whether two filesystems are the same place, so a move between them can be a rename rather than a copy and a delete.
Two sessions to one machine are the same place even though they are two connections, and two values standing for this machine are the same place even though they are two values. Comparing the values themselves answers neither, and comparing the names answers wrongly: a name is only what the window calls a machine, so a move that read two machines as one because they were called the same thing would put the file on the machine it came from.
func Spelled ¶
Spelled is a path the way f takes it. A Windows path handed to a filesystem whose separator is "/" -- a Windows machine over SFTP -- becomes "/C:/dir", the way SFTP names that machine's drives. Its server reads "C:\dir" as a name under the folder it started in. A pane's shell on that machine says its folder the Windows way, which is how such a path arrives. Any other path comes back as it is.
Types ¶
type Entry ¶
type Entry struct {
// Name is the name in its directory, with no path in front of it.
Name string
// Size is the length in bytes. It means nothing for a directory.
Size int64
// Mode is the kind and the permissions.
Mode fs.FileMode
// Mod is when it last changed.
Mod time.Time
// Link is what a symbolic link points at, and is empty for
// everything else. What it points at is not followed: a browser
// shows the link, and the user decides.
Link string
// Attrs are the Windows attributes that say how a cloud provider
// keeps the item, as a kakel window serving its files sends them
// (see package winattrs), and zero from anything else.
Attrs uint32
}
Entry is one name in a directory.
type FS ¶
type FS interface {
// Name is what the panel calls this filesystem: "Local", or the
// machine a connection reaches.
Name() string
// Place is which machine the filesystem reads, as a value equal for
// two filesystems on one machine and for nothing else. It is what
// Same asks, and it has to be comparable.
//
// It is not the name. A name is a label the window can change, and
// two machines can end up called the same thing.
Place() any
// Roots are the places a path on it can start: one on a POSIX
// machine, one per drive on Windows. A pane at the top of the
// filesystem has these to go to and nowhere else.
//
// What the machine says it has, not what answers: a drive is listed
// whether or not there is a disk in it, because "there is a drive
// here and it will not answer" is something the user is entitled to
// find out by going to it. An empty list means the machine would not
// say, and a pane then has only where it already is.
//
// It is asked on the goroutine that draws, so it does not go to the
// disk.
Roots() []string
// Sep is the separator between the parts of a path on it. A Windows
// pane and a POSIX one sit side by side, so neither can assume.
Sep() byte
// Home is where a pane starts.
Home() (string, error)
// ReadDir lists a directory. The entries are in no particular order;
// sorting is the pane's business.
ReadDir(path string) ([]Entry, error)
// Stat reads one name. It does not follow a symbolic link: a browser
// shows the link.
Stat(path string) (Entry, error)
// Open reads a file.
Open(path string) (io.ReadCloser, error)
// Create makes a file, replacing one that is there.
//
// The mode is what a new file gets, whatever the machine's umask
// would have said. A file that is already there keeps its own: a
// copy over an existing file changes what is in it, not who may
// read it.
Create(path string, mode fs.FileMode) (io.WriteCloser, error)
// Mkdir makes one directory. Its parent has to exist, and the mode
// is what it gets whatever the machine's umask would have said.
Mkdir(path string, mode fs.FileMode) error
// Symlink makes a symbolic link at path pointing at target. The
// target is not checked and need not exist: that is what a link is.
Symlink(target, path string) error
// Remove takes away one file or one empty directory.
Remove(path string) error
// Rename moves a name to another, on the same filesystem.
Rename(from, to string) error
// Chmod sets the permissions. Only the nine permission bits are
// used: setuid, setgid and the sticky bit are left alone, because a
// copy between two machines must not quietly hand out rights on the
// far one.
Chmod(path string, mode fs.FileMode) error
// Close lets go of whatever the filesystem is holding. A local one
// holds nothing; a remote one holds a channel on a connection.
Close() error
}
FS is a filesystem a pane can browse.
An implementation must be safe to use from several goroutines: a background copy reads through the same FS the pane is listing with.
Every method returns the failure it met. A ReadDir that could not read the whole directory returns no entries and the error, because a short listing shown as a whole one is worse than no listing at all.
type Local ¶
type Local struct{}
Local is the filesystem kakel is running on.
It holds nothing and costs nothing to make, so a pane that shows this machine makes its own rather than sharing one.
func (*Local) Create ¶
Create makes a file, replacing one that is there.
The mode is set rather than left to the umask, so a file made here and the same file made on a machine at the far end come out the same. One that is already there keeps the mode it has.
func (*Local) Mkdir ¶
Mkdir makes one directory, with the mode it was asked for rather than whatever the umask allows.
func (*Local) Open ¶
func (l *Local) Open(path string) (io.ReadCloser, error)
Open reads a file.
A directory is refused here rather than at the first read. A copy that opened one would already have emptied the file it was copying to before finding out.
func (*Local) ReadDir ¶
ReadDir lists a directory.
A name that cannot be read is the whole listing's failure. A browser showing a directory with a file quietly missing from it is worse than one that says it could not read the directory.
func (*Local) Roots ¶
Roots are the places a path here can start: one on a POSIX machine, and one per drive on Windows.
func (*Local) Sep ¶
Sep is the separator between the parts of a path here: a backslash on Windows, a slash everywhere else.
type SFTP ¶
type SFTP struct {
// contains filtered or unexported fields
}
SFTP is the filesystem of a machine on the far end of a connection.
Paths are POSIX whatever this machine runs, because they are read over there. A Windows pane and one of these sit side by side and neither may assume the other's separator.
A Windows path it is handed, "C:\dir", is read as "/C:/dir": see Spelled.
func NewSFTP ¶
NewSFTP wraps an SFTP session as a filesystem. name is what the panel calls the machine, place says which machine it is, and close ends the session.
func (*SFTP) CanKeepOnDevice ¶ added in v0.12.1
CanKeepOnDevice reports whether the machine tells its cloud provider which items to keep on its device, as a kakel window on Windows does for OneDrive: its server names winattrs.KeepName among its extensions.
func (*SFTP) Chtimes ¶ added in v0.4.0
Chtimes sets when the item at path was last changed, and last read.
func (*SFTP) Create ¶
Create makes a file, replacing one that is there.
The mode is set after it is made: SFTP's own create does not carry one, and a file left with whatever the far end's umask gave it is not the file that was asked for. One that is already there keeps the mode it has, which is what happens on this machine too.
func (*SFTP) CreateNew ¶ added in v0.4.0
CreateNew makes a file at path that is not there yet, failing with an error that matches fs.ErrExist when something is, whatever comes there meanwhile: the server makes it only if it isn't there. It is given mode before anything is written to it.
func (*SFTP) Follow ¶ added in v0.4.0
Follow says what is at path, following a link at the end of it, as Stat does not.
func (*SFTP) KeepOnDevice ¶ added in v0.12.1
KeepOnDevice has the machine's cloud provider keep the item at path, and all a folder holds, on its device with keep, or free their space without, as Explorer's Always keep on this device and Free up space do. A machine that cannot fails with an error that matches errors.ErrUnsupported. Once asked, the machine carries on to the end: SFTP has no way to call a request off.
func (*SFTP) Mkdir ¶
Mkdir makes one directory, with the mode it was asked for rather than whatever the far end's umask allows.
func (*SFTP) Open ¶
func (s *SFTP) Open(path string) (io.ReadCloser, error)
Open reads a file.
A directory is refused here rather than at the first read. A copy that opened one would already have emptied the file it was copying to before finding out.
func (*SFTP) ReadDir ¶
ReadDir lists a directory.
A name that cannot be read is the whole listing's failure, the same as on this machine: a listing with something quietly missing from it is worse than one that says it could not be read.
func (*SFTP) RealPath ¶ added in v0.4.0
RealPath is path with the links along it followed, as the server resolves it.
func (*SFTP) Rename ¶
Rename moves a name to another, replacing what is there.
SFTP's own rename refuses a name that is already taken, while renaming on this machine replaces it. OpenSSH's posix-rename extension is what makes the two agree, so it is used wherever the far end has it.
func (*SFTP) Renamed ¶
Renamed says the machine is called something else now.
The name is what the window matches a pane against to find which machine it is on, so one that kept the old name would be left behind when its connection closed.
func (*SFTP) Roots ¶
Roots is the one place a POSIX path can start.
SFTP paths are POSIX whatever the far machine runs, so a Windows machine reached this way puts its drives under the root rather than beside it.
func (*SFTP) Sep ¶
Sep is the separator between the parts of a path over there, which SFTP defines as a slash whatever the machine runs.
func (*SFTP) Space ¶ added in v0.4.0
Space is how many bytes are free and in all on the volume that holds path, as OpenSSH's statvfs extension says. A server without it fails with an error that matches errors.ErrUnsupported, and so does one that has it and can't answer, as Go's SFTP server, kakel's own, can't on Windows.