MWCC/command_line/CmdLine/Src/MacEmul/Files.c

748 lines
19 KiB
C

#include "cmdline.h"
typedef struct MacFileInfo {
UInt32 ioFlCrDat;
UInt32 ioFlMdDat;
SInt32 ioFlLgLen;
SInt32 ioFlPyLen;
SInt32 ioFlRLgLen;
SInt32 ioFlRPyLen;
SInt32 ioFlStBlk;
SInt32 ioFlRStBlk;
SInt8 ioFlAttrib;
} MacFileInfo;
static int OS_GetFileParamInfo(const OSSpec *spec, MacFileInfo *mfi, FInfo *fi) {
time_t crtm;
time_t chtm;
OSType ft;
OSType fc;
UInt32 ttime;
UInt32 dsize;
UInt32 rsize;
OSSpec rsrc;
int ref;
int err;
char buffer[32];
UInt32 count;
Boolean isopen;
if (mfi) {
OS_GetFileTime(spec, &crtm, &chtm);
OS_TimeToMac(crtm, &ttime);
mfi->ioFlCrDat = ttime;
OS_TimeToMac(chtm, &ttime);
mfi->ioFlMdDat = ttime;
}
err = OS_Open(spec, OSReadOnly, &ref);
if (err < 0)
return err;
count = sizeof(buffer);
if (OS_Read(ref, buffer, &count))
count = 0;
if (mfi) {
mfi->ioFlAttrib = OS_IsDir(spec) ? ioDirMask : 0;
OS_GetSize(ref, &dsize);
mfi->ioFlLgLen = mfi->ioFlPyLen = dsize;
mfi->ioFlStBlk = 0;
}
OS_Close(ref);
OS_GetMacFileTypeMagic(buffer, count, &ft);
fc = 'CWIE';
if (OS_UsingMacResourceForkInfo() && !OS_GetRsrcOSSpec(spec, &rsrc, 0) && !OS_Status(&rsrc)) {
isopen = OS_SearchMacResourceForkList(&rsrc, &ref);
if (isopen || !OS_Open(&rsrc, 0, &ref)) {
if (mfi) {
OS_GetSize(ref, &rsize);
mfi->ioFlRLgLen = mfi->ioFlRPyLen = rsize;
mfi->ioFlRStBlk = 0;
}
OS_GetMacResourceForkCreatorAndType(ref, &fc, &ft);
if (!isopen)
OS_Close(ref);
}
} else {
if (mfi) {
mfi->ioFlRPyLen = 0;
mfi->ioFlRLgLen = 0;
mfi->ioFlRStBlk = 0;
}
}
fi->fdType = ft;
fi->fdCreator = fc;
fi->fdFlags = OS_IsLink(spec) ? kIsAlias : 0;
fi->fdLocation.v = 0;
fi->fdLocation.h = 0;
fi->fdFldr = 0;
return 0;
}
static int OS_SetFileParamInfo(const OSSpec *spec, MacFileInfo *mfi, FInfo *fi) {
time_t crtm;
time_t chtm;
OSSpec rspec;
int ref;
Boolean isopen;
OS_MacToTime(mfi->ioFlCrDat, &crtm);
OS_MacToTime(mfi->ioFlMdDat, &chtm);
OS_SetFileTime(spec, &crtm, &chtm);
OS_SetMacFileType(spec, fi->fdType);
if (OS_UsingMacResourceForkInfo() && !OS_GetRsrcOSSpec(spec, &rspec, 0) && !OS_Status(&rspec)) {
isopen = OS_SearchMacResourceForkList(&rspec, &ref);
if (!isopen && OS_Open(&rspec, OSReadWrite, &ref))
return 0;
OS_SetMacResourceForkCreatorAndType(ref, fi->fdCreator, fi->fdType);
if (!isopen)
OS_Close(ref);
}
return 0;
}
OSErr HCreate(SInt16 volume, SInt32 dirid, ConstStr255Param fileName, OSType creator, OSType type) {
FSSpec fss;
OSErr __err;
__err = FSMakeFSSpec(volume, dirid, fileName, &fss);
if (__err && __err != fnfErr)
return __err;
return FSpCreate(&fss, creator, type, -1);
}
OSErr HOpen(SInt16 vRefNum, SInt32 dirID, ConstStr255Param fileName, SInt8 permission, SInt16 *refNum) {
FSSpec fss;
OSErr __err;
__err = FSMakeFSSpec(vRefNum, dirID, fileName, &fss);
if (__err && __err != fnfErr)
return __err;
return FSpOpenDF(&fss, permission, refNum);
}
OSErr HOpenDF(SInt16 vRefNum, SInt32 dirID, ConstStr255Param fileName, SInt8 permission, SInt16 *refNum) {
FSSpec fss;
OSErr __err;
__err = FSMakeFSSpec(vRefNum, dirID, fileName, &fss);
if (__err && __err != fnfErr)
return __err;
return FSpOpenDF(&fss, permission, refNum);
}
OSErr HDelete(SInt16 vRefNum, SInt32 dirID, ConstStr255Param fileName) {
FSSpec fss;
OSErr __err;
__err = FSMakeFSSpec(vRefNum, dirID, fileName, &fss);
if (__err && __err != fnfErr)
return __err;
return FSpDelete(&fss);
}
OSErr HRename(SInt16 vRefNum, SInt32 dirID, ConstStr255Param oldName, ConstStr255Param newName) {
FSSpec fss;
OSErr __err;
__err = FSMakeFSSpec(vRefNum, dirID, oldName, &fss);
if (__err && __err != fnfErr)
return __err;
return FSpRename(&fss, newName);
}
OSErr HGetFInfo(SInt16 vRefNum, SInt32 dirID, ConstStr255Param fileName, FInfo *fndrInfo) {
FSSpec fss;
OSErr __err;
__err = FSMakeFSSpec(vRefNum, dirID, fileName, &fss);
if (__err && __err != fnfErr)
return __err;
return FSpGetFInfo(&fss, fndrInfo);
}
OSErr HSetFInfo(SInt16 vRefNum, SInt32 dirID, ConstStr255Param fileName, const FInfo *fndrInfo) {
FSSpec fss;
OSErr __err;
__err = FSMakeFSSpec(vRefNum, dirID, fileName, &fss);
if (__err && __err != fnfErr)
return __err;
return FSpSetFInfo(&fss, fndrInfo);
}
OSErr FSpCreate(const FSSpec *fss, OSType creator, OSType fileType, ScriptCode scriptTag) {
int err;
OSSpec spec;
FInfo finfo;
err = OS_FSSpec_To_OSSpec(fss, &spec);
if (err)
return OS_MacError(err);
if (!OS_Status(&spec))
return dupFNErr;
err = OS_Create(&spec, &OS_TEXTTYPE);
if (err)
return OS_MacError(err);
memset(&finfo, 0, sizeof(FInfo));
finfo.fdType = fileType;
finfo.fdCreator = creator;
FSpSetFInfo(fss, &finfo);
return 0;
}
OSErr FSpDirCreate(const FSSpec *fss, ScriptCode scriptTag, SInt32 *createdDirID) {
int err;
OSSpec spec;
err = OS_FSSpec_To_OSSpec(fss, &spec);
if (err)
return OS_MacError(err);
err = OS_Mkdir(&spec);
if (err)
return OS_MacError(err);
return 0;
}
OSErr FSpOpenDF(const FSSpec *fss, SInt8 permission, SInt16 *refNum) {
static OSOpenMode MacOpens[5] = {
OSReadWrite, OSReadOnly, OSWrite, OSReadWrite, OSReadWrite
};
OSSpec spec;
int err;
int ref;
*refNum = 0;
err = OS_FSSpec_To_OSSpec(fss, &spec);
if (err)
return OS_MacError(err);
if (OS_IsDir(&spec))
return dirNFErr;
err = OS_Open(&spec, MacOpens[permission], &ref);
if (err)
return OS_MacError(err);
*refNum = OS_RefToMac(ref);
return 0;
}
OSErr FSpDelete(const FSSpec *fss) {
OSSpec spec;
OSSpec rspec;
int err;
err = OS_FSSpec_To_OSSpec(fss, &spec);
if (err)
return OS_MacError(err);
err = OS_Delete(&spec);
if (!OS_GetRsrcOSSpec(&spec, &rspec, 0)) {
err = OS_Delete(&rspec);
OS_CleanupMacResourceForkDir(&rspec.path);
}
return OS_MacError(err);
}
OSErr FSpRename(const FSSpec *oldfss, ConstStr255Param newName) {
FSSpec newfss;
OSSpec oldspec;
OSSpec newspec;
OSSpec oldrspec;
OSSpec newrspec;
int err;
err = OS_FSSpec_To_OSSpec(oldfss, &oldspec);
if (err)
return OS_MacError(err);
newfss.vRefNum = oldfss->vRefNum;
newfss.parID = oldfss->parID;
_pstrcpy(newfss.name, newName);
err = OS_FSSpec_To_OSSpec(&newfss, &newspec);
if (err)
return OS_MacError(err);
err = OS_Rename(&oldspec, &newspec);
if (!OS_GetRsrcOSSpec(&oldspec, &oldrspec, 0)) {
OS_GetRsrcOSSpec(&newspec, &newrspec, 0);
err = OS_Rename(&oldrspec, &newrspec);
}
return OS_MacError(err);
}
OSErr FSpGetFInfo(const FSSpec *fss, FInfo *fndrInfo) {
int err;
OSSpec spec;
FInfo fi;
err = OS_FSSpec_To_OSSpec(fss, &spec);
if (err)
return OS_MacError(err);
err = OS_GetFileParamInfo(&spec, 0, &fi);
if (err)
return OS_MacError(err);
memcpy(fndrInfo, &fi, sizeof(FInfo));
return 0;
}
OSErr FSpSetFInfo(const FSSpec *fss, const FInfo *fndrInfo) {
HParamBlockRec hpb;
OSErr err;
Str255 fname;
_pstrcpy(fname, fss->name);
hpb.fileParam.ioVRefNum = fss->vRefNum;
hpb.fileParam.ioDirID = fss->parID;
hpb.fileParam.ioNamePtr = fname;
hpb.fileParam.ioFDirIndex = 0;
err = PBHGetFInfoSync(&hpb);
if (!err) {
hpb.fileParam.ioFlFndrInfo = *fndrInfo;
err = PBHSetFInfoSync(&hpb);
}
return err;
}
OSErr HGetVol(StringPtr volName, SInt16 *vRefNum, SInt32 *dirID) {
OSSpec spec;
int err;
FSSpec fss;
char vn[256];
if (volName && volName[0]) {
p2cstrcpy(vn, volName);
err = OS_MakePathSpec(vn, 0, &spec.path);
if (err)
return OS_MacError(err);
} else {
err = OS_MakePathSpec(0, 0, &spec.path);
if (err)
return OS_MacError(err);
}
OS_MakeNameSpec("", &spec.name);
err = OS_OSSpec_To_FSSpec(&spec, &fss);
if (err)
return OS_MacError(err);
*vRefNum = fss.vRefNum;
*dirID = fss.parID;
return 0;
}
OSErr HSetVol(ConstStr63Param volName, SInt16 vRefNum, SInt32 dirID) {
FSSpec fss;
int err;
OSSpec spec;
OSErr __err;
__err = FSMakeFSSpec(vRefNum, dirID, volName ? volName : "\p", &fss);
if (__err && __err != fnfErr)
return __err;
err = OS_FSSpec_To_OSSpec(&fss, &spec);
if (err)
return OS_MacError(err);
return OS_MacError(OS_Chdir(&spec.path));
}
OSErr FlushVol(ConstStr63Param volName, SInt16 vRefNum) {
return 0;
}
OSErr FSRead(SInt16 fRefNum, SInt32 *Size, void *Buffer) {
if (fRefNum == 0)
return rfNumErr;
return OS_MacError(OS_Read(OS_MacToRef(fRefNum), Buffer, (UInt32 *) Size));
}
OSErr FSWrite(SInt16 fRefNum, SInt32 *Size, const void *Buffer) {
if (fRefNum == 0)
return rfNumErr;
return OS_MacError(OS_Write(OS_MacToRef(fRefNum), Buffer, (UInt32 *) Size));
}
OSErr FSClose(SInt16 fRefNum) {
OSErr err;
OSSpec *rspec;
int ref;
UInt32 size;
int oerr;
if (fRefNum == 0)
return rfNumErr;
ref = OS_MacToRef(fRefNum);
rspec = OS_GetMacResourceForkFromRef(ref);
if (rspec) {
oerr = OS_GetSize(ref, &size);
err = OS_MacError(OS_Close(ref));
if (!oerr && !size) {
OS_Delete(rspec);
OS_CleanupMacResourceForkDir(&rspec->path);
}
OS_RemoveMacResourceForkRef(ref);
} else {
err = OS_MacError(OS_Close(ref));
}
return err;
}
OSErr GetEOF(SInt16 fRefNum, SInt32 *curEOF) {
if (fRefNum == 0)
return rfNumErr;
return OS_MacError(OS_GetSize(OS_MacToRef(fRefNum), (UInt32 *) curEOF));
}
OSErr SetEOF(SInt16 fRefNum, SInt32 newEOF) {
if (fRefNum == 0)
return rfNumErr;
return OS_MacError(OS_SetSize(OS_MacToRef(fRefNum), newEOF));
}
OSErr GetFPos(SInt16 fRefNum, SInt32 *pos) {
if (fRefNum == 0)
return rfNumErr;
return OS_MacError(OS_Tell(OS_MacToRef(fRefNum), pos));
}
static OSSeekMode MacSeek[4] = {
OSSeekAbs, OSSeekAbs, OSSeekEnd, OSSeekRel
};
OSErr SetFPos(SInt16 fRefNum, SInt16 posMode, SInt32 posOffset) {
SInt32 pos;
SInt32 npos;
UInt32 size;
int err;
int ref;
ref = OS_MacToRef(fRefNum);
if (fRefNum == 0)
return rfNumErr;
if (posMode & 3) {
err = OS_Tell(ref, &pos);
if (err)
return OS_MacError(err);
err = OS_GetSize(ref, &size);
if (err)
return OS_MacError(err);
if ((posMode & 3) == fsFromStart) {
npos = posOffset;
} else if ((posMode & 3) == fsFromLEOF) {
npos = size + posOffset;
} else if ((posMode & 3) == fsFromMark) {
npos = pos + posOffset;
} else {
return paramErr;
}
err = OS_Seek(ref, OSSeekAbs, npos);
if (err)
return OS_MacError(err);
if (npos > size) {
OS_Seek(ref, OSSeekAbs, pos);
return eofErr;
}
}
return 0;
}
OSErr GetVInfo(SInt16 vRefNum, StringPtr name, SInt16 *vRef, SInt32 *hDir) {
int err;
OSNameSpec spec;
SInt32 parID;
*vRef = 0;
*hDir = 0;
err = OS_VolDir_To_OSNameSpec(vRefNum, 2, &spec, &parID);
if (!err) {
OS_NameSpecToString(&spec, (char *) name, 256);
c2pstr((char *) name);
_pstrcharcat(name, OS_PATHSEP);
return 0;
} else {
return OS_MacError(err);
}
}
OSErr PBWriteSync(ParmBlkPtr paramBlock) {
int err;
int ref;
ref = OS_MacToRef(paramBlock->ioParam.ioRefNum);
if (!paramBlock->ioParam.ioRefNum) {
return (paramBlock->ioParam.ioResult = rfNumErr);
} else {
if (paramBlock->ioParam.ioPosMode & 3) {
err = OS_Seek(ref, MacSeek[paramBlock->ioParam.ioPosMode & 3], paramBlock->ioParam.ioPosOffset);
if (err)
return (paramBlock->ioParam.ioResult = OS_MacError(err));
}
paramBlock->ioParam.ioActCount = paramBlock->ioParam.ioReqCount;
err = OS_Write(ref, paramBlock->ioParam.ioBuffer, (UInt32 *) &paramBlock->ioParam.ioActCount);
return (paramBlock->ioParam.ioResult = OS_MacError(err));
}
}
OSErr PBHGetFInfoSync(HParmBlkPtr paramBlock) {
HFileParam fp;
FSSpec fss;
OSErr err;
int oserr;
OSSpec spec;
MacFileInfo mfi;
FInfo fi;
memcpy(&fp, &paramBlock->fileParam, sizeof(HFileParam));
err = FSMakeFSSpec(fp.ioVRefNum, fp.ioDirID, (fp.ioFDirIndex != -1) ? fp.ioNamePtr : "\p", &fss);
if (!err) {
oserr = OS_FSSpec_To_OSSpec(&fss, &spec);
if (!oserr) {
OS_GetFileParamInfo(&spec, &mfi, &fi);
fp.ioFlCrDat = mfi.ioFlCrDat;
fp.ioFlMdDat = mfi.ioFlMdDat;
fp.ioFlLgLen = mfi.ioFlLgLen;
fp.ioFlPyLen = mfi.ioFlPyLen;
fp.ioFlRLgLen = mfi.ioFlRLgLen;
fp.ioFlRPyLen = mfi.ioFlRPyLen;
fp.ioFlAttrib = mfi.ioFlAttrib;
memcpy(&fp.ioFlFndrInfo, &fi, sizeof(FInfo));
} else {
memset(&fp, 0, sizeof(fp));
}
}
fp.ioResult = err;
memcpy(&paramBlock->fileParam, &fp, sizeof(HFileParam));
return err;
}
OSErr PBHSetFInfoSync(HParmBlkPtr paramBlock) {
HFileParam fp;
FInfo *pfi;
FSSpec fss;
OSErr err;
int oserr;
OSSpec spec;
MacFileInfo mfi;
FInfo fi;
pfi = &fp.ioFlFndrInfo;
memcpy(&fp, &paramBlock->fileParam, sizeof(HFileParam));
err = FSMakeFSSpec(fp.ioVRefNum, fp.ioDirID, fp.ioNamePtr, &fss);
if (!err) {
oserr = OS_FSSpec_To_OSSpec(&fss, &spec);
if (!oserr) {
memcpy(&fi, pfi, sizeof(FInfo));
memset(&mfi, 0, sizeof(mfi));
mfi.ioFlCrDat = fp.ioFlCrDat;
mfi.ioFlMdDat = fp.ioFlMdDat;
oserr = OS_SetFileParamInfo(&spec, &mfi, &fi);
}
err = OS_MacError(oserr);
}
fp.ioResult = err;
memcpy(&paramBlock->fileParam, &fp, sizeof(HFileParam));
return err;
}
OSErr PBGetCatInfoSync(CInfoPBPtr paramBlock) {
OSErr err;
FSSpec fss;
OSSpec spec;
int oserr;
HFileInfo hfi;
MacFileInfo mfi;
FInfo fi;
char tmp[64];
memcpy(&hfi, &paramBlock->hFileInfo, sizeof(HFileInfo));
err = FSMakeFSSpec(hfi.ioVRefNum, hfi.ioDirID, (hfi.ioFDirIndex > 0) ? hfi.ioNamePtr : "\p", &fss);
if (!err) {
oserr = OS_FSSpec_To_OSSpec(&fss, &spec);
if (!oserr) {
OS_VolDir_To_OSNameSpec(hfi.ioVRefNum, hfi.ioDirID, &spec.name, &hfi.ioFlParID);
if (hfi.ioNamePtr) {
OS_NameSpecToString(&spec.name, tmp, 256);
c2pstrcpy(hfi.ioNamePtr, tmp);
}
oserr = OS_GetFileParamInfo(&spec, &mfi, &fi);
if (!oserr) {
hfi.ioFlCrDat = mfi.ioFlCrDat;
hfi.ioFlMdDat = mfi.ioFlMdDat;
hfi.ioFlLgLen = mfi.ioFlLgLen;
hfi.ioFlPyLen = mfi.ioFlPyLen;
hfi.ioFlRLgLen = mfi.ioFlRLgLen;
hfi.ioFlRPyLen = mfi.ioFlRPyLen;
hfi.ioFlStBlk = mfi.ioFlRStBlk;
hfi.ioFlRStBlk = mfi.ioFlRStBlk;
hfi.ioFlAttrib = mfi.ioFlAttrib;
memcpy(&hfi.ioFlFndrInfo, &fi, sizeof(FInfo));
}
}
err = OS_MacError(err);
}
hfi.ioResult = err;
memcpy(&paramBlock->hFileInfo, &hfi, sizeof(HFileInfo));
return hfi.ioResult;
}
OSErr ResolveAliasFile(FSSpec *fss, Boolean resolveChains, Boolean *isFolder, Boolean *wasAliased) {
OSSpec spec;
int err;
*isFolder = 0;
*wasAliased = 0;
err = OS_FSSpec_To_OSSpec(fss, &spec);
if (err)
return OS_MacError(err);
*wasAliased = 0;
while (OS_IsLink(&spec)) {
*wasAliased = 1;
OS_ResolveLink(&spec, &spec);
if (!resolveChains)
break;
}
*isFolder = OS_IsDir(&spec);
err = OS_OSSpec_To_FSSpec(&spec, fss);
if (err)
return OS_MacError(err);
return 0;
}
OSErr FSMakeFSSpec(SInt16 vRefNum, SInt32 dirID, ConstStr255Param pathName, FSSpec *fss) {
OSSpec spec;
int err;
char path[256];
FSSpec tmpfss;
int idx;
char *pptr;
char vol[8];
char *nmptr;
int len;
fss->vRefNum = 0;
fss->parID = 0;
if (!vRefNum && !dirID) {
err = OS_GetCWD(&spec.path);
if (err) {
fss->name[0] = 0;
return OS_MacError(err);
}
OS_PathSpecToString(&spec.path, path, 256);
} else {
OS_ASSERT(840, vRefNum!=0);
tmpfss.vRefNum = vRefNum;
tmpfss.parID = dirID ? dirID : 2;
tmpfss.name[0] = 0;
err = OS_FSSpec_To_OSSpec(&tmpfss, &spec);
if (err) {
fss->name[0] = 0;
return OS_MacError(err);
}
OS_PathSpecToString(&spec.path, path, 256);
}
if (pstrchr(pathName, ':')) {
idx = 1;
if (pathName[1] != ':') {
while (idx <= pathName[0]) {
if (pathName[idx] == ':')
break;
vol[idx - 1] = pathName[idx];
idx++;
if (idx >= 8) {
fss->name[0] = 0;
return nsvErr;
}
}
vol[idx - 1] = 0;
idx++;
if (!OS_MakePathSpec(vol, 0, &spec.path)) {
OS_PathSpecToString(&spec.path, path, 256);
} else {
c2pstrcpy(fss->name, vol);
return nsvErr;
}
}
pptr = path + strlen(path);
while (idx <= pathName[0]) {
if (pathName[idx] == ':') {
if (idx < pathName[0] && pathName[idx + 1] == ':') {
do {
pptr += sprintf(pptr, "../");
} while (++idx < pathName[0] && pathName[idx + 1] == ':');
} else {
*(pptr++) = OS_PATHSEP;
}
} else {
*(pptr++) = pathName[idx];
}
++idx;
}
*pptr = 0;
} else {
p2cstrcpy(path + strlen(path), pathName);
}
err = OS_MakeSpec(path, &spec, 0);
if (!err) {
OS_OSSpec_To_FSSpec(&spec, fss);
return OS_MacError(OS_Status(&spec));
} else {
nmptr = OS_GetFileNamePtr(path);
len = strlen(nmptr);
if (len >= sizeof(fss->name))
len = 255;
fss->name[0] = len;
memcpy(&fss->name[1], nmptr, len);
return OS_MacError(err);
}
}
OSErr Allocate(SInt16 refNum, SInt32 *byteCount) {
return SetEOF(refNum, *byteCount);
}