mirror of
https://github.com/rclone/rclone.git
synced 2025-12-12 06:24:14 +01:00
local: add Metadata support #111
This commit is contained in:
87
backend/local/xattr.go
Normal file
87
backend/local/xattr.go
Normal file
@@ -0,0 +1,87 @@
|
||||
//go:build !openbsd && !plan9
|
||||
// +build !openbsd,!plan9
|
||||
|
||||
package local
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/xattr"
|
||||
"github.com/rclone/rclone/fs"
|
||||
)
|
||||
|
||||
const (
|
||||
xattrPrefix = "user." // FIXME is this correct for all unixes?
|
||||
xattrSupported = xattr.XATTR_SUPPORTED
|
||||
)
|
||||
|
||||
// getXattr returns the extended attributes for an object
|
||||
//
|
||||
// It doesn't return any attributes owned by this backend in
|
||||
// metadataKeys
|
||||
func (o *Object) getXattr() (metadata fs.Metadata, err error) {
|
||||
if !xattrSupported {
|
||||
return nil, nil
|
||||
}
|
||||
var list []string
|
||||
if o.fs.opt.FollowSymlinks {
|
||||
list, err = xattr.List(o.path)
|
||||
} else {
|
||||
list, err = xattr.LList(o.path)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read xattr: %w", err)
|
||||
}
|
||||
if len(list) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
metadata = make(fs.Metadata, len(list))
|
||||
for _, k := range list {
|
||||
var v []byte
|
||||
if o.fs.opt.FollowSymlinks {
|
||||
v, err = xattr.Get(o.path, k)
|
||||
} else {
|
||||
v, err = xattr.LGet(o.path, k)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read xattr key %q: %w", k, err)
|
||||
}
|
||||
k = strings.ToLower(k)
|
||||
if !strings.HasPrefix(k, xattrPrefix) {
|
||||
continue
|
||||
}
|
||||
k = k[len(xattrPrefix):]
|
||||
if _, found := systemMetadataInfo[k]; found {
|
||||
continue
|
||||
}
|
||||
metadata[k] = string(v)
|
||||
}
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
// setXattr sets the metadata on the file Xattrs
|
||||
//
|
||||
// It doesn't set any attributes owned by this backend in metadataKeys
|
||||
func (o *Object) setXattr(metadata fs.Metadata) (err error) {
|
||||
if !xattrSupported {
|
||||
return nil
|
||||
}
|
||||
for k, value := range metadata {
|
||||
k = strings.ToLower(k)
|
||||
if _, found := systemMetadataInfo[k]; found {
|
||||
continue
|
||||
}
|
||||
k = xattrPrefix + k
|
||||
v := []byte(value)
|
||||
if o.fs.opt.FollowSymlinks {
|
||||
err = xattr.Set(o.path, k, v)
|
||||
} else {
|
||||
err = xattr.LSet(o.path, k, v)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set xattr key %q: %w", k, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user