mirror of
https://github.com/ksherlock/mpw.git
synced 2024-11-25 04:31:52 +00:00
SetFileDates (create / mod / backup)
This commit is contained in:
parent
b7aa23f163
commit
2c3388f76a
156
toolbox/os.cpp
156
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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <sys/attr.h>
|
||||
#include <sys/paths.h>
|
||||
|
||||
#include <machine/endian.h>
|
||||
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user