/* Lately, dirSpec appears to be (rightfully) unused. */ __private_extern__ CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType) { CFMutableArrayRef files = NULL; Boolean releaseBase = false; CFIndex pathLength = dirPath ? strlen(dirPath) : 0; // MF:!!! Need to use four-letter type codes where appropriate. CFStringRef extension = (matchingAbstractType ? _CFCopyExtensionForAbstractType(matchingAbstractType) : NULL); CFIndex targetExtLen = (extension ? CFStringGetLength(extension) : 0); #if DEPLOYMENT_TARGET_WINDOWS // This is a replacement for 'dirent' below, and also uses wchar_t to support unicode paths wchar_t extBuff[CFMaxPathSize]; int extBuffInteriorDotCount = 0; //people insist on using extensions like ".trace.plist", so we need to know how many dots back to look :( if (targetExtLen > 0) { CFIndex usedBytes = 0; CFStringGetBytes(extension, CFRangeMake(0, targetExtLen), kCFStringEncodingUTF16, 0, false, (uint8_t *)extBuff, CFMaxPathLength, &usedBytes); targetExtLen = usedBytes / sizeof(wchar_t); extBuff[targetExtLen] = '\0'; wchar_t *extBuffStr = (wchar_t *)extBuff; if (extBuffStr[0] == '.') extBuffStr++; //skip the first dot, it's legitimate to have ".plist" for example wchar_t *extBuffDotPtr = extBuffStr; while ((extBuffDotPtr = wcschr(extBuffStr, '.'))) { //find the next . in the extension... extBuffInteriorDotCount++; extBuffStr = extBuffDotPtr + 1; } } wchar_t pathBuf[CFMaxPathSize]; if (!dirPath) { if (!_CFURLGetWideFileSystemRepresentation(dirURL, true, pathBuf, CFMaxPathLength)) { if (extension) CFRelease(extension); return NULL; } pathLength = wcslen(pathBuf); } else { // Convert dirPath to a wide representation and put it into our pathBuf // Get the real length of the string in UTF16 characters CFStringRef dirPathStr = CFStringCreateWithCString(kCFAllocatorSystemDefault, dirPath, kCFStringEncodingUTF8); CFIndex strLen = CFStringGetLength(dirPathStr); // Copy the string into the buffer and terminate CFStringGetCharacters(dirPathStr, CFRangeMake(0, strLen), (UniChar *)pathBuf); pathBuf[strLen] = 0; CFRelease(dirPathStr); } WIN32_FIND_DATAW file; HANDLE handle; if (pathLength + 2 >= CFMaxPathLength) { if (extension) { CFRelease(extension); } return NULL; } pathBuf[pathLength] = '\\'; pathBuf[pathLength + 1] = '*'; pathBuf[pathLength + 2] = '\0'; handle = FindFirstFileW(pathBuf, (LPWIN32_FIND_DATAW)&file); if (INVALID_HANDLE_VALUE == handle) { pathBuf[pathLength] = '\0'; if (extension) { CFRelease(extension); } return NULL; } files = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks); do { CFURLRef fileURL; CFIndex namelen = wcslen(file.cFileName); if (file.cFileName[0] == '.' && (namelen == 1 || (namelen == 2 && file.cFileName[1] == '.'))) { continue; } if (targetExtLen > namelen) continue; // if the extension is the same length or longer than the name, it can't possibly match. if (targetExtLen > 0) { if (file.cFileName[namelen - 1] == '.') continue; //filename ends with a dot, no extension wchar_t *fileExt = NULL; if (extBuffInteriorDotCount == 0) { fileExt = wcsrchr(file.cFileName, '.'); } else { //find the Nth occurrence of . from the end of the string, to handle ".foo.bar" wchar_t *save = file.cFileName; while ((save = wcschr(save, '.')) && !fileExt) { wchar_t *temp = save; int moreDots = 0; while ((temp = wcschr(temp, '.'))) { if (++moreDots == extBuffInteriorDotCount) break; } if (moreDots == extBuffInteriorDotCount) { fileExt = save; } } } if (!fileExt) continue; //no extension if (((const wchar_t *)extBuff)[0] != '.') fileExt++; //omit the dot if the target file extension omits the dot CFIndex fileExtLen = wcslen(fileExt); //if the extensions are different lengths, they can't possibly match if (fileExtLen != targetExtLen) continue; // Check to see if it matches the extension we're looking for. if (_wcsicmp(fileExt, (const wchar_t *)extBuff) != 0) { continue; } } if (dirURL == NULL) { CFStringRef dirURLStr = CFStringCreateWithBytes(alloc, (const uint8_t *)pathBuf, pathLength * sizeof(wchar_t), kCFStringEncodingUTF16, NO); dirURL = CFURLCreateWithFileSystemPath(alloc, dirURLStr, kCFURLWindowsPathStyle, true); CFRelease(dirURLStr); releaseBase = true; } // MF:!!! What about the trailing slash? CFStringRef fileURLStr = CFStringCreateWithBytes(alloc, (const uint8_t *)file.cFileName, namelen * sizeof(wchar_t), kCFStringEncodingUTF16, NO); fileURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, fileURLStr, kCFURLWindowsPathStyle, (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false, dirURL); CFArrayAppendValue(files, fileURL); CFRelease(fileURL); CFRelease(fileURLStr); } while (FindNextFileW(handle, &file)); FindClose(handle); pathBuf[pathLength] = '\0'; #elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD uint8_t extBuff[CFMaxPathSize]; int extBuffInteriorDotCount = 0; //people insist on using extensions like ".trace.plist", so we need to know how many dots back to look :( if (targetExtLen > 0) { CFStringGetBytes(extension, CFRangeMake(0, targetExtLen), CFStringFileSystemEncoding(), 0, false, extBuff, CFMaxPathLength, &targetExtLen); extBuff[targetExtLen] = '\0'; char *extBuffStr = (char *)extBuff; if (extBuffStr[0] == '.') extBuffStr++; //skip the first dot, it's legitimate to have ".plist" for example char *extBuffDotPtr = extBuffStr; while ((extBuffDotPtr = strchr(extBuffStr, '.'))) { //find the next . in the extension... extBuffInteriorDotCount++; extBuffStr = extBuffDotPtr + 1; } } uint8_t pathBuf[CFMaxPathSize]; if (!dirPath) { if (!CFURLGetFileSystemRepresentation(dirURL, true, pathBuf, CFMaxPathLength)) { if (extension) CFRelease(extension); return NULL; } else { dirPath = (char *)pathBuf; pathLength = strlen(dirPath); } } struct dirent buffer; struct dirent *dp; int err; int no_hang_fd = __CFProphylacticAutofsAccess ? open("/dev/autofs_nowait", 0) : -1; DIR *dirp = opendir(dirPath); if (!dirp) { if (extension) { CFRelease(extension); } if (-1 != no_hang_fd) close(no_hang_fd); return NULL; // raiseErrno("opendir", path); } files = CFArrayCreateMutable(alloc, 0, & kCFTypeArrayCallBacks); while((0 == readdir_r(dirp, &buffer, &dp)) && dp) { CFURLRef fileURL; unsigned namelen = strlen(dp->d_name); // skip . & ..; they cause descenders to go berserk if (dp->d_name[0] == '.' && (namelen == 1 || (namelen == 2 && dp->d_name[1] == '.'))) { continue; } if (targetExtLen > namelen) continue; // if the extension is the same length or longer than the name, it can't possibly match. if (targetExtLen > 0) { if (dp->d_name[namelen - 1] == '.') continue; //filename ends with a dot, no extension char *fileExt = NULL; if (extBuffInteriorDotCount == 0) { fileExt = strrchr(dp->d_name, '.'); } else { //find the Nth occurrence of . from the end of the string, to handle ".foo.bar" char *save = dp->d_name; while ((save = strchr(save, '.')) && !fileExt) { char *temp = save; int moreDots = 0; while ((temp = strchr(temp, '.'))) { if (++moreDots == extBuffInteriorDotCount) break; } if (moreDots == extBuffInteriorDotCount) { fileExt = save; } } } if (!fileExt) continue; //no extension if (((char *)extBuff)[0] != '.') fileExt++; //omit the dot if the target extension omits the dot; safe, because we checked to make sure it isn't the last character just before size_t fileExtLen = strlen(fileExt); //if the extensions are different lengths, they can't possibly match if (fileExtLen != targetExtLen) continue; // Check to see if it matches the extension we're looking for. if (strncmp(fileExt, (char *)extBuff, fileExtLen) != 0) { continue; } } if (dirURL == NULL) { dirURL = CFURLCreateFromFileSystemRepresentation(alloc, (uint8_t *)dirPath, pathLength, true); releaseBase = true; } if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN || dp->d_type == DT_LNK || dp->d_type == DT_WHT) { Boolean isDir = (dp->d_type == DT_DIR); if (!isDir) { // Ugh; must stat. char subdirPath[CFMaxPathLength]; struct statinfo statBuf; strlcpy(subdirPath, dirPath, sizeof(subdirPath)); strlcat(subdirPath, "/", sizeof(subdirPath)); strlcat(subdirPath, dp->d_name, sizeof(subdirPath)); if (stat(subdirPath, &statBuf) == 0) { isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR); } } #if DEPLOYMENT_TARGET_LINUX fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, (uint8_t *)dp->d_name, namelen, isDir, dirURL); #else fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, (uint8_t *)dp->d_name, dp->d_namlen, isDir, dirURL); #endif } else { #if DEPLOYMENT_TARGET_LINUX fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc, (uint8_t *)dp->d_name, namelen, false, dirURL); #else fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc, (uint8_t *)dp->d_name, dp->d_namlen, false, dirURL); #endif } CFArrayAppendValue(files, fileURL); CFRelease(fileURL); } err = closedir(dirp); if (-1 != no_hang_fd) close(no_hang_fd); if (err != 0) { CFRelease(files); if (releaseBase) { CFRelease(dirURL); } if (extension) { CFRelease(extension); } return NULL; } #else #error _CFContentsOfDirectory() unknown architecture, not implemented #endif if (extension) { CFRelease(extension); } if (releaseBase) { CFRelease(dirURL); } return files; }
/* On Mac OS 8/9, one of dirSpec and dirURL must be non-NULL. On all other platforms, one of path and dirURL must be non-NULL If both are present, they are assumed to be in-synch; that is, they both refer to the same directory. */ __private_extern__ CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType) { CFMutableArrayRef files = NULL; Boolean releaseBase = false; CFIndex pathLength = dirPath ? strlen(dirPath) : 0; // MF:!!! Need to use four-letter type codes where appropriate. CFStringRef extension = (matchingAbstractType ? _CFCopyExtensionForAbstractType(matchingAbstractType) : NULL); CFIndex extLen = (extension ? CFStringGetLength(extension) : 0); uint8_t extBuff[CFMaxPathSize]; #if defined(__WIN32__) /* Windows Variables */ /* The Win32 code has not been updated for: path has been renamed dirPath base has been renamed dirURL dirPath may be NULL (in which case dirURL is not) if dirPath is NULL, pathLength is 0 */ WIN32_FIND_DATA file; HANDLE handle; #elif defined(__svr4__) || defined(__hpux__) || defined(__LINUX__) || defined(__FREEBSD__) /* Solaris and HPUX Variables */ /* The Solaris and HPUX code has not been updated for: base has been renamed dirURL dirPath may be NULL (in which case dirURL is not) if dirPath is NULL, pathLength is 0 */ DIR *dirp; struct dirent *dp; int err; #elif defined(__MACH__) /* Mac OS X Variables */ int fd, numread; long basep; char dirge[8192]; uint8_t pathBuf[CFMaxPathSize]; #endif if (extLen > 0) { CFStringGetBytes(extension, CFRangeMake(0, extLen), CFStringFileSystemEncoding(), 0, false, extBuff, CFMaxPathSize, &extLen); extBuff[extLen] = '\0'; } #if defined(__WIN32__) /* Windows Implementation */ if (pathLength + 2 >= CFMaxPathLength) { if (extension) { CFRelease(extension); } return NULL; } if (NULL != dirPath) { dirPath[pathLength] = '\''; dirPath[pathLength + 1] = '*'; dirPath[pathLength + 2] = '\0'; handle = FindFirstFileA(dirPath, &file); if (INVALID_HANDLE_VALUE == handle) { dirPath[pathLength] = '\0'; if (extension) { CFRelease(extension); } return NULL; } } else { pathLength = 0; } files = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks); do { CFURLRef fileURL; CFIndex namelen = strlen(file.cFileName); if (file.cFileName[0] == '.' && (namelen == 1 || (namelen == 2 && file.cFileName[1] == '.'))) { continue; } if (extLen > 0) { // Check to see if it matches the extension we're looking for. if (_stricmp(&(file.cFileName[namelen - extLen]), extBuff) != 0) { continue; } } if (dirURL == NULL) { dirURL = CFURLCreateFromFileSystemRepresentation(alloc, dirPath, pathLength, true); releaseBase = true; } // MF:!!! What about the trailing slash? fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, file.cFileName, namelen, false, dirURL); CFArrayAppendValue(files, fileURL); CFRelease(fileURL); } while (FindNextFileA(handle, &file)); FindClose(handle); dirPath[pathLength] = '\0'; #elif defined(__svr4__) || defined(__hpux__) || defined(__LINUX__) || defined(__FREEBSD__) /* Solaris and HPUX Implementation */ dirp = opendir(dirPath); if (!dirp) { if (extension) { CFRelease(extension); } return NULL; // raiseErrno("opendir", path); } files = CFArrayCreateMutable(alloc, 0, & kCFTypeArrayCallBacks); while((dp = readdir(dirp)) != NULL) { CFURLRef fileURL; unsigned namelen = strlen(dp->d_name); // skip . & ..; they cause descenders to go berserk if (dp->d_name[0] == '.' && (namelen == 1 || (namelen == 2 && dp->d_name[1] == '.'))) { continue; } if (extLen > 0) { // Check to see if it matches the extension we're looking for. if (strncmp(&(dp->d_name[namelen - extLen]), extBuff, extLen) != 0) { continue; } } if (dirURL == NULL) { dirURL = CFURLCreateFromFileSystemRepresentation(alloc, dirPath, pathLength, true); releaseBase = true; } // MF:!!! What about the trailing slash? fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, dp->d_name, namelen, false, dirURL); CFArrayAppendValue(files, fileURL); CFRelease(fileURL); } err = closedir(dirp); if (err != 0) { CFRelease(files); if (releaseBase) { CFRelease(dirURL); } if (extension) { CFRelease(extension); } return NULL; // raiseErrno("closedir", path); } #elif defined(__MACH__) /* Mac OS X Variables - repeated for convenience */ // int fd, numread; // long basep; // char dirge[8192]; // UInt8 pathBuf[CFMaxPathSize]; /* Mac OS X Implementation */ if (!dirPath) { if (!CFURLGetFileSystemRepresentation(dirURL, true, pathBuf, CFMaxPathLength)) { if (extension) CFRelease(extension); return NULL; } else { dirPath = pathBuf; pathLength = strlen(dirPath); } } fd = open(dirPath, O_RDONLY, 0777); if (fd < 0) { if (extension) { CFRelease(extension); } return NULL; } files = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks); while ((numread = getdirentries(fd, dirge, sizeof(dirge), &basep)) > 0) { struct dirent *dent; for (dent = (struct dirent *)dirge; dent < (struct dirent *)(dirge + numread); dent = (struct dirent *)((char *)dent + dent->d_reclen)) { CFURLRef fileURL; CFIndex nameLen; nameLen = dent->d_namlen; // skip . & ..; they cause descenders to go berserk if (0 == dent->d_fileno || (dent->d_name[0] == '.' && (nameLen == 1 || (nameLen == 2 && dent->d_name[1] == '.')))) { continue; } if (extLen > 0) { // Check to see if it matches the extension we're looking for. if (strncmp(&(dent->d_name[nameLen - extLen]), extBuff, extLen) != 0) { continue; } } if (dirURL == NULL) { dirURL = CFURLCreateFromFileSystemRepresentation(alloc, dirPath, pathLength, true); releaseBase = true; } if (dent->d_type == DT_DIR || dent->d_type == DT_UNKNOWN) { Boolean isDir = (dent->d_type == DT_DIR); if (!isDir) { // Ugh; must stat. char subdirPath[CFMaxPathLength]; struct stat statBuf; strncpy(subdirPath, dirPath, pathLength); subdirPath[pathLength] = '/'; strncpy(subdirPath + pathLength + 1, dent->d_name, nameLen); subdirPath[pathLength + nameLen + 1] = '\0'; if (stat(subdirPath, &statBuf) == 0) { isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR); } } fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, dent->d_name, nameLen, isDir, dirURL); } else { fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc, dent->d_name, nameLen, false, dirURL); } CFArrayAppendValue(files, fileURL); CFRelease(fileURL); } } close(fd); if (-1 == numread) { CFRelease(files); if (releaseBase) { CFRelease(dirURL); } if (extension) { CFRelease(extension); } return NULL; } #else #error _CFContentsOfDirectory() unknown architechture, not implemented #endif if (extension) { CFRelease(extension); } if (releaseBase) { CFRelease(dirURL); } return files; }
static void __DAFileSystemListRefresh( const char * directory ) { CFURLRef base; base = CFURLCreateFromFileSystemRepresentation( kCFAllocatorDefault, ( void * ) directory, strlen( directory ), TRUE ); if ( base ) { DIR * folder; /* * Scan the filesystems in the file system folder. */ folder = opendir( directory ); if ( folder ) { struct dirent * item; DALogDebugHeader( "filesystems have been refreshed." ); while ( ( item = readdir( folder ) ) ) { char * suffix; suffix = item->d_name + strlen( item->d_name ) - strlen( FS_DIR_SUFFIX ); if ( suffix > item->d_name ) { if ( strcmp( suffix, FS_DIR_SUFFIX ) == 0 ) { CFURLRef path; path = CFURLCreateFromFileSystemRepresentationRelativeToBase( kCFAllocatorDefault, ( void * ) item->d_name, strlen( item->d_name ), TRUE, base ); if ( path ) { DAFileSystemRef filesystem; /* * Create a file system object for this file system. */ filesystem = DAFileSystemCreate( kCFAllocatorDefault, path ); if ( filesystem ) { CFDictionaryRef probe; /* * Add this file system object to our list. */ DALogDebug( " created filesystem, id = %@.", filesystem ); CFArrayAppendValue( gDAFileSystemList, filesystem ); probe = DAFileSystemGetProbeList( filesystem ); if ( probe ) { CFDictionaryApplyFunction( probe, __DAFileSystemProbeListAppendValue, filesystem ); } CFRelease( filesystem ); } CFRelease( path ); } } } } closedir( folder ); } CFRelease( base ); } }
NS_IMETHODIMP nsCommandLine::ResolveFile(const nsAString& aArgument, nsIFile* *aResult) { NS_ENSURE_TRUE(mWorkingDir, NS_ERROR_NOT_INITIALIZED); // This is some seriously screwed-up code. nsIFile.appendRelativeNativePath // explicitly does not accept .. or . path parts, but that is exactly what we // need here. So we hack around it. nsresult rv; #if defined(MOZ_WIDGET_COCOA) nsCOMPtr<nsILocalFileMac> lfm (do_QueryInterface(mWorkingDir)); NS_ENSURE_TRUE(lfm, NS_ERROR_NO_INTERFACE); nsCOMPtr<nsILocalFileMac> newfile (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); NS_ENSURE_TRUE(newfile, NS_ERROR_OUT_OF_MEMORY); CFURLRef baseurl; rv = lfm->GetCFURL(&baseurl); NS_ENSURE_SUCCESS(rv, rv); nsAutoCString path; NS_CopyUnicodeToNative(aArgument, path); CFURLRef newurl = CFURLCreateFromFileSystemRepresentationRelativeToBase(nullptr, (const UInt8*) path.get(), path.Length(), true, baseurl); CFRelease(baseurl); rv = newfile->InitWithCFURL(newurl); CFRelease(newurl); if (NS_FAILED(rv)) return rv; newfile.forget(aResult); return NS_OK; #elif defined(XP_UNIX) nsCOMPtr<nsIFile> lf (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); NS_ENSURE_TRUE(lf, NS_ERROR_OUT_OF_MEMORY); if (aArgument.First() == '/') { // absolute path rv = lf->InitWithPath(aArgument); if (NS_FAILED(rv)) return rv; NS_ADDREF(*aResult = lf); return NS_OK; } nsAutoCString nativeArg; NS_CopyUnicodeToNative(aArgument, nativeArg); nsAutoCString newpath; mWorkingDir->GetNativePath(newpath); newpath.Append('/'); newpath.Append(nativeArg); rv = lf->InitWithNativePath(newpath); if (NS_FAILED(rv)) return rv; rv = lf->Normalize(); if (NS_FAILED(rv)) return rv; lf.forget(aResult); return NS_OK; #elif defined(XP_WIN32) nsCOMPtr<nsIFile> lf (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); NS_ENSURE_TRUE(lf, NS_ERROR_OUT_OF_MEMORY); rv = lf->InitWithPath(aArgument); if (NS_FAILED(rv)) { // If it's a relative path, the Init is *going* to fail. We use string magic and // win32 _fullpath. Note that paths of the form "\Relative\To\CurDrive" are // going to fail, and I haven't figured out a way to work around this without // the PathCombine() function, which is not available in plain win95/nt4 nsAutoString fullPath; mWorkingDir->GetPath(fullPath); fullPath.Append('\\'); fullPath.Append(aArgument); WCHAR pathBuf[MAX_PATH]; if (!_wfullpath(pathBuf, fullPath.get(), MAX_PATH)) return NS_ERROR_FAILURE; rv = lf->InitWithPath(nsDependentString(pathBuf)); if (NS_FAILED(rv)) return rv; } lf.forget(aResult); return NS_OK; #else #error Need platform-specific logic here. #endif }
/* Lately, dirSpec appears to be (rightfully) unused. */ __private_extern__ CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType) { CFMutableArrayRef files = NULL; Boolean releaseBase = false; CFIndex pathLength = dirPath ? (CFIndex)strlen(dirPath) : 0; // MF:!!! Need to use four-letter type codes where appropriate. CFStringRef extension = (matchingAbstractType ? _CFCopyExtensionForAbstractType(matchingAbstractType) : NULL); CFIndex extLen = (extension ? CFStringGetLength(extension) : 0); uint8_t extBuff[CFMaxPathSize]; if (extLen > 0) { CFStringGetBytes(extension, CFRangeMake(0, extLen), CFStringFileSystemEncoding(), 0, false, extBuff, CFMaxPathLength, &extLen); extBuff[extLen] = '\0'; } uint8_t pathBuf[CFMaxPathSize]; if (!dirPath) { if (!CFURLGetFileSystemRepresentation(dirURL, true, pathBuf, CFMaxPathLength)) { if (extension) CFRelease(extension); return NULL; } else { dirPath = (char *)pathBuf; pathLength = (CFIndex)strlen(dirPath); } } #if (DEPLOYMENT_TARGET_MACOSX) || defined(__svr4__) || defined(__hpux__) || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD struct dirent buffer; struct dirent *dp; int err; int no_hang_fd = open("/dev/autofs_nowait", 0); DIR *dirp = opendir(dirPath); if (!dirp) { if (extension) { CFRelease(extension); } close(no_hang_fd); return NULL; // raiseErrno("opendir", path); } files = CFArrayCreateMutable(alloc, 0, & kCFTypeArrayCallBacks); while((0 == readdir_r(dirp, &buffer, &dp)) && dp) { CFURLRef fileURL; unsigned namelen = strlen(dp->d_name); // skip . & ..; they cause descenders to go berserk if (dp->d_name[0] == '.' && (namelen == 1 || (namelen == 2 && dp->d_name[1] == '.'))) { continue; } if (extLen > namelen) continue; // if the extension is the same length or longer than the name, it can't possibly match. if (extLen > 0) { // Check to see if it matches the extension we're looking for. if (strncmp(&(dp->d_name[namelen - extLen]), (char *)extBuff, extLen) != 0) { continue; } } if (dirURL == NULL) { dirURL = CFURLCreateFromFileSystemRepresentation(alloc, (uint8_t *)dirPath, pathLength, true); releaseBase = true; } if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) { Boolean isDir = (dp->d_type == DT_DIR); if (!isDir) { // Ugh; must stat. char subdirPath[CFMaxPathLength]; struct stat statBuf; strlcpy(subdirPath, dirPath, sizeof(subdirPath)); strlcat(subdirPath, "/", sizeof(subdirPath)); strlcat(subdirPath, dp->d_name, sizeof(subdirPath)); if (stat(subdirPath, &statBuf) == 0) { isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR); } } fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, (uint8_t *)dp->d_name, namelen, isDir, dirURL); } else { fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc, (uint8_t *)dp->d_name, namelen, false, dirURL); } CFArrayAppendValue(files, fileURL); CFRelease(fileURL); } err = closedir(dirp); close(no_hang_fd); if (err != 0) { CFRelease(files); if (releaseBase) { CFRelease(dirURL); } if (extension) { CFRelease(extension); } return NULL; } #elif DEPLOYMENT_TARGET_WINDOWS WIN32_FIND_DATAA file; HANDLE handle; if (pathLength + 2 >= CFMaxPathLength) { if (extension) { CFRelease(extension); } return NULL; } if (NULL != dirPath) { dirPath[pathLength] = '\''; dirPath[pathLength + 1] = '*'; dirPath[pathLength + 2] = '\0'; handle = FindFirstFileA(dirPath, &file); if (INVALID_HANDLE_VALUE == handle) { dirPath[pathLength] = '\0'; if (extension) { CFRelease(extension); } return NULL; } } else { pathLength = 0; } files = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks); do { CFURLRef fileURL; CFIndex namelen = (CFIndex)strlen(file.cFileName); if (file.cFileName[0] == '.' && (namelen == 1 || (namelen == 2 && file.cFileName[1] == '.'))) { continue; } if (extLen > 0) { // Check to see if it matches the extension we're looking for. if (_stricmp((char*)&(file.cFileName[namelen - extLen]), (char*)extBuff) != 0) { continue; } } if (dirURL == NULL) { dirURL = CFURLCreateFromFileSystemRepresentation(alloc, (UInt8*)dirPath, pathLength, true); releaseBase = true; } // MF:!!! What about the trailing slash? fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, (UInt8*)file.cFileName, namelen, false, dirURL); CFArrayAppendValue(files, fileURL); CFRelease(fileURL); } while (FindNextFileA(handle, &file)); FindClose(handle); dirPath[pathLength] = '\0'; #else #error _CFContentsOfDirectory() unknown architechture, not implemented #endif if (extension) { CFRelease(extension); } if (releaseBase) { CFRelease(dirURL); } return files; }
// Note: as of November 2006, the matchingAbstractType isn't used at this function's only call site static CFMutableArrayRef _IOContentsOfDirectory(CFAllocatorRef alloc, char path[CFMaxPathLength], CFURLRef base, CFStringRef matchingAbstractType) { CFMutableArrayRef files; Boolean releaseBase = FALSE; CFIndex pathLength = strlen(path); // MF:!!! Need to use four-letter type codes where appropriate. CFStringRef extension = (matchingAbstractType ? CFRetain(matchingAbstractType) : NULL); CFIndex extLen = (extension ? CFStringGetLength(extension) : 0); char extBuff[CFMaxPathSize]; int fd, numread; long basep; char dirge[8192]; if (extLen > 0) { // not sure what extension might contain ... currently unused CFStringGetBytes(extension, CFRangeMake(0, extLen), kCFStringEncodingMacRoman, 0, FALSE, extBuff, CFMaxPathSize, &extLen); extBuff[extLen] = '\0'; // CFStringGetBytes set extLen to number of bytes in converted string } fd = open(path, O_RDONLY, 0777); if (fd < 0) { if (extension) { CFRelease(extension); } return NULL; } files = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks); while ((numread = getdirentries(fd, dirge, sizeof(dirge), &basep)) > 0) { struct dirent *dent; for (dent = (struct dirent *)dirge; dent < (struct dirent *)(dirge + numread); dent = (struct dirent *)((char *)dent + dent->d_reclen)) { CFURLRef fileURL; CFIndex nameLen; nameLen = dent->d_namlen; // skip . & ..; they cause descenders to go berserk if (0 == dent->d_ino /*d_fileno*/ || (dent->d_name[0] == '.' && (nameLen == 1 || (nameLen == 2 && dent->d_name[1] == '.')))) { continue; } if (extLen > 0) { // Check to see if it matches the extension we're looking for. if (strncmp(&(dent->d_name[nameLen - extLen]), extBuff, extLen) != 0) { continue; } } if (base == NULL) { base = CFURLCreateFromFileSystemRepresentation(alloc, path, pathLength, TRUE); releaseBase = TRUE; } if (dent->d_type == DT_DIR || dent->d_type == DT_UNKNOWN) { Boolean isDir = (dent->d_type == DT_DIR); if (!isDir) { // Ugh; must stat. char subdirPath[CFMaxPathLength]; struct stat statBuf; strncpy(subdirPath, path, pathLength); subdirPath[pathLength] = '/'; strncpy(subdirPath + pathLength + 1, dent->d_name, nameLen); subdirPath[pathLength + nameLen + 1] = '\0'; if (stat(subdirPath, &statBuf) == 0) { isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR); } } fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, dent->d_name, nameLen, isDir, base); } else { fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc, dent->d_name, nameLen, FALSE, base); } CFArrayAppendValue(files, fileURL); CFRelease(fileURL); } } close(fd); if (-1 == numread) { CFRelease(files); if (releaseBase) { CFRelease(base); } if (extension) { CFRelease(extension); } return NULL; } if (extension) { CFRelease(extension); } if (releaseBase) { CFRelease(base); } return files; }