예제 #1
0
파일: catalog.c 프로젝트: mucit/opensn0w
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;
}
예제 #2
0
QString FileSystemActor::getTargetPath() const
{
	return isFileSystemType(Link) ? getLinkTarget() : getFullPath();
}