HFSPlusCatalogRecord* getRecordFromPath3(const char* path, Volume* volume, char **name, HFSPlusCatalogKey* retKey, char traverse, char returnLink, HFSCatalogNodeID parentID) { HFSPlusCatalogKey key; HFSPlusCatalogRecord* record; char* origPath; char* myPath; char* word; char* pathLimit; uint32_t realParent; int exact; if(path[0] == '\0' || (path[0] == '/' && path[1] == '\0')) { if(name != NULL) *name = (char*)path; key.keyLength = sizeof(key.parentID) + sizeof(key.nodeName.length); key.parentID = kHFSRootFolderID; key.nodeName.length = 0; record = (HFSPlusCatalogRecord*) search(volume->catalogTree, (BTKey*)(&key), &exact, NULL, NULL); key.parentID = ((HFSPlusCatalogThread*)record)->parentID; key.nodeName = ((HFSPlusCatalogThread*)record)->nodeName; free(record); record = (HFSPlusCatalogRecord*) search(volume->catalogTree, (BTKey*)(&key), &exact, NULL, NULL); return record; } myPath = strdup(path); origPath = myPath; record = NULL; if(path[0] == '/') { key.parentID = kHFSRootFolderID; } else { key.parentID = parentID; } pathLimit = myPath + strlen(myPath); for(word = (char*)strtok(myPath, "/"); word && (word < pathLimit); word = ((word + strlen(word) + 1) < pathLimit) ? (char*)strtok(word + strlen(word) + 1, "/") : NULL) { if(name != NULL) *name = (char*)(path + (word - origPath)); if(record != NULL) { free(record); record = NULL; } if(word[0] == '\0') { continue; } ASCIIToUnicode(word, &key.nodeName); key.keyLength = sizeof(key.parentID) + sizeof(key.nodeName.length) + (sizeof(uint16_t) * key.nodeName.length); record = (HFSPlusCatalogRecord*) search(volume->catalogTree, (BTKey*)(&key), &exact, NULL, NULL); if(record == NULL || exact == FALSE) { free(origPath); if(record != NULL) { free(record); } return NULL; } if(traverse) { if(((word + strlen(word) + 1) < pathLimit) || returnLink) { record = getLinkTarget(record, key.parentID, &key, volume); if(record == NULL || exact == FALSE) { free(origPath); return NULL; } } } if(record->recordType == kHFSPlusFileRecord) { if((word + strlen(word) + 1) >= pathLimit) { free(origPath); if(retKey != NULL) { memcpy(retKey, &key, sizeof(HFSPlusCatalogKey)); } return record; } else { free(origPath); free(record); return NULL; } } if(record->recordType != kHFSPlusFolderRecord) hfs_panic("inconsistent catalog tree!"); realParent = key.parentID; key.parentID = ((HFSPlusCatalogFolder*)record)->folderID; } if(retKey != NULL) { memcpy(retKey, &key, sizeof(HFSPlusCatalogKey)); retKey->parentID = realParent; } free(origPath); return record; }
QString FileSystemActor::getTargetPath() const { return isFileSystemType(Link) ? getLinkTarget() : getFullPath(); }