static long ResolvePathToInode( char * filePath, long * flags, InodePtr fileInode, InodePtr dirInode ) { char * restPath; long ret, cnt; // if filePath is empty the we want this directory. if (*filePath == '\0') { bcopy((char *)dirInode, (char *)fileInode, sizeof(Inode)); return 0; } // Copy the file name to gTempName cnt = 0; while ((filePath[cnt] != '/') && (filePath[cnt] != '\0')) cnt++; strlcpy(gTempName, filePath, cnt+1); // Move restPath to the right place. if (filePath[cnt] != '\0') cnt++; restPath = filePath + cnt; // gTempName is a name in the current Dir. // restPath is the rest of the path if any. ret = FindFileInDir(gTempName, flags, fileInode, dirInode); if (ret == -1) return -1; if ((*restPath != '\0') && ((*flags & kFileTypeMask) == kFileTypeDirectory)) ret = ResolvePathToInode(restPath, flags, fileInode, fileInode); return ret; }
long UFSGetDirEntry( CICell ih, char * dirPath, long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid) { long ret, fileInodeNum, dirFlags; Inode tmpInode; if (UFSInitPartition(ih) == -1) return -1; if (infoValid) *infoValid = 0; // Skip a leading '/' if present if (*dirPath == '/') dirPath++; if (*dirPath == '/') dirPath++; ret = ResolvePathToInode(dirPath, &dirFlags, gFileInodePtr, gRootInodePtr); if ((ret == -1) || ((dirFlags & kFileTypeMask) != kFileTypeDirectory)) return -1; ret = ReadDirEntry(gFileInodePtr, &fileInodeNum, dirIndex, name); if (ret != 0) return ret; ReadInode(fileInodeNum, &tmpInode, flags, time); return 0; }
long UFSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock) { long ret, flags; if (UFSInitPartition(ih) == -1) return -1; // Skip one or two leading '/'. if (*filePath == '/') filePath++; if (*filePath == '/') filePath++; ret = ResolvePathToInode(filePath, &flags, gFileInodePtr, gRootInodePtr); if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1; *firstBlock = (gPartitionBase + 1ULL * gFileInodePtr->di_db[0] * gBlockSize) / 512ULL; return 0; }
long Ext2GetDirEntry(CICell ih, char *dirPath, long *dirIndex, char **name, long *flags, long *time) { long ret, fileInodeNum, dirFlags; Inode tmpInode; if (Ext2InitPartition(ih) == -1) return -1; // Skip a leading '\' if present if (dirPath[0] == '\\') dirPath++; ret = ResolvePathToInode(dirPath, &dirFlags, &gFileInode, &gRootInode); if ((ret == -1) || ((dirFlags & kFileTypeMask) != kFileTypeDirectory)) return -1; ret = ReadDirEntry(&gFileInode, &fileInodeNum, dirIndex, name); if (ret != 0) return ret; ReadInode(fileInodeNum, &tmpInode, flags, time); return 0; }
long Ext2LoadFile(CICell ih, char *filePath) { long ret, length, flags; if (Ext2InitPartition(ih) == -1) return -1; printf("Loading Ext2 file: [%s] from %x.\n", filePath, ih); // Skip one or two leading '\'. if (*filePath == '\\') filePath++; if (*filePath == '\\') filePath++; ret = ResolvePathToInode(filePath, &flags, &gFileInode, &gRootInode); if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1; if (flags & (kOwnerNotRoot | kPermGroupWrite | kPermOtherWrite)) return -1; ret = ReadFile(&gFileInode, &length); if (ret != 0) return -1; return length; }
long UFSReadFile( CICell ih, char * filePath, void * base, uint64_t offset, uint64_t length ) { long ret, flags; #if !BOOT1 verbose("Loading UFS file: [%s] from %x.\n", filePath, (unsigned)ih); #endif if (UFSInitPartition(ih) == -1) return -1; // Skip one or two leading '/'. if (*filePath == '/') filePath++; if (*filePath == '/') filePath++; ret = ResolvePathToInode(filePath, &flags, gFileInodePtr, gRootInodePtr); if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1; ret = ReadFile(gFileInodePtr, &length, base, offset); if (ret == -1) return -1; return length; }