diff --git a/README.md b/README.md index a869c29..ae5d1f9 100644 --- a/README.md +++ b/README.md @@ -85,11 +85,14 @@ hfsfuse-specific options are shown below you should only set this if you are sure it is being misdetected -o rsrc_ext=suffix special suffix for filenames which can be used to access their resource fork or alternatively their data fork if mounted in rsrc_only mode - + -o default_file_mode=N octal filesystem permissions for Mac OS Classic files (755) -o default_dir_mode=N octal filesystem permissions for Mac OS Classic directories (777) -o default_uid=N unix user ID for Mac OS Classic files (0) -o default_gid=N unix group ID for Mac OS Classic files (0) + + -o disable_symlinks treat symbolic links as regular files. may be used to view extended attributes + of these on systems that don't support symlink xattrs -o noublio disable ublio read layer -o ublio_items=N number of ublio cache entries, 0 for no caching (64) @@ -127,6 +130,8 @@ Because of this, the more familiar `/rsrc` suffix used by previous releases of m Finally, the entire volume may be mounted in resource-fork only mode using the `rsrc_only` option. In this mode, all entries on the filesystem are presented using the size and contents of their resource fork. Files with no resource fork will appear as empty, 0 size entries. This option may be combined with the `rsrc_ext` option described above, in which case the special suffix will instead be used to access the regular data fork. +### OS-specific extended attribute behavior + On Linux you may encounter the following error when inspecting xattrs: `user.com.apple.ResourceFork: Argument list too long` This occurs when the resource fork is larger than the maximum allowed extended attribute size of 64kb. In this case you can still access the resource fork as described above by setting the `rsrc_ext` option or mounting in `rsrc_only` mode. @@ -139,6 +144,9 @@ catattr -r user.com.apple.ResourceFork file | xxd -r -p Extended attributes are presented in the preferred namespace for the OS, typically `user.`. Alternate namespaces may be chosen when building hfsfuse by setting the `XATTR_NAMESPACE` make var. This should include the trailing `.` as an empty value indicates no namespacing (such as on macOS.) +HFS+ symbolic links may contain extended attributes of their own separate from their link destination. +For systems such as Linux that do not support reading user-namespace extended attributes of symlinks, these can be viewed by using the `-o disable_symlinks` mount option, which will cause hfsfuse to display all symlinks as regular files. + ## Mac OS Classic file permissions HFS+ filesystems created on Mac OS Classic do not contain the typical set of Unix ownership and permission information for files and folders. For these hfsfuse provides the options default_file_mode, default_dir_mode, default_uid, and default_gid to specify fallback values if needed. diff --git a/lib/libhfsuser/hfsuser.c b/lib/libhfsuser/hfsuser.c index 11255af..37f2eb0 100644 --- a/lib/libhfsuser/hfsuser.c +++ b/lib/libhfsuser/hfsuser.c @@ -79,6 +79,7 @@ struct hfs_device { gid_t default_gid; void* read_buf; pthread_mutex_t read_mutex; + bool disable_symlinks; #ifdef HAVE_UBLIO bool use_ublio; ublio_filehandle_t ubfh; @@ -393,6 +394,9 @@ void hfs_stat(hfs_volume* vol, hfs_catalog_keyed_record_t* key, struct stat* st, HFS_IFMODES #undef X + if(dev->disable_symlinks && S_ISLNK(st->st_mode)) + st->st_mode = (st->st_mode & ~S_IFLNK) | S_IFREG; + if(key->file.bsd.owner_id > UID_MAX) { hfslib_error("hfs_stat: owner_id %" PRIu32 " too large for CNID %" PRIu32 ", using default",NULL,0,key->file.bsd.owner_id,key->file.cnid); st->st_uid = dev->default_uid; @@ -590,6 +594,8 @@ int hfs_open(hfs_volume* vol, const char* name, hfs_callback_args* cbargs) { BAIL(ERANGE); dev->default_gid = cfg.default_gid; + dev->disable_symlinks = cfg.disable_symlinks; + #ifdef HAVE_UBLIO dev->use_ublio = !cfg.noublio; if(dev->use_ublio) { diff --git a/lib/libhfsuser/hfsuser.h b/lib/libhfsuser/hfsuser.h index f85b3d6..448df94 100644 --- a/lib/libhfsuser/hfsuser.h +++ b/lib/libhfsuser/hfsuser.h @@ -62,6 +62,8 @@ struct hfs_volume_config { uint16_t default_file_mode, default_dir_mode; uint32_t default_uid, default_gid; + + int disable_symlinks; }; // HFS+ compression support diff --git a/src/hfsfuse.c b/src/hfsfuse.c index f630af5..abc18ec 100644 --- a/src/hfsfuse.c +++ b/src/hfsfuse.c @@ -575,6 +575,7 @@ static struct fuse_opt hfsfuse_opts[] = { HFS_OPTION("default_dir_mode=%"SCNo16,default_dir_mode), HFS_OPTION("default_uid=%" SCNu32,default_uid), HFS_OPTION("default_gid=%" SCNu32,default_gid), + HFS_OPTION("disable_symlinks", disable_symlinks), FUSE_OPT_END }; @@ -606,6 +607,9 @@ static void help(const char* self, struct hfsfuse_config* cfg) { " -o default_dir_mode=N octal filesystem permissions for Mac OS Classic directories (%" PRIo16 ")\n" " -o default_uid=N unix user ID for Mac OS Classic files (%" PRIu32 ")\n" " -o default_gid=N unix group ID for Mac OS Classic files (%" PRIu32 ")\n" + "\n" + " -o disable_symlinks treat symbolic links as regular files. may be used to view extended attributes\n" + " of these on systems that don't support symlink xattrs\n" "\n", cfg->volume_config.cache_size, cfg->volume_config.default_file_mode,