static void dirck(struct exfat* ef, const char* path) { struct exfat_node* parent; struct exfat_node* node; struct exfat_iterator it; int rc; size_t path_length; char* entry_path; if (exfat_lookup(ef, &parent, path) != 0) exfat_bug("directory '%s' is not found", path); if (!(parent->flags & EXFAT_ATTRIB_DIR)) exfat_bug("'%s' is not a directory (0x%x)", path, parent->flags); if (nodeck(ef, parent) != 0) { exfat_put_node(ef, parent); return; } path_length = strlen(path); entry_path = malloc(path_length + 1 + UTF8_BYTES(EXFAT_NAME_MAX) + 1); if (entry_path == NULL) { exfat_put_node(ef, parent); exfat_error("out of memory"); return; } strcpy(entry_path, path); strcat(entry_path, "/"); rc = exfat_opendir(ef, parent, &it); if (rc != 0) { free(entry_path); exfat_put_node(ef, parent); return; } while ((node = exfat_readdir(ef, &it))) { exfat_get_name(node, entry_path + path_length + 1, UTF8_BYTES(EXFAT_NAME_MAX)); exfat_debug("%s: %s, %"PRIu64" bytes, cluster %u", entry_path, IS_CONTIGUOUS(*node) ? "contiguous" : "fragmented", node->size, node->start_cluster); if (node->flags & EXFAT_ATTRIB_DIR) { directories_count++; dirck(ef, entry_path); } else { files_count++; nodeck(ef, node); } exfat_put_node(ef, node); } exfat_closedir(ef, &it); exfat_put_node(ef, parent); free(entry_path); }
static int fuse_exfat_open(const char* path, struct fuse_file_info* fi) { struct exfat_node* node; int rc; exfat_debug("[%s] %s", __func__, path); rc = exfat_lookup(&ef, &node, path); if (rc != 0) return rc; set_node(fi, node); return 0; }
static int fuse_exfat_getattr(const char* path, struct stat* stbuf) { struct exfat_node* node; int rc; exfat_debug("[%s] %s", __func__, path); rc = exfat_lookup(&ef, &node, path); if (rc != 0) return rc; exfat_stat(&ef, node, stbuf); exfat_put_node(&ef, node); return 0; }
static int fuse_exfat_truncate(const char* path, off64_t size) { struct exfat_node* node; int rc; exfat_debug("[%s] %s, %"PRId64, __func__, path, size); rc = exfat_lookup(&ef, &node, path); if (rc != 0) return rc; rc = exfat_truncate(&ef, node, size); exfat_put_node(&ef, node); return rc; }
static int fuse_exfat_utimens(const char* path, const struct timespec tv[2]) { struct exfat_node* node; int rc; exfat_debug("[%s] %s", __func__, path); rc = exfat_lookup(&ef, &node, path); if (rc != 0) return rc; exfat_utimes(node, tv); exfat_put_node(&ef, node); return 0; }
static int fuse_exfat_rmdir(const char* path) { struct exfat_node* node; int rc; exfat_debug("[%s] %s", __func__, path); rc = exfat_lookup(&ef, &node, path); if (rc != 0) return rc; rc = exfat_rmdir(&ef, node); exfat_put_node(&ef, node); return rc; }
static int fuse_exfat_create(const char* path, mode_t mode, struct fuse_file_info* fi) { struct exfat_node* node; int rc; exfat_debug("[%s] %s 0%ho", __func__, path, mode); rc = exfat_mknod(&ef, path); if (rc != 0) return rc; rc = exfat_lookup(&ef, &node, path); if (rc != 0) return rc; set_node(fi, node); return 0; }
static int fuse_exfat_readdir(const char* path, void* buffer, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info* fi) { struct exfat_node* parent; struct exfat_node* node; struct exfat_iterator it; int rc; char name[UTF8_BYTES(EXFAT_NAME_MAX) + 1]; exfat_debug("[%s] %s", __func__, path); rc = exfat_lookup(&ef, &parent, path); if (rc != 0) return rc; if (!(parent->flags & EXFAT_ATTRIB_DIR)) { exfat_put_node(&ef, parent); exfat_error("'%s' is not a directory (0x%x)", path, parent->flags); return -ENOTDIR; } filler(buffer, ".", NULL, 0); filler(buffer, "..", NULL, 0); rc = exfat_opendir(&ef, parent, &it); if (rc != 0) { exfat_put_node(&ef, parent); exfat_error("failed to open directory '%s'", path); return rc; } while ((node = exfat_readdir(&ef, &it))) { exfat_get_name(node, name, sizeof(name) - 1); exfat_debug("[%s] %s: %s, %"PRId64" bytes, cluster 0x%x", __func__, name, IS_CONTIGUOUS(*node) ? "contiguous" : "fragmented", node->size, node->start_cluster); filler(buffer, name, NULL, 0); exfat_put_node(&ef, node); } exfat_closedir(&ef, &it); exfat_put_node(&ef, parent); return 0; }
static int fuse_exfat_truncate(const char* path, fbx_off_t size) { struct exfat_node* node; int rc; exfat_debug("[%s] %s, %"PRId64, __func__, path, size); rc = exfat_lookup(&ef, &node, path); if (rc != 0) return rc; rc = exfat_truncate(&ef, node, size, true); if (rc != 0) { exfat_flush_node(&ef, node); /* ignore return code */ exfat_put_node(&ef, node); return rc; } rc = exfat_flush_node(&ef, node); exfat_put_node(&ef, node); return rc; }