diff --git a/sources/main.c b/sources/main.c index a625b69..3bf17e8 100644 --- a/sources/main.c +++ b/sources/main.c @@ -1,10 +1,15 @@ +#include +#include +#include +#include #include +#include #define FUSE_USE_VERSION 31 #include "sourcefs.h" #include -const char *mountpoint; +const char *mountpoint = NULL; /* * #In this function we need to: @@ -16,40 +21,65 @@ static void *icfs_init(struct fuse_conn_info *conn, struct fuse_config *cfg) { (void)conn; /* Explicit way to tell we ignore these arguments. */ (void)cfg; /* This also silences the compiler warnings. */ - source_init(mountpoint); + int ret = source_init(mountpoint); + if (ret != 0) { + perror("Failed to initialize filesystem."); + exit(EXIT_FAILURE); + } + return NULL; } static int icfs_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi) { + (void)stbuf; + (void)fi; int statret = source_stat(path, stbuf); - - //(void)fi; - - /* - int res = 0; - - memset(stbuf, 0, sizeof(struct stat)); - if (strcmp(path, "/") == 0) { - stbuf->st_mode = S_IFDIR | 0755; - stbuf->st_nlink = 2; - } else if (strcmp(path + 1, options.filename) == 0) { - stbuf->st_mode = S_IFREG | 0444; - stbuf->st_nlink = 1; - stbuf->st_size = strlen(options.contents); - } else - res = -ENOENT; - - */ - // return res; + if (statret != 0) + perror("Stat failed."); return statret; } +static int icfs_opendir(const char *path, struct fuse_file_info *fi) { + DIR *dir_stream = source_opendir(path); + + if (dir_stream == NULL) { + perror("Opendir failed."); + return 1; + } + + fi->fh = (intptr_t)dir_stream; + + return 0; +} + +static int icfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, + off_t offset, struct fuse_file_info *fi, + enum fuse_readdir_flags flags) { + DIR *dir_stream = (DIR *)fi->fh; + struct dirent *dir_entry = source_readdir(dir_stream); + if (dir_entry == NULL) { + perror("Readdir failed."); + return 1; + } + + do { + int filler_ret = filler(buf, dir_entry->d_name, NULL, 0, 0); + if (filler_ret != 0) { + return -ENOMEM; + } + } while ((dir_entry = source_readdir(dir_stream)) != NULL); + + return 0; +} + static const struct fuse_operations icfs_oper = { .init = icfs_init, .getattr = icfs_getattr, + .opendir = icfs_opendir, + .readdir = icfs_readdir, }; int main(int argc, char *argv[]) { @@ -58,7 +88,7 @@ int main(int argc, char *argv[]) { // FUSE won't tell us the mountpoint on it's own, so we need to extract it // ourselves. - mountpoint = realpath(argv[argc - 2], NULL); + mountpoint = realpath(argv[argc - 1], NULL); ret = fuse_main(argc, argv, &icfs_oper, NULL); diff --git a/sources/sourcefs.c b/sources/sourcefs.c index 41a625d..00f6a68 100644 --- a/sources/sourcefs.c +++ b/sources/sourcefs.c @@ -1,6 +1,7 @@ #define _GNU_SOURCE #include "sourcefs.h" +#include #include #include #include @@ -9,6 +10,8 @@ static struct source_files_handle { int root_fd; } handle; +void source_fname_translate(const char *filename) {} + int source_init(const char *root_path) { int root_fd = open(root_path, O_PATH); @@ -26,3 +29,12 @@ int source_stat(const char *restrict pathname, struct stat *restrict statbuf) { int statret = fstatat(handle.root_fd, pathname, statbuf, 0); return statret; } + +DIR *source_opendir(const char *filename) { + int fd = openat(handle.root_fd, filename, NULL); + DIR *dir_pointer = fdopendir(fd); + return dir_pointer; +} + +// Just regular readdir in disguise. +struct dirent *source_readdir(DIR *dirp) { return readdir(dirp); } diff --git a/sources/sourcefs.h b/sources/sourcefs.h index 4b1a0e8..1a017ba 100644 --- a/sources/sourcefs.h +++ b/sources/sourcefs.h @@ -3,13 +3,14 @@ #ifndef SOURCEFS_H #define SOURCEFS_H +#include #include /** * Initializes the source file handling. * * @param root_path The root of the source files folder. - * @return 0 on success, 1 on failure. + * @return 0 on success, -1 on failure. */ int source_init(const char *root_path); @@ -20,4 +21,18 @@ int source_init(const char *root_path); */ int source_stat(const char *restrict pathname, struct stat *restrict statbuf); +/** + * `readdir()`, but for source files. + * + * @see `readdir(3)` + */ +struct dirent *source_readdir(DIR *dirp); + +/** + * `opendir()`, but for source files. + * + * @see `opendir()` + */ +DIR *source_opendir(const char *filename); + #endif // !SOURCEFS_H