32
32
static int xmp_getattr(const char *path, struct stat *stbuf)
36
res = lstat(path, stbuf);
36
res = lstat(path, stbuf);
43
43
static int xmp_fgetattr(const char *path, struct stat *stbuf,
44
struct fuse_file_info *fi)
44
struct fuse_file_info *fi)
50
res = fstat(fi->fh, stbuf);
50
res = fstat(fi->fh, stbuf);
57
57
static int xmp_access(const char *path, int mask)
61
res = access(path, mask);
61
res = access(path, mask);
68
68
static int xmp_readlink(const char *path, char *buf, size_t size)
72
res = readlink(path, buf, size - 1);
72
res = readlink(path, buf, size - 1);
80
80
static int xmp_opendir(const char *path, struct fuse_file_info *fi)
82
DIR *dp = opendir(path);
82
DIR *dp = opendir(path);
86
fi->fh = (unsigned long) dp;
86
fi->fh = (unsigned long) dp;
90
90
static inline DIR *get_dirp(struct fuse_file_info *fi)
92
return (DIR *) (uintptr_t) fi->fh;
92
return (DIR *) (uintptr_t) fi->fh;
95
95
static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
96
off_t offset, struct fuse_file_info *fi)
96
off_t offset, struct fuse_file_info *fi)
98
DIR *dp = get_dirp(fi);
103
while ((de = readdir(dp)) != NULL) {
105
memset(&st, 0, sizeof(st));
106
st.st_ino = de->d_ino;
107
st.st_mode = de->d_type << 12;
108
if (filler(buf, de->d_name, &st, telldir(dp)))
98
DIR *dp = get_dirp(fi);
103
while ((de = readdir(dp)) != NULL) {
105
memset(&st, 0, sizeof(st));
106
st.st_ino = de->d_ino;
107
st.st_mode = de->d_type << 12;
108
if (filler(buf, de->d_name, &st, telldir(dp)))
115
115
static int xmp_releasedir(const char *path, struct fuse_file_info *fi)
117
DIR *dp = get_dirp(fi);
117
DIR *dp = get_dirp(fi);
123
123
static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
128
res = mkfifo(path, mode);
130
res = mknod(path, mode, rdev);
128
res = mkfifo(path, mode);
130
res = mknod(path, mode, rdev);
137
137
static int xmp_mkdir(const char *path, mode_t mode)
141
res = mkdir(path, mode);
141
res = mkdir(path, mode);
148
148
static int xmp_unlink(const char *path)
159
159
static int xmp_rmdir(const char *path)
170
170
static int xmp_symlink(const char *from, const char *to)
174
res = symlink(from, to);
174
res = symlink(from, to);
181
181
static int xmp_rename(const char *from, const char *to)
185
res = rename(from, to);
185
res = rename(from, to);
192
192
static int xmp_link(const char *from, const char *to)
196
res = link(from, to);
196
res = link(from, to);
203
203
static int xmp_chmod(const char *path, mode_t mode)
207
res = chmod(path, mode);
207
res = chmod(path, mode);
214
214
static int xmp_chown(const char *path, uid_t uid, gid_t gid)
218
res = lchown(path, uid, gid);
218
res = lchown(path, uid, gid);
225
225
static int xmp_truncate(const char *path, off_t size)
229
res = truncate(path, size);
229
res = truncate(path, size);
236
236
static int xmp_ftruncate(const char *path, off_t size,
237
struct fuse_file_info *fi)
237
struct fuse_file_info *fi)
243
res = ftruncate(fi->fh, size);
243
res = ftruncate(fi->fh, size);
250
250
static int xmp_utimens(const char *path, const struct timespec ts[2])
253
struct timeval tv[2];
255
tv[0].tv_sec = ts[0].tv_sec;
256
tv[0].tv_usec = ts[0].tv_nsec / 1000;
257
tv[1].tv_sec = ts[1].tv_sec;
258
tv[1].tv_usec = ts[1].tv_nsec / 1000;
260
res = utimes(path, tv);
253
struct timeval tv[2];
255
tv[0].tv_sec = ts[0].tv_sec;
256
tv[0].tv_usec = ts[0].tv_nsec / 1000;
257
tv[1].tv_sec = ts[1].tv_sec;
258
tv[1].tv_usec = ts[1].tv_nsec / 1000;
260
res = utimes(path, tv);
267
267
static int xmp_create(const char *path, mode_t mode, struct fuse_file_info *fi)
271
fd = open(path, fi->flags, mode);
271
fd = open(path, fi->flags, mode);
279
279
static int xmp_open(const char *path, struct fuse_file_info *fi)
283
fd = open(path, fi->flags);
283
fd = open(path, fi->flags);
291
291
static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
292
struct fuse_file_info *fi)
292
struct fuse_file_info *fi)
297
res = pread(fi->fh, buf, size, offset);
297
res = pread(fi->fh, buf, size, offset);
304
304
static int xmp_write(const char *path, const char *buf, size_t size,
305
off_t offset, struct fuse_file_info *fi)
305
off_t offset, struct fuse_file_info *fi)
310
res = pwrite(fi->fh, buf, size, offset);
310
res = pwrite(fi->fh, buf, size, offset);
317
317
static int xmp_statfs(const char *path, struct statvfs *stbuf)
321
res = statvfs(path, stbuf);
321
res = statvfs(path, stbuf);
328
328
static int xmp_flush(const char *path, struct fuse_file_info *fi)
333
/* This is called from every close on an open file, so call the
334
close on the underlying filesystem. But since flush may be
335
called multiple times for an open file, this must not really
336
close the file. This is important if used on a network
337
filesystem like NFS which flush the data/metadata on close() */
338
res = close(dup(fi->fh));
333
/* This is called from every close on an open file, so call the
334
close on the underlying filesystem. But since flush may be
335
called multiple times for an open file, this must not really
336
close the file. This is important if used on a network
337
filesystem like NFS which flush the data/metadata on close() */
338
res = close(dup(fi->fh));
345
345
static int xmp_release(const char *path, struct fuse_file_info *fi)
353
353
static int xmp_fsync(const char *path, int isdatasync,
354
struct fuse_file_info *fi)
354
struct fuse_file_info *fi)
359
359
#ifndef HAVE_FDATASYNC
363
res = fdatasync(fi->fh);
363
res = fdatasync(fi->fh);
373
373
#ifdef HAVE_SETXATTR
374
374
/* xattr operations are optional and can safely be left unimplemented */
375
375
static int xmp_setxattr(const char *path, const char *name, const char *value,
376
size_t size, int flags)
376
size_t size, int flags)
378
int res = lsetxattr(path, name, value, size, flags);
378
int res = lsetxattr(path, name, value, size, flags);
384
384
static int xmp_getxattr(const char *path, const char *name, char *value,
387
int res = lgetxattr(path, name, value, size);
387
int res = lgetxattr(path, name, value, size);
393
393
static int xmp_listxattr(const char *path, char *list, size_t size)
395
int res = llistxattr(path, list, size);
395
int res = llistxattr(path, list, size);
401
401
static int xmp_removexattr(const char *path, const char *name)
403
int res = lremovexattr(path, name);
403
int res = lremovexattr(path, name);
408
408
#endif /* HAVE_SETXATTR */
410
410
static int xmp_lock(const char *path, struct fuse_file_info *fi, int cmd,
415
return ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner,
416
sizeof(fi->lock_owner));
415
return ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner,
416
sizeof(fi->lock_owner));
419
419
static struct fuse_operations xmp_oper = {
420
.getattr = xmp_getattr,
421
.fgetattr = xmp_fgetattr,
422
.access = xmp_access,
423
.readlink = xmp_readlink,
424
.opendir = xmp_opendir,
425
.readdir = xmp_readdir,
426
.releasedir = xmp_releasedir,
429
.symlink = xmp_symlink,
430
.unlink = xmp_unlink,
432
.rename = xmp_rename,
436
.truncate = xmp_truncate,
437
.ftruncate = xmp_ftruncate,
438
.utimens = xmp_utimens,
439
.create = xmp_create,
443
.statfs = xmp_statfs,
445
.release = xmp_release,
420
.getattr = xmp_getattr,
421
.fgetattr = xmp_fgetattr,
422
.access = xmp_access,
423
.readlink = xmp_readlink,
424
.opendir = xmp_opendir,
425
.readdir = xmp_readdir,
426
.releasedir = xmp_releasedir,
429
.symlink = xmp_symlink,
430
.unlink = xmp_unlink,
432
.rename = xmp_rename,
436
.truncate = xmp_truncate,
437
.ftruncate = xmp_ftruncate,
438
.utimens = xmp_utimens,
439
.create = xmp_create,
443
.statfs = xmp_statfs,
445
.release = xmp_release,
447
447
#ifdef HAVE_SETXATTR
448
.setxattr = xmp_setxattr,
449
.getxattr = xmp_getxattr,
450
.listxattr = xmp_listxattr,
451
.removexattr= xmp_removexattr,
448
.setxattr = xmp_setxattr,
449
.getxattr = xmp_getxattr,
450
.listxattr = xmp_listxattr,
451
.removexattr = xmp_removexattr,
456
456
int main(int argc, char *argv[])
459
return fuse_main(argc, argv, &xmp_oper, NULL);
459
return fuse_main(argc, argv, &xmp_oper, NULL);