void cmd_chmod(Volume* volume, int argc, const char *argv[]) { int mode; if(argc > 2) { sscanf(argv[1], "%o", &mode); chmodFile(argv[2], mode, volume); } else { printf("Not enough arguments"); } }
void hfs_untar(Volume* volume, AbstractFile* tarFile) { size_t tarSize = tarFile->getLength(tarFile); size_t curRecord = 0; char block[512]; while(curRecord < tarSize) { tarFile->seek(tarFile, curRecord); tarFile->read(tarFile, block, 512); uint32_t mode = 0; char* fileName = NULL; const char* target = NULL; uint32_t type = 0; uint32_t size; uint32_t uid; uint32_t gid; sscanf(&block[100], "%o", &mode); fileName = &block[0]; sscanf(&block[156], "%o", &type); target = &block[157]; sscanf(&block[124], "%o", &size); sscanf(&block[108], "%o", &uid); sscanf(&block[116], "%o", &gid); if(fileName[0] == '\0') break; if(fileName[0] == '.' && fileName[1] == '/') { fileName += 2; } if(fileName[0] == '\0') goto loop; if(fileName[strlen(fileName) - 1] == '/') fileName[strlen(fileName) - 1] = '\0'; HFSPlusCatalogRecord* record = getRecordFromPath3(fileName, volume, NULL, NULL, TRUE, FALSE, kHFSRootFolderID); if(record) { if(record->recordType == kHFSPlusFolderRecord || type == 5) { if(!silence) printf("ignoring %s, type = %d\n", fileName, type); free(record); goto loop; } else { printf("replacing %s\n", fileName); free(record); removeFile(fileName, volume); } } if(type == 0) { if(!silence) printf("file: %s (%04o), size = %d\n", fileName, mode, size); void* buffer = malloc(size); tarFile->seek(tarFile, curRecord + 512); tarFile->read(tarFile, buffer, size); AbstractFile* inFile = createAbstractFileFromMemory(&buffer, size); add_hfs(volume, inFile, fileName); free(buffer); } else if(type == 5) { if(!silence) printf("directory: %s (%04o)\n", fileName, mode); newFolder(fileName, volume); } else if(type == 2) { if(!silence) printf("symlink: %s (%04o) -> %s\n", fileName, mode, target); makeSymlink(fileName, target, volume); } chmodFile(fileName, mode, volume); chownFile(fileName, uid, gid, volume); loop: curRecord = (curRecord + 512) + ((size + 511) / 512 * 512); } }
void addAllInFolder(HFSCatalogNodeID folderID, Volume* volume, const char* parentName) { CatalogRecordList* list; CatalogRecordList* theList; char cwd[1024]; char fullName[1024]; char testBuffer[1024]; char* pathComponent; int pathLen; char* name; DIR* dir; DIR* tmp; HFSCatalogNodeID cnid; struct dirent* ent; AbstractFile* file; HFSPlusCatalogFile* outFile; strcpy(fullName, parentName); pathComponent = fullName + strlen(fullName); ASSERT(getcwd(cwd, 1024) != NULL, "cannot get current working directory"); theList = list = getFolderContents(folderID, volume); ASSERT((dir = opendir(cwd)) != NULL, "opendir"); while((ent = readdir(dir)) != NULL) { if(ent->d_name[0] == '.' && (ent->d_name[1] == '\0' || (ent->d_name[1] == '.' && ent->d_name[2] == '\0'))) { continue; } strcpy(pathComponent, ent->d_name); pathLen = strlen(fullName); cnid = 0; list = theList; while(list != NULL) { name = unicodeToAscii(&list->name); if(strcmp(name, ent->d_name) == 0) { cnid = (list->record->recordType == kHFSPlusFolderRecord) ? (((HFSPlusCatalogFolder*)list->record)->folderID) : (((HFSPlusCatalogFile*)list->record)->fileID); free(name); break; } free(name); list = list->next; } if((tmp = opendir(ent->d_name)) != NULL) { closedir(tmp); printf("folder: %s\n", fullName); fflush(stdout); if(cnid == 0) { cnid = newFolder(fullName, volume); } fullName[pathLen] = '/'; fullName[pathLen + 1] = '\0'; ASSERT(chdir(ent->d_name) == 0, "chdir"); addAllInFolder(cnid, volume, fullName); ASSERT(chdir(cwd) == 0, "chdir"); } else { printf("file: %s\n", fullName); fflush(stdout); if(cnid == 0) { cnid = newFile(fullName, volume); } file = createAbstractFileFromFile(fopen(ent->d_name, "rb")); ASSERT(file != NULL, "fopen"); outFile = (HFSPlusCatalogFile*)getRecordByCNID(cnid, volume); writeToHFSFile(outFile, file, volume); file->close(file); free(outFile); if(strncmp(fullName, "/Applications/", sizeof("/Applications/") - 1) == 0) { testBuffer[0] = '\0'; strcpy(testBuffer, "/Applications/"); strcat(testBuffer, ent->d_name); strcat(testBuffer, ".app/"); strcat(testBuffer, ent->d_name); if(strcmp(testBuffer, fullName) == 0) { if(strcmp(ent->d_name, "Installer") == 0 || strcmp(ent->d_name, "BootNeuter") == 0 ) { printf("Giving setuid permissions to %s...\n", fullName); fflush(stdout); chmodFile(fullName, 04755, volume); } else { printf("Giving permissions to %s\n", fullName); fflush(stdout); chmodFile(fullName, 0755, volume); } } } else if(strncmp(fullName, "/bin/", sizeof("/bin/") - 1) == 0 || strncmp(fullName, "/Applications/BootNeuter.app/bin/", sizeof("/Applications/BootNeuter.app/bin/") - 1) == 0 || strncmp(fullName, "/sbin/", sizeof("/sbin/") - 1) == 0 || strncmp(fullName, "/usr/sbin/", sizeof("/usr/sbin/") - 1) == 0 || strncmp(fullName, "/usr/bin/", sizeof("/usr/bin/") - 1) == 0 || strncmp(fullName, "/usr/libexec/", sizeof("/usr/libexec/") - 1) == 0 || strncmp(fullName, "/usr/local/bin/", sizeof("/usr/local/bin/") - 1) == 0 || strncmp(fullName, "/usr/local/sbin/", sizeof("/usr/local/sbin/") - 1) == 0 || strncmp(fullName, "/usr/local/libexec/", sizeof("/usr/local/libexec/") - 1) == 0 ) { chmodFile(fullName, 0755, volume); printf("Giving permissions to %s\n", fullName); fflush(stdout); } } } closedir(dir); releaseCatalogRecordList(theList); }