sqInt dir_Lookup(char *pathString, sqInt pathStringLength, sqInt index, /* outputs: */ char *name, sqInt *nameLength, sqInt *creationDate, sqInt *modificationDate, sqInt *isDirectory, squeakFileOffsetType *sizeIfFile) #endif { /* Lookup the index-th entry of the directory with the given path, starting at the root of the file system. Set the name, name length, creation date, creation time, directory flag, and file size (if the entry is a file). Return: 0 if a entry is found at the given index 1 if the directory has fewer than index entries 2 if the given path has bad syntax or does not reach a directory */ int i; int nameLen= 0; struct dirent *dirEntry= 0; char unixPath[MAXPATHLEN+1]; struct stat statBuf; /* default return values */ *name = 0; *nameLength = 0; *creationDate = 0; *modificationDate = 0; *isDirectory = false; *sizeIfFile = 0; #if PharoVM *posixPermissions = 0; *isSymlink = false; #endif if ((pathStringLength == 0)) strcpy(unixPath, "."); else if (!sq2uxPath(pathString, pathStringLength, unixPath, MAXPATHLEN, 1)) return BAD_PATH; /* get file or directory info */ if (!maybeOpenDir(unixPath)) return BAD_PATH; if (++lastIndex == index) index= 1; /* fake that the dir is rewound and we want the first entry */ else { rewinddir(openDir); /* really rewind it, and read to the index */ lastIndex= index; } for (i= 0; i < index; i++) { nextEntry: do { errno= 0; dirEntry= readdir(openDir); } while ((dirEntry == 0) && (errno == EINTR)); if (!dirEntry) return NO_MORE_ENTRIES; nameLen= NAMLEN(dirEntry); /* ignore '.' and '..' (these are not *guaranteed* to be first) */ if (nameLen < 3 && dirEntry->d_name[0] == '.') if (nameLen == 1 || dirEntry->d_name[1] == '.') goto nextEntry; } *nameLength= ux2sqPath(dirEntry->d_name, nameLen, name, MAXPATHLEN, 0); { char terminatedName[MAXPATHLEN+1]; if(nameLen > MAXPATHLEN) return BAD_PATH; strncpy(terminatedName, dirEntry->d_name, nameLen); terminatedName[nameLen]= '\0'; if(strlen(unixPath) + 1 + nameLen > MAXPATHLEN) return BAD_PATH; strcat(unixPath, "/"); strcat(unixPath, terminatedName); if (stat(unixPath, &statBuf) && lstat(unixPath, &statBuf)) { /* We can't stat the entry, but failing here would invalidate the whole directory --bertf */ return ENTRY_FOUND; } } /* last change time */ *creationDate= convertToSqueakTime(statBuf.st_ctime); /* modification time */ *modificationDate= convertToSqueakTime(statBuf.st_mtime); if (S_ISDIR(statBuf.st_mode)) *isDirectory= true; else *sizeIfFile= statBuf.st_size; #if PharoVM *isSymlink = S_ISLNK(statBuf.st_mode); *posixPermissions = statBuf.st_mode & 0777; #endif return ENTRY_FOUND; }
sqInt dir_Lookup(char *pathString, sqInt pathStringLength, sqInt index, /* outputs: */ char *name, sqInt *nameLength, sqInt *creationDate, sqInt *modificationDate, sqInt *isDirectory, squeakFileOffsetType *sizeIfFile) { /* Lookup the index-th entry of the directory with the given path, starting at the root of the file system. Set the name, name length, creation date, creation time, directory flag, and file size (if the entry is a file). Return: 0 if a entry is found at the given index 1 if the directory has fewer than index entries 2 if the given path has bad syntax or does not reach a directory */ int i; int nameLen= 0; struct dirent *dirEntry= 0; char unixPath[DOCUMENT_NAME_SIZE+1]; struct stat statBuf; /* default return values */ *name = 0; *nameLength = 0; *creationDate = 0; *modificationDate = 0; *isDirectory = false; *sizeIfFile = 0; if ((pathStringLength == 0)) strcpy(unixPath, "."); else { if (!ioFilenamefromStringofLengthresolveAliasesRetry(unixPath, pathString,pathStringLength, true, true)) return BAD_PATH; } /* get file or directory info */ if (!maybeOpenDir(unixPath)) return BAD_PATH; if (++lastIndex == index) index= 1; /* fake that the dir is rewound and we want the first entry */ else { rewinddir(openDir); /* really rewind it, and read to the index */ lastIndex= index; } for (i= 0; i < index; i++) { nextEntry: do { errno= 0; dirEntry= readdir(openDir); } while ((dirEntry == 0) && (errno == EINTR)); if (!dirEntry) return NO_MORE_ENTRIES; nameLen= NAMLEN(dirEntry); /* ignore '.' and '..' (these are not *guaranteed* to be first) */ if (nameLen < 3 && dirEntry->d_name[0] == '.') if (nameLen == 1 || dirEntry->d_name[1] == '.') goto nextEntry; } *nameLength= ux2sqPath(dirEntry->d_name, nameLen, name, 256, 0); { char terminatedName[DOCUMENT_NAME_SIZE+1]; strncpy(terminatedName, dirEntry->d_name, nameLen); terminatedName[nameLen]= '\0'; strcat(unixPath, "/"); strcat(unixPath, terminatedName); if (stat(unixPath, &statBuf) && lstat(unixPath, &statBuf)) { /* We can't stat the entry, but failing here would invalidate the whole directory --bertf */ return ENTRY_FOUND; } } /* last change time */ *creationDate= convertToSqueakTime(statBuf.st_ctime); /* modification time */ *modificationDate= convertToSqueakTime(statBuf.st_mtime); { FSRef targetFSRef; Boolean targetIsFolder,wasAliased; OSErr err; err = getFSRef(unixPath,&targetFSRef,kCFStringEncodingUTF8); if (!err) { FSResolveAliasFileWithMountFlags(&targetFSRef,true,&targetIsFolder,&wasAliased,kResolveAliasFileNoUI); if (wasAliased && targetIsFolder) { *isDirectory= true; return ENTRY_FOUND; } } } if (S_ISDIR(statBuf.st_mode)) *isDirectory= true; else *sizeIfFile= statBuf.st_size; return ENTRY_FOUND; }