/* This function is an adaptation of the function FSpLocationFromPath in tclMacUtils.c in the Tcl 8.0 distribution */ OSErr FSMakeFSSpecFromPath(ConstStr255Param fileName, FSSpecPtr spec) { Boolean isDir, wasAlias; int pos, end; OSErr err; Str255 Name; short vRefNum; long dirID; /* get the initial directory information and set up first path component */ CopyNamePart(Name, fileName, 1); if (Name[0] < fileName[0] && Name[1] != ':') { /* absolute path */ Name[0]++; Name[Name[0]] = ':'; if ((err = FSMakeFSSpec(0, 0, Name, spec)) != noErr) return err; if ((err = FSpGetDirectoryID(spec, &dirID, &isDir)) != noErr) return err; if (! isDir) return dirNFErr; vRefNum = spec->vRefNum; pos = Name[0] + 1; CopyNamePart(Name, fileName, pos); } else { dirID = 0; vRefNum = 0; pos = 1; isDir = true; } /* process remaining path parts */ end = fileName[0] + 1; while (true) { if ((err = FSMakeFSSpec(vRefNum, dirID, Name[0] == 0 ? NULL : Name, spec)) != noErr || (err = ResolveAliasFile(spec, true, &isDir, &wasAlias)) != noErr) return err; pos += Name[0]; if (pos < end) { if ((err = FSpGetDirectoryID(spec, &dirID, &isDir)) != noErr) return err; if (! isDir) return dirNFErr; vRefNum = spec->vRefNum; CopyNamePart(Name, fileName, pos); } else return noErr; } }
/*------------------------------------------------------------------- * XPI Stub Load/Unload *-------------------------------------------------------------------*/ OSErr LoadXPIStub(XPI_InitProc* pfnInit, XPI_InstallProc* pfnInstall, XPI_ExitProc* pfnExit, CFragConnectionID* connID, FSSpec& aTargetDir, Str255 errName) { OSErr err; FSSpec fslib; Str63 fragName = XPISTUB_DLL; Ptr mainAddr, symAddr; CFragSymbolClass symClass; long tgtDirID; Boolean isDir; err = FSpGetDirectoryID( &aTargetDir, &tgtDirID, &isDir ); if (err!=noErr) return err; else if (!isDir) return paramErr; err = FSMakeFSSpec(aTargetDir.vRefNum, tgtDirID, fragName, &fslib); if (err!=noErr) return err; err = GetDiskFragment(&fslib, 0, kCFragGoesToEOF, nil, /*kPrivateCFragCopy*/kReferenceCFrag, connID, &mainAddr, errName); if ( err == noErr && *connID != NULL) { ERR_CHECK_RET( FindSymbol(*connID, "\pXPI_Init", &symAddr, &symClass), err ); *pfnInit = (XPI_InitProc) symAddr; ERR_CHECK_RET( FindSymbol(*connID, "\pXPI_Install", &symAddr, &symClass), err); *pfnInstall = (XPI_InstallProc) symAddr; ERR_CHECK_RET( FindSymbol(*connID, "\pXPI_Exit", &symAddr, &symClass), err); *pfnExit = (XPI_ExitProc) symAddr; }
void InitOptObject(void) { FSSpec tmp; OSErr err=noErr; Boolean isDir; gControls->opt = (Options*)NewPtrClear(sizeof(Options)); if (!gControls->opt) { ErrorHandler(eMem, nil); return; } /* SetupTypeWin options */ gControls->opt->instChoice = 1; gControls->opt->folder = (unsigned char *)NewPtrClear(64*sizeof(unsigned char)); if (!gControls->opt->folder) { ErrorHandler(eMem, nil); return; } /* TerminalWIn options */ gControls->opt->siteChoice = 1; gControls->opt->saveBits = false; gControls->opt->vRefNum = -1; err = FSMakeFSSpec(gControls->opt->vRefNum, 0, "\p", &tmp); pstrcpy( gControls->opt->folder, tmp.name ); err = FSpGetDirectoryID( &tmp, &gControls->opt->dirID, &isDir ); }
/* フォルダアイコンをチェック */ OSErr FolderIconCheck(const FSSpec *theFolderSpec,short *alertMode) { OSErr err; long dirID; FSSpec theIconFile; Str15 iconFileName; Boolean isDirectory; #ifdef __MOREFILESX__ FSRef fsRef; FinderInfo info; err = FSpMakeFSRef(theFolderSpec,&fsRef); if (err != noErr) return err; #else DInfo dirInfo; #endif /* まず、カスタムアイコンフラグが立っているかどうかを調べる */ /* ここでエラーが発生する場合はおそらくフォルダアイコン編集も不可能なのでそのまま返る */ #ifdef __MOREFILESX__ err = FSGetFinderInfo(&fsRef,&info,NULL,NULL); #else err=FSpGetDInfo(theFolderSpec,&dirInfo); #endif if (err!=noErr) return err; /* カスタムアイコンフラグが立っていなければ問題なし */ #ifdef __MOREFILESX__ if ((info.folder.finderFlags & kHasCustomIcon) == 0) return noErr; #else if ((dirInfo.frFlags & kHasCustomIcon) == 0) return noErr; #endif /* 立っている場合は、カスタムアイコンをチェック */ #ifdef __MOREFILESX__ err = FSGetNodeID(&fsRef,&dirID,&isDirectory); #else err=FSpGetDirectoryID(theFolderSpec,&dirID,&isDirectory); #endif if (err!=noErr) return err; GetIndString(iconFileName,140,3); err=FSMakeFSSpec(theFolderSpec->vRefNum,dirID,iconFileName,&theIconFile); if (err==fnfErr) /* アイコンファイルが見つからない場合は、フラグが間違っているわけだから修正 */ { #ifdef __MOREFILESX__ err = FSClearHasCustomIcon(&fsRef); #else err=FSpClearHasCustomIcon(theFolderSpec); #endif return noErr; } else if (err!=noErr) /* それ以外のエラーなら編集できないだろうから戻る */ return err; return FileIconCheck(&theIconFile,alertMode); }
void CleanTemp(void) { OSErr err = noErr; short vRefNum; long dirID; FSSpec viewerFSp; XPISpec *xpiList, *currXPI = 0, *nextXPI = 0; #ifdef MIW_DEBUG Boolean isDir = false; #endif #ifndef MIW_DEBUG /* get "viewer" in "Temporary Items" folder */ ERR_CHECK(FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder, &vRefNum, &dirID)); err = FSMakeFSSpec(vRefNum, dirID, kViewerFolder, &viewerFSp); #else /* for DEBUG builds temp is "<currProcessVolume>:Temp NSInstall:" */ ERR_CHECK(GetCWD(&dirID, &vRefNum)); err = FSMakeFSSpec(vRefNum, 0, kTempFolder, &viewerFSp); if (err == fnfErr) return; /* no debug temp exists */ err = FSpGetDirectoryID(&viewerFSp, &dirID, &isDir); if (err != noErr || !isDir) return; err = FSMakeFSSpec(vRefNum, dirID, kViewerFolder, &viewerFSp); #endif /* whack the viewer folder if it exists */ if (err == noErr) { ERR_CHECK(DeleteDirectory(viewerFSp.vRefNum, viewerFSp.parID, viewerFSp.name)); } /* clean out the zippies (.xpi's) */ xpiList = (XPISpec *) NewPtrClear(sizeof(XPISpec)); if (!xpiList) return; IterateDirectory(vRefNum, dirID, "\p", 1, CheckIfXPI, (void*)&xpiList); if (xpiList) { currXPI = xpiList; while(currXPI) { nextXPI = currXPI->next; /* save nextXPI before we blow away currXPI */ if (currXPI->FSp) { FSpDelete(currXPI->FSp); DisposePtr((Ptr)currXPI->FSp); } DisposePtr((Ptr)currXPI); currXPI = nextXPI; } } }
static int GetFileFinderAttributes( Tcl_Interp *interp, /* The interp to report errors with. */ int objIndex, /* The index of the attribute option. */ char *fileName, /* The name of the file. */ Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */ { OSErr err; FSSpec fileSpec; FInfo finfo; err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec); if (err == noErr) { err = FSpGetFInfo(&fileSpec, &finfo); } if (err == noErr) { switch (objIndex) { case MAC_CREATOR_ATTRIBUTE: *attributePtrPtr = Tcl_NewOSTypeObj(finfo.fdCreator); break; case MAC_HIDDEN_ATTRIBUTE: *attributePtrPtr = Tcl_NewBooleanObj(finfo.fdFlags & kIsInvisible); break; case MAC_TYPE_ATTRIBUTE: *attributePtrPtr = Tcl_NewOSTypeObj(finfo.fdType); break; } } else if (err == fnfErr) { long dirID; Boolean isDirectory = 0; err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); if ((err == noErr) && isDirectory) { if (objIndex == MAC_HIDDEN_ATTRIBUTE) { *attributePtrPtr = Tcl_NewBooleanObj(0); } else { *attributePtrPtr = Tcl_NewOSTypeObj('Fldr'); } } } if (err != noErr) { errno = TclMacOSErrorToPosixError(err); Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "couldn't get attributes for file \"", fileName, "\": ", Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } return TCL_OK; }
static int SetFileReadOnly( Tcl_Interp *interp, /* The interp to report errors with. */ int objIndex, /* The index of the attribute. */ char *fileName, /* The name of the file. */ Tcl_Obj *readOnlyPtr) /* The command line object. */ { OSErr err; FSSpec fileSpec; HParamBlockRec paramBlock; int hidden; err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec); if (err == noErr) { if (Tcl_GetBooleanFromObj(interp, readOnlyPtr, &hidden) != TCL_OK) { return TCL_ERROR; } paramBlock.fileParam.ioCompletion = NULL; paramBlock.fileParam.ioNamePtr = fileSpec.name; paramBlock.fileParam.ioVRefNum = fileSpec.vRefNum; paramBlock.fileParam.ioDirID = fileSpec.parID; if (hidden) { err = PBHSetFLock(¶mBlock, 0); } else { err = PBHRstFLock(¶mBlock, 0); } } if (err == fnfErr) { long dirID; Boolean isDirectory = 0; err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); if ((err == noErr) && isDirectory) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "cannot set a directory to read-only when File Sharing is turned off", (char *) NULL); return TCL_ERROR; } else { err = fnfErr; } } if (err != noErr) { errno = TclMacOSErrorToPosixError(err); Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "couldn't set attributes for file \"", fileName, "\": ", Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } return TCL_OK; }
static OSErr GetFileSpecs( char *path, /* The path to query. */ FSSpec *pathSpecPtr, /* Filled with information about path. */ FSSpec *dirSpecPtr, /* Filled with information about path's * parent directory. */ Boolean *pathExistsPtr, /* Set to true if path actually exists, * false if it doesn't or there was an * error reading the specified path. */ Boolean *pathIsDirectoryPtr)/* Set to true if path is itself a directory, * otherwise false. */ { char *dirName; OSErr err; int argc; char **argv; long d; Tcl_DString buffer; *pathExistsPtr = false; *pathIsDirectoryPtr = false; Tcl_DStringInit(&buffer); Tcl_SplitPath(path, &argc, &argv); if (argc == 1) { dirName = ":"; } else { dirName = Tcl_JoinPath(argc - 1, argv, &buffer); } err = FSpLocationFromPath(strlen(dirName), dirName, dirSpecPtr); Tcl_DStringFree(&buffer); ckfree((char *) argv); if (err == noErr) { err = FSpLocationFromPath(strlen(path), path, pathSpecPtr); if (err == noErr) { *pathExistsPtr = true; err = FSpGetDirectoryID(pathSpecPtr, &d, pathIsDirectoryPtr); } else if (err == fnfErr) { err = noErr; } } return err; }
wxDirData::wxDirData(const wxString& dirname) : m_dirname(dirname) { m_ok = false; OSErr err; // throw away the trailing slashes size_t n = m_dirname.length(); wxCHECK_RET( n, _T("empty dir name in wxDir") ); while ( n > 0 && wxIsPathSeparator(m_dirname[--n]) ) ; m_dirname.Truncate(n + 1); #ifdef __DARWIN__ FSRef theRef; // get the FSRef associated with the POSIX path err = FSPathMakeRef((const UInt8 *) m_dirname.c_str(), &theRef, NULL); FSGetVRefNum(&theRef, &(m_CPB.hFileInfo.ioVRefNum)); err = FSGetNodeID( &theRef , &m_dirId , &m_isDir ) ; #else FSSpec fsspec ; wxMacFilename2FSSpec( m_dirname , &fsspec ) ; m_CPB.hFileInfo.ioVRefNum = fsspec.vRefNum ; err = FSpGetDirectoryID( &fsspec , &m_dirId , &m_isDir ) ; #endif //wxASSERT_MSG( (err == noErr) || (err == nsvErr) , wxT("Error accessing directory " + m_dirname)) ; if ( (err == noErr) || (err == nsvErr)) m_ok = true; else wxLogError(wxString(wxT("Error accessing directory ")) + m_dirname); m_CPB.hFileInfo.ioNamePtr = m_name ; m_index = 0 ; }
int TclpDeleteFile( char *path) /* Pathname of file to be removed. */ { OSErr err; FSSpec fileSpec; Boolean isDirectory; long dirID; err = FSpLocationFromPath(strlen(path), path, &fileSpec); if (err == noErr) { /* * Since FSpDeleteCompat will delete an empty directory, make sure * that this isn't a directory first. */ FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); if (isDirectory == true) { errno = EISDIR; return TCL_ERROR; } } err = FSpDeleteCompat(&fileSpec); if (err == fLckdErr) { FSpRstFLockCompat(&fileSpec); err = FSpDeleteCompat(&fileSpec); if (err != noErr) { FSpSetFLockCompat(&fileSpec); } } if (err != noErr) { errno = TclMacOSErrorToPosixError(err); return TCL_ERROR; } return TCL_OK; }
static OSErr MoveRename( const FSSpec *srcFileSpecPtr, /* Source object. */ const FSSpec *dstDirSpecPtr, /* Destination directory. */ StringPtr copyName) /* New name for object in destination * directory. */ { OSErr err; long srcID, dstID; Boolean srcIsDir, dstIsDir; Str31 tmpName; FSSpec dstFileSpec, srcDirSpec, tmpSrcFileSpec, tmpDstFileSpec; Boolean locked; if (srcFileSpecPtr->parID == 1) { /* * Trying to rename a volume. */ return badMovErr; } if (srcFileSpecPtr->vRefNum != dstDirSpecPtr->vRefNum) { /* * Renaming across volumes. */ return diffVolErr; } err = FSpGetFLockCompat(srcFileSpecPtr, &locked); if (locked) { FSpRstFLockCompat(srcFileSpecPtr); } if (err == noErr) { err = FSpGetDirectoryID(dstDirSpecPtr, &dstID, &dstIsDir); } if (err == noErr) { if (srcFileSpecPtr->parID == dstID) { /* * Renaming object within directory. */ err = FSpRenameCompat(srcFileSpecPtr, copyName); goto done; } if (Pstrequal(srcFileSpecPtr->name, copyName)) { /* * Moving object to another directory (under same name). */ err = FSpCatMoveCompat(srcFileSpecPtr, dstDirSpecPtr); goto done; } err = FSpGetDirectoryID(srcFileSpecPtr, &srcID, &srcIsDir); } if (err == noErr) { /* * Fullblown: rename source object to temp name, move temp to * dest directory, and rename temp to target. */ err = GenerateUniqueName(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID, dstID, tmpName); FSMakeFSSpecCompat(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID, tmpName, &tmpSrcFileSpec); FSMakeFSSpecCompat(dstDirSpecPtr->vRefNum, dstID, tmpName, &tmpDstFileSpec); } if (err == noErr) { err = FSpRenameCompat(srcFileSpecPtr, tmpName); } if (err == noErr) { err = FSpCatMoveCompat(&tmpSrcFileSpec, dstDirSpecPtr); if (err == noErr) { err = FSpRenameCompat(&tmpDstFileSpec, copyName); if (err == noErr) { goto done; } FSMakeFSSpecCompat(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID, NULL, &srcDirSpec); FSpCatMoveCompat(&tmpDstFileSpec, &srcDirSpec); } FSpRenameCompat(&tmpSrcFileSpec, srcFileSpecPtr->name); } done: if (locked != false) { if (err == noErr) { FSMakeFSSpecCompat(dstDirSpecPtr->vRefNum, dstID, copyName, &dstFileSpec); FSpSetFLockCompat(&dstFileSpec); } else { FSpSetFLockCompat(srcFileSpecPtr); } } return err; }
int TclpRemoveDirectory( char *path, /* Pathname of directory to be removed. */ int recursive, /* If non-zero, removes directories that * are nonempty. Otherwise, will only remove * empty directories. */ Tcl_DString *errorPtr) /* If non-NULL, initialized DString for * error reporting. */ { OSErr err; FSSpec fileSpec; long dirID; int locked; Boolean isDirectory; CInfoPBRec pb; Str255 fileName; locked = 0; err = FSpLocationFromPath(strlen(path), path, &fileSpec); if (err != noErr) { goto done; } /* * Since FSpDeleteCompat will delete a file, make sure this isn't * a file first. */ isDirectory = 1; FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); if (isDirectory == 0) { errno = ENOTDIR; return TCL_ERROR; } err = FSpDeleteCompat(&fileSpec); if (err == fLckdErr) { locked = 1; FSpRstFLockCompat(&fileSpec); err = FSpDeleteCompat(&fileSpec); } if (err == noErr) { return TCL_OK; } if (err != fBsyErr) { goto done; } if (recursive == 0) { /* * fBsyErr means one of three things: file busy, directory not empty, * or working directory control block open. Determine if directory * is empty. If directory is not empty, return EEXIST. */ pb.hFileInfo.ioVRefNum = fileSpec.vRefNum; pb.hFileInfo.ioDirID = dirID; pb.hFileInfo.ioNamePtr = (StringPtr) fileName; pb.hFileInfo.ioFDirIndex = 1; if (PBGetCatInfoSync(&pb) == noErr) { err = dupFNErr; /* EEXIST */ goto done; } } /* * DeleteDirectory removes a directory and all its contents, including * any locked files. There is no interface to get the name of the * file that caused the error, if an error occurs deleting this tree, * unless we rewrite DeleteDirectory ourselves. */ err = DeleteDirectory(fileSpec.vRefNum, dirID, NULL); done: if (err != noErr) { if (errorPtr != NULL) { Tcl_DStringAppend(errorPtr, path, -1); } if (locked) { FSpSetFLockCompat(&fileSpec); } errno = TclMacOSErrorToPosixError(err); return TCL_ERROR; } return TCL_OK; }
int TclpCopyDirectory( char *src, /* Pathname of directory to be copied. */ char *dst, /* Pathname of target directory. */ Tcl_DString *errorPtr) /* If non-NULL, initialized DString for * error reporting. */ { OSErr err, saveErr; long srcID, tmpDirID; FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpDirSpec, tmpFileSpec; Boolean srcIsDirectory, srcLocked; Boolean dstIsDirectory, dstExists; Str31 tmpName; err = FSpLocationFromPath(strlen(src), src, &srcFileSpec); if (err == noErr) { err = FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory); } if (err == noErr) { if (srcIsDirectory == false) { err = afpObjectTypeErr; /* ENOTDIR. */ } } if (err == noErr) { err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists, &dstIsDirectory); } if (dstExists) { if (dstIsDirectory == false) { err = afpObjectTypeErr; /* ENOTDIR. */ } else { err = dupFNErr; /* EEXIST. */ } } if (err != noErr) { goto done; } if ((srcFileSpec.vRefNum == dstFileSpec.vRefNum) && (srcFileSpec.parID == dstFileSpec.parID) && (Pstrequal(srcFileSpec.name, dstFileSpec.name) != 0)) { /* * Copying on top of self. No-op. */ goto done; } /* * This algorthm will work making a copy of the source directory in * the current directory with a new name, in a new directory with the * same name, and in a new directory with a new name: * * 1. Make dstDir/tmpDir. * 2. Copy srcDir/src to dstDir/tmpDir/src * 3. Rename dstDir/tmpDir/src to dstDir/tmpDir/dst (if necessary). * 4. CatMove dstDir/tmpDir/dst to dstDir/dst. * 5. Remove dstDir/tmpDir. */ err = FSpGetFLockCompat(&srcFileSpec, &srcLocked); if (srcLocked) { FSpRstFLockCompat(&srcFileSpec); } if (err == noErr) { err = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID, dstFileSpec.parID, tmpName); } if (err == noErr) { FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID, tmpName, &tmpDirSpec); err = FSpDirCreateCompat(&tmpDirSpec, smSystemScript, &tmpDirID); } if (err == noErr) { err = FSpDirectoryCopy(&srcFileSpec, &tmpDirSpec, NULL, 0, true, CopyErrHandler); } /* * Even if the Copy failed, Rename/Move whatever did get copied to the * appropriate final destination, if possible. */ saveErr = err; err = noErr; if (Pstrequal(srcFileSpec.name, dstFileSpec.name) == 0) { err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID, srcFileSpec.name, &tmpFileSpec); if (err == noErr) { err = FSpRenameCompat(&tmpFileSpec, dstFileSpec.name); } } if (err == noErr) { err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID, dstFileSpec.name, &tmpFileSpec); } if (err == noErr) { err = FSpCatMoveCompat(&tmpFileSpec, &dstDirSpec); } if (err == noErr) { if (srcLocked) { FSpSetFLockCompat(&dstFileSpec); } } FSpDeleteCompat(&tmpDirSpec); if (saveErr != noErr) { err = saveErr; } done: if (err != noErr) { errno = TclMacOSErrorToPosixError(err); if (errorPtr != NULL) { Tcl_DStringAppend(errorPtr, dst, -1); } return TCL_ERROR; } return TCL_OK; }
int TclpRenameFile( char *src, /* Pathname of file or dir to be renamed. */ char *dst) /* New pathname for file or directory. */ { FSSpec srcFileSpec, dstFileSpec, dstDirSpec; OSErr err; long srcID, dummy; Boolean srcIsDirectory, dstIsDirectory, dstExists, dstLocked; err = FSpLocationFromPath(strlen(src), src, &srcFileSpec); if (err == noErr) { FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory); } if (err == noErr) { err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists, &dstIsDirectory); } if (err == noErr) { if (dstExists == 0) { err = MoveRename(&srcFileSpec, &dstDirSpec, dstFileSpec.name); goto end; } err = FSpGetFLockCompat(&dstFileSpec, &dstLocked); if (dstLocked) { FSpRstFLockCompat(&dstFileSpec); } } if (err == noErr) { if (srcIsDirectory) { if (dstIsDirectory) { /* * The following call will remove an empty directory. If it * fails, it's because it wasn't empty. */ if (TclpRemoveDirectory(dst, 0, NULL) != TCL_OK) { return TCL_ERROR; } /* * Now that that empty directory is gone, we can try * renaming src. If that fails, we'll put this empty * directory back, for completeness. */ err = MoveRename(&srcFileSpec, &dstDirSpec, dstFileSpec.name); if (err != noErr) { FSpDirCreateCompat(&dstFileSpec, smSystemScript, &dummy); if (dstLocked) { FSpSetFLockCompat(&dstFileSpec); } } } else { errno = ENOTDIR; return TCL_ERROR; } } else { if (dstIsDirectory) { errno = EISDIR; return TCL_ERROR; } else { /* * Overwrite existing file by: * * 1. Rename existing file to temp name. * 2. Rename old file to new name. * 3. If success, delete temp file. If failure, * put temp file back to old name. */ Str31 tmpName; FSSpec tmpFileSpec; err = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID, dstFileSpec.parID, tmpName); if (err == noErr) { err = FSpRenameCompat(&dstFileSpec, tmpName); } if (err == noErr) { err = FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID, tmpName, &tmpFileSpec); } if (err == noErr) { err = MoveRename(&srcFileSpec, &dstDirSpec, dstFileSpec.name); } if (err == noErr) { FSpDeleteCompat(&tmpFileSpec); } else { FSpDeleteCompat(&dstFileSpec); FSpRenameCompat(&tmpFileSpec, dstFileSpec.name); if (dstLocked) { FSpSetFLockCompat(&dstFileSpec); } } } } } end: if (err != noErr) { errno = TclMacOSErrorToPosixError(err); return TCL_ERROR; } return TCL_OK; }
static int FSpLocationFromPathAlias( int length, /* Length of path. */ CONST char *path, /* The path to convert. */ FSSpecPtr fileSpecPtr, /* On return the spec for the path. */ Boolean resolveLink) /* Resolve the last path component? */ { Str255 fileName; OSErr err; short vRefNum; long dirID; int pos, cur; Boolean isDirectory; Boolean wasAlias=FALSE; FSSpec lastFileSpec; /* * Check to see if this is a full path. If partial * we assume that path starts with the current working * directory. (Ie. volume & dir = 0) */ vRefNum = 0; dirID = 0; cur = 0; if (length == 0) { return fnfErr; } if (path[cur] == ':') { cur++; if (cur >= length) { /* * If path = ":", just return current directory. */ FSMakeFSSpecCompat(0, 0, NULL, fileSpecPtr); return noErr; } } else { while (path[cur] != ':' && cur < length) { cur++; } if (cur > 255) { return bdNamErr; } if (cur < length) { /* * This is a full path */ cur++; strncpy((char *) fileName + 1, path, cur); fileName[0] = cur; err = FSMakeFSSpecCompat(0, 0, fileName, fileSpecPtr); if (err != noErr) return err; FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory); vRefNum = fileSpecPtr->vRefNum; } else { cur = 0; } } isDirectory = 1; while (cur < length) { if (!isDirectory) { return dirNFErr; } pos = cur; while (path[pos] != ':' && pos < length) { pos++; } if (pos == cur) { /* Move up one dir */ /* cur++; */ strcpy((char *) fileName + 1, "::"); fileName[0] = 2; } else if (pos - cur > 255) { return bdNamErr; } else { strncpy((char *) fileName + 1, &path[cur], pos - cur); fileName[0] = pos - cur; } err = FSMakeFSSpecCompat(vRefNum, dirID, fileName, fileSpecPtr); if (err != noErr) return err; lastFileSpec=*fileSpecPtr; err = ResolveAliasFile(fileSpecPtr, true, &isDirectory, &wasAlias); if (err != noErr) { /* ignore alias resolve errors on last path component */ if (pos < length) return err; else *fileSpecPtr=lastFileSpec; } FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory); vRefNum = fileSpecPtr->vRefNum; cur = pos; if (path[cur] == ':') { cur++; } } if(!resolveLink && wasAlias) *fileSpecPtr=lastFileSpec; return noErr; }
static int SetFileFinderAttributes( Tcl_Interp *interp, /* The interp to report errors with. */ int objIndex, /* The index of the attribute. */ char *fileName, /* The name of the file. */ Tcl_Obj *attributePtr) /* The command line object. */ { OSErr err; FSSpec fileSpec; FInfo finfo; err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec); if (err == noErr) { err = FSpGetFInfo(&fileSpec, &finfo); } if (err == noErr) { switch (objIndex) { case MAC_CREATOR_ATTRIBUTE: if (Tcl_GetOSTypeFromObj(interp, attributePtr, &finfo.fdCreator) != TCL_OK) { return TCL_ERROR; } break; case MAC_HIDDEN_ATTRIBUTE: { int hidden; if (Tcl_GetBooleanFromObj(interp, attributePtr, &hidden) != TCL_OK) { return TCL_ERROR; } if (hidden) { finfo.fdFlags |= kIsInvisible; } else { finfo.fdFlags &= ~kIsInvisible; } break; } case MAC_TYPE_ATTRIBUTE: if (Tcl_GetOSTypeFromObj(interp, attributePtr, &finfo.fdType) != TCL_OK) { return TCL_ERROR; } break; } err = FSpSetFInfo(&fileSpec, &finfo); } else if (err == fnfErr) { long dirID; Boolean isDirectory = 0; err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); if ((err == noErr) && isDirectory) { Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); Tcl_AppendStringsToObj(resultPtr, "cannot set ", tclpFileAttrStrings[objIndex], ": \"", fileName, "\" is a directory", (char *) NULL); return TCL_ERROR; } } if (err != noErr) { errno = TclMacOSErrorToPosixError(err); Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "couldn't set attributes for file \"", fileName, "\": ", Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } return TCL_OK; }
pascal OSErr FSpGetDirectoryIDTcl (CONST FSSpec * spec, long * theDirID, Boolean * isDirectory) { return(FSpGetDirectoryID(spec, theDirID, isDirectory)); }
/* create folder with IPIcon */ OSErr MakeFolderWithIPIcon(const FSSpec *theFolder,const IPIconRec *ipIcon) { OSErr err; long dirID; FSSpec theIconFile; Str15 iconFileName; #ifdef __MOREFILESX__ FSRef fsRef; #endif /* create a folder */ err=FSpDirCreate(theFolder,smSystemScript,&dirID); if (err==dupFNErr || err==dirNFErr) { Boolean isDirectory; #ifdef __MOREFILESX__ err = FSpMakeFSRef(theFolder,&fsRef); err = FSGetNodeID(&fsRef,&dirID,&isDirectory); #else err=FSpGetDirectoryID(theFolder,&dirID,&isDirectory); #endif if (!isDirectory) return -1; } if (err!=noErr) return err; #ifdef __MOREFILESX__ err = FSpMakeFSRef(theFolder,&fsRef); #endif /* create icon file */ GetIndString(iconFileName,140,3); err=FSMakeFSSpec(theFolder->vRefNum,dirID,iconFileName,&theIconFile); if (err==fnfErr) { FInfo fndrInfo; FSpCreateResFile(&theIconFile,kFinderCreator,'icon',smSystemScript); err=FSpGetFInfo(&theIconFile,&fndrInfo); fndrInfo.fdFlags |= kIsInvisible; err=FSpSetFInfo(&theIconFile,&fndrInfo); } /* save icon data */ if (err==noErr) { short refNum; IconActionUPP addIconUPP; MyIconResRec newIcon; #ifndef __MOREFILESX__ DInfo dInfo; #endif newIcon.resID=kCustomIconResource; GetIndString(newIcon.resName,141,2); newIcon.attrs=0; refNum=FSpOpenResFile(&theIconFile,fsWrPerm); UseResFile(refNum); /* save icon family(separated icons) */ if (ipIcon->iconSuite != NULL) { addIconUPP = NewIconActionUPP(AddIconToFile); err=ForEachIconDo(ipIcon->iconSuite,kSelectorMyData,addIconUPP,&newIcon); DisposeIconActionUPP(addIconUPP); } /* save icns(single icon) */ if (isIconServicesAvailable) { IconFamilyHandle iconFamily; err=IPIconToIconFamily(ipIcon,&iconFamily); if (err==noErr) { SaveDataToResource(*iconFamily,GetHandleSize((Handle)iconFamily), kIconFamilyType,newIcon.resID,newIcon.resName,newIcon.attrs); DisposeHandle((Handle)iconFamily); } } else /* delete icns resource */ DeleteIconFamilyResource(); CloseResFile(refNum); UseResFile(gApplRefNum); /* set flag for custom icons */ #ifdef __MOREFILESX__ err = FSSetHasCustomIcon(&fsRef); err = FSClearHasBeenInited(&fsRef); #else err=FSpGetDInfo(theFolder,&dInfo); dInfo.frFlags |= kHasCustomIcon; dInfo.frFlags &= ~kHasBeenInited; err=FSpSetDInfo(theFolder,&dInfo); #endif gUsedCount.exportNum++; } FlushVol(0L,theFolder->vRefNum); /* update folder icon */ UpdateFinderIcon(theFolder); return err; }
static OSErr MacPathname2FSSpec(const char *inPathname, FSSpec *outFSS) { OSErr err; size_t len; char *p; short vRefNum; long dirID; FSSpec fss; if (inPathname == NULL || outFSS == NULL) { return paramErr; } err = HGetVol(NULL, &vRefNum, &dirID); /* default volume and directory */ if (err != noErr) return err; len = strlen(inPathname); p = strchr(inPathname, ':'); if (p == NULL) { /* Partial pathname -- filename only */ Str31 filename; assert(len <= 31); c2pstrcpy(filename, inPathname); err = FSMakeFSSpec(vRefNum, dirID, filename, outFSS); } else { Str31 name; int nameLen; if (inPathname[0] == ':') { /* Relative pathname including directory path */ } else { /* Absolute pathname */ /* Str31 volName; We would use Str28 if it was defined -- 27, plus 1 for ':'. */ nameLen = p - inPathname; assert(nameLen <= 27); name[0] = nameLen + 1; memcpy(name + 1, inPathname, nameLen + 1); /* Copy the volume name and the colon. */ err = DetermineVRefNum(name, 0, &vRefNum); if (err != noErr) return err; dirID = 2; } /* vRefNum and dirID now specify the directory in which we should descend the path pointed to by p (pointing to the first colon). */ p++; while (p != NULL && *p != '\0') { char *q = strchr(p, ':'); if (q != NULL) { Boolean isDir; nameLen = q - p; assert(nameLen <= 31); name[0] = nameLen; memcpy(name + 1, p, nameLen); err = FSMakeFSSpec(vRefNum, dirID, name, &fss); if (err != noErr) return err; if (q[1] == '\0') { p = NULL; *outFSS = fss; } else { err = FSpGetDirectoryID(&fss, &dirID, &isDir); assert(isDir == true); if (err != noErr) return err; p = q + 1; } } else { q = strchr(p, '\0'); /* go to end of string */ nameLen = q - p; assert(nameLen > 0); assert(nameLen <= 31); c2pstrcpy(name, p); p = NULL; err = FSMakeFSSpec(vRefNum, dirID, name, outFSS); } } } return err; }
int Zmacstat(const char *Fname, struct stat *buf) { OSErr err, rc; short fullPathLength; Handle hFullPath; char path[NAME_MAX], path2[NAME_MAX]; HVolumeParam vpb; static unsigned long count_of_files = 0; AssertStr(Fname,Fname) Assert_it(buf,"","") UserStop(); memset(buf, 0, sizeof(buf)); /* zero out all fields */ RfDfFilen2Real(path2, Fname, MacZip.MacZipMode, MacZip.DataForkOnly, &MacZip.CurrentFork); GetCompletePath(path, path2, &MacZip.fileSpec, &err); err = PrintUserHFSerr((err != -43) && (err != 0), err, path); printerr("GetCompletePath:", err, err, __LINE__, __FILE__, path); if (err != noErr) { errno = err; return -1; } /* Collect here some more information, it's not related to Macstat. (note: filespec gets changed later in this function) */ /* clear string-buffer */ memset(MacZip.FullPath, 0x00, sizeof(MacZip.FullPath)); rc = FSpGetFullPath(&MacZip.fileSpec, &fullPathLength, &hFullPath); strncpy(MacZip.FullPath, *hFullPath, fullPathLength); DisposeHandle(hFullPath); /* we don't need it any more */ /* Collect some more information not related to Macstat */ /* * Fill the fpb & vpb struct up with info about file or directory. */ FSpGetDirectoryID(&MacZip.fileSpec, &MacZip.dirID, &MacZip.isDirectory); vpb.ioVRefNum = MacZip.fpb.hFileInfo.ioVRefNum = MacZip.fileSpec.vRefNum; vpb.ioNamePtr = MacZip.fpb.hFileInfo.ioNamePtr = MacZip.fileSpec.name; if (MacZip.isDirectory) { MacZip.fpb.hFileInfo.ioDirID = MacZip.fileSpec.parID; /* * Directories are executable by everyone. */ buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH | UNX_IFDIR; } else { MacZip.fpb.hFileInfo.ioDirID = MacZip.dirID; } MacZip.fpb.hFileInfo.ioFDirIndex = 0; err = PBGetCatInfoSync((CInfoPBPtr)&MacZip.fpb); if (err == noErr) { vpb.ioVolIndex = 0; err = PBHGetVInfoSync((HParmBlkPtr)&vpb); if (err == noErr && buf != NULL) { /* * Files are always readable by everyone. */ buf->st_mode |= UNX_IRUSR | UNX_IRGRP | UNX_IROTH; /* * Use the Volume Info & File Info to fill out stat buf. */ if (MacZip.fpb.hFileInfo.ioFlAttrib & 0x10) { buf->st_mode |= UNX_IFDIR; buf->st_nlink = 2; } else { buf->st_nlink = 1; if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags & 0x8000) { buf->st_mode |= UNX_IFLNK; } else { buf->st_mode |= UNX_IFREG; } } if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType == 'APPL') { /* * Applications are executable by everyone. */ buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH; } if ((MacZip.fpb.hFileInfo.ioFlAttrib & 0x01) == 0){ /* * If not locked, then everyone has write acces. */ buf->st_mode |= UNX_IWUSR | UNX_IWGRP | UNX_IWOTH; } buf->st_ino = MacZip.fpb.hFileInfo.ioDirID; buf->st_dev = MacZip.fpb.hFileInfo.ioVRefNum; buf->st_uid = -1; buf->st_gid = -1; buf->st_rdev = 0; if (MacZip.CurrentFork == ResourceFork) buf->st_size = MacZip.fpb.hFileInfo.ioFlRLgLen; else buf->st_size = MacZip.fpb.hFileInfo.ioFlLgLen; buf->st_blksize = vpb.ioVAlBlkSiz; buf->st_blocks = (buf->st_size + buf->st_blksize - 1) / buf->st_blksize; /* * The times returned by the Mac file system are in the * local time zone. We convert them to GMT so that the * epoch starts from GMT. This is also consistent with * what is returned from "clock seconds". */ if (!MacZip.isDirectory) { MacZip.CreatDate = MacZip.fpb.hFileInfo.ioFlCrDat; MacZip.ModDate = MacZip.fpb.hFileInfo.ioFlMdDat; MacZip.BackDate = MacZip.fpb.hFileInfo.ioFlBkDat; } else { MacZip.CreatDate = MacZip.fpb.dirInfo.ioDrCrDat; MacZip.ModDate = MacZip.fpb.dirInfo.ioDrMdDat; MacZip.BackDate = MacZip.fpb.dirInfo.ioDrBkDat; } #ifdef IZ_CHECK_TZ if (!zp_tz_is_valid) { MacZip.HaveGMToffset = false; MacZip.Md_UTCoffs = 0L; MacZip.Cr_UTCoffs = 0L; MacZip.Bk_UTCoffs = 0L; } else #endif { /* Do not use GMT offsets when Md_UTCoffs calculation * fails, since this time stamp is used for time * comparisons in Zip and UnZip operations. * We do not bother when GMT offset calculation fails for * any other time stamp value. Instead we simply assume * a default value of 0. */ MacZip.HaveGMToffset = GetGMToffsetMac(MacZip.ModDate, &MacZip.Md_UTCoffs); if (MacZip.HaveGMToffset) { GetGMToffsetMac(MacZip.CreatDate, &MacZip.Cr_UTCoffs); GetGMToffsetMac(MacZip.BackDate, &MacZip.Bk_UTCoffs); } else { MacZip.Cr_UTCoffs = 0L; MacZip.Bk_UTCoffs = 0L; } } #ifdef DEBUG_TIME { printf("\nZmacstat: MacZip.HaveGMToffset: %d", MacZip.HaveGMToffset); printf("\nZmacstat: Mac modif: %lu local -> UTOffset: %d", MacZip.ModDate, MacZip.Md_UTCoffs); printf("\nZmacstat: Mac creat: %lu local -> UTOffset: %d", MacZip.CreatDate, MacZip.Cr_UTCoffs); printf("\nZmacstat: Mac back: %lu local -> UTOffset: %d", MacZip.BackDate, MacZip.Bk_UTCoffs); } #endif /* DEBUG_TIME */ buf->st_mtime = MacFtime2UnixFtime(MacZip.ModDate); buf->st_ctime = MacFtime2UnixFtime(MacZip.CreatDate); buf->st_atime = buf->st_mtime; #ifdef DEBUG_TIME { printf("\nZmacstat: Unix modif: %lu UTC; Mac: %lu local", buf->st_mtime, MacZip.ModDate); printf("\nZmacstat: Unix creat: %lu UTC; Mac: %lu local\n", buf->st_ctime, MacZip.CreatDate); } #endif /* DEBUG_TIME */ if (noisy) { if (MacZip.StatingProgress) { count_of_files++; InformProgress(MacZip.RawCountOfItems, count_of_files ); } else count_of_files = 0; } } } if (err != noErr) { errno = err; } MacZip.isMacStatValid = true; return (err == noErr ? 0 : -1); }