stuffy/src/stuffy.c

237 lines
7.7 KiB
C
Raw Normal View History

2022-11-08 20:37:57 -06:00
#include <fcntl.h>
2022-11-02 15:29:00 -05:00
#include <stdio.h>
#include <stdlib.h>
2022-11-08 20:37:57 -06:00
#include <string.h>
2022-11-02 15:29:00 -05:00
#include <unistd.h>
2022-11-08 20:37:57 -06:00
#include <sys/types.h>
2022-11-02 15:29:00 -05:00
#include "stuffy.h"
2022-11-10 18:30:35 -06:00
// 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));
2022-11-10 18:30:35 -06:00
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);
2022-11-10 18:30:35 -06:00
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
2022-11-02 15:29:00 -05:00
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;
}
2022-11-10 18:30:35 -06:00
// Checks for argument, if argument is found then returns argument number.
// Returns -1 if not found
2022-11-02 15:29:00 -05:00
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;
}
2022-11-10 18:30:35 -06:00
// Redirects program to necessary action function
2022-11-02 15:29:00 -05:00
void StuffyAction(char* argv[], int archiveAction)
{
2022-11-08 20:37:57 -06:00
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);
}
2022-11-10 18:30:35 -06:00
// Checks if filename is found in a header of archive
int IsFileArchived(char* archiveName, char* filename)
2022-11-08 20:37:57 -06:00
{
2022-11-10 18:30:35 -06:00
ModuleStruct module;
2022-11-08 20:37:57 -06:00
long long int moduleSize;
2022-11-10 18:30:35 -06:00
ssize_t readSize;
char* newFilename = StripFilename(filename);
int archiveFile = open(archiveName, O_RDONLY | O_CREAT, 0644);
SafetyCheck((archiveFile < 0), "Archive failed to open.");
do
2022-11-08 20:37:57 -06:00
{
2022-11-10 18:30:35 -06:00
readSize = ReadSingleModule(archiveFile, &(module));
free(module.moduleData);
module.moduleData = NULL;
2022-11-10 18:30:35 -06:00
printf("%s\n", newFilename);
if (!strcmp(module.moduleHeader.moduleName, filename))
{
free(newFilename);
close(archiveFile);
2022-11-08 20:37:57 -06:00
return 1;
2022-11-10 18:30:35 -06:00
}
} while (readSize > 0);
free(newFilename);
close(archiveFile);
2022-11-08 20:37:57 -06:00
return 0;
2022-11-02 15:29:00 -05:00
}
2022-11-10 18:30:35 -06:00
// 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)
2022-11-02 15:29:00 -05:00
{
// SafetyCheck(IsFileArchived(archiveName, filename),
// "File already exists in archive, try removing file first.");
2022-11-08 20:37:57 -06:00
int archiveFile = open(archiveName, O_RDWR | O_CREAT, 0644);
2022-11-10 18:30:35 -06:00
SafetyCheck((archiveFile < 0), "Archive failed to open.");
ssize_t readSize;
// long long int moduleSize;
2022-11-10 18:30:35 -06:00
ModuleStruct module;
// readSize = read(archiveFile, &module.moduleHeader, sizeof(module.moduleHeader));
2022-11-10 18:30:35 -06:00
do
readSize = ReadSingleModule(archiveFile, &(module));
while (readSize > 0);
char* newFilename = StripFilename(filename);
WriteSingleModule(archiveFile, &module, newFilename);
2022-11-10 18:30:35 -06:00
free(newFilename);
free(module.moduleData);
// return;
2022-11-02 15:29:00 -05:00
}
2022-11-10 18:30:35 -06:00
// 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)
2022-11-02 15:29:00 -05:00
{
printf("'RemoveFromArchive()' function is still broken.\n");
return;
ssize_t readSize;
2022-11-10 18:30:35 -06:00
long long int moduleSize;
char* newFileName;
strcpy(newFileName, filename);
strcat(newFileName, ".tmp");
int archiveFile = open(archiveName, O_RDWR | O_CREAT, 0644);
2022-11-10 18:30:35 -06:00
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
{
2022-11-10 18:30:35 -06:00
readSize = ReadSingleModule(archiveFile, &(module));
write(newArchiveFile, &module.moduleHeader, sizeof(module.moduleHeader));
write(newArchiveFile, &module.moduleData, moduleSize);
}
2022-11-10 18:30:35 -06:00
while (readSize > 0);
close(archiveFile);
close(newArchiveFile);
SafetyCheck(remove(archiveName), "Old archive failed removal.");
SafetyCheck(rename(newFileName, archiveName),
"New archive failed name change.");
return;
2022-11-02 15:29:00 -05:00
}
2022-11-10 18:30:35 -06:00
// List names and sizes of files stored in archive
// Last line prints total size of all files in archive
2022-11-02 15:29:00 -05:00
void ListArchive(char* archiveName)
{
2022-11-08 20:37:57 -06:00
int archiveFile = open(archiveName, O_RDONLY);
ssize_t readSize;
long long int moduleSize;
2022-11-10 18:30:35 -06:00
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);
2022-11-08 20:37:57 -06:00
HeaderStruct moduleHeader;
readSize = read(archiveFile, &moduleHeader, sizeof(moduleHeader));
2022-11-08 20:37:57 -06:00
while (readSize > 0)
{
moduleSize = (long long) moduleHeader.moduleInfo.st_size;
printf("Name: %s | Size: %lld\n", moduleHeader.moduleName, moduleSize);
2022-11-08 20:37:57 -06:00
char moduleData[moduleSize];
read(archiveFile, &moduleData, moduleSize);
readSize = read(archiveFile, &moduleHeader, sizeof(moduleHeader));
2022-11-08 20:37:57 -06:00
}
return;
2022-11-02 15:29:00 -05:00
}
2022-11-10 18:30:35 -06:00
// Extract data of name file from archive to stdout, which is then redirected
// Extracted data remains in archive
2022-11-08 20:37:57 -06:00
void ExtractArchive(char* argv[])
2022-11-02 15:29:00 -05:00
{
printf("'ExtractArchive()' function is still broken.\n");
return;
2022-11-02 15:29:00 -05:00
}