2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2006 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
16 /* For pread()/pwrite() */
17 #define _XOPEN_SOURCE 500
29 #include <sys/xattr.h>
32 static int xmp_getattr(const char *path
, struct stat
*stbuf
)
36 res
= lstat(path
, stbuf
);
43 static int xmp_access(const char *path
, int mask
)
47 res
= access(path
, mask
);
54 static int xmp_readlink(const char *path
, char *buf
, size_t size
)
58 res
= readlink(path
, buf
, size
- 1);
67 static int xmp_readdir(const char *path
, void *buf
, fuse_fill_dir_t filler
,
68 off_t offset
, struct fuse_file_info
*fi
)
80 while ((de
= readdir(dp
)) != NULL
) {
82 memset(&st
, 0, sizeof(st
));
83 st
.st_ino
= de
->d_ino
;
84 st
.st_mode
= de
->d_type
<< 12;
85 if (filler(buf
, de
->d_name
, &st
, 0))
93 static int xmp_mknod(const char *path
, mode_t mode
, dev_t rdev
)
97 /* On Linux this could just be 'mknod(path, mode, rdev)' but this
100 res
= open(path
, O_CREAT
| O_EXCL
| O_WRONLY
, mode
);
103 } else if (S_ISFIFO(mode
))
104 res
= mkfifo(path
, mode
);
106 res
= mknod(path
, mode
, rdev
);
113 static int xmp_mkdir(const char *path
, mode_t mode
)
117 res
= mkdir(path
, mode
);
124 static int xmp_unlink(const char *path
)
135 static int xmp_rmdir(const char *path
)
146 static int xmp_symlink(const char *from
, const char *to
)
150 res
= symlink(from
, to
);
157 static int xmp_rename(const char *from
, const char *to
)
161 res
= rename(from
, to
);
168 static int xmp_link(const char *from
, const char *to
)
172 res
= link(from
, to
);
179 static int xmp_chmod(const char *path
, mode_t mode
)
183 res
= chmod(path
, mode
);
190 static int xmp_chown(const char *path
, uid_t uid
, gid_t gid
)
194 res
= lchown(path
, uid
, gid
);
201 static int xmp_truncate(const char *path
, off_t size
)
205 res
= truncate(path
, size
);
212 static int xmp_utimens(const char *path
, const struct timespec ts
[2])
215 struct timeval tv
[2];
217 tv
[0].tv_sec
= ts
[0].tv_sec
;
218 tv
[0].tv_usec
= ts
[0].tv_nsec
/ 1000;
219 tv
[1].tv_sec
= ts
[1].tv_sec
;
220 tv
[1].tv_usec
= ts
[1].tv_nsec
/ 1000;
222 res
= utimes(path
, tv
);
229 static int xmp_open(const char *path
, struct fuse_file_info
*fi
)
233 res
= open(path
, fi
->flags
);
241 static int xmp_read(const char *path
, char *buf
, size_t size
, off_t offset
,
242 struct fuse_file_info
*fi
)
248 fd
= open(path
, O_RDONLY
);
252 res
= pread(fd
, buf
, size
, offset
);
260 static int xmp_write(const char *path
, const char *buf
, size_t size
,
261 off_t offset
, struct fuse_file_info
*fi
)
267 fd
= open(path
, O_WRONLY
);
271 res
= pwrite(fd
, buf
, size
, offset
);
279 static int xmp_statfs(const char *path
, struct statvfs
*stbuf
)
283 res
= statvfs(path
, stbuf
);
290 static int xmp_release(const char *path
, struct fuse_file_info
*fi
)
292 /* Just a stub. This method is optional and can safely be left
300 static int xmp_fsync(const char *path
, int isdatasync
,
301 struct fuse_file_info
*fi
)
303 /* Just a stub. This method is optional and can safely be left
313 /* xattr operations are optional and can safely be left unimplemented */
314 static int xmp_setxattr(const char *path
, const char *name
, const char *value
,
315 size_t size
, int flags
)
317 int res
= lsetxattr(path
, name
, value
, size
, flags
);
323 static int xmp_getxattr(const char *path
, const char *name
, char *value
,
326 int res
= lgetxattr(path
, name
, value
, size
);
332 static int xmp_listxattr(const char *path
, char *list
, size_t size
)
334 int res
= llistxattr(path
, list
, size
);
340 static int xmp_removexattr(const char *path
, const char *name
)
342 int res
= lremovexattr(path
, name
);
347 #endif /* HAVE_SETXATTR */
349 static struct fuse_operations xmp_oper
= {
350 .getattr
= xmp_getattr
,
351 .access
= xmp_access
,
352 .readlink
= xmp_readlink
,
353 .readdir
= xmp_readdir
,
356 .symlink
= xmp_symlink
,
357 .unlink
= xmp_unlink
,
359 .rename
= xmp_rename
,
363 .truncate
= xmp_truncate
,
364 .utimens
= xmp_utimens
,
368 .statfs
= xmp_statfs
,
369 .release
= xmp_release
,
372 .setxattr
= xmp_setxattr
,
373 .getxattr
= xmp_getxattr
,
374 .listxattr
= xmp_listxattr
,
375 .removexattr
= xmp_removexattr
,
379 int main(int argc
, char *argv
[])
382 return fuse_main(argc
, argv
, &xmp_oper
, NULL
);