#define _GNU_SOURCE #include "sourcefs.h" #include #include #include #include #include #include #include static struct source_files_handle { int root_fd; } handle; const char *source_fname_translate(const char *filename) { if (strcmp("/", filename) == 0) { return "."; } else { return filename + 1; } } int source_init(const char *root_path) { int root_fd = open(root_path, O_PATH); if (root_fd == -1) { return -1; } handle.root_fd = root_fd; return 0; } int source_mkdir(const char *filename, mode_t mode) { const char *relative_filename = source_fname_translate(filename); return mkdirat(handle.root_fd, relative_filename, mode); } int source_unlink(const char *filename) { const char *relative_filename = source_fname_translate(filename); return unlinkat(handle.root_fd, relative_filename, 0); } int source_stat(const char *restrict filename, struct stat *restrict statbuf) { const char *relative_filename = source_fname_translate(filename); return fstatat(handle.root_fd, relative_filename, statbuf, 0); } int source_rmdir(const char *filename) { const char *relative_filename = source_fname_translate(filename); return unlinkat(handle.root_fd, relative_filename, AT_REMOVEDIR); } int source_symlink(const char *target, const char *linkpath) { const char *relative_linkpath = source_fname_translate(linkpath); return symlinkat(target, handle.root_fd, relative_linkpath); } DIR *source_opendir(const char *filename) { const char *relative_filename = source_fname_translate(filename); int fd = openat(handle.root_fd, relative_filename, NULL); if (fd < 0) { perror("Openat failed"); return NULL; } DIR *dir_pointer = fdopendir(fd); return dir_pointer; } int source_rename(const char *oldpath, const char *newpath) { const char *relative_oldpath = source_fname_translate(oldpath); const char *relative_newpath = source_fname_translate(newpath); return renameat(handle.root_fd, relative_oldpath, handle.root_fd, relative_newpath); } int source_link(const char *oldpath, const char *newpath) { const char *relative_oldpath = source_fname_translate(oldpath); const char *relative_newpath = source_fname_translate(newpath); return linkat(handle.root_fd, relative_oldpath, handle.root_fd, relative_newpath, 0); // NOTE: perhaps the flags here need to be reevaluated. } int source_chmod(const char *filename, mode_t mode) { const char *relative_filename = source_fname_translate(filename); return fchmodat(handle.root_fd, relative_filename, mode, 0); // NOTE: perhaps the flags here need to be reevaluated. } int source_chown(const char *filename, uid_t owner, gid_t group) { const char *relative_filename = source_fname_translate(filename); return fchownat(handle.root_fd, filename, owner, group, AT_SYMLINK_NOFOLLOW); } int source_truncate(const char *filename, off_t length) { const char *relative_filename = source_fname_translate(filename); int fd = openat(handle.root_fd, relative_filename, NULL); if (fd < 0) { perror("Openat failed"); return -1; } return ftruncate(fd, length); } int source_open(const char *filename, int flags) { const char *relative_filename = source_fname_translate(filename); return openat(handle.root_fd, relative_filename, flags); } int source_create(const char *filename, int flags, mode_t mode) { const char *relative_filename = source_fname_translate(filename); return openat(handle.root_fd, relative_filename, flags, mode); }