2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 Copyright (C) 2011 Sebastian Pipping <sebastian@pipping.org>
6 This program can be distributed under the terms of the GNU GPL.
9 gcc -Wall fusexmp.c `pkg-config fuse --cflags --libs` -o fusexmp
12 #define FUSE_USE_VERSION 26
19 /* For pread()/pwrite()/utimensat() */
20 #define _XOPEN_SOURCE 700
33 #include <sys/xattr.h>
36 static int xmp_getattr(const char *path, struct stat *stbuf)
40 res = lstat(path, stbuf);
47 static int xmp_access(const char *path, int mask)
51 res = access(path, mask);
58 static int xmp_readlink(const char *path, char *buf, size_t size)
62 res = readlink(path, buf, size - 1);
71 static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
72 off_t offset, struct fuse_file_info *fi)
84 while ((de = readdir(dp)) != NULL) {
86 memset(&st, 0, sizeof(st));
87 st.st_ino = de->d_ino;
88 st.st_mode = de->d_type << 12;
89 if (filler(buf, de->d_name, &st, 0))
97 static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
101 /* On Linux this could just be 'mknod(path, mode, rdev)' but this
104 res = open(path, O_CREAT | O_EXCL | O_WRONLY, mode);
107 } else if (S_ISFIFO(mode))
108 res = mkfifo(path, mode);
110 res = mknod(path, mode, rdev);
117 static int xmp_mkdir(const char *path, mode_t mode)
121 res = mkdir(path, mode);
128 static int xmp_unlink(const char *path)
139 static int xmp_rmdir(const char *path)
150 static int xmp_symlink(const char *from, const char *to)
154 res = symlink(from, to);
161 static int xmp_rename(const char *from, const char *to)
165 res = rename(from, to);
172 static int xmp_link(const char *from, const char *to)
176 res = link(from, to);
183 static int xmp_chmod(const char *path, mode_t mode)
187 res = chmod(path, mode);
194 static int xmp_chown(const char *path, uid_t uid, gid_t gid)
198 res = lchown(path, uid, gid);
205 static int xmp_truncate(const char *path, off_t size)
209 res = truncate(path, size);
216 #ifdef HAVE_UTIMENSAT
217 static int xmp_utimens(const char *path, const struct timespec ts[2])
221 /* don't use utime/utimes since they follow symlinks */
222 res = utimensat(0, path, ts, AT_SYMLINK_NOFOLLOW);
230 static int xmp_open(const char *path, struct fuse_file_info *fi)
234 res = open(path, fi->flags);
242 static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
243 struct fuse_file_info *fi)
249 fd = open(path, O_RDONLY);
253 res = pread(fd, buf, size, offset);
261 static int xmp_write(const char *path, const char *buf, size_t size,
262 off_t offset, struct fuse_file_info *fi)
268 fd = open(path, O_WRONLY);
272 res = pwrite(fd, buf, size, offset);
280 static int xmp_statfs(const char *path, struct statvfs *stbuf)
284 res = statvfs(path, stbuf);
291 static int xmp_release(const char *path, struct fuse_file_info *fi)
293 /* Just a stub. This method is optional and can safely be left
301 static int xmp_fsync(const char *path, int isdatasync,
302 struct fuse_file_info *fi)
304 /* Just a stub. This method is optional and can safely be left
313 #ifdef HAVE_POSIX_FALLOCATE
314 static int xmp_fallocate(const char *path, int mode,
315 off_t offset, off_t length, struct fuse_file_info *fi)
325 fd = open(path, O_WRONLY);
329 res = -posix_fallocate(fd, offset, length);
337 /* xattr operations are optional and can safely be left unimplemented */
338 static int xmp_setxattr(const char *path, const char *name, const char *value,
339 size_t size, int flags)
341 int res = lsetxattr(path, name, value, size, flags);
347 static int xmp_getxattr(const char *path, const char *name, char *value,
350 int res = lgetxattr(path, name, value, size);
356 static int xmp_listxattr(const char *path, char *list, size_t size)
358 int res = llistxattr(path, list, size);
364 static int xmp_removexattr(const char *path, const char *name)
366 int res = lremovexattr(path, name);
371 #endif /* HAVE_SETXATTR */
373 static struct fuse_operations xmp_oper = {
374 .getattr = xmp_getattr,
375 .access = xmp_access,
376 .readlink = xmp_readlink,
377 .readdir = xmp_readdir,
380 .symlink = xmp_symlink,
381 .unlink = xmp_unlink,
383 .rename = xmp_rename,
387 .truncate = xmp_truncate,
388 #ifdef HAVE_UTIMENSAT
389 .utimens = xmp_utimens,
394 .statfs = xmp_statfs,
395 .release = xmp_release,
397 #ifdef HAVE_POSIX_FALLOCATE
398 .fallocate = xmp_fallocate,
401 .setxattr = xmp_setxattr,
402 .getxattr = xmp_getxattr,
403 .listxattr = xmp_listxattr,
404 .removexattr = xmp_removexattr,
408 int main(int argc, char *argv[])
411 return fuse_main(argc, argv, &xmp_oper, NULL);