QString QFileInfo::readLink() const { #if defined(Q_OS_UNIX) && !defined(Q_OS_OS2EMX) char s[PATH_MAX+1]; if ( !isSymLink() ) return QString(); int len = readlink( QFile::encodeName(fn).data(), s, PATH_MAX ); if ( len >= 0 ) { s[len] = '\0'; return QFile::decodeName(s); } #endif #if !defined(QWS) && defined(Q_OS_MAC) { FSRef fref; if(FSPathMakeRef((const UInt8 *)QFile::encodeName(fn).data(), &fref, NULL) == noErr) { Boolean isAlias, isFolder; if(FSResolveAliasFile(&fref, TRUE, &isFolder, &isAlias) == noErr && isAlias) { AliasHandle alias; if(FSNewAlias(0, &fref, &alias) == noErr && alias) { CFStringRef cfstr; if(FSCopyAliasInfo(alias, 0, 0, &cfstr, 0, 0) == noErr) { QString cfstring2qstring(CFStringRef str); //qglobal.cpp return cfstring2qstring(cfstr); } } } } } #endif return QString(); }
int sc_ResolveIfAlias(const char *path, char *returnPath, bool &isAlias, int length) { isAlias = false; #if defined(__APPLE__) && !defined(SC_IPHONE) FSRef dirRef; OSStatus osStatusErr = FSPathMakeRef ((const UInt8 *) path, &dirRef, NULL); if ( !osStatusErr ) { Boolean isFolder; Boolean wasAliased; OSErr err = FSResolveAliasFile (&dirRef, true, &isFolder, &wasAliased); if (err) { return -1; } isAlias = wasAliased; if (wasAliased) { UInt8 resolvedPath[PATH_MAX]; osStatusErr = FSRefMakePath (&dirRef, resolvedPath, length); if (osStatusErr) { return -1; } strncpy(returnPath, (char *) resolvedPath, length); return 0; } } #endif strcpy(returnPath, path); return 0; }
static bfs::path readLink(const bfs::path& path) { bfs::path rval; char buf[PATH_MAX+1]; int r = ::readlink(path.c_str(), buf, sizeof(buf)); if (r > 0) { int index = r < PATH_MAX ? r : PATH_MAX; buf[index] = '\0'; rval = buf; } #ifdef MACOSX // aliases appear as regular files if (rval.empty()) { FSRef ref; if (FSPathMakeRef((const UInt8*)path.c_str(), &ref, NULL) == noErr) { Boolean isFolder = false, wasAliased = false; (void) FSResolveAliasFile(&ref, true, &isFolder, &wasAliased); if (wasAliased) { if (FSRefMakePath(&ref, (UInt8*)buf, sizeof(buf)) == noErr) { rval = buf; } } } } #endif return rval; }
QString darwinResolveAlias(const QString &strFile) { OSErr err = noErr; FSRef fileRef; QString strTarget; do { Boolean fDir; if ((err = FSPathMakeRef((const UInt8*)strFile.toUtf8().constData(), &fileRef, &fDir)) != noErr) break; Boolean fAlias = FALSE; if ((err = FSIsAliasFile(&fileRef, &fAlias, &fDir)) != noErr) break; if (fAlias == TRUE) { if ((err = FSResolveAliasFile(&fileRef, TRUE, &fAlias, &fDir)) != noErr) break; char pszPath[1024]; if ((err = FSRefMakePath(&fileRef, (UInt8*)pszPath, 1024)) != noErr) break; strTarget = QString::fromUtf8(pszPath); }else strTarget = strFile; }while(0); return strTarget; }
/* resolve_alias ------------- Resolves the Macintosh alias file at the path pointed to by path and stores the resolved path in resolved_path. The return value is a pointer to the resolved path upon success. On error the return value is zero and both errno and mac_errno should be consulted. */ char* resolve_alias (const char *path, char *resolved_path) { #ifdef HAVE_CORESERVICES FSRef *fspath; Boolean isdir = 0, isalias = 0; #endif #ifndef HAVE_CORESERVICES /* this function is for resolving macintosh aliases. if we don't have the CoreServices API it's impossible, so why fool ourselves, let's just return error now and save the cpu cycles for something else */ errno = EIO; /* returning a generic I/O error */ return 0; #endif /* reset it for each occurrence */ /* mac_errno = 0; */ if (!path) return 0; /* if the second parameter is null, assume caller wants it allocated */ if (!resolved_path) { resolved_path = (char *)malloc(PATH_MAX + 1); if (!resolved_path) return 0; } #ifdef HAVE_CORESERVICES /* allocate memory for the resolved path(s) */ fspath = (FSRef *)malloc(sizeof(FSRef)); /* attempt to convert the target path into an FSRef */ mac_errno = FSPathMakeRef(path, fspath, 0); if (mac_errno) return 0; /* check if the file is actually an alias */ mac_errno = FSIsAliasFile(fspath, &isalias, &isdir); if (mac_errno) return 0; /* resolve the path completely */ mac_errno = FSResolveAliasFile(fspath, true, &isdir, &isalias); if (mac_errno) return 0; /* obtain the resolved path */ mac_errno = FSRefMakePath(fspath, resolved_path, PATH_MAX); if (mac_errno) return 0; #endif /* return the resolved path upon success */ return resolved_path; }
static OSErr FSOpenDFCompat(FSRef *ref, char permission, short *refNum) { HFSUniStr255 forkName; OSErr theErr; Boolean isFolder, wasChanged; theErr = FSResolveAliasFile(ref, TRUE, &isFolder, &wasChanged); if (theErr != noErr) { return theErr; } FSGetDataForkName(&forkName); #ifdef PLATFORM_64BIT theErr = FSOpenFork(ref, forkName.length, forkName.unicode, permission, (FSIORefNum *)refNum); #else theErr = FSOpenFork(ref, forkName.length, forkName.unicode, permission, refNum); #endif return theErr; }
int wd_apple_resolve_alias(char *dst, char *src, size_t size) { FSRef fsPath; Boolean isDir, isAlias; strlcpy(dst, src, size); if(!wd_chroot) { if(FSPathMakeRef(src, &fsPath, NULL) != 0) return -1; if(FSIsAliasFile(&fsPath, &isAlias, &isDir) != 0) return -1; if(FSResolveAliasFile(&fsPath, true, &isDir, &isAlias) != 0) return -1; if(FSRefMakePath(&fsPath, dst, size) != 0) return -1; } return 1; }
/////////////////////////////////////// // On being passed the path to a MacOS alias, // returns path to the original file to which // it refers. Returns null if file not found. ////////////////////////////////////// static OSErr PrintAliasSource (FSRef *fileRef) { OSErr err = noErr; static char srcPath[2048]; Boolean isAlias, isFolder; FSRef aliasRef; //make sure we're dealing with an alias err = FSIsAliasFile (fileRef, &isAlias, &isFolder); if (err != noErr) { fprintf(stderr, "Error determining alias properties.\n"); return err; } if (!isAlias) { fprintf(stderr, "Argument is not an alias.\n"); return TRUE; } //resolve alias --> get file reference to file err = FSResolveAliasFile (fileRef, TRUE, &isFolder, &isAlias); if (err != noErr) { fprintf(stderr, "Error resolving alias.\n"); return err; } //get path to file that alias points to err = FSMakePath(*fileRef, (char *)&srcPath, strlen(srcPath)); if (err != noErr) { fprintf(stderr, "Error getting path from file reference\n"); return err; } printf("%s\n", &srcPath); }
QString QFSFileEngine::fileName(FileName file) const { Q_D(const QFSFileEngine); if (file == BundleName) { #if !defined(QWS) && defined(Q_OS_MAC) QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath), kCFURLPOSIXPathStyle, true); if(CFDictionaryRef dict = CFBundleCopyInfoDictionaryForURL(url)) { if(CFTypeRef name = (CFTypeRef)CFDictionaryGetValue(dict, kCFBundleNameKey)) { if(CFGetTypeID(name) == CFStringGetTypeID()) return QCFString::toQString((CFStringRef)name); } } #endif return QString(); } else if (file == BaseName) { int slash = d->filePath.lastIndexOf(QLatin1Char('/')); if (slash != -1) return d->filePath.mid(slash + 1); } else if (file == PathName) { int slash = d->filePath.lastIndexOf(QLatin1Char('/')); if (slash == -1) return QLatin1String("."); else if (!slash) return QLatin1String("/"); return d->filePath.left(slash); } else if (file == AbsoluteName || file == AbsolutePathName) { QString ret; if (d->filePath.isEmpty() || !d->filePath.startsWith(QLatin1Char('/'))) ret = QDir::currentPath(); if (!d->filePath.isEmpty() && d->filePath != QLatin1String(".")) { if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) ret += QLatin1Char('/'); ret += d->filePath; } if (ret == QLatin1String("/")) return ret; bool isDir = ret.endsWith(QLatin1Char('/')); ret = QDir::cleanPath(ret); if (isDir) ret += QLatin1String("/"); if (file == AbsolutePathName) { int slash = ret.lastIndexOf(QLatin1Char('/')); if (slash == -1) return QDir::currentPath(); else if (!slash) return QLatin1String("/"); return ret.left(slash); } return ret; } else if (file == CanonicalName || file == CanonicalPathName) { if (!(fileFlags(ExistsFlag) & ExistsFlag)) return QString(); QString ret = QFSFileEnginePrivate::canonicalized(fileName(AbsoluteName)); if (!ret.isEmpty() && file == CanonicalPathName) { int slash = ret.lastIndexOf(QLatin1Char('/')); if (slash == -1) ret = QDir::currentPath(); else if (slash == 0) ret = QLatin1String("/"); ret = ret.left(slash); } return ret; } else if (file == LinkName) { if (d->isSymlink()) { #if defined(__GLIBC__) && !defined(PATH_MAX) #define PATH_CHUNK_SIZE 256 char *s = 0; int len = -1; int size = PATH_CHUNK_SIZE; while (1) { s = (char *) ::realloc(s, size); if (s == 0) { len = -1; break; } len = ::readlink(d->nativeFilePath.constData(), s, size); if (len < 0) { ::free(s); break; } if (len < size) { break; } size *= 2; } #else char s[PATH_MAX+1]; int len = readlink(d->nativeFilePath.constData(), s, PATH_MAX); #endif if (len > 0) { QString ret; if (S_ISDIR(d->st.st_mode) && s[0] != '/') { QDir parent(d->filePath); parent.cdUp(); ret = parent.path(); if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) ret += QLatin1Char('/'); } s[len] = '\0'; ret += QFile::decodeName(QByteArray(s)); #if defined(__GLIBC__) && !defined(PATH_MAX) ::free(s); #endif if (!ret.startsWith(QLatin1Char('/'))) { if (d->filePath.startsWith(QLatin1Char('/'))) { ret.prepend(d->filePath.left(d->filePath.lastIndexOf(QLatin1Char('/'))) + QLatin1Char('/')); } else { ret.prepend(QDir::currentPath() + QLatin1Char('/')); } } ret = QDir::cleanPath(ret); if (ret.size() > 1 && ret.endsWith(QLatin1Char('/'))) ret.chop(1); return ret; } } #if !defined(QWS) && defined(Q_OS_MAC) { FSRef fref; if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->filePath)).data(), &fref, 0) == noErr) { Boolean isAlias, isFolder; if (FSResolveAliasFile(&fref, true, &isFolder, &isAlias) == noErr && isAlias) { AliasHandle alias; if (FSNewAlias(0, &fref, &alias) == noErr && alias) { CFStringRef cfstr; if (FSCopyAliasInfo(alias, 0, 0, &cfstr, 0, 0) == noErr) return QCFString::toQString(cfstr); } } } } #endif return QString(); } return d->filePath; }
static int quicklyMakePath(char *pathString, int pathStringLength,char *dst, Boolean resolveAlias) { CFStringRef filePath; CFURLRef sillyThing,firstPartOfPath; FSRef theFSRef; Boolean isFolder,isAlias; OSErr err; filePath = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)pathString,pathStringLength,gCurrentVMEncoding,false); if (filePath == nil) return -1; CFMutableStringRef str= CFStringCreateMutableCopy(NULL, 0, filePath); // HFS+ imposes Unicode2.1 decomposed UTF-8 encoding on all path elements if (gCurrentVMEncoding == kCFStringEncodingUTF8) CFStringNormalize(str, kCFStringNormalizationFormKC); // canonical decomposition sillyThing = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, str, kCFURLHFSPathStyle,false); if (sillyThing == NULL) { CFRelease(filePath); return -2; } CFRelease(str); if (!CFURLGetFSRef(sillyThing,&theFSRef)) { firstPartOfPath = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault,sillyThing); if (!CFURLGetFSRef(firstPartOfPath,&theFSRef)) { CFRelease(firstPartOfPath); CFRelease(filePath); CFRelease(sillyThing); return -1; } else { CFStringRef lastPathPart; char lastpart[256]; CFRelease(filePath); CFRelease(firstPartOfPath); lastPathPart = CFURLCopyLastPathComponent(sillyThing); CFRelease(sillyThing); err = noErr; if (resolveAlias) err = FSResolveAliasFile (&theFSRef,true,&isFolder,&isAlias); if (err) return 2; err = FSRefMakePath(&theFSRef,(UInt8 *)dst,1000); CFStringGetCString(lastPathPart,lastpart,256, kCFStringEncodingUTF8); CFRelease(lastPathPart); if (strlen(dst)+1+strlen(lastpart) < 1000) { strcat(dst,"/"); strcat(dst,lastpart); #if defined(__MWERKS__) && !defined(__APPLE__) && !defined(__MACH__) filePath = CFStringCreateWithBytes(kCFAllocatorDefault,(UInt8 *)dst,strlen(dst),gCurrentVMEncoding,false); if (filePath == nil) return 2; sillyThing = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,filePath,kCFURLPOSIXPathStyle,true); CFRelease(filePath); filePath = CFURLCopyFileSystemPath (sillyThing, kCFURLHFSPathStyle); CFStringGetCString (filePath,dst,1000, gCurrentVMEncoding); CFRelease(sillyThing); CFRelease(filePath); #endif return 0; } else return 2; } } CFRelease(filePath); CFRelease(sillyThing); if (resolveAlias) err = FSResolveAliasFile (&theFSRef,true,&isFolder,&isAlias); #if defined(__MWERKS__) && !defined(__APPLE__) && !defined(__MACH__) sillyThing = CFURLCreateFromFSRef(kCFAllocatorDefault,&theFSRef); filePath = CFURLCopyFileSystemPath (sillyThing, kCFURLHFSPathStyle); CFStringGetCString (filePath,dst,1000, gCurrentVMEncoding); CFRelease(sillyThing); CFRelease(filePath); return 0; #else err = FSRefMakePath(&theFSRef,(UInt8 *)dst,1000); return err; #endif }
//static QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { #if defined(__GLIBC__) && !defined(PATH_MAX) #define PATH_CHUNK_SIZE 256 char *s = 0; int len = -1; int size = PATH_CHUNK_SIZE; while (1) { s = (char *) ::realloc(s, size); Q_CHECK_PTR(s); len = ::readlink(link.nativeFilePath().constData(), s, size); if (len < 0) { ::free(s); break; } if (len < size) { break; } size *= 2; } #else char s[PATH_MAX+1]; int len = readlink(link.nativeFilePath().constData(), s, PATH_MAX); #endif if (len > 0) { QString ret; if (!data.hasFlags(QFileSystemMetaData::DirectoryType)) fillMetaData(link, data, QFileSystemMetaData::DirectoryType); if (data.isDirectory() && s[0] != '/') { QDir parent(link.filePath()); parent.cdUp(); ret = parent.path(); if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) ret += QLatin1Char('/'); } s[len] = '\0'; ret += QFile::decodeName(QByteArray(s)); #if defined(__GLIBC__) && !defined(PATH_MAX) ::free(s); #endif if (!ret.startsWith(QLatin1Char('/'))) { if (link.filePath().startsWith(QLatin1Char('/'))) { ret.prepend(link.filePath().left(link.filePath().lastIndexOf(QLatin1Char('/'))) + QLatin1Char('/')); } else { ret.prepend(QDir::currentPath() + QLatin1Char('/')); } } ret = QDir::cleanPath(ret); if (ret.size() > 1 && ret.endsWith(QLatin1Char('/'))) ret.chop(1); return QFileSystemEntry(ret); } #if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) { FSRef fref; if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(link.filePath())).data(), &fref, 0) == noErr) { // TODO get the meta data info from the QFileSystemMetaData object Boolean isAlias, isFolder; if (FSResolveAliasFile(&fref, true, &isFolder, &isAlias) == noErr && isAlias) { AliasHandle alias; if (FSNewAlias(0, &fref, &alias) == noErr && alias) { QCFString cfstr; if (FSCopyAliasInfo(alias, 0, 0, &cfstr, 0, 0) == noErr) return QFileSystemEntry(QCFString::toQString(cfstr)); } } } } #endif return QFileSystemEntry(); }
bool wxDirData::Read(wxString *filename) { wxString result; OSStatus err = noErr ; if ( NULL == m_iterator ) { FSRef dirRef; err = wxMacPathToFSRef( m_dirname , &dirRef ) ; if ( err == noErr ) { Boolean isFolder, wasAliased; FSResolveAliasFile( &dirRef, TRUE, &isFolder, &wasAliased ); err = FSOpenIterator(&dirRef, kFSIterateFlat, &m_iterator); } if ( err ) { Close() ; return false ; } } wxString name ; wxString lowerfilespec = m_filespec.Lower(); while( noErr == err ) { HFSUniStr255 uniname ; FSRef fileRef; FSCatalogInfo catalogInfo; ItemCount fetched = 0; err = FSGetCatalogInfoBulk( m_iterator, 1, &fetched, NULL, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo , &catalogInfo , &fileRef, NULL, &uniname ); // expected error codes if ( errFSNoMoreItems == err ) return false ; if ( afpAccessDenied == err ) return false ; if ( noErr != err ) break ; name = wxMacHFSUniStrToString( &uniname ) ; wxString lowername = name.Lower(); if ( ( name == wxT(".") || name == wxT("..") ) && !(m_flags & wxDIR_DOTDOT) ) continue; if ( ( name[0U] == '.' ) && !(m_flags & wxDIR_HIDDEN ) ) continue ; Boolean isFolder, wasAliased; FSResolveAliasFile( &fileRef, TRUE, &isFolder, &wasAliased ); if ( wasAliased ) { FSGetCatalogInfo( &fileRef, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL ); } if ( (((FileInfo*)&catalogInfo.finderInfo)->finderFlags & kIsInvisible ) && !(m_flags & wxDIR_HIDDEN ) ) continue ; // its a dir and we don't want it if ( (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) && !(m_flags & wxDIR_DIRS) ) continue ; // its a file but we don't want it if ( (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) == 0 && !(m_flags & wxDIR_FILES ) ) continue ; if ( m_filespec.empty() || m_filespec == wxT("*.*") || m_filespec == wxT("*") ) { } else if ( !wxMatchWild(lowerfilespec, lowername , false) ) { continue ; } break ; } if ( err != noErr ) { return false ; } *filename = name ; return true; }