2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
5 This program can be distributed under the terms of the GNU GPL.
8 gcc -Wall `pkg-config fuse --cflags --libs` fusexmp.c -o fusexmp
11 #define FUSE_USE_VERSION 26
18 /* For pread()/pwrite() */
19 #define _XOPEN_SOURCE 500
31 #include <sys/xattr.h>
34 static int xmp_getattr(const char *path
, struct stat
*stbuf
)
38 res
= lstat(path
, stbuf
);
45 static int xmp_access(const char *path
, int mask
)
49 res
= access(path
, mask
);
56 static int xmp_readlink(const char *path
, char *buf
, size_t size
)
60 res
= readlink(path
, buf
, size
- 1);
69 static int xmp_readdir(const char *path
, void *buf
, fuse_fill_dir_t filler
,
70 off_t offset
, struct fuse_file_info
*fi
)
82 while ((de
= readdir(dp
)) != NULL
) {
84 memset(&st
, 0, sizeof(st
));
85 st
.st_ino
= de
->d_ino
;
86 st
.st_mode
= de
->d_type
<< 12;
87 if (filler(buf
, de
->d_name
, &st
, 0))
95 static int xmp_mknod(const char *path
, mode_t mode
, dev_t rdev
)
99 /* On Linux this could just be 'mknod(path, mode, rdev)' but this
102 res
= open(path
, O_CREAT
| O_EXCL
| O_WRONLY
, mode
);
105 } else if (S_ISFIFO(mode
))
106 res
= mkfifo(path
, mode
);
108 res
= mknod(path
, mode
, rdev
);
115 static int xmp_mkdir(const char *path
, mode_t mode
)
119 res
= mkdir(path
, mode
);
126 static int xmp_unlink(const char *path
)
137 static int xmp_rmdir(const char *path
)
148 static int xmp_symlink(const char *from
, const char *to
)
152 res
= symlink(from
, to
);
159 static int xmp_rename(const char *from
, const char *to
)
163 res
= rename(from
, to
);
170 static int xmp_link(const char *from
, const char *to
)
174 res
= link(from
, to
);
181 static int xmp_chmod(const char *path
, mode_t mode
)
185 res
= chmod(path
, mode
);
192 static int xmp_chown(const char *path
, uid_t uid
, gid_t gid
)
196 res
= lchown(path
, uid
, gid
);
203 static int xmp_truncate(const char *path
, off_t size
)
207 res
= truncate(path
, size
);
214 static int xmp_utimens(const char *path
, const struct timespec ts
[2])
217 struct timeval tv
[2];
219 tv
[0].tv_sec
= ts
[0].tv_sec
;
220 tv
[0].tv_usec
= ts
[0].tv_nsec
/ 1000;
221 tv
[1].tv_sec
= ts
[1].tv_sec
;
222 tv
[1].tv_usec
= ts
[1].tv_nsec
/ 1000;
224 res
= utimes(path
, tv
);
231 static int xmp_open(const char *path
, struct fuse_file_info
*fi
)
235 res
= open(path
, fi
->flags
);
243 static int xmp_read(const char *path
, char *buf
, size_t size
, off_t offset
,
244 struct fuse_file_info
*fi
)
250 fd
= open(path
, O_RDONLY
);
254 res
= pread(fd
, buf
, size
, offset
);
262 static int xmp_write(const char *path
, const char *buf
, size_t size
,
263 off_t offset
, struct fuse_file_info
*fi
)
269 fd
= open(path
, O_WRONLY
);
273 res
= pwrite(fd
, buf
, size
, offset
);
281 static int xmp_statfs(const char *path
, struct statvfs
*stbuf
)
285 res
= statvfs(path
, stbuf
);
292 static int xmp_release(const char *path
, struct fuse_file_info
*fi
)
294 /* Just a stub. This method is optional and can safely be left
302 static int xmp_fsync(const char *path
, int isdatasync
,
303 struct fuse_file_info
*fi
)
305 /* Just a stub. This method is optional and can safely be left
315 /* xattr operations are optional and can safely be left unimplemented */
316 static int xmp_setxattr(const char *path
, const char *name
, const char *value
,
317 size_t size
, int flags
)
319 int res
= lsetxattr(path
, name
, value
, size
, flags
);
325 static int xmp_getxattr(const char *path
, const char *name
, char *value
,
328 int res
= lgetxattr(path
, name
, value
, size
);
334 static int xmp_listxattr(const char *path
, char *list
, size_t size
)
336 int res
= llistxattr(path
, list
, size
);
342 static int xmp_removexattr(const char *path
, const char *name
)
344 int res
= lremovexattr(path
, name
);
349 #endif /* HAVE_SETXATTR */
351 static struct fuse_operations xmp_oper
= {
352 .getattr
= xmp_getattr
,
353 .access
= xmp_access
,
354 .readlink
= xmp_readlink
,
355 .readdir
= xmp_readdir
,
358 .symlink
= xmp_symlink
,
359 .unlink
= xmp_unlink
,
361 .rename
= xmp_rename
,
365 .truncate
= xmp_truncate
,
366 .utimens
= xmp_utimens
,
370 .statfs
= xmp_statfs
,
371 .release
= xmp_release
,
374 .setxattr
= xmp_setxattr
,
375 .getxattr
= xmp_getxattr
,
376 .listxattr
= xmp_listxattr
,
377 .removexattr
= xmp_removexattr
,
381 int main(int argc
, char *argv
[])
384 return fuse_main(argc
, argv
, &xmp_oper
, NULL
);