/* * Add support for resolving Mac native alias files (not the same as unix alias files) * (what are "unix alias files"?) * returns 0 on success. */ int macxp_resolveAlias(char *path, int buflen) { #if HAVE_FEATURE_MACOSX_SANDBOX /* Avoid unnecessary messages in the system.log: * * soffice(57342) deny file-read-data /Users/tml/Documents/b.odt/..namedfork/rsrc * etc. * * Just don't bother with resolving aliases. I doubt its usefulness anyway. */ (void) path; (void) buflen; return 0; #else #if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 FSRef aFSRef; OSStatus nErr; Boolean bFolder; Boolean bAliased; #else CFStringRef cfpath; CFURLRef cfurl; CFErrorRef cferror; CFDataRef cfbookmark; #endif char *unprocessedPath = path; if ( *unprocessedPath == '/' ) unprocessedPath++; int nRet = 0; while ( !nRet && unprocessedPath && *unprocessedPath ) { unprocessedPath = strchr( unprocessedPath, '/' ); if ( unprocessedPath ) *unprocessedPath = '\0'; #if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 nErr = noErr; bFolder = FALSE; bAliased = FALSE; if ( FSPathMakeRef( (const UInt8 *)path, &aFSRef, 0 ) == noErr ) { nErr = FSResolveAliasFileWithMountFlags( &aFSRef, TRUE, &bFolder, &bAliased, kResolveAliasFileNoUI ); if ( nErr == nsvErr ) { errno = ENOENT; nRet = -1; } else if ( nErr == noErr && bAliased ) { char tmpPath[ PATH_MAX ]; if ( FSRefMakePath( &aFSRef, (UInt8 *)tmpPath, PATH_MAX ) == noErr ) { int nLen = strlen( tmpPath ) + ( unprocessedPath ? strlen( unprocessedPath + 1 ) + 1 : 0 ); if ( nLen < buflen && nLen < PATH_MAX ) { if ( unprocessedPath ) { int nTmpPathLen = strlen( tmpPath ); strcat( tmpPath, "/" ); strcat( tmpPath, unprocessedPath + 1 ); strcpy( path, tmpPath); unprocessedPath = path + nTmpPathLen; } else if ( !unprocessedPath ) { strcpy( path, tmpPath); } } else { errno = ENAMETOOLONG; nRet = -1; } } } } #else cfpath = CFStringCreateWithCString( NULL, path, kCFStringEncodingUTF8 ); cfurl = CFURLCreateWithFileSystemPath( NULL, cfpath, kCFURLPOSIXPathStyle, false ); CFRelease( cfpath ); cferror = NULL; cfbookmark = CFURLCreateBookmarkDataFromFile( NULL, cfurl, &cferror ); CFRelease( cfurl ); if ( cfbookmark == NULL ) { if(cferror) { CFRelease( cferror ); } } else { Boolean isStale; cfurl = CFURLCreateByResolvingBookmarkData( NULL, cfbookmark, kCFBookmarkResolutionWithoutUIMask, NULL, NULL, &isStale, &cferror ); CFRelease( cfbookmark ); if ( cfurl == NULL ) { CFRelease( cferror ); } else { cfpath = CFURLCopyFileSystemPath( cfurl, kCFURLPOSIXPathStyle ); CFRelease( cfurl ); if ( cfpath != NULL ) { char tmpPath[ PATH_MAX ]; if ( CFStringGetCString( cfpath, tmpPath, PATH_MAX, kCFStringEncodingUTF8 ) ) { int nLen = strlen( tmpPath ) + ( unprocessedPath ? strlen( unprocessedPath + 1 ) + 1 : 0 ); if ( nLen < buflen && nLen < PATH_MAX ) { if ( unprocessedPath ) { int nTmpPathLen = strlen( tmpPath ); strcat( tmpPath, "/" ); strcat( tmpPath, unprocessedPath + 1 ); strcpy( path, tmpPath); unprocessedPath = path + nTmpPathLen; } else if ( !unprocessedPath ) { strcpy( path, tmpPath ); } } else { errno = ENAMETOOLONG; nRet = -1; } } CFRelease( cfpath ); } } } #endif if ( unprocessedPath ) *unprocessedPath++ = '/'; } return nRet; #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(Q_OS_DARWIN) { QCFString path = CFStringCreateWithFileSystemRepresentation(0, QFile::encodeName(QDir::cleanPath(link.filePath())).data()); if (!path) return QFileSystemEntry(); QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, path, kCFURLPOSIXPathStyle, data.hasFlags(QFileSystemMetaData::DirectoryType)); if (!url) return QFileSystemEntry(); QCFType<CFDataRef> bookmarkData = CFURLCreateBookmarkDataFromFile(0, url, NULL); if (!bookmarkData) return QFileSystemEntry(); QCFType<CFURLRef> resolvedUrl = CFURLCreateByResolvingBookmarkData(0, bookmarkData, (CFURLBookmarkResolutionOptions)(kCFBookmarkResolutionWithoutUIMask | kCFBookmarkResolutionWithoutMountingMask), NULL, NULL, NULL, NULL); if (!resolvedUrl) return QFileSystemEntry(); QCFString cfstr(CFURLCopyFileSystemPath(resolvedUrl, kCFURLPOSIXPathStyle)); if (!cfstr) return QFileSystemEntry(); return QFileSystemEntry(QCFString::toQString(cfstr)); } #endif return QFileSystemEntry(); }