📄 macio.c
字号:
PR_DELETE(mdDir->currentEntryName); mdDir->currentEntryName = NULL; // We誺e got all the info we need, just get info about this guy. pb.hFileInfo.ioNamePtr = pascalName; pb.hFileInfo.ioVRefNum = mdDir->ioVRefNum; pb.hFileInfo.ioFDirIndex = mdDir->ioFDirIndex; pb.hFileInfo.ioDirID = mdDir->ioDirID; err = PBGetCatInfoSync(&pb); if (err != noErr) goto ErrorExit; // Convert the Pascal string to a C string (actual allocation occurs in CStrFromPStr) CStrFromPStr(pascalName, &returnedCStr); mdDir->currentEntryName = returnedCStr; mdDir->ioFDirIndex++; // If it is not a hidden file and the flags did not specify skipping, we are done. if ((flags & PR_SKIP_HIDDEN) && (pb.hFileInfo.ioFlFndrInfo.fdFlags & fInvisible)) foundEntry = PR_FALSE; else foundEntry = PR_TRUE; } while (!foundEntry); return (mdDir->currentEntryName);ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; _MD_SetError(err); return NULL;}void _MD_CloseDir(_MDDir *mdDir){ // Emulate the Unix closedir() routine PR_DELETE(mdDir->currentEntryName);}PRInt32 _MD_MkDir(char *unixPath, PRIntn mode){ HFileParam fpb; Str255 pascalName = "\p"; char *cMacPath = NULL; OSErr err; #pragma unused (mode) // Mode is ignored on the Mac if (unixPath) { err = ConvertUnixPathToMacPath(unixPath, &cMacPath); if (err != noErr) goto ErrorExit; PStrFromCStr(cMacPath, pascalName); PR_DELETE(cMacPath); fpb.ioNamePtr = pascalName; fpb.ioVRefNum = 0; fpb.ioDirID = 0L; err = PBDirCreateSync((HParmBlkPtr)&fpb); if (err != noErr) goto ErrorExit; } return 0; ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; _MD_SetError(err); return -1;}PRInt32 _MD_Delete(char *unixPath){ HFileParam fpb; Str255 pascalName = "\p"; char *cMacPath = NULL; OSErr err; if (unixPath) { err = ConvertUnixPathToMacPath(unixPath, &cMacPath); if (err != noErr) goto ErrorExit; PStrFromCStr(cMacPath, pascalName); PR_DELETE(cMacPath); fpb.ioNamePtr = pascalName; fpb.ioVRefNum = 0; fpb.ioDirID = 0L; err = PBHDeleteSync((HParmBlkPtr)&fpb); if (err != noErr) goto ErrorExit; } return 0; ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; _MD_SetError(err); return -1;}PRInt32 _MD_Rename(char *fromUnixPath, char *toUnixPath){ OSErr err; FSSpec fromSpec; FSSpec toSpec; FSSpec destDirSpec; FSSpec beforeRenameSpec; if (fromUnixPath && toUnixPath) { err = ConvertUnixPathToFSSpec(fromUnixPath, &fromSpec); if (err != noErr) goto ErrorExit; err = ConvertUnixPathToFSSpec(toUnixPath, &toSpec); if (err != noErr && err != fnfErr) goto ErrorExit; /* make an FSSpec for the destination directory */ err = FSMakeFSSpec(toSpec.vRefNum, toSpec.parID, nil, &destDirSpec); if (err != noErr) /* parent directory must exist */ goto ErrorExit; // move it to the directory specified err = FSpCatMove(&fromSpec, &destDirSpec); if (err != noErr) goto ErrorExit; // make a new FSSpec for the file or directory in its new location err = FSMakeFSSpec(toSpec.vRefNum, toSpec.parID, fromSpec.name, &beforeRenameSpec); if (err != noErr) goto ErrorExit; // rename the file or directory err = FSpRename(&beforeRenameSpec, toSpec.name); if (err != noErr) goto ErrorExit; } else { err = paramErr; goto ErrorExit; } return 0; ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; _MD_SetError(err); return -1;}#define kWriteAccessAllowed (0x100)PRInt32 _MD_Access(char *unixPath, int amode){ // // Emulate the Unix access routine // OSErr err; CInfoPBRec pb; FCBPBRec fcbpb; char *cMacPath = NULL; Str255 pascalMacPath; struct stat info; // Convert to a Mac style path err = ConvertUnixPathToMacPath(unixPath, &cMacPath); if (err != noErr) goto ErrorExit; err = stat(cMacPath, &info); if (err != noErr) goto ErrorExit; // If all we誶e doing is checking for the existence of the file, we誶e out of here. // On the Mac, if a file exists, you can read from it. // This doesn誸 handle remote AppleShare volumes. Does it need to? if ((amode == PR_ACCESS_EXISTS) || (amode == PR_ACCESS_READ_OK)) { goto success; } PStrFromCStr(cMacPath, pascalMacPath); pb.hFileInfo.ioNamePtr = pascalMacPath; pb.hFileInfo.ioVRefNum = info.st_dev; pb.hFileInfo.ioDirID = 0; pb.hFileInfo.ioFDirIndex = 0; err = PBGetCatInfoSync(&pb); if (err != noErr) goto ErrorExit; // Check out all the access permissions. if (amode == PR_ACCESS_WRITE_OK) { fcbpb.ioNamePtr = NULL; fcbpb.ioVRefNum = pb.hFileInfo.ioVRefNum; fcbpb.ioRefNum = pb.hFileInfo.ioFRefNum; fcbpb.ioFCBIndx = 0; err = PBGetFCBInfoSync(&fcbpb); if (err != noErr) goto ErrorExit; /* Look at Inside Mac IV-180 */ if ((fcbpb.ioFCBFlags & kWriteAccessAllowed) == 0) { err = permErr; goto ErrorExit; } } success: PR_DELETE(cMacPath); return 0; ErrorExit: if (cMacPath != NULL) PR_DELETE(cMacPath); _PR_MD_CURRENT_THREAD()->md.osErrCode = err; _MD_SetError(err); return -1;}PRInt32 _MD_GetFileInfo(char *unixPath, PRFileInfo *info){ CInfoPBRec pb; OSErr err; char *cMacPath = NULL; Str255 pascalMacPath; PRTime oneMillion, dateInMicroSeconds; // Convert to a Mac style path err = ConvertUnixPathToMacPath(unixPath, &cMacPath); if (err != noErr) goto ErrorExit; PStrFromCStr(cMacPath, pascalMacPath); PR_DELETE(cMacPath); pb.hFileInfo.ioNamePtr = pascalMacPath; pb.hFileInfo.ioVRefNum = 0; pb.hFileInfo.ioDirID = 0; pb.hFileInfo.ioFDirIndex = 0; err = PBGetCatInfoSync(&pb); if (err != noErr) goto ErrorExit; if (pb.hFileInfo.ioFlAttrib & ioDirMask) { info->type = PR_FILE_DIRECTORY; info->size = 0; } else { info->type = PR_FILE_FILE; info->size = pb.hFileInfo.ioFlLgLen + pb.hFileInfo.ioFlRLgLen; } pb.hFileInfo.ioFlCrDat -= gJanuaryFirst1970Seconds; LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlCrDat); LL_I2L(oneMillion, PR_USEC_PER_SEC); LL_MUL(info->creationTime, oneMillion, dateInMicroSeconds); pb.hFileInfo.ioFlMdDat -= gJanuaryFirst1970Seconds; LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlMdDat); LL_MUL(info->modifyTime, oneMillion, dateInMicroSeconds); return 0; ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; _MD_SetError(err); return -1;}PRInt32 _MD_GetOpenFileInfo(const PRFileDesc *fd, PRFileInfo *info){ OSErr err; FCBPBRec fcbpb; CInfoPBRec pb; Str255 pascalMacPath; PRTime oneMillion, dateInMicroSeconds; fcbpb.ioNamePtr = pascalMacPath; fcbpb.ioVRefNum = 0; fcbpb.ioRefNum = fd->secret->md.osfd; fcbpb.ioFCBIndx = 0; err = PBGetFCBInfoSync(&fcbpb); if (err != noErr) goto ErrorExit; info->type = PR_FILE_FILE; info->size = fcbpb.ioFCBEOF; pb.hFileInfo.ioNamePtr = pascalMacPath; pb.hFileInfo.ioVRefNum = fcbpb.ioFCBVRefNum; pb.hFileInfo.ioDirID = fcbpb.ioFCBParID; pb.hFileInfo.ioFDirIndex = 0; err = PBGetCatInfoSync(&pb); if (err != noErr) goto ErrorExit; pb.hFileInfo.ioFlCrDat -= gJanuaryFirst1970Seconds; LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlCrDat); LL_I2L(oneMillion, PR_USEC_PER_SEC); LL_MUL(info->creationTime, oneMillion, dateInMicroSeconds); pb.hFileInfo.ioFlMdDat -= gJanuaryFirst1970Seconds; LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlMdDat); LL_MUL(info->modifyTime, oneMillion, dateInMicroSeconds); return 0; ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; _MD_SetError(err); return -1;}PRInt32 _MD_Stat(const char *path, struct stat *buf){ OSErr err; char *macFileName = NULL; err = ConvertUnixPathToMacPath(path, &macFileName); if (err != noErr) goto ErrorExit; err = stat(macFileName, buf); if (err != noErr) goto ErrorExit; PR_DELETE(macFileName); return 0;ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; _MD_SetError(err); return -1;}PRStatus _MD_LockFile(PRInt32 fd){ OSErr err; FCBPBRec fcbpb; HFileParam fpb; Str255 pascalName; fcbpb.ioNamePtr = pascalName; fcbpb.ioVRefNum = 0; fcbpb.ioRefNum = fd; fcbpb.ioFCBIndx = 0; err = PBGetFCBInfoSync(&fcbpb); if (err != noErr) goto ErrorExit; fpb.ioCompletion = NULL; fpb.ioNamePtr = pascalName; fpb.ioVRefNum = fcbpb.ioFCBVRefNum; fpb.ioDirID = fcbpb.ioFCBParID; err = PBHSetFLockSync((HParmBlkPtr)&fpb); if (err != noErr) goto ErrorExit; return PR_SUCCESS; ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; _MD_SetError(err); return PR_FAILURE;}PRStatus _MD_TLockFile(PRInt32 fd){ return (_MD_LockFile(fd));}PRStatus _MD_UnlockFile(PRInt32 fd){ OSErr err; FCBPBRec fcbpb; HFileParam fpb; Str255 pascalName; fcbpb.ioNamePtr = pascalName; fcbpb.ioVRefNum = 0; fcbpb.ioRefNum = fd; fcbpb.ioFCBIndx = 0; err = PBGetFCBInfoSync(&fcbpb); if (err != noErr) goto ErrorExit; fpb.ioCompletion = NULL; fpb.ioNamePtr = pascalName; fpb.ioVRefNum = fcbpb.ioFCBVRefNum; fpb.ioDirID = fcbpb.ioFCBParID; err = PBHRstFLockSync((HParmBlkPtr)&fpb); if (err != noErr) goto ErrorExit; return PR_SUCCESS; ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; _MD_SetError(err); return PR_FAILURE;}void SetLogFileTypeCreator(const char *logFile){ HParamBlockRec pb; OSErr err; Str31 pName; PStrFromCStr(logFile, pName); pb.fileParam.ioCompletion = nil; pb.fileParam.ioNamePtr = pName; pb.fileParam.ioVRefNum = 0; pb.fileParam.ioFDirIndex = 0; pb.fileParam.ioDirID = 0; err = PBHGetFInfoSync(&pb); PR_ASSERT(err == noErr); pb.fileParam.ioDirID = 0; pb.fileParam.ioFlFndrInfo.fdType = 'TEXT'; pb.fileParam.ioFlFndrInfo.fdCreator = 'ttxt'; err = PBHSetFInfoSync(&pb); PR_ASSERT(err == noErr);}#if DEVELOPER_DEBUGPR_IMPLEMENT (void)SetupMacPrintfLog(char *logFile){ /* * We do _PR_InitLog() twice. The first to force the implicit initialization which * will set logging to highest levels in _MD_EARLY_INIT. Then, change the env variable * to disable kernel logging and call _PR_InitLog() again to make it effective. Since * we are using logging to log test program output, we disable kernel logging to avoid * all Kernel logging output. */#ifdef PR_INTERNAL_LOGGING _PR_InitLog(); _MD_PutEnv("NSPR_LOG_MODULES=clock:0,cmon:0,io:0,mon:0,linker:0,cvar:0,sched:0,thread:0"); _PR_InitLog();#endif PR_ASSERT(PR_SetLogFile(logFile) == PR_TRUE); SetLogFileTypeCreator(logFile);}#endif/*********************** Old name related stuff that is unchanged. ***********************/#if !defined(MAC_NSPR_STANDALONE)short GetVolumeRefNumFromName(const char *cTgtVolName){ OSErr err; Str32 pVolName; char *cVolName = NULL; HParamBlockRec hPB; short refNum = 0; hPB.volumeParam.ioVolIndex = 0; hPB.volumeParam.ioNamePtr = pVolName; do { hPB.volumeParam.ioVolIndex++; err = PBHGetVInfoSync(&hPB); CStrFromPStr(pVolName, &cVolName); if (strcmp(cTgtVolName, cVolName) == 0) { refNum = hPB.volumeParam.ioVRefNum; PR_DELETE(cVolName); break; } PR_DELETE(cVolName); } while (err == noErr); return refNum;}static OSErr CreateMacPathFromUnixPath(const char *unixPath, char **macPath){ // Given a Unix style path with '/' directory separators, this allocates // a path with Mac style directory separators in the path. // // It does not do any special directory translation; use ConvertUnixPathToMacPath // for that. const char *src; char *tgt; OSErr err = noErr; PR_ASSERT(unixPath != nil); if (nil == unixPath) { err = paramErr; goto exit; } // If unixPath is a zero-length string, we copy ":" into // macPath, so we need a minimum of two bytes to handle // the case of ":". *macPath = malloc(strlen(unixPath) + 2); // Will be enough extra space. require_action (*macPath != NULL, exit, err = memFullErr;); src = unixPath; tgt = *macPath; if (PL_strchr(src, PR_DIRECTORY_SEPARATOR) == src) // If we誶e dealing with an absolute src++; // path, skip the separator else *(tgt++) = PR_PATH_SEPARATOR; if (PL_strstr(src, UNIX_THIS_DIRECTORY_STR) == src) // If it starts with / src += 2; // skip it. while (*src) { // deal with the rest of the path if (PL_strstr(src, UNIX_PARENT_DIRECTORY_STR) == src) { // Going up? *(tgt++) = PR_PATH_SEPARATOR; // simply add an extra colon. src +=3; } else if (*src == PR_DIRECTORY_SEPARATOR) { // Change the separator *(tgt++) = PR_PATH_SEPARATOR; src++; } else *(tgt++) = *(src++); } *tgt = NULL; // make sure it誷 null terminated.exit: return err;}static ProcessInfoRec gNavigatorProcInfo;static FSSpec gGutsFolder;static FSSpec gNetscapeFolder;static OSErr SetupRequiredFSSpecs(void){ OSErr err; CInfoPBRec pb; ProcessSerialNumber curPSN = {0, kCurrentProcess}; gNavigatorProcInfo.processInfoLength = sizeof(ProcessInfoRec); gNavigatorProcInfo.processName = NULL; gNavigatorProcInfo.processAppSpec = &gNetscapeFolder; err = GetProcessInformation (&curPSN, &gNavigatorProcInfo); if (err != noErr) goto ErrorExit; /* guts folder resides at the same place as the app file itself */ gGutsFolder = gNetscapeFolder; /* How else do we do this hack??? * Should NSPR have a string resource for this ? */ GetIndString( gGutsFolder.name, 300, 34); /* * vRefNum and parentDirID are now set up correctly for the app file itself. * parentDirID is the Netscape Folder's ID. Then Find it's parent ID to * set up the FSSpec and its own name. */ pb.dirInfo.ioCompletion = NULL; pb.dirInfo.ioNamePtr = gNetscapeFolder.name; pb.dirInfo.ioVRefNum = gNetscapeFolder.vRefNum; pb.dirInfo.ioFDirIndex = -1; pb.dirInfo.ioDrDirID = gNetscapeFolder.parID; err = PBGetCatInfoSync(&pb); if (err != noErr) goto ErrorExit; gNetscapeFolder.parID = pb.dirInfo.ioDrParID; return noErr; ErrorExit: return err;}static OSErr FindGutsFolder(FSSpec *foundSpec){ OSErr err; if (gNavigatorProcInfo.processInfoLength == 0) { /* Uninitialized? */ err = SetupRequiredFSSpecs(); if (err != noErr) goto ErrorExit; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -