HFSCatalogNodeID newFolder()

in hfs/catalog.c [927:1019]


HFSCatalogNodeID newFolder(const char* pathName, Volume* volume) {
  HFSPlusCatalogFolder* parentFolder;
  HFSPlusCatalogFolder folder;
  HFSPlusCatalogKey key;
  HFSPlusCatalogThread thread;
  
  uint32_t newFolderID;
  
  int threadLength;
  
  char* path;
  char* name;
  char* curChar;
  char* lastSeparator;
  
  path = strdup(pathName);
  
  curChar = path;
  lastSeparator = NULL;
  
  while((*curChar) != '\0') {
    if((*curChar) == '/')
      lastSeparator = curChar;
    curChar++;
  }
  
  if(lastSeparator == NULL) {
    parentFolder = (HFSPlusCatalogFolder*) getRecordFromPath("/", volume, NULL, NULL);
    name = path;
  } else {
    name = lastSeparator + 1;
    *lastSeparator = '\0';
    parentFolder = (HFSPlusCatalogFolder*) getRecordFromPath(path, volume, NULL, NULL);  
  }

  if(parentFolder == NULL || parentFolder->recordType != kHFSPlusFolderRecord) {
    free(path);
    free(parentFolder);
    return FALSE;
  }
  
  newFolderID = volume->volumeHeader->nextCatalogID++;
  volume->volumeHeader->folderCount++;
  
  folder.recordType = kHFSPlusFolderRecord;
  folder.flags = kHFSHasFolderCountMask;
  folder.valence = 0;
  folder.folderID = newFolderID;
  folder.createDate = UNIX_TO_APPLE_TIME(time(NULL));
  folder.contentModDate = folder.createDate;
  folder.attributeModDate = folder.createDate;
  folder.accessDate = folder.createDate;
  folder.backupDate = folder.createDate;
  folder.permissions.ownerID = parentFolder->permissions.ownerID;
  folder.permissions.groupID = parentFolder->permissions.groupID;
  folder.permissions.adminFlags = 0;
  folder.permissions.ownerFlags = 0;
  folder.permissions.fileMode = S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
  folder.permissions.special.iNodeNum = 0;
  memset(&folder.userInfo, 0, sizeof(folder.userInfo));
  memset(&folder.finderInfo, 0, sizeof(folder.finderInfo));
  folder.textEncoding = 0;
  folder.folderCount = 0;
  
  key.parentID = parentFolder->folderID;
  ASCIIToUnicode(name, &key.nodeName);
  key.keyLength = sizeof(key.parentID) + STR_SIZE(key.nodeName);
  
  thread.recordType = kHFSPlusFolderThreadRecord;
  thread.reserved = 0;
  thread.parentID = parentFolder->folderID;
  ASCIIToUnicode(name, &thread.nodeName);
  threadLength = sizeof(thread.recordType) + sizeof(thread.reserved) + sizeof(thread.parentID) + STR_SIZE(thread.nodeName);
  flipCatalogThread(&thread, TRUE);
  flipCatalogFolder(&folder);
  
  ASSERT(addToBTree(volume->catalogTree, (BTKey*)(&key), sizeof(HFSPlusCatalogFolder), (unsigned char *)(&folder)), "addToBTree");
  key.nodeName.length = 0;
  key.parentID = newFolderID;
  key.keyLength = sizeof(key.parentID) + sizeof(key.nodeName.length);
  ASSERT(addToBTree(volume->catalogTree, (BTKey*)(&key), threadLength, (unsigned char *)(&thread)), "addToBTree");
  
  parentFolder->folderCount++;
  parentFolder->valence++;
  updateCatalog(volume, (HFSPlusCatalogRecord*) parentFolder);
  
  updateVolume(volume);
  
  free(parentFolder);
  free(path);
  
  return newFolderID;
}