2 fuse_xattrs - Add xattrs support using sidecar files
4 Copyright (C) 2016-2017 Felipe Barriga Richards <felipe {at} felipebarriga.cl>
6 Based on passthrough.c (libfuse example)
8 This program can be distributed under the terms of the GNU GPL.
12 #define FUSE_USE_VERSION 30
14 /* For pread()/pwrite()/utimensat() */
15 #define _XOPEN_SOURCE 700
25 #include "fuse_xattrs_config.h"
27 #include "xattrs_config.h"
30 int xmp_getattr(const char *path, struct stat *stbuf) {
33 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
34 res = lstat(_path, stbuf);
43 int xmp_access(const char *path, int mask) {
46 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
47 res = access(_path, mask);
56 int xmp_readlink(const char *path, char *buf, size_t size) {
59 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
60 res = readlink(_path, buf, size - 1);
70 int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
71 off_t offset, struct fuse_file_info *fi)
79 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
86 while ((de = readdir(dp)) != NULL) {
88 memset(&st, 0, sizeof(st));
89 st.st_ino = de->d_ino;
90 st.st_mode = de->d_type << 12;
91 if (filler(buf, de->d_name, &st, 0))
99 int xmp_mknod(const char *path, mode_t mode, dev_t rdev) {
101 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
103 /* On Linux this could just be 'mknod(path, mode, rdev)' but this
106 res = open(_path, O_CREAT | O_EXCL | O_WRONLY, mode);
109 } else if (S_ISFIFO(mode))
110 res = mkfifo(_path, mode);
112 res = mknod(_path, mode, rdev);
121 int xmp_mkdir(const char *path, mode_t mode) {
124 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
125 res = mkdir(_path, mode);
134 int xmp_unlink(const char *path) {
137 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
147 int xmp_rmdir(const char *path) {
150 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
160 int xmp_symlink(const char *from, const char *to) {
163 char *_to = prepend_source_directory(xattrs_config.source_dir, to);
164 res = symlink(from, _to);
173 int xmp_rename(const char *from, const char *to) {
176 char *_from = prepend_source_directory(xattrs_config.source_dir, from);
177 char *_to = prepend_source_directory(xattrs_config.source_dir, to);
178 res = rename(_from, _to);
188 int xmp_link(const char *from, const char *to) {
191 char *_from = prepend_source_directory(xattrs_config.source_dir, from);
192 char *_to = prepend_source_directory(xattrs_config.source_dir, to);
193 res = link(_from, _to);
203 int xmp_chmod(const char *path, mode_t mode) {
206 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
207 res = chmod(_path, mode);
216 int xmp_chown(const char *path, uid_t uid, gid_t gid) {
219 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
220 res = lchown(_path, uid, gid);
229 int xmp_truncate(const char *path, off_t size) {
232 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
233 res = truncate(_path, size);
242 #ifdef HAVE_UTIMENSAT
243 int xmp_utimens(const char *path, const struct timespec ts[2],
244 struct fuse_file_info *fi)
249 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
250 /* don't use utime/utimes since they follow symlinks */
251 res = utimensat(0, _path, ts, AT_SYMLINK_NOFOLLOW);
260 int xmp_open(const char *path, struct fuse_file_info *fi) {
263 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
264 res = open(_path, fi->flags);
274 int xmp_read(const char *path, char *buf, size_t size, off_t offset,
275 struct fuse_file_info *fi) {
280 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
281 fd = open(_path, O_RDONLY);
287 res = pread(fd, buf, size, offset);
295 int xmp_write(const char *path, const char *buf, size_t size,
296 off_t offset, struct fuse_file_info *fi) {
301 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
302 fd = open(_path, O_WRONLY);
308 res = pwrite(fd, buf, size, offset);
316 int xmp_statfs(const char *path, struct statvfs *stbuf) {
319 char *_path = prepend_source_directory(xattrs_config.source_dir, path);
320 res = statvfs(_path, stbuf);
329 int xmp_release(const char *path, struct fuse_file_info *fi) {
330 /* Just a stub. This method is optional and can safely be left
338 int xmp_fsync(const char *path, int isdatasync,
339 struct fuse_file_info *fi) {
340 /* Just a stub. This method is optional and can safely be left
349 #ifdef HAVE_POSIX_FALLOCATE
350 int xmp_fallocate(const char *path, int mode,
351 off_t offset, off_t length, struct fuse_file_info *fi)
361 char *_path = concat(xattrs_config.source_dir, path);
362 fd = open(_path, O_WRONLY);
368 res = -posix_fallocate(fd, offset, length);