// shouldn't that comment be "if" there is no.... ? int sfs_mknod(const char *path, mode_t mode, dev_t dev) { int retstat = 0; char fpath[PATH_MAX]; printf("\nsfs_mknod(path=\"%s\", mode=0%3o, dev=%lld)\n", path, mode, dev); sfs_fullpath(fpath, path); // On Linux this could just be 'mknod(path, mode, rdev)' but this // is more portable if (S_ISREG(mode)) { retstat = open(fpath, O_CREAT | O_EXCL | O_WRONLY, mode); if (retstat < 0) { retstat = sfs_error("sfs_mknod open"); } else { retstat = close(retstat); if (retstat < 0) { retstat = sfs_error("sfs_mknod close"); } } } else if (S_ISFIFO(mode)) { retstat = mkfifo(fpath, mode); if (retstat < 0) { retstat = sfs_error("sfs_mknod mkfifo"); } } else { retstat = mknod(fpath, mode, dev); if (retstat < 0) { retstat = sfs_error("sfs_mknod mknod"); } } return retstat; }
int sfs_rename(const char *path, const char *newpath) { int retstat = 0; char fpath[PATH_MAX]; char fnewpath[PATH_MAX]; nlink_t nlink = 0; ino_t ino = 0 ; sfs_fullpath(fpath, path); sfs_fullpath(fnewpath, newpath); struct stat st; if (stat(fnewpath, &st) != -1) { nlink = st.st_nlink; ino = st.st_ino; } retstat = rename(fpath, fnewpath); if (retstat != -1) { // logonly successful attempts // don't log if rename did not remove oldpath (which means that both // path and newpath refer to same file if (!fileExists(fpath)) logRename(path, newpath, nlink, ino); } if (retstat < 0) retstat = sfs_error("sfs_rename rename"); return retstat; }
/** Read directory * * This supersedes the old getdir() interface. New applications * should use this. * * The filesystem may choose between two modes of operation: * * 1) The readdir implementation ignores the offset parameter, and * passes zero to the filler function's offset. The filler * function will not return '1' (unless an error happens), so the * whole directory is read in a single readdir operation. This * works just like the old getdir() method. * * 2) The readdir implementation keeps track of the offsets of the * directory entries. It uses the offset parameter and always * passes non-zero offset to the filler function. When the buffer * is full (or an error happens) the filler function will return * '1'. * * Introduced in version 2.3 */ int sfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { int retstat = 0; DIR *dp; struct dirent *de; // once again, no need for fullpath -- but note that I need to cast fi->fh dp = (DIR *) (uintptr_t) fi->fh; // Every directory contains at least two entries: . and .. If my // first call to the system readdir() returns NULL I've got an // error; near as I can tell, that's the only condition under // which I can get an error from readdir() de = readdir(dp); if (de == 0) { retstat = sfs_error("sfs_readdir readdir"); return retstat; } // This will copy the entire directory into the buffer. The loop exits // when either the system readdir() returns NULL, or filler() // returns something non-zero. The first case just means I've // read the whole directory; the second means the buffer is full. do { if (filler(buf, de->d_name, NULL, 0) != 0) { return -ENOMEM; } } while ((de = readdir(dp)) != NULL); return retstat; }
int sfs_fgetattr(const char *path, struct stat *statbuf, struct fuse_file_info *fi) { int retstat = 0; retstat = fstat(fi->fh, statbuf); if (retstat < 0) retstat = sfs_error("sfs_fgetattr fstat"); return retstat; }
/* note -- I'll want to change this as soon as 2.6 is in debian testing */ int sfs_utime(const char *path, struct utimbuf *ubuf) { int retstat = 0; char fpath[PATH_MAX]; sfs_fullpath(fpath, path); retstat = utime(fpath, ubuf); if (retstat < 0) retstat = sfs_error("sfs_utime utime"); return retstat; }
/** Get extended attributes */ int sfs_getxattr(const char *path, const char *name, char *value, size_t size) { int retstat = 0; char fpath[PATH_MAX]; sfs_fullpath(fpath, path); retstat = lgetxattr(fpath, name, value, size); if (retstat < 0) retstat = sfs_error("sfs_getxattr lgetxattr"); return retstat; }
/** Get file attributes. * * Similar to stat(). The 'st_dev' and 'st_blksize' fields are * ignored. The 'st_ino' field is ignored except if the 'use_ino' * mount option is given. */ int sfs_getattr(const char *path, struct stat *statbuf) { int retstat = 0; char fpath[PATH_MAX]; sfs_fullpath(fpath, path); retstat = lstat(fpath, statbuf); if (retstat != 0) retstat = sfs_error("sfs_getattr lstat"); return retstat; }
/** List extended attributes */ int sfs_listxattr(const char *path, char *list, size_t size) { int retstat = 0; char fpath[PATH_MAX]; sfs_fullpath(fpath, path); retstat = llistxattr(fpath, list, size); if (retstat < 0) retstat = sfs_error("sfs_listxattr llistxattr"); return retstat; }
/** Get file system statistics * * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored * * Replaced 'struct statfs' parameter with 'struct statvfs' in * version 2.5 */ int sfs_statfs(const char *path, struct statvfs *statv) { int retstat = 0; char fpath[PATH_MAX]; sfs_fullpath(fpath, path); // get stats for underlying filesystem retstat = statvfs(fpath, statv); if (retstat < 0) retstat = sfs_error("sfs_statfs statvfs"); return retstat; }
/** Set extended attributes */ int sfs_setxattr(const char *path, const char *name, const char *value, size_t size, int flags) { int retstat = 0; char fpath[PATH_MAX]; // TODO: log? sfs_fullpath(fpath, path); retstat = lsetxattr(fpath, name, value, size, flags); if (retstat < 0) retstat = sfs_error("sfs_setxattr lsetxattr"); return retstat; }
/** Remove extended attributes */ int sfs_removexattr(const char *path, const char *name) { int retstat = 0; char fpath[PATH_MAX]; // TODO: log? sfs_fullpath(fpath, path); retstat = lremovexattr(fpath, name); if (retstat < 0) retstat = sfs_error("sfs_removexattr lrmovexattr"); return retstat; }
/** * Change the size of an open file * * This method is called instead of the truncate() method if the * truncation was invoked from an ftruncate() system call. * * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the truncate() method will be * called instead. * * Introduced in version 2.5 */ int sfs_ftruncate(const char *path, off_t offset, struct fuse_file_info *fi) { int retstat = 0; printf("\nsfs_ftruncate(path=\"%s\", offset=%lld, fi=0x%08x)\n", path, offset, fi); retstat = ftruncate(fi->fh, offset); if (retstat < 0) { retstat = sfs_error("sfs_ftruncate ftruncate"); } return retstat; }
/** * Check file access permissions * * This will be called for the access() system call. If the * 'default_permissions' mount option is given, this method is not * called. * * This method is not called under Linux kernel versions 2.4.x * * Introduced in version 2.5 */ int sfs_access(const char *path, int mask) { int retstat = 0; char fpath[PATH_MAX]; sfs_fullpath(fpath, path); retstat = access(fpath, mask); if (retstat < 0) retstat = sfs_error("sfs_access access"); return retstat; }
/** Synchronize file contents * * If the datasync parameter is non-zero, then only the user data * should be flushed, not the meta data. * * Changed in version 2.2 */ int sfs_fsync(const char *path, int datasync, struct fuse_file_info *fi) { int retstat = 0; if (datasync) retstat = fdatasync(fi->fh); else retstat = fsync(fi->fh); if (retstat < 0) sfs_error("sfs_fsync fsync"); return retstat; }
int sfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int retstat = 0; // no need to get fpath on this one, since I work from fi->fh not the path retstat = pread(fi->fh, buf, size, offset); if (retstat < 0) retstat = sfs_error("sfs_read read"); return retstat; }
/* note -- I'll want to change this as soon as 2.6 is in debian testing */ int sfs_utime(const char *path, struct utimbuf *ubuf) { int retstat = 0; char fpath[PATH_MAX]; printf("\nsfs_utime(path=\"%s\", ubuf=0x%08x)\n", path, ubuf); sfs_fullpath(fpath, path); retstat = utime(fpath, ubuf); if (retstat < 0) { retstat = sfs_error("sfs_utime utime"); } return retstat; }
/** Remove a directory */ int sfs_rmdir(const char *path) { int retstat = 0; char fpath[PATH_MAX]; printf("sfs_rmdir(path=\"%s\")\n", path); sfs_fullpath(fpath, path); retstat = rmdir(fpath); if (retstat < 0) { retstat = sfs_error("sfs_rmdir rmdir"); } return retstat; }
/** Change the permission bits of a file */ int sfs_chmod(const char *path, mode_t mode) { int retstat = 0; char fpath[PATH_MAX]; printf("\nsfs_chmod(fpath=\"%s\", mode=0%03o)\n", path, mode); sfs_fullpath(fpath, path); retstat = chmod(fpath, mode); if (retstat < 0) { retstat = sfs_error("sfs_chmod chmod"); } return retstat; }
/** Get file attributes. * * Similar to stat(). The 'st_dev' and 'st_blksize' fields are * ignored. The 'st_ino' field is ignored except if the 'use_ino' * mount option is given. */ int sfs_getattr(const char *path, struct stat *statbuf) { int retstat = 0; char fpath[PATH_MAX]; printf("\nsfs_getattr(path=\"%s\", statbuf=0x%08x)\n", path, statbuf); sfs_fullpath(fpath, path); retstat = lstat(fpath, statbuf); if (retstat != 0) { retstat = sfs_error("sfs_getattr lstat"); } return retstat; }
/** Remove a file */ int sfs_unlink(const char *path) { int retstat = 0; char fpath[PATH_MAX]; printf("sfs_unlink(path=\"%s\")\n", path); sfs_fullpath(fpath, path); retstat = unlink(fpath); if (retstat < 0) { retstat = sfs_error("sfs_unlink unlink"); } return retstat; }
/** Change the size of a file */ int sfs_truncate(const char *path, off_t newsize) { int retstat = 0; char fpath[PATH_MAX]; printf("\nsfs_truncate(path=\"%s\", newsize=%lld)\n", path, newsize); sfs_fullpath(fpath, path); retstat = truncate(fpath, newsize); if (retstat < 0) { sfs_error("sfs_truncate truncate"); } return retstat; }
// The parameters here are a little bit confusing, but do correspond // to the symlink() system call. The 'path' is where the link points, // while the 'link' is the link itself. So we need to leave the path // unaltered, but insert the link into the mounted directory. int sfs_symlink(const char *path, const char *link) { int retstat = 0; char flink[PATH_MAX]; printf("\nsfs_symlink(path=\"%s\", link=\"%s\")\n", path, link); sfs_fullpath(flink, link); retstat = symlink(path, flink); if (retstat < 0) { retstat = sfs_error("sfs_symlink symlink"); } return retstat; }
/** * Change the size of an open file * * This method is called instead of the truncate() method if the * truncation was invoked from an ftruncate() system call. * * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the truncate() method will be * called instead. * * Introduced in version 2.5 */ int sfs_ftruncate(const char *path, off_t offset, struct fuse_file_info *fi) { int retstat = 0; retstat = ftruncate(fi->fh, offset); // TODO: check if path is properly populated if (retstat != -1) // log only successful attempts as truncate operation logTruncate(path, offset); if (retstat < 0) retstat = sfs_error("sfs_ftruncate ftruncate"); return retstat; }
int sfs_mknod(const char *path, mode_t mode, dev_t dev) { int retstat = 0; char fpath[PATH_MAX]; sfs_fullpath(fpath, path); // On Linux this could just be 'mknod(path, mode, rdev)' but this // is more portable if (S_ISREG(mode)) { retstat = open(fpath, O_CREAT | O_EXCL | O_WRONLY, mode); if (retstat < 0) { retstat = sfs_error("sfs_mknod open"); } else { logMknod(path, mode, dev); // log only successful attempts retstat = close(retstat); if (retstat < 0) retstat = sfs_error("sfs_mknod close"); } } else { if (S_ISFIFO(mode)) { retstat = mkfifo(fpath, mode); if (retstat < 0) retstat = sfs_error("sfs_mknod mkfifo"); else logMknod(path, mode, dev); // log only successful attempts } else { retstat = mknod(fpath, mode, dev); if (retstat < 0) retstat = sfs_error("sfs_mknod mknod"); else logMknod(path, mode, dev); // log only successful attempts } } return retstat; }
/** Get file system statistics * * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored * * Replaced 'struct statfs' parameter with 'struct statvfs' in * version 2.5 */ int sfs_statfs(const char *path, struct statvfs *statv) { int retstat = 0; char fpath[PATH_MAX]; printf("\nsfs_statfs(path=\"%s\", statv=0x%08x)\n", path, statv); sfs_fullpath(fpath, path); // get stats for underlying filesystem retstat = statvfs(fpath, statv); if (retstat < 0) { retstat = sfs_error("sfs_statfs statvfs"); } return retstat; }
/** * Check file access permissions * * This will be called for the access() system call. If the * 'default_permissions' mount option is given, this method is not * called. * * This method is not called under Linux kernel versions 2.4.x * * Introduced in version 2.5 */ int sfs_access(const char *path, int mask) { int retstat = 0; char fpath[PATH_MAX]; printf("\nsfs_access(path=\"%s\", mask=0%o)\n", path, mask); sfs_fullpath(fpath, path); retstat = access(fpath, mask); if (retstat < 0) { retstat = sfs_error("sfs_access access"); } return retstat; }
/** Create a hard link to a file */ int sfs_link(const char *path, const char *newpath) { int retstat = 0; char fpath[PATH_MAX], fnewpath[PATH_MAX]; printf("\nsfs_link(path=\"%s\", newpath=\"%s\")\n", path, newpath); sfs_fullpath(fpath, path); sfs_fullpath(fnewpath, newpath); retstat = link(fpath, fnewpath); if (retstat < 0) { retstat = sfs_error("sfs_link link"); } return retstat; }
/** File open operation * * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC) * will be passed to open(). Open should check if the operation * is permitted for the given flags. Optionally open may also * return an arbitrary filehandle in the fuse_file_info structure, * which will be passed to all file operations. * * Changed in version 2.2 */ int sfs_open(const char *path, struct fuse_file_info *fi) { int retstat = 0; int fd; char fpath[PATH_MAX]; sfs_fullpath(fpath, path); fd = open(fpath, fi->flags); if (fd < 0) retstat = sfs_error("sfs_open open"); fi->fh = fd; return retstat; }
/** Open directory * * This method should check if the open operation is permitted for * this directory * * Introduced in version 2.3 */ int sfs_opendir(const char *path, struct fuse_file_info *fi) { DIR *dp; int retstat = 0; char fpath[PATH_MAX]; sfs_fullpath(fpath, path); dp = opendir(fpath); if (dp == NULL) retstat = sfs_error("sfs_opendir opendir"); fi->fh = (intptr_t) dp; return retstat; }
/** Change the size of a file */ int sfs_truncate(const char *path, off_t newsize) { int retstat = 0; char fpath[PATH_MAX]; sfs_fullpath(fpath, path); retstat = truncate(fpath, newsize); if (retstat != -1) // log only successful attempts logTruncate(path, newsize); if (retstat < 0) sfs_error("sfs_truncate truncate"); return retstat; }