diff --git a/toolbox/os.cpp b/toolbox/os.cpp index b42a48d..d664a42 100644 --- a/toolbox/os.cpp +++ b/toolbox/os.cpp @@ -741,162 +741,6 @@ namespace OS } -#if 0 - uint16_t GetFileInfo(uint16_t trap) - { - - uint16_t d0; - - uint32_t parm = cpuGetAReg(0); - - Log("%04x GetFileInfo(%08x)\n", trap, parm); - - //uint32_t ioCompletion = memoryReadLong(parm + 12); - uint32_t ioNamePtr = memoryReadLong(parm + 18); - //uint16_t ioVRefNum = memoryReadWord(parm + 22); - //uint8_t ioFVersNum = memoryReadByte(parm + 26); - int16_t ioFDirIndex = memoryReadWord(parm + 28); - - if (ioFDirIndex <= 0) - { - // based name - std::string sname; - - if (!ioNamePtr) - { - memoryWriteWord(MacOS::bdNamErr, parm + 16); - return MacOS::bdNamErr; - } - - sname = ToolBox::ReadPString(ioNamePtr, true); - - Log(" GetFileInfo(%s)\n", sname.c_str()); - - // todo -- how are absolute, relative, etc paths handled... - - - struct stat st; - - if (::stat(sname.c_str(), &st) < 0) - { - d0 = macos_error_from_errno(); - - memoryWriteWord(d0, parm + 16); - return d0; - } - - - Internal::GetFinderInfo(sname, memoryPointer(parm + 32), false); - - - // file reference number - memoryWriteWord(0, parm + 24); - // file attributes - memoryWriteByte(0, parm + 30); - // version (unused) - memoryWriteByte(0, parm + 31); - - // file id - memoryWriteLong(0, parm + 48); - - - // file size - memoryWriteWord(0, parm + 52); - memoryWriteLong(st.st_size, parm + 54); - memoryWriteLong(st.st_size, parm + 58); - - // create date. - memoryWriteLong(UnixToMac(st.st_birthtime), parm + 72); - memoryWriteLong(UnixToMac(st.st_mtime), parm + 76); - - // res fork... - // do this last since it adjusts the name and the stat. - - sname.append(_PATH_RSRCFORKSPEC); - if (::stat(sname.c_str(), &st) >= 0) - { - memoryWriteWord(0, parm + 62); - memoryWriteLong(st.st_size, parm + 64); - memoryWriteLong(st.st_size, parm + 68); - } - else - { - memoryWriteWord(0, parm + 62); - memoryWriteLong(0, parm + 64); - memoryWriteLong(0, parm + 68); - } - - // no error. - memoryWriteWord(0, parm + 16); - - - } - else - { - fprintf(stderr, "GetFileInfo -- ioFDirIndex not yet supported\n"); - exit(1); - } - - // if iocompletion handler && asyn call.... - - return 0; - } - - uint16_t SetFileInfo(uint16_t trap) - { - std::string sname; - uint16_t d0; - - - uint32_t parm = cpuGetAReg(0); - - Log("%04x SetFileInfo(%08x)\n", trap, parm); - - //uint32_t ioCompletion = memoryReadLong(parm + 12); - uint32_t ioNamePtr = memoryReadLong(parm + 18); - //uint16_t ioVRefNum = memoryReadWord(parm + 22); - //uint8_t ioFVersNum = memoryReadByte(parm + 26); - //int16_t ioFDirIndex = memoryReadWord(parm + 28); - - // + 32 = finder data - 16 bytes. - - //uint32_t ioFlCrDat = memoryReadLong(parm + 72); - //uint32_t ioFlMdDat = memoryReadLong(parm + 76); - - // currently, only sets finder info. - - if (!ioNamePtr) - { - memoryWriteWord(MacOS::bdNamErr, parm + 16); - return MacOS::bdNamErr; - } - - sname = ToolBox::ReadPString(ioNamePtr, true); - Log(" SetFileInfo(%s)\n", sname.c_str()); - - // check if the file actually exists - { - struct stat st; - int ok; - - ok = ::stat(sname.c_str(), &st); - if (ok < 0) - { - d0 = macos_error_from_errno(); - memoryWriteWord(d0, parm + 16); - return d0; - } - - - } - - d0 = Internal::SetFinderInfo(sname, memoryPointer(parm + 32), false); - - memoryWriteWord(d0, parm + 16); - return d0; - } -#endif - #pragma mark - String Utilities uint16_t CmpString(uint16_t trap) diff --git a/toolbox/os_fileinfo.cpp b/toolbox/os_fileinfo.cpp index e193e7b..a4e5fb7 100644 --- a/toolbox/os_fileinfo.cpp +++ b/toolbox/os_fileinfo.cpp @@ -288,7 +288,7 @@ namespace OS { } d0 = Internal::SetFinderInfo(sname, memoryPointer(parm + 32), false); - + if (d0 == 0) d0 = Internal::SetFileDates(sname, memoryReadLong(parm + _ioFlCrDat), memoryReadLong(parm + _ioFlMdDat), 0); memoryWriteWord(d0, parm + _ioResult); return d0; } diff --git a/toolbox/os_hfs_dispatch.cpp b/toolbox/os_hfs_dispatch.cpp index 7c60617..8a45c4b 100644 --- a/toolbox/os_hfs_dispatch.cpp +++ b/toolbox/os_hfs_dispatch.cpp @@ -362,6 +362,12 @@ namespace OS { if (S_ISDIR(st.st_mode)) { d0 = 0; + + d0 = Internal::SetFileDates(sname, + memoryReadLong(parm + _ioDrCrDat), + memoryReadLong(parm + _ioDrMdDat), + memoryReadLong(parm + _ioDrBkDat)); + memoryWriteWord(d0, parm + _ioResult); return d0; } @@ -371,6 +377,12 @@ namespace OS { // set the finder info. could also call utimes or setattrlist, I suppose. d0 = Internal::SetFinderInfo(sname, memoryPointer(parm + _ioFlFndrInfo), false); + if (d0 == 0) d0 = Internal::SetFileDates(sname, + memoryReadLong(parm + _ioFlCrDat), + memoryReadLong(parm + _ioFlMdDat), + memoryReadLong(parm + _ioFlBkDat)); + + memoryWriteWord(d0, parm + _ioResult); return d0; diff --git a/toolbox/os_internal.cpp b/toolbox/os_internal.cpp index 94786cc..507b14e 100644 --- a/toolbox/os_internal.cpp +++ b/toolbox/os_internal.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -288,6 +289,70 @@ namespace OS { namespace Internal { } + uint16_t SetFileDates(const std::string &pathname, uint32_t createDate, uint32_t modificationDate, uint32_t backupDate) + { + // utimes(2) sets the access and mod times. + // setattrlist sets the create and mod times (among other things) + + // this is kind of unfortunate in that a roundtrip will strip any nanoseconds, etc from the date/time. + + int rv; + struct attrlist list; + unsigned i = 0; + + timespec dates[3]; + + + memset(&list, 0, sizeof(list)); + memset(dates, 0, sizeof(dates)); + + list.bitmapcount = ATTR_BIT_MAP_COUNT; + list.commonattr = 0; + + if (createDate) + { + dates[i++].tv_sec = MacToUnix(createDate); + list.commonattr |= ATTR_CMN_CRTIME; + } + + if (modificationDate) + { + dates[i++].tv_sec = MacToUnix(modificationDate); + list.commonattr |= ATTR_CMN_MODTIME; + } + + if (backupDate) + { + dates[i++].tv_sec = MacToUnix(backupDate); + list.commonattr |= ATTR_CMN_BKUPTIME; + } + + + + if (!i) return 0; + + rv = setattrlist(pathname.c_str(), &list, dates, i * sizeof(timespec), 0); + + if (rv < 0 && errno == ENOTSUP) + { + // try utimes. + + struct timeval tv[2]; + memset(tv, 0, sizeof(tv)); + + if (modificationDate) { + tv[1].tv_sec = MacToUnix(modificationDate); + rv = utimes(pathname.c_str(), tv); + } + + } + + if (rv < 0) return macos_error_from_errno(); + + return 0; + } + + int32_t mac_seek(uint16_t refNum, uint16_t mode, int32_t offset) { off_t rv; diff --git a/toolbox/os_internal.h b/toolbox/os_internal.h index 9ae43d0..b8e12fe 100644 --- a/toolbox/os_internal.h +++ b/toolbox/os_internal.h @@ -11,6 +11,8 @@ namespace OS { namespace Internal { uint16_t SetFinderInfo(const std::string &pathName, uint32_t fileType, uint32_t creator); + uint16_t SetFileDates(const std::string &pathname, uint32_t createDate, uint32_t modificationDate, uint32_t backupDate); + uint16_t GetFileType(const std::string &pathname, uint16_t *fileType, uint32_t *auxType); int32_t mac_seek(uint16_t refNum, uint16_t mode, int32_t offset);