📄 macio.c
字号:
*foundSpec = gGutsFolder; return noErr; ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; return err; }static OSErr FindNetscapeFolder(FSSpec *foundSpec){ OSErr err; if (gNavigatorProcInfo.processInfoLength == 0) { /* Uninitialized? */ err = SetupRequiredFSSpecs(); if (err != noErr) goto ErrorExit; } *foundSpec = gNetscapeFolder; return noErr; ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; return err; }PR_IMPLEMENT (OSErr)ConvertUnixPathToMacPath(const char *unixPath, char **macPath){ OSErr err = noErr; // ******** HACK ALERT ******** // // Java really wants long file names (>31 chars). We truncate file names // greater than 31 characters long. Truncation is from the middle. // // Convert UNIX style path names (with . and / separators) into a Macintosh // style path (with :). // // There are also a couple of special paths that need to be dealt with // by translating them to the appropriate Mac special folders. These include: // // /usr/tmp/file => {TempFolder}file // // The file conversions we need to do are as follows: // // file => file // dir/file => :dir:file // ./file => file // ../file => ::file // ../dir/file => ::dir:file // /file => ::BootDrive:file // /dir/file => ::BootDrive:dir:file if (!strcmp(unixPath, ".")) { *macPath = malloc(sizeof(":")); if (*macPath == NULL) err = memFullErr; (*macPath)[0] = ':'; (*macPath)[1] = '\0'; } else if (*unixPath != PR_DIRECTORY_SEPARATOR) { // Not root relative, just convert it. err = CreateMacPathFromUnixPath(unixPath, macPath); } else { // We誶e root-relative. This is either a special Unix directory, or a // full path (which we誰l support on the Mac since they might be generated). // This is not condoning the use of full-paths on the Macintosh for file // specification. FSSpec foundSpec; short pathBufferSize; char *temp; int tempLen; // Are we dealing with the temp folder? if ((strncmp(unixPath, "/usr/tmp", strlen("/usr/tmp")) == 0) || ((strncmp(unixPath, "/tmp", strlen("/tmp")) == 0))) { CInfoPBRec pb; unixPath = PL_strchr(unixPath, PR_DIRECTORY_SEPARATOR); if (strncmp(unixPath, "/tmp", strlen("/tmp")) == 0) // skip past temp spec unixPath += 5; else unixPath += 9; err = FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder, // Create if needed &foundSpec.vRefNum, &foundSpec.parID); if (err == noErr) { pb.dirInfo.ioCompletion = NULL; pb.dirInfo.ioNamePtr = foundSpec.name; pb.dirInfo.ioVRefNum = foundSpec.vRefNum; pb.dirInfo.ioFDirIndex = -1; pb.dirInfo.ioDrDirID = foundSpec.parID; err = PBGetCatInfoSync(&pb); foundSpec.parID = pb.dirInfo.ioDrParID; } } else if (!strncmp(unixPath, "/usr/local/netscape/", (tempLen = strlen("/usr/local/netscape/")))) { unixPath += tempLen; if (!strncmp(unixPath, "RequiredGuts/", (tempLen = strlen("RequiredGuts/")))) { unixPath += tempLen; err = FindGutsFolder(&foundSpec); } else if (!strncmp(unixPath, "bin/", (tempLen = strlen("bin/")))) { unixPath += tempLen; err = FindNetscapeFolder(&foundSpec); } else if (*unixPath == '\0') { // it's /usr/local/netscape err = FindGutsFolder(&foundSpec); } } else { // This is a root relative directory, we誰l just convert the whole thing. err = CreateMacPathFromUnixPath(unixPath, macPath); goto Exit_ConvertUnixPathToMacPath; } // We誶e dealing with a special folder if (err == noErr) { Handle hPathStr; // Get the path to the root-relative directory err = FSpGetFullPath(&foundSpec, &pathBufferSize, &hPathStr); // NewHandle's hPathStr if (noErr == err) { // convert handle to c-string // add one for NULL termination // pathBufferSize is now one greater than the length of the string pathBufferSize++; *macPath = (char*) malloc(sizeof(char) * pathBufferSize); (*macPath)[pathBufferSize - 1] = '\0'; BlockMoveData(*hPathStr, *macPath, pathBufferSize - 1); DisposeHandle(hPathStr); } } if (err == noErr) { UInt32 unixPathLeft; UInt32 macPathLen; unixPathLeft = strlen(unixPath); macPathLen = strlen(*macPath); // copy over the remaining file name, converting if (pathBufferSize - 1 < macPathLen + unixPathLeft) { // need to grow string *macPath = realloc(*macPath, macPathLen + unixPathLeft + 1); err = (*macPath == NULL ? memFullErr : noErr); } if (err == noErr) { // carefully remove the '/''s out of the unix path. If we see an "escaped" / // we will leave it in there, otherwise we take it out and replace it with a : // we have to do this before we convert to a mac-path, so we can tell what is // really a path separator and what is in the name of a file or directory // Make sure that all of the /誷 are :誷 in the final pathname // effectively we do a // strcat(*macPath, unixPath); while replace all occurrences of / with : in unixPath char* dp; const char* sp; sp = unixPath; dp = *macPath + macPathLen; for (;*sp != '\0'; sp++, dp++) { if (*sp == PR_DIRECTORY_SEPARATOR) { // if we can look at the previous character if (sp > unixPath) { // check to see if previous character is an escape if (sp[-1] == '\\') { // leave it in, and cycle continue; } else { *dp = PR_PATH_SEPARATOR; } } else *dp = PR_PATH_SEPARATOR; } else { // just copy; *dp = *sp; } } *dp = '\0'; // NULL terminate *macPath }#if DEBUG // we used to check here, now we check above, we leave this in // the debug build to make sure we didn't screw up // Make sure that all of the /誷 are :誷 in the final pathname for (temp = *macPath + strlen(*macPath) - strlen(unixPath); *temp != '\0'; temp++) { if (*temp == PR_DIRECTORY_SEPARATOR) { DebugStr("\pFound a slash"); *temp = PR_PATH_SEPARATOR; } }#endif } } Exit_ConvertUnixPathToMacPath: return err;}// Hey! Before you delete this "hack" you should look at how it's being// used by sun-java/netscape/applet/appletStubs.c.PR_IMPLEMENT (OSErr)ConvertMacPathToUnixPath(const char *macPath, char **unixPath) { // *** HACK *** // Get minimal version working char *unixPathPtr; *unixPath = malloc(strlen(macPath) + 2); // Add one for the front slash, one for null if (*unixPath == NULL) return (memFullErr); unixPathPtr = *unixPath; *unixPathPtr++ = PR_DIRECTORY_SEPARATOR; do { // Translate all colons to slashes if (*macPath == PR_PATH_SEPARATOR) *unixPathPtr = PR_DIRECTORY_SEPARATOR; else *unixPathPtr = *macPath; unixPathPtr++; macPath++; } while (*macPath != NULL); // Terminate the string *unixPathPtr = '\0'; return (noErr);}OSErrConvertUnixPathToFSSpec(const char *unixPath, FSSpec *fileSpec){ char* macPath; OSErr convertError; int len; convertError = ConvertUnixPathToMacPath(unixPath, &macPath); if (convertError != noErr) return convertError; len = strlen(macPath); if (*macPath == PR_PATH_SEPARATOR) { if (len < sizeof(Str255)) { short vRefNum; long dirID; Str255 pascalMacPath; convertError = HGetVol(NULL, &vRefNum, &dirID); if (convertError == noErr) { PStrFromCStr(macPath, pascalMacPath); convertError = FSMakeFSSpec(vRefNum, dirID, pascalMacPath, fileSpec); } } else convertError = paramErr; } else { convertError = FSpLocationFromFullPath(len, macPath, fileSpec); if (convertError == fnfErr) { CInfoPBRec pb; Str255 pascalMacPath; OSErr err; PStrFromCStr(macPath, pascalMacPath); /* FSpLocationFromFullPath does not work for directories unless there is a ":" at the end. We will make sure of an existence of a directory. If so, the returned fileSpec is valid from FSpLocationFromFullPath eventhough it returned an error. */ pb.hFileInfo.ioNamePtr = pascalMacPath; pb.hFileInfo.ioVRefNum = 0; pb.hFileInfo.ioDirID = 0; pb.hFileInfo.ioFDirIndex = 0; err = PBGetCatInfoSync(&pb); if (err == noErr) convertError = noErr; } } free(macPath); return (convertError);} FILE *_OS_FOPEN(const char *filename, const char *mode) { OSErr err = noErr; char *macFileName = NULL; FILE *result; err = ConvertUnixPathToMacPath(filename, &macFileName); if (err != noErr) goto ErrorExit; result = fopen(macFileName, mode); PR_DELETE(macFileName); return result;ErrorExit: _PR_MD_CURRENT_THREAD()->md.osErrCode = err; _MD_SetError(err); return NULL;}#elseshort 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 GetFullPath(short vRefNum, long dirID, char **fullPath, int *strSize){ Str255 pascalDirName; char cDirName[256]; char *tmpPath = NULL; // needed since sprintf isn誸 safe CInfoPBRec myPB; OSErr err = noErr; // get the full path of the temp folder. *strSize = 256; *fullPath = NULL; *fullPath = malloc(*strSize); // How big should this thing be? require_action (*fullPath != NULL, errorExit, err = memFullErr;); tmpPath = malloc(*strSize); require_action (tmpPath != NULL, errorExit, err = memFullErr;); strcpy(*fullPath, ""); // Clear C result strcpy(tmpPath, ""); pascalDirName[0] = 0; // Clear Pascal intermediate string myPB.dirInfo.ioNamePtr = &pascalDirName[0]; myPB.dirInfo.ioVRefNum = vRefNum; myPB.dirInfo.ioDrParID = dirID; myPB.dirInfo.ioFDirIndex = -1; // Getting info about do { myPB.dirInfo.ioDrDirID = myPB.dirInfo.ioDrParID; err = PBGetCatInfoSync(&myPB); require(err == noErr, errorExit); // Move the name into C domain memcpy(&cDirName, &pascalDirName, 256); p2cstr((unsigned char *)&cDirName); // Changes in place! if ((strlen(cDirName) + strlen(*fullPath)) > *strSize) { // We need to grow the string, do it in 256 byte chunks (*strSize) += 256; *fullPath = PR_REALLOC(*fullPath, *strSize); require_action (*fullPath != NULL, errorExit, err = memFullErr;); tmpPath = PR_REALLOC(tmpPath, *strSize); require_action (tmpPath != NULL, errorExit, err = memFullErr;); } sprintf(tmpPath, "%s:%s", cDirName, *fullPath); strcpy(*fullPath, tmpPath); } while (myPB.dirInfo.ioDrDirID != fsRtDirID); PR_DELETE(tmpPath); return noErr; errorExit: PR_DELETE(*fullPath); PR_DELETE(tmpPath); return err;}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 OSErr ConvertUnixPathToMacPath(const char *unixPath, char **macPath){ OSErr err = noErr; // // Convert UNIX style path names (with . and / separators) into a Macintosh // style path (with :). // // There are also a couple of special paths that need to be dealt with // by translating them to the appropriate Mac special folders. These include: // // /usr/tmp/file => {TempFolder}file // // The file conversions we need to do are as follows: // // file => file // dir/file => :dir:file // ./file => file // ../file => ::file // ../dir/file => ::dir:file // /file => ::BootDrive:file // /dir/file => ::BootDrive:dir:file if (*unixPath != PR_DIRECTORY_SEPARATOR) { // Not root relative, just convert it. err = CreateMacPathFromUnixPath(unixPath, macPath); } else { // We誶e root-relative. This is either a special Unix directory, or a // full path (which we誰l support on the Mac since they might be generated). // This is not condoning the use of full-paths on the Macintosh for file // specification. short foundVRefNum; long foundDirID; int pathBufferSize; char *temp; char isNetscapeDir = false; // Are we dealing with the temp folder? if (strncmp(unixPath, "/usr/tmp", strlen("/usr/tmp")) == 0){ unixPath += 8; if (*unixPath == PR_DIRECTORY_SEPARATOR) unixPath++; // Skip the slash err = FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder, // Create if needed &foundVRefNum, &foundDirID); } if (strncmp(unixPath, "/tmp", strlen("/tmp")) == 0) { unixPath += 4; // Skip the slash if (*unixPath == PR_DIRECTORY_SEPARATOR) unixPath++; // Skip the slash err = FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder, // Create if needed &foundVRefNum, &foundDirID); } else if (strncmp(unixPath, "/usr", strlen("/usr")) == 0) { int usrNetscapePathLen; usrNetscapePathLen = strlen("/usr/local/netscape/"); if (strncmp(unixPath, "/usr/local/netscape/", usrNetscapePathLen) == 0) { unixPath += usrNetscapePathLen; // err = FindPreferencesFolder(&foundVRefNum, &foundDirID); err = paramErr; isNetscapeDir = true; } else { dprintf("Unable to translate Unix file path %s to Mac path\n", unixPath); err = -1; goto Exit_ConvertUnixPathToMacPath; } } else { // This is a root relative directory, we誰l just convert the whole thing. err = CreateMacPathFromUnixPath(unixPath, macPath); goto Exit_ConvertUnixPathToMacPath; } // We誶e dealing with a special folder if (err == noErr) // Get the path to the root-relative directory err = GetFullPath(foundVRefNum, foundDirID, macPath, &pathBufferSize); // mallocs macPath if (err == noErr){ // copy over the remaining file name, converting if (pathBufferSize < (strlen(*macPath) + strlen(unixPath))) { // need to grow string *macPath = PR_REALLOC(*macPath, (strlen(*macPath) + strlen(unixPath) + (isNetscapeDir ? strlen("Netscape
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -