static int FuseHFS_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { dprintf("readdir %s\n", path); // convert to hfs path char *hfspath = mkhfspath(path); if (hfspath == NULL) return -ENOENT; // default directories filler(buf, ".", NULL, 0); /* Current directory (.) */ filler(buf, "..", NULL, 0); /* Parent directory (..) */ // open directory hfsdir *dir = hfs_opendir(NULL, hfspath); if (dir == NULL) { free(hfspath); dprintf("readdir: ENOENT\n"); return -ENOENT; } // read contents hfsdirent ent; struct stat stbuf; char dname[4*HFS_MAX_FLEN+3]; while (hfs_readdir(dir, &ent) == 0) { // File or directory dirent_to_stbuf(&ent, &stbuf); hfs_to_utf8(ent.name, dname, 4*HFS_MAX_FLEN); filler(buf, dname, &stbuf, 0); } // close hfs_closedir(dir); free(hfspath); return 0; }
/* * NAME: hfs->umount() * DESCRIPTION: close an HFS volume */ int hfs_umount(hfsvol *vol) { int result = 0; if (getvol(&vol) == -1) goto fail; if (--vol->refs) { result = v_flush(vol); goto done; } /* close all open files and directories */ while (vol->files) { if (hfs_close(vol->files) == -1) result = -1; } while (vol->dirs) { if (hfs_closedir(vol->dirs) == -1) result = -1; } /* close medium */ if (v_close(vol) == -1) result = -1; /* remove from linked list of volumes */ if (vol->prev) vol->prev->next = vol->next; if (vol->next) vol->next->prev = vol->prev; if (vol == hfs_mounts) hfs_mounts = vol->next; if (vol == curvol) curvol = 0; FREE(vol); done: return result; fail: return -1; }
/* * NAME: hfs->umount() * DESCRIPTION: close an HFS volume */ int hfs_umount(hfsvol *vol) { int result = 0; if (v_getvol(&vol) < 0) return -1; if (--vol->refs) return v_flush(vol, 0); /* close all open files and directories */ while (vol->files) hfs_close(vol->files); while (vol->dirs) hfs_closedir(vol->dirs); if (v_flush(vol, 1) < 0) result = -1; if ( #if 0 close(vol->fd) < 0 && #endif result == 0) { ERROR(errno, "error closing device"); result = -1; } if (vol->prev) vol->prev->next = vol->next; if (vol->next) vol->next->prev = vol->prev; if (vol == hfs_mounts) hfs_mounts = vol->next; if (vol == hfs_curvol) hfs_curvol = 0; v_destruct(vol); return result; }
/* * NAME: hfs->callback_close() * DESCRIPTION: close an HFS volume */ int hfs_callback_close(hfsvol *vol) { int result = 0; if (getvol(&vol) == -1) goto fail; if (--vol->refs) { result = v_flush(vol); goto done; } /* close all open files and directories */ while (vol->files) { if (hfs_close(vol->files) == -1) result = -1; } while (vol->dirs) { if (hfs_closedir(vol->dirs) == -1) result = -1; } /* close medium */ if (v_close(vol) == -1) result = -1; FREE(vol); done: return result; fail: return -1; }
/* * NAME: process() * DESCRIPTION: sort and display results */ static int process(hfsvol *vol, darray *dirs, darray *files, int flags, int options, int width) { int i, dsz, fsz; queueent *ents; int result = 0; dsz = darr_size(dirs); fsz = darr_size(files); if (fsz) { sortfiles(files, flags, options); if (showfiles(files, flags, options, width) == -1) result = -1; flags |= HLS_NAME | HLS_SPACE; } else if (dsz > 1) flags |= HLS_NAME; ents = darr_array(dirs); for (i = 0; i < dsz; ++i) { const char *path; hfsdir *dir; queueent ent; darr_shrink(files, 0); path = PATH(ents[i]); dir = hfs_opendir(vol, path); if (dir == 0) { hfsutil_perrorp(path); result = -1; continue; } while (hfs_readdir(dir, &ent.dirent) != -1) { if ((ent.dirent.fdflags & HFS_FNDR_ISINVISIBLE) && ! (flags & HLS_ALL_FILES)) continue; ent.path = 0; ent.free = 0; if (darr_append(files, &ent) == 0) { fprintf(stderr, "%s: not enough memory\n", argv0); result = -1; break; } if ((ent.dirent.flags & HFS_ISDIR) && (flags & HLS_RECURSIVE)) { dstring str; dstr_init(&str); if (strchr(path, ':') == 0 && dstr_append(&str, ":", 1) == -1) result = -1; if (dstr_append(&str, path, -1) == -1) result = -1; if (path[strlen(path) - 1] != ':' && dstr_append(&str, ":", 1) == -1) result = -1; if (dstr_append(&str, ent.dirent.name, -1) == -1) result = -1; ent.path = strdup(dstr_string(&str)); if (ent.path) ent.free = dpfree; else result = -1; dstr_free(&str); if (darr_append(dirs, &ent) == 0) { result = -1; if (ent.path) free(ent.path); } if (result) { fprintf(stderr, "%s: not enough memory\n", argv0); break; } dsz = darr_size(dirs); ents = darr_array(dirs); } } hfs_closedir(dir); if (result) break; if (flags & HLS_SPACE) printf("\n"); if (flags & HLS_NAME) printf("%s%s", path, path[strlen(path) - 1] == ':' ? "\n" : ":\n"); sortfiles(files, flags, options); if (showfiles(files, flags, options, width) == -1) result = -1; flags |= HLS_NAME | HLS_SPACE; } return result; }