diff --git a/backend/local/local.go b/backend/local/local.go index 984cd4910..4acb1b788 100644 --- a/backend/local/local.go +++ b/backend/local/local.go @@ -266,7 +266,10 @@ type Object struct { // ------------------------------------------------------------ -var errLinksAndCopyLinks = errors.New("can't use -l/--links with -L/--copy-links") +var ( + errLinksAndCopyLinks = errors.New("can't use -l/--links with -L/--copy-links") + errLinksNeedsSuffix = errors.New("need \"" + linkSuffix + "\" suffix to refer to symlink when using -l/--links") +) // NewFs constructs an Fs from the path func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) { @@ -310,7 +313,16 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e if err == nil { f.dev = readDevice(fi, f.opt.OneFileSystem) } + // Check to see if this is a .rclonelink if not found + hasLinkSuffix := strings.HasSuffix(f.root, linkSuffix) + if hasLinkSuffix && opt.TranslateSymlinks && os.IsNotExist(err) { + fi, err = f.lstat(strings.TrimSuffix(f.root, linkSuffix)) + } if err == nil && f.isRegular(fi.Mode()) { + // Handle the odd case, that a symlink was specified by name without the link suffix + if !hasLinkSuffix && opt.TranslateSymlinks && fi.Mode()&os.ModeSymlink != 0 { + return nil, errLinksNeedsSuffix + } // It is a file, so use the parent as the root f.root = filepath.Dir(f.root) // return an error with an fs which points to the parent diff --git a/backend/local/local_internal_test.go b/backend/local/local_internal_test.go index 7fcacaf33..2e2cfbca6 100644 --- a/backend/local/local_internal_test.go +++ b/backend/local/local_internal_test.go @@ -146,6 +146,20 @@ func TestSymlink(t *testing.T) { _, err = r.Flocal.NewObject(ctx, "symlink2.txt") require.Equal(t, fs.ErrorObjectNotFound, err) + // Check that NewFs works with the suffixed version and --links + f2, err := NewFs(ctx, "local", filepath.Join(dir, "symlink2.txt"+linkSuffix), configmap.Simple{ + "links": "true", + }) + require.Equal(t, fs.ErrorIsFile, err) + require.Equal(t, dir, f2.(*Fs).root) + + // Check that NewFs doesn't see the non suffixed version with --links + f2, err = NewFs(ctx, "local", filepath.Join(dir, "symlink2.txt"), configmap.Simple{ + "links": "true", + }) + require.Equal(t, errLinksNeedsSuffix, err) + require.Nil(t, f2) + // Check reading the object in, err := o.Open(ctx) require.NoError(t, err)