#include "mwcc_decomp.h" #define OPTION_ASSERT(cond) do { if (!(cond)) { printf("%s:%u: failed assertion\n", __FILE__, __LINE__); abort(); } } while(0) 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 *) ¶mBlock->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, ¶mBlock->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(¶mBlock->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, ¶mBlock->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(¶mBlock->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, ¶mBlock->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(¶mBlock->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 { #line 840 OPTION_ASSERT(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); }