#include #include #include #include #include #include #include #include #include "abstractfile.h" #include char endianness; void cmd_ls(Volume* volume, int argc, const char *argv[]) { if(argc > 1) hfs_ls(volume, argv[1]); else hfs_ls(volume, "/"); } void cmd_cat(Volume* volume, int argc, const char *argv[]) { HFSPlusCatalogRecord* record; AbstractFile* stdoutFile; record = getRecordFromPath(argv[1], volume, NULL, NULL); stdoutFile = createAbstractFileFromFile(stdout); if(record != NULL) { if(record->recordType == kHFSPlusFileRecord) writeToFile((HFSPlusCatalogFile*)record, stdoutFile, volume); else printf("Not a file\n"); } else { printf("No such file or directory\n"); } free(record); free(stdoutFile); } void cmd_extract(Volume* volume, int argc, const char *argv[]) { HFSPlusCatalogRecord* record; AbstractFile *outFile; if(argc < 3) { printf("Not enough arguments"); return; } outFile = createAbstractFileFromFile(fopen(argv[2], "wb")); if(outFile == NULL) { printf("cannot create file"); } record = getRecordFromPath(argv[1], volume, NULL, NULL); if(record != NULL) { if(record->recordType == kHFSPlusFileRecord) writeToFile((HFSPlusCatalogFile*)record, outFile, volume); else printf("Not a file\n"); } else { printf("No such file or directory\n"); } outFile->close(outFile); free(record); } void cmd_mv(Volume* volume, int argc, const char *argv[]) { if(argc > 2) { move(argv[1], argv[2], volume); } else { printf("Not enough arguments"); } } void cmd_symlink(Volume* volume, int argc, const char *argv[]) { if(argc > 2) { makeSymlink(argv[1], argv[2], volume); } else { printf("Not enough arguments"); } } void cmd_mkdir(Volume* volume, int argc, const char *argv[]) { if(argc > 1) { newFolder(argv[1], volume); } else { printf("Not enough arguments"); } } void cmd_add(Volume* volume, int argc, const char *argv[]) { AbstractFile *inFile; if(argc < 3) { printf("Not enough arguments"); return; } inFile = createAbstractFileFromFile(fopen(argv[1], "rb")); if(inFile == NULL) { printf("file to add not found"); } add_hfs(volume, inFile, argv[2]); } void cmd_rm(Volume* volume, int argc, const char *argv[]) { if(argc > 1) { removeFile(argv[1], volume); } else { printf("Not enough arguments"); } } 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 cmd_extractall(Volume* volume, int argc, const char *argv[]) { HFSPlusCatalogRecord* record; char cwd[1024]; char* name; ASSERT(getcwd(cwd, 1024) != NULL, "cannot get current working directory"); if(argc > 1) record = getRecordFromPath(argv[1], volume, &name, NULL); else record = getRecordFromPath("/", volume, &name, NULL); if(argc > 2) { ASSERT(chdir(argv[2]) == 0, "chdir"); } if(record != NULL) { if(record->recordType == kHFSPlusFolderRecord) extractAllInFolder(((HFSPlusCatalogFolder*)record)->folderID, volume); else printf("Not a folder\n"); } else { printf("No such file or directory\n"); } free(record); ASSERT(chdir(cwd) == 0, "chdir"); } void cmd_rmall(Volume* volume, int argc, const char *argv[]) { HFSPlusCatalogRecord* record; char* name; char initPath[1024]; int lastCharOfPath; if(argc > 1) { record = getRecordFromPath(argv[1], volume, &name, NULL); strcpy(initPath, argv[1]); lastCharOfPath = strlen(argv[1]) - 1; if(argv[1][lastCharOfPath] != '/') { initPath[lastCharOfPath + 1] = '/'; initPath[lastCharOfPath + 2] = '\0'; } } else { record = getRecordFromPath("/", volume, &name, NULL); initPath[0] = '/'; initPath[1] = '\0'; } if(record != NULL) { if(record->recordType == kHFSPlusFolderRecord) { removeAllInFolder(((HFSPlusCatalogFolder*)record)->folderID, volume, initPath); } else { printf("Not a folder\n"); } } else { printf("No such file or directory\n"); } free(record); } void cmd_addall(Volume* volume, int argc, const char *argv[]) { if(argc < 2) { printf("Not enough arguments"); return; } if(argc > 2) { addall_hfs(volume, argv[1], argv[2]); } else { addall_hfs(volume, argv[1], "/"); } } void cmd_grow(Volume* volume, int argc, const char *argv[]) { uint64_t newSize; if(argc < 2) { printf("Not enough arguments\n"); return; } newSize = 0; sscanf(argv[1], "%" PRId64, &newSize); grow_hfs(volume, newSize); printf("grew volume: %" PRId64 "\n", newSize); } void cmd_getattr(Volume* volume, int argc, const char *argv[]) { HFSPlusCatalogRecord* record; if(argc < 3) { printf("Not enough arguments"); return; } record = getRecordFromPath(argv[1], volume, NULL, NULL); if(record != NULL) { HFSCatalogNodeID id; uint8_t* data; size_t size; if(record->recordType == kHFSPlusFileRecord) id = ((HFSPlusCatalogFile*)record)->fileID; else id = ((HFSPlusCatalogFolder*)record)->folderID; size = getAttribute(volume, id, argv[2], &data); if(size > 0) { fwrite(data, size, 1, stdout); free(data); } else { printf("No such attribute\n"); } } else { printf("No such file or directory\n"); } free(record); } void TestByteOrder() { short int word = 0x0001; char *byte = (char *) &word; endianness = byte[0] ? IS_LITTLE_ENDIAN : IS_BIG_ENDIAN; } int main(int argc, const char *argv[]) { io_func* io; Volume* volume; TestByteOrder(); if(argc < 3) { printf("usage: %s \n", argv[0]); return 0; } io = openFlatFile(argv[1]); if(io == NULL) { fprintf(stderr, "error: Cannot open image-file.\n"); return 1; } volume = openVolume(io); if(volume == NULL) { fprintf(stderr, "error: Cannot open volume.\n"); CLOSE(io); return 1; } if(argc > 1) { if(strcmp(argv[2], "ls") == 0) { cmd_ls(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "cat") == 0) { cmd_cat(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "mv") == 0) { cmd_mv(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "symlink") == 0) { cmd_symlink(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "mkdir") == 0) { cmd_mkdir(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "add") == 0) { cmd_add(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "rm") == 0) { cmd_rm(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "chmod") == 0) { cmd_chmod(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "extract") == 0) { cmd_extract(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "extractall") == 0) { cmd_extractall(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "rmall") == 0) { cmd_rmall(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "addall") == 0) { cmd_addall(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "grow") == 0) { cmd_grow(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "getattr") == 0) { cmd_getattr(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "debug") == 0) { if(argc > 3 && strcmp(argv[3], "verbose") == 0) { debugBTree(volume->catalogTree, TRUE); } else { debugBTree(volume->catalogTree, FALSE); } } } closeVolume(volume); CLOSE(io); return 0; }