in hfs/catalog.c [1021:1114]
HFSCatalogNodeID newFile(const char* pathName, Volume* volume) {
HFSPlusCatalogFolder* parentFolder;
HFSPlusCatalogFile file;
HFSPlusCatalogKey key;
HFSPlusCatalogThread thread;
uint32_t newFileID;
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;
}
newFileID = volume->volumeHeader->nextCatalogID++;
volume->volumeHeader->fileCount++;
file.recordType = kHFSPlusFileRecord;
file.flags = kHFSThreadExistsMask;
file.reserved1 = 0;
file.fileID = newFileID;
file.createDate = UNIX_TO_APPLE_TIME(time(NULL));
file.contentModDate = file.createDate;
file.attributeModDate = file.createDate;
file.accessDate = file.createDate;
file.backupDate = file.createDate;
file.permissions.ownerID = parentFolder->permissions.ownerID;
file.permissions.groupID = parentFolder->permissions.groupID;
file.permissions.adminFlags = 0;
file.permissions.ownerFlags = 0;
file.permissions.fileMode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
file.permissions.special.iNodeNum = 0;
memset(&file.userInfo, 0, sizeof(file.userInfo));
memset(&file.finderInfo, 0, sizeof(file.finderInfo));
file.textEncoding = 0;
file.reserved2 = 0;
memset(&file.dataFork, 0, sizeof(file.dataFork));
memset(&file.resourceFork, 0, sizeof(file.resourceFork));
key.parentID = parentFolder->folderID;
ASCIIToUnicode(name, &key.nodeName);
key.keyLength = sizeof(key.parentID) + STR_SIZE(key.nodeName);
thread.recordType = kHFSPlusFileThreadRecord;
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);
flipCatalogFile(&file);
ASSERT(addToBTree(volume->catalogTree, (BTKey*)(&key), sizeof(HFSPlusCatalogFile), (unsigned char *)(&file)), "addToBTree");
key.nodeName.length = 0;
key.parentID = newFileID;
key.keyLength = sizeof(key.parentID) + sizeof(key.nodeName.length);
ASSERT(addToBTree(volume->catalogTree, (BTKey*)(&key), threadLength, (unsigned char *)(&thread)), "addToBTree");
parentFolder->valence++;
updateCatalog(volume, (HFSPlusCatalogRecord*) parentFolder);
updateVolume(volume);
free(parentFolder);
free(path);
return newFileID;
}