#include #include #include #include #include #include #include "stuffy.h" // Put a module header into a HeaderStruct and read (skip) module data // Returns size of data read when reading a module header int ReadSingleModule(int fd, ModuleStruct* module) { int readSize; long long int moduleSize; readSize = read(fd, &(module->moduleHeader), sizeof(module->moduleHeader)); moduleSize = (long long) module->moduleHeader.moduleInfo.st_size; module->moduleData = malloc(moduleSize); readSize = read(fd, module->moduleData, moduleSize); return readSize; } // Put a module header into a HeaderStruct and read (skip) module data // Returns size of data read when reading a module header int WriteSingleModule(int fd, ModuleStruct* module, char* filename) { int readSize; long long int moduleSize; readSize = read(fd, &(module->moduleHeader), sizeof(module->moduleHeader)); moduleSize = (long long) module->moduleHeader.moduleInfo.st_size; module->moduleData = malloc(moduleSize); readSize = read(fd, module->moduleData, moduleSize); // strcpy(module.moduleHeader.moduleName, newFilename); // stat(filename, &(module.moduleHeader.moduleInfo)); // write(archiveFile, &module.moduleHeader, sizeof(module.moduleHeader)); // moduleSize = (long long) module.moduleHeader.moduleInfo.st_size; // char moduleData[moduleSize]; // write(archiveFile, moduleData, moduleSize); // close(archiveFile); return readSize; } // Checks if operation went ok, if not then prints message and exits void SafetyCheck(int status, char* message) { if (status) { fprintf(stderr, "%s\n", message); exit(1); } return; } // Strip path from filename for adding to archive char* StripFilename(char* filename) { int nameStartPosition = -1; for (int i = 0; i < strlen(filename); i++) if (filename[i] == '/') nameStartPosition = i+1; if (nameStartPosition == -1) nameStartPosition = 0; int copySize = strlen(filename) - nameStartPosition; char* newFilename = malloc(copySize + 1); strncpy(newFilename, &filename[nameStartPosition], copySize); strcat(newFilename, "\0"); return newFilename; } // Overhead function for archive operations void Stuffy(int argc, char* argv[]) { int archiveAction = StuffyArgument(argc, argv); if (archiveAction < 0) { fprintf(stderr, "Usage: stuffy.out [OPTION] [ARCHIVE] [FILE]"); exit(1); } StuffyAction(argv, archiveAction); return; } // Checks for argument, if argument is found then returns argument number. // Returns -1 if not found int StuffyArgument(int argc, char* argv[]) { for (int i = 1; i < argc; i++) { if ((argv[i][0] == '-') && (argv[i][1] == 'a')) return 0; if ((argv[i][0] == '-') && (argv[i][1] == 'r')) return 1; if ((argv[i][0] == '-') && (argv[i][1] == 'l')) return 2; if ((argv[i][0] == '-') && (argv[i][1] == 'e')) return 3; } return -1; } // Redirects program to necessary action function void StuffyAction(char* argv[], int archiveAction) { if (archiveAction == 0) AddToArchive(argv[2], argv[3]); if (archiveAction == 1) RemoveFromArchive(argv[2], argv[3]); if (archiveAction == 2) ListArchive(argv[2]); if (archiveAction == 3) ExtractArchive(argv); } // Checks if filename is found in a header of archive int IsFileArchived(char* archiveName, char* filename) { ModuleStruct module; long long int moduleSize; ssize_t readSize; char* newFilename = StripFilename(filename); int archiveFile = open(archiveName, O_RDONLY | O_CREAT, 0644); SafetyCheck((archiveFile < 0), "Archive failed to open."); do { readSize = ReadSingleModule(archiveFile, &(module)); free(module.moduleData); module.moduleData = NULL; printf("%s\n", newFilename); if (!strcmp(module.moduleHeader.moduleName, filename)) { free(newFilename); close(archiveFile); return 1; } } while (readSize > 0); free(newFilename); close(archiveFile); return 0; } // Check through archive for file, if in archive then inform user // Adds file to archive and can be repeatedly used to add more to the archive // If file is already in archive, then exit, let user know, and suggest removing // file already inside the archive void AddToArchive(char* archiveName, char* filename) { // SafetyCheck(IsFileArchived(archiveName, filename), // "File already exists in archive, try removing file first."); int archiveFile = open(archiveName, O_RDWR | O_CREAT, 0644); SafetyCheck((archiveFile < 0), "Archive failed to open."); ssize_t readSize; // long long int moduleSize; ModuleStruct module; // readSize = read(archiveFile, &module.moduleHeader, sizeof(module.moduleHeader)); do readSize = ReadSingleModule(archiveFile, &(module)); while (readSize > 0); char* newFilename = StripFilename(filename); WriteSingleModule(archiveFile, &module, newFilename); free(newFilename); free(module.moduleData); // return; } // Check through archive for file, if file exists with name, remove it // If file not in archive, print "somefile was not found." void RemoveFromArchive(char* archiveName, char* filename) { printf("'RemoveFromArchive()' function is still broken.\n"); return; ssize_t readSize; long long int moduleSize; char* newFileName; strcpy(newFileName, filename); strcat(newFileName, ".tmp"); int archiveFile = open(archiveName, O_RDWR | O_CREAT, 0644); SafetyCheck((archiveFile < 0), "Archive failed to open."); SafetyCheck(IsFileArchived(archiveName, filename), strcat("Failed to find ", newFileName)); ModuleStruct module; int newArchiveFile = open(newFileName, O_WRONLY | O_CREAT, 0644); SafetyCheck((newArchiveFile < 0), "New archive failed to open."); do { readSize = ReadSingleModule(archiveFile, &(module)); write(newArchiveFile, &module.moduleHeader, sizeof(module.moduleHeader)); write(newArchiveFile, &module.moduleData, moduleSize); } while (readSize > 0); close(archiveFile); close(newArchiveFile); SafetyCheck(remove(archiveName), "Old archive failed removal."); SafetyCheck(rename(newFileName, archiveName), "New archive failed name change."); return; } // List names and sizes of files stored in archive // Last line prints total size of all files in archive void ListArchive(char* archiveName) { int archiveFile = open(archiveName, O_RDONLY); ssize_t readSize; long long int moduleSize; SafetyCheck((archiveFile < 0), "Archive failed to open."); // ModuleStruct module; // do // { // readSize = ReadSingleModule(archiveFile, &module); // printf("Name: %s | Size: %lld\n", module.moduleHeader.moduleName, moduleSize); // } // while (readSize > 0); HeaderStruct moduleHeader; readSize = read(archiveFile, &moduleHeader, sizeof(moduleHeader)); while (readSize > 0) { moduleSize = (long long) moduleHeader.moduleInfo.st_size; printf("Name: %s | Size: %lld\n", moduleHeader.moduleName, moduleSize); char moduleData[moduleSize]; read(archiveFile, &moduleData, moduleSize); readSize = read(archiveFile, &moduleHeader, sizeof(moduleHeader)); } return; } // Extract data of name file from archive to stdout, which is then redirected // Extracted data remains in archive void ExtractArchive(char* argv[]) { printf("'ExtractArchive()' function is still broken.\n"); return; }