diff --git a/toolbox/rm-new.cpp b/toolbox/rm-new.cpp index bcdef97..766b1a6 100644 --- a/toolbox/rm-new.cpp +++ b/toolbox/rm-new.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -696,13 +697,69 @@ namespace Native { + /* + * CreateResFile returns an error if the file already exists. others do not... + */ tool_return CreateResFile(const std::string &path, uint32_t creator, uint32_t fileType) { - if (path.empty()) return MacOS::paramErr; - fprintf(stderr, "%s : not yet implemented!\n", __func__); - exit(1); - return noErr; + uint8_t empty_resource_fork[] = { + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff + }; + + + if (path.empty()) return SetResError(MacOS::bdNamErr); + + + struct stat st; + + + int fd = native::open_fork(path, 1, O_WRONLY, 0666); + if (fd < 0) return SetResError(macos_error_from_errno()); + + // need to check if resource fork size > 0 -- don't clobber an existing fork. + if (fstat(fd, &st) < 0) { + auto rv = macos_error_from_errno(); + close(fd); + return SetResError(rv); + } + if (st.st_size > 0) { + close(fd); + return SetResError(noErr); + } + + ssize_t ok = write(fd, empty_resource_fork, sizeof(empty_resource_fork)); + if (ok != sizeof(empty_resource_fork)) { + auto rv = macos_error_from_errno(); + close(fd); + return SetResError(rv); + } + + close(fd); + return SetResError(noErr); } @@ -1264,12 +1321,14 @@ namespace Native { std::string sname = ToolBox::ReadPString(fileName, true); Log("%04x CreateResFile(%s)\n", trap, sname.c_str()); - if (!sname.length()) return SetResError(MacOS::paramErr); + if (!sname.length()) return SetResError(MacOS::bdNamErr); + /* check if file exists ... */ + int fd = open(sname.c_str(), O_CREAT|O_EXCL|O_WRONLY, 0666); + if (fd < 0 && errno == EEXIST) return SetResError(dupFNErr); + if (fd >= 0) close(fd); - auto rv = Native::CreateResFile(sname); - - return rv.error(); + return Native::CreateResFile(sname).error(); } uint16_t HCreateResFile(uint16_t trap) @@ -1291,13 +1350,9 @@ namespace Native { sname = OS::FSSpecManager::ExpandPath(sname, dirID); if (sname.empty()) - { return SetResError(MacOS::dirNFErr); - } - auto rv = Native::CreateResFile(sname); - - return SetResError(rv.error() == MacOS::dupFNErr ? 0 : rv.error()); + return Native::CreateResFile(sname).error(); } @@ -1329,13 +1384,9 @@ namespace Native { sname = OS::FSSpecManager::ExpandPath(sname, parentID); if (sname.empty()) - { return SetResError(MacOS::dirNFErr); - } - auto rv = Native::CreateResFile(sname, creator, fileType); - - return SetResError(rv.error() == MacOS::dupFNErr ? 0 : rv.error()); + return Native::CreateResFile(sname, creator, fileType).error(); }