From b05713f0176f76d2494f9c9436e75b075df9ded2 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 20 Aug 2020 11:28:45 -0400 Subject: [PATCH] Linux host fst resource support. --- src/host_fst.c | 41 ++++++++++++++++++++++++++++++++++++----- src/unix_host_common.c | 25 ++++++++++++++++++++----- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/host_fst.c b/src/host_fst.c index 40043e9..4cc0536 100644 --- a/src/host_fst.c +++ b/src/host_fst.c @@ -406,6 +406,14 @@ static char *get_path2(void) { return NULL; } +#if defined (__linux__) +static void get_resource_pathname(const char *path, char *rpath) { + char *pos=strrchr(path,'/'); + strncpy(rpath, path, (pos-path)+1); + strcat(rpath, "._"); + strcat(rpath, pos+1); +} +#endif /* * shutdown is called when switching to p8. @@ -546,6 +554,17 @@ static word32 fst_destroy(int class, const char *path) { int ok = S_ISDIR(st.st_mode) ? rmdir(path) : unlink(path); +#if defined(__linux__) + if (! S_ISDIR(st.st_mode)) { + // on linux remove the resource fork file as well. + char rpath[1024]; + get_resource_pathname(path, rpath); + if (stat(rpath, &st) == 0) { + int ok2 = unlink(rpath); + if (ok2 < 0) return host_map_errno_path(errno, path); + } + } +#endif if (ok < 0) return host_map_errno_path(errno, path); return 0; } @@ -768,12 +787,18 @@ static int open_data_fork(const char *path, word16 *access, word16 *error) { return fd; } +#if defined(__APPLE__) || defined(__linux__) +static int open_resource_fork(const char *path, word16 *access, word16 *error) { #if defined(__APPLE__) static int open_resource_fork(const char *path, word16 *access, word16 *error) { // os x / hfs/apfs don't need to specifically create a resource fork. // or do they? char *rpath = host_gc_append_path(path, _PATH_RSRCFORKSPEC); +#else + char rpath[1024]; + get_resource_pathname(path, rpath); +#endif int fd = -1; for (;;) { @@ -852,11 +877,6 @@ static int open_resource_fork(const char *path, word16 *access, word16 *error) { return fd; } -#elif defined __linux__ -static int open_resource_fork(const char *path, word16 *access, word16 *error) { - *error = resForkNotFound; - return -1; -} #else static int open_resource_fork(const char *path, word16 *access, word16 *error) { *error = resForkNotFound; @@ -1534,9 +1554,20 @@ static word32 fst_change_path(int class, const char *path1, const char *path2) { return invalidAccess; // rename will delete any previous file. ChangePath should return an error. +#if ! defined(__linux__) if (stat(path2, &st) == 0) return dupPathname; if (rename(path1, path2) < 0) return host_map_errno_path(errno, path2); +#else + //on linux rename both the file and the resource file. + char rpath1[1024], rpath2[1024]; + get_resource_pathname(path1, rpath1); + get_resource_pathname(path2, rpath2); + if (stat(path2, &st) == 0 || stat(rpath2, &st) == 0) return dupPathname; + if (rename(path1, path2) < 0) return host_map_errno_path(errno, path2); + if (rename(rpath1, rpath2) < 0) return host_map_errno_path(errno, rpath2); + +#endif return 0; } diff --git a/src/unix_host_common.c b/src/unix_host_common.c index 30523c0..3af7f73 100644 --- a/src/unix_host_common.c +++ b/src/unix_host_common.c @@ -256,10 +256,25 @@ void host_get_file_xinfo(const char *path, struct file_info *fi) { void host_get_file_xinfo(const char *path, struct file_info *fi) { ssize_t tmp; - tmp = getxattr(path, "user.com.apple.ResourceFork", NULL, 0); - if (tmp < 0) tmp = 0; - fi->resource_eof = tmp; - fi->resource_blocks = (tmp + 511) / 512; + struct stat st; + char rpath[1024] = {0}; + char *pos=strrchr(path,'/'); + if (pos) { + strncpy(rpath, path, (pos-path)+1); + } else { + pos = (char *)path - 1; + } + strcat(rpath, "._"); + strcat(rpath, pos+1); + + int ok = stat(rpath, &st); + if (ok < 0) { + fi->resource_eof = 0; + fi->resource_blocks = 0; + } else { + fi->resource_eof = st.st_size; + fi->resource_blocks = st.st_blocks; + } tmp = getxattr(path, "user.com.apple.FinderInfo", fi->finder_info, 32); if (tmp == 16 || tmp == 32) { @@ -398,7 +413,7 @@ word32 host_set_file_info(const char *path, struct file_info *fi) { word32 host_set_file_info(const char *path, struct file_info *fi) { if (fi->has_fi && fi->storage_type != 0x0d) { - int ok = setxattr(path, "user.apple.FinderInfo", fi->finder_info, 32, 0); + int ok = setxattr(path, "user.com.apple.FinderInfo", fi->finder_info, 32, 0); if (ok < 0) return host_map_errno(errno); }