--- BasiliskII/src/AmigaOS/extfs_amiga.cpp 1999/11/08 16:43:10 1.2 +++ BasiliskII/src/AmigaOS/extfs_amiga.cpp 2000/07/21 18:01:06 1.8 @@ -1,7 +1,7 @@ /* * extfs_amiga.cpp - MacOS file system for access native file system access, AmigaOS specific stuff * - * Basilisk II (C) 1997-1999 Christian Bauer + * Basilisk II (C) 1997-2000 Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -77,16 +77,11 @@ void add_path_component(char *path, cons * /path/.finf/file * Resource fork: * /path/.rsrc/file + * + * The .finf files store a FInfo/DInfo, followed by a FXInfo/DXInfo + * (16+16 bytes) */ -// Layout of Finder info helper files (all fields big-endian) -struct finf_struct { - uint32 type; - uint32 creator; - uint16 flags; - uint16 pad0; -}; - static void make_helper_path(const char *src, char *dest, const char *add, bool only_dir = false) { dest[0] = 0; @@ -110,6 +105,8 @@ static int create_helper_dir(const char { char helper_dir[MAX_PATH_LENGTH]; make_helper_path(path, helper_dir, add, true); + if (helper_dir[strlen(helper_dir) - 1] == '/') // Remove trailing "/" + helper_dir[strlen(helper_dir) - 1] = 0; return mkdir(helper_dir, 0777); } @@ -187,6 +184,7 @@ static const ext2type e2t_translation[] {".tga", 'TPIC', 'ogle'}, {".tif", 'TIFF', 'ogle'}, {".tiff", 'TIFF', 'ogle'}, + {".htm", 'TEXT', 'MOSS'}, {".html", 'TEXT', 'MOSS'}, {".txt", 'TEXT', 'ttxt'}, {".rtf", 'TEXT', 'MSWD'}, @@ -207,106 +205,61 @@ static const ext2type e2t_translation[] {".mov", 'MooV', 'TVOD'}, {".fli", 'FLI ', 'TVOD'}, {".avi", 'VfW ', 'TVOD'}, + {".qxd", 'XDOC', 'XPR3'}, + {".hfv", 'DDim', 'ddsk'}, + {".dsk", 'DDim', 'ddsk'}, + {".img", 'rohd', 'ddsk'}, {NULL, 0, 0} // End marker }; -void get_finder_type(const char *path, uint32 &type, uint32 &creator) +void get_finfo(const char *path, uint32 finfo, uint32 fxinfo) { - type = 0; - creator = 0; + // Set default finder info + Mac_memset(finfo, 0, SIZEOF_FInfo); + if (fxinfo) + Mac_memset(fxinfo, 0, SIZEOF_FXInfo); + WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS); + WriteMacInt32(finfo + fdLocation, (uint32)-1); - // Open Finder info file + // Read Finder info file int fd = open_finf(path, O_RDONLY); if (fd >= 0) { - - // Read file - finf_struct finf; - if (read(fd, &finf, sizeof(finf_struct)) == sizeof(finf_struct)) { - - // Type/creator are in Finder info file, return them - type = ntohl(finf.type); - creator = ntohl(finf.creator); - close(fd); - return; - } + ssize_t actual = read(fd, Mac2HostAddr(finfo), SIZEOF_FInfo); + if (fxinfo) + actual += read(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo); close(fd); + if (actual >= SIZEOF_FInfo) + return; } // No Finder info file, translate file name extension to MacOS type/creator - int path_len = strlen(path); - for (int i=0; e2t_translation[i].ext; i++) { - int ext_len = strlen(e2t_translation[i].ext); - if (path_len < ext_len) - continue; - if (!strcmp(path + path_len - ext_len, e2t_translation[i].ext)) { - type = e2t_translation[i].type; - creator = e2t_translation[i].creator; - break; + struct stat st; + if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode)) { + int path_len = strlen(path); + for (int i=0; e2t_translation[i].ext; i++) { + int ext_len = strlen(e2t_translation[i].ext); + if (path_len < ext_len) + continue; + if (!strcasecmp(path + path_len - ext_len, e2t_translation[i].ext)) { + WriteMacInt32(finfo + fdType, e2t_translation[i].type); + WriteMacInt32(finfo + fdCreator, e2t_translation[i].creator); + break; + } } } } -void set_finder_type(const char *path, uint32 type, uint32 creator) +void set_finfo(const char *path, uint32 finfo, uint32 fxinfo) { // Open Finder info file int fd = open_finf(path, O_RDWR); if (fd < 0) return; - // Read file - finf_struct finf = {0, 0, DEFAULT_FINDER_FLAGS, 0}; - read(fd, &finf, sizeof(finf_struct)); - - // Set Finder flags - finf.type = htonl(type); - finf.creator = htonl(creator); - - // Update file - lseek(fd, 0, SEEK_SET); - write(fd, &finf, sizeof(finf_struct)); - close(fd); -} - - -/* - * Get/set finder flags for file/dir specified by full path - */ - -void get_finder_flags(const char *path, uint16 &flags) -{ - flags = DEFAULT_FINDER_FLAGS; // Default - - // Open Finder info file - int fd = open_finf(path, O_RDONLY); - if (fd < 0) - return; - - // Read Finder flags - finf_struct finf; - if (read(fd, &finf, sizeof(finf_struct)) == sizeof(finf_struct)) - flags = ntohs(finf.flags); - - // Close file - close(fd); -} - -void set_finder_flags(const char *path, uint16 flags) -{ - // Open Finder info file - int fd = open_finf(path, O_RDWR); - if (fd < 0) - return; - - // Read file - finf_struct finf = {0, 0, DEFAULT_FINDER_FLAGS, 0}; - read(fd, &finf, sizeof(finf_struct)); - - // Set Finder flags - finf.flags = htons(flags); - - // Update file - lseek(fd, 0, SEEK_SET); - write(fd, &finf, sizeof(finf_struct)); + // Write file + write(fd, Mac2HostAddr(finfo), SIZEOF_FInfo); + if (fxinfo) + write(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo); close(fd); } @@ -343,28 +296,82 @@ void close_rfork(const char *path, int f /* * Read "length" bytes from file to "buffer", - * returns number of bytes read (or 0) + * returns number of bytes read (or -1 on error) */ -size_t extfs_read(int fd, void *buffer, size_t length) +ssize_t extfs_read(int fd, void *buffer, size_t length) { - errno = 0; return read(fd, buffer, length); } /* * Write "length" bytes from "buffer" to file, - * returns number of bytes written (or 0) + * returns number of bytes written (or -1 on error) */ -size_t extfs_write(int fd, void *buffer, size_t length) +ssize_t extfs_write(int fd, void *buffer, size_t length) { - errno = 0; return write(fd, buffer, length); } +/* + * Remove file/directory (and associated helper files), + * returns false on error (and sets errno) + */ + +bool extfs_remove(const char *path) +{ + // Remove helpers first, don't complain if this fails + char helper_path[MAX_PATH_LENGTH]; + make_helper_path(path, helper_path, ".finf/", false); + remove(helper_path); + make_helper_path(path, helper_path, ".rsrc/", false); + remove(helper_path); + + // Now remove file or directory (and helper directories in the directory) + if (remove(path) < 0) { + if (errno == EISDIR || errno == ENOTEMPTY) { + helper_path[0] = 0; + strncpy(helper_path, path, MAX_PATH_LENGTH-1); + add_path_component(helper_path, ".finf"); + rmdir(helper_path); + helper_path[0] = 0; + strncpy(helper_path, path, MAX_PATH_LENGTH-1); + add_path_component(helper_path, ".rsrc"); + rmdir(helper_path); + return rmdir(path) == 0; + } else + return false; + } + return true; +} + + +/* + * Rename/move file/directory (and associated helper files), + * returns false on error (and sets errno) + */ + +bool extfs_rename(const char *old_path, const char *new_path) +{ + // Rename helpers first, don't complain if this fails + char old_helper_path[MAX_PATH_LENGTH], new_helper_path[MAX_PATH_LENGTH]; + make_helper_path(old_path, old_helper_path, ".finf/", false); + make_helper_path(new_path, new_helper_path, ".finf/", false); + create_helper_dir(new_path, ".finf/"); + rename(old_helper_path, new_helper_path); + make_helper_path(old_path, old_helper_path, ".rsrc/", false); + make_helper_path(new_path, new_helper_path, ".rsrc/", false); + create_helper_dir(new_path, ".rsrc/"); + rename(old_helper_path, new_helper_path); + + // Now rename file + return rename(old_path, new_path) == 0; +} + + /* * ftruncate() is missing from libnix */