fix: failure on broken symlink deletion
parent
34d7d2c8c4
commit
8650d2ffe7
|
@ -34,6 +34,7 @@ type FileInfo struct {
|
||||||
ModTime time.Time `json:"modified"`
|
ModTime time.Time `json:"modified"`
|
||||||
Mode os.FileMode `json:"mode"`
|
Mode os.FileMode `json:"mode"`
|
||||||
IsDir bool `json:"isDir"`
|
IsDir bool `json:"isDir"`
|
||||||
|
IsSymlink bool `json:"isSymlink"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Subtitles []string `json:"subtitles,omitempty"`
|
Subtitles []string `json:"subtitles,omitempty"`
|
||||||
Content string `json:"content,omitempty"`
|
Content string `json:"content,omitempty"`
|
||||||
|
@ -61,23 +62,11 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) {
|
||||||
return nil, os.ErrPermission
|
return nil, os.ErrPermission
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := opts.Fs.Stat(opts.Path)
|
file, err := stat(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
file := &FileInfo{
|
|
||||||
Fs: opts.Fs,
|
|
||||||
Path: opts.Path,
|
|
||||||
Name: info.Name(),
|
|
||||||
ModTime: info.ModTime(),
|
|
||||||
Mode: info.Mode(),
|
|
||||||
IsDir: info.IsDir(),
|
|
||||||
Size: info.Size(),
|
|
||||||
Extension: filepath.Ext(info.Name()),
|
|
||||||
Token: opts.Token,
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.Expand {
|
if opts.Expand {
|
||||||
if file.IsDir {
|
if file.IsDir {
|
||||||
if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil { //nolint:govet
|
if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil { //nolint:govet
|
||||||
|
@ -95,6 +84,64 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) {
|
||||||
return file, err
|
return file, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stat(opts FileOptions) (*FileInfo, error) {
|
||||||
|
var file *FileInfo
|
||||||
|
|
||||||
|
if lstaterFs, ok := opts.Fs.(afero.Lstater); ok {
|
||||||
|
info, _, err := lstaterFs.LstatIfPossible(opts.Path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
file = &FileInfo{
|
||||||
|
Fs: opts.Fs,
|
||||||
|
Path: opts.Path,
|
||||||
|
Name: info.Name(),
|
||||||
|
ModTime: info.ModTime(),
|
||||||
|
Mode: info.Mode(),
|
||||||
|
IsDir: info.IsDir(),
|
||||||
|
IsSymlink: IsSymlink(info.Mode()),
|
||||||
|
Size: info.Size(),
|
||||||
|
Extension: filepath.Ext(info.Name()),
|
||||||
|
Token: opts.Token,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// regular file
|
||||||
|
if file != nil && !file.IsSymlink {
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// fs doesn't support afero.Lstater interface or the file is a symlink
|
||||||
|
info, err := opts.Fs.Stat(opts.Path)
|
||||||
|
if err != nil {
|
||||||
|
// can't follow symlink
|
||||||
|
if file != nil && file.IsSymlink {
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// set correct file size in case of symlink
|
||||||
|
if file != nil && file.IsSymlink {
|
||||||
|
file.Size = info.Size()
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
file = &FileInfo{
|
||||||
|
Fs: opts.Fs,
|
||||||
|
Path: opts.Path,
|
||||||
|
Name: info.Name(),
|
||||||
|
ModTime: info.ModTime(),
|
||||||
|
Mode: info.Mode(),
|
||||||
|
IsDir: info.IsDir(),
|
||||||
|
Size: info.Size(),
|
||||||
|
Extension: filepath.Ext(info.Name()),
|
||||||
|
Token: opts.Token,
|
||||||
|
}
|
||||||
|
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Checksum checksums a given File for a given User, using a specific
|
// Checksum checksums a given File for a given User, using a specific
|
||||||
// algorithm. The checksums data is saved on File object.
|
// algorithm. The checksums data is saved on File object.
|
||||||
func (i *FileInfo) Checksum(algo string) error {
|
func (i *FileInfo) Checksum(algo string) error {
|
||||||
|
@ -252,7 +299,9 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isSymlink := false
|
||||||
if IsSymlink(f.Mode()) {
|
if IsSymlink(f.Mode()) {
|
||||||
|
isSymlink = true
|
||||||
// It's a symbolic link. We try to follow it. If it doesn't work,
|
// It's a symbolic link. We try to follow it. If it doesn't work,
|
||||||
// we stay with the link information instead of the target's.
|
// we stay with the link information instead of the target's.
|
||||||
info, err := i.Fs.Stat(fPath)
|
info, err := i.Fs.Stat(fPath)
|
||||||
|
@ -268,6 +317,7 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||||
ModTime: f.ModTime(),
|
ModTime: f.ModTime(),
|
||||||
Mode: f.Mode(),
|
Mode: f.Mode(),
|
||||||
IsDir: f.IsDir(),
|
IsDir: f.IsDir(),
|
||||||
|
IsSymlink: isSymlink,
|
||||||
Extension: filepath.Ext(name),
|
Extension: filepath.Ext(name),
|
||||||
Path: fPath,
|
Path: fPath,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue