Beginning of refactoring
This commit is contained in:
parent
62a18af402
commit
4e20f39ecd
7
Makefile
7
Makefile
@ -1,5 +1,6 @@
|
|||||||
UNITY = test/unity/
|
UNITYPATH = test/unity/
|
||||||
INC := -I include -I $(UNITY)
|
INC := -I include
|
||||||
|
UNITY := -I $(UNITYPATH)
|
||||||
|
|
||||||
all: compile link
|
all: compile link
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ link:
|
|||||||
test: testCompile testLink testExec
|
test: testCompile testLink testExec
|
||||||
|
|
||||||
testCompile:
|
testCompile:
|
||||||
gcc $(INC) -g -c -o build/unity.o $(UNITY)/unity.c
|
gcc $(INC) $(UNITY) -g -c -o build/unity.o $(UNITYPATH)/unity.c
|
||||||
gcc $(INC) -g -c -o build/stuffy.o src/stuffy.c
|
gcc $(INC) -g -c -o build/stuffy.o src/stuffy.c
|
||||||
gcc $(INC) -g -c -o build/test.o test/test.c
|
gcc $(INC) -g -c -o build/test.o test/test.c
|
||||||
|
|
||||||
|
@ -8,12 +8,22 @@ typedef struct HeaderStruct
|
|||||||
struct stat moduleInfo;
|
struct stat moduleInfo;
|
||||||
} HeaderStruct;
|
} HeaderStruct;
|
||||||
|
|
||||||
|
typedef struct ModuleStruct
|
||||||
|
{
|
||||||
|
HeaderStruct moduleHeader;
|
||||||
|
void* moduleData;
|
||||||
|
} ModuleStruct;
|
||||||
|
|
||||||
|
int ReadSingleModule(int fd, ModuleStruct* module);
|
||||||
|
|
||||||
|
void SafetyCheck(int status, char* message);
|
||||||
|
char* StripFilename(char* filename);
|
||||||
void Stuffy(int argc, char* argv[]);
|
void Stuffy(int argc, char* argv[]);
|
||||||
int StuffyArgument(int argc, char** argv);
|
int StuffyArgument(int argc, char** argv);
|
||||||
void StuffyAction(char* argv[], int archiveAction);
|
void StuffyAction(char* argv[], int archiveAction);
|
||||||
int IsFileArchived(int archiveFile, char* fileName);
|
int IsFileArchived(char* archiveName, char* filename);
|
||||||
void AddToArchive(char* archiveName, char* fileName);
|
void AddToArchive(char* archiveName, char* filename);
|
||||||
void RemoveFromArchive(char* archiveName, char* fileName);
|
void RemoveFromArchive(char* archiveName, char* filename);
|
||||||
void ListArchive(char* archiveName);
|
void ListArchive(char* archiveName);
|
||||||
void ExtractArchive(char* argv[]);
|
void ExtractArchive(char* argv[]);
|
||||||
|
|
||||||
|
169
src/stuffy.c
169
src/stuffy.c
@ -6,22 +6,61 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "stuffy.h"
|
#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(HeaderStruct));
|
||||||
|
moduleSize = (long long) module->moduleHeader.moduleInfo.st_size;
|
||||||
|
module->moduleData = malloc(moduleSize);
|
||||||
|
read(fd, &module->moduleData, moduleSize);
|
||||||
|
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[])
|
void Stuffy(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
// Check for argument
|
|
||||||
int archiveAction = StuffyArgument(argc, argv);
|
int archiveAction = StuffyArgument(argc, argv);
|
||||||
if (archiveAction < 0)
|
if (archiveAction < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: stuffy.out [OPTION] [ARCHIVE] [FILE]");
|
fprintf(stderr, "Usage: stuffy.out [OPTION] [ARCHIVE] [FILE]");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
// Perform action based on argument
|
|
||||||
StuffyAction(argv, archiveAction);
|
StuffyAction(argv, archiveAction);
|
||||||
// Check for redirection
|
|
||||||
// If redirection, then perform redirection
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks for argument, if argument is found then returns argument number.
|
||||||
|
// Returns -1 if not found
|
||||||
int StuffyArgument(int argc, char* argv[])
|
int StuffyArgument(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
@ -38,6 +77,7 @@ int StuffyArgument(int argc, char* argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Redirects program to necessary action function
|
||||||
void StuffyAction(char* argv[], int archiveAction)
|
void StuffyAction(char* argv[], int archiveAction)
|
||||||
{
|
{
|
||||||
if (archiveAction == 0)
|
if (archiveAction == 0)
|
||||||
@ -50,83 +90,102 @@ void StuffyAction(char* argv[], int archiveAction)
|
|||||||
ExtractArchive(argv);
|
ExtractArchive(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
int IsFileArchived(int archiveFile, char* fileName)
|
// Checks if filename is found in a header of archive
|
||||||
|
int IsFileArchived(char* archiveName, char* filename)
|
||||||
{
|
{
|
||||||
ssize_t readSize;
|
ModuleStruct module;
|
||||||
long long int moduleSize;
|
long long int moduleSize;
|
||||||
HeaderStruct moduleHeader;
|
ssize_t readSize;
|
||||||
readSize = read(archiveFile, &moduleHeader, sizeof(HeaderStruct));
|
char* newFilename = StripFilename(filename);
|
||||||
if (!strcmp(moduleHeader.moduleName, fileName))
|
int archiveFile = open(archiveName, O_RDONLY | O_CREAT, 0644);
|
||||||
return 1;
|
SafetyCheck((archiveFile < 0), "Archive failed to open.");
|
||||||
while (readSize > 0)
|
do
|
||||||
{
|
{
|
||||||
moduleSize = (long long) moduleHeader.moduleInfo.st_size;
|
readSize = ReadSingleModule(archiveFile, &(module));
|
||||||
char moduleData[moduleSize];
|
printf("Size of data: %ld", sizeof(module.moduleData));
|
||||||
readSize = read(archiveFile, &moduleData, moduleSize);
|
free(module.moduleData);
|
||||||
readSize = read(archiveFile, &moduleHeader, sizeof(HeaderStruct));
|
printf("%s\n", newFilename);
|
||||||
if (!strcmp(moduleHeader.moduleName, fileName))
|
if (!strcmp(module.moduleHeader.moduleName, filename))
|
||||||
|
{
|
||||||
|
free(newFilename);
|
||||||
|
close(archiveFile);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
} while (readSize > 0);
|
||||||
|
free(newFilename);
|
||||||
|
close(archiveFile);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddToArchive(char* archiveName, char* fileName)
|
// 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);
|
int archiveFile = open(archiveName, O_RDWR | O_CREAT, 0644);
|
||||||
if (archiveFile < 0)
|
SafetyCheck((archiveFile < 0), "Archive failed to open.");
|
||||||
{
|
ssize_t readSize;
|
||||||
fprintf(stderr, "%s failed to open.\n", archiveName);
|
long long int moduleSize;
|
||||||
exit(1);
|
ModuleStruct module;
|
||||||
}
|
readSize = read(archiveFile, &module.moduleHeader, sizeof(module.moduleHeader));
|
||||||
if (IsFileArchived(archiveFile, fileName))
|
do
|
||||||
{
|
readSize = ReadSingleModule(archiveFile, &(module));
|
||||||
fprintf(stderr, "File already exists\n");
|
while (readSize > 0);
|
||||||
exit(1);
|
char* newFilename = StripFilename(filename);
|
||||||
}
|
strcpy(module.moduleHeader.moduleName, newFilename);
|
||||||
HeaderStruct newModuleHeader;
|
stat(filename, &(module.moduleHeader.moduleInfo));
|
||||||
strcpy(newModuleHeader.moduleName, fileName);
|
write(archiveFile, &module.moduleHeader, sizeof(module.moduleHeader));
|
||||||
stat(fileName, &(newModuleHeader.moduleInfo));
|
moduleSize = (long long) module.moduleHeader.moduleInfo.st_size;
|
||||||
write(archiveFile, &newModuleHeader, sizeof(newModuleHeader));
|
char moduleData[moduleSize];
|
||||||
long long int newModuleSize = (long long) newModuleHeader.moduleInfo.st_size;
|
write(archiveFile, moduleData, moduleSize);
|
||||||
char newModuleData[newModuleSize];
|
|
||||||
write(archiveFile, newModuleData, newModuleSize);
|
|
||||||
close(archiveFile);
|
close(archiveFile);
|
||||||
|
free(newFilename);
|
||||||
|
free(module.moduleData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveFromArchive(char* archiveName, char* fileName)
|
// 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)
|
||||||
{
|
{
|
||||||
ssize_t readSize;
|
ssize_t readSize;
|
||||||
|
long long int moduleSize;
|
||||||
|
char* newFileName;
|
||||||
|
strcpy(newFileName, filename);
|
||||||
|
strcat(newFileName, ".tmp");
|
||||||
int archiveFile = open(archiveName, O_RDWR | O_CREAT, 0644);
|
int archiveFile = open(archiveName, O_RDWR | O_CREAT, 0644);
|
||||||
if (archiveFile < 0)
|
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
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s failed to open.\n", archiveName);
|
readSize = ReadSingleModule(archiveFile, &(module));
|
||||||
exit(1);
|
write(newArchiveFile, &module.moduleHeader, sizeof(module.moduleHeader));
|
||||||
}
|
write(newArchiveFile, &module.moduleData, moduleSize);
|
||||||
if (!IsFileArchived(archiveFile, fileName))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "File not found.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
HeaderStruct moduleHeader;
|
|
||||||
readSize = read(archiveFile, &moduleHeader, sizeof(moduleHeader));
|
|
||||||
while (readSize > 0)
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
while (readSize > 0);
|
||||||
|
close(archiveFile);
|
||||||
|
close(newArchiveFile);
|
||||||
|
SafetyCheck(remove(archiveName), "Old archive failed removal.");
|
||||||
|
SafetyCheck(rename(newFileName, archiveName),
|
||||||
|
"New archive failed name change.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// List names and sizes of files stored in archive
|
||||||
|
// Last line prints total size of all files in archive
|
||||||
void ListArchive(char* archiveName)
|
void ListArchive(char* archiveName)
|
||||||
{
|
{
|
||||||
int archiveFile = open(archiveName, O_RDONLY);
|
int archiveFile = open(archiveName, O_RDONLY);
|
||||||
ssize_t readSize;
|
ssize_t readSize;
|
||||||
long long int moduleSize;
|
long long int moduleSize;
|
||||||
if (archiveFile < 0)
|
SafetyCheck((archiveFile < 0), "Archive failed to open.");
|
||||||
{
|
|
||||||
fprintf(stderr, "%s does not exist.\n", archiveName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
HeaderStruct moduleHeader;
|
HeaderStruct moduleHeader;
|
||||||
readSize = read(archiveFile, &moduleHeader, sizeof(moduleHeader));
|
readSize = read(archiveFile, &moduleHeader, sizeof(moduleHeader));
|
||||||
while (readSize > 0)
|
while (readSize > 0)
|
||||||
@ -140,6 +199,8 @@ void ListArchive(char* archiveName)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract data of name file from archive to stdout, which is then redirected
|
||||||
|
// Extracted data remains in archive
|
||||||
void ExtractArchive(char* argv[])
|
void ExtractArchive(char* argv[])
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
|
35
test/test.c
35
test/test.c
@ -1,3 +1,4 @@
|
|||||||
|
#include <unistd.h>
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "stuffy.h"
|
#include "stuffy.h"
|
||||||
|
|
||||||
@ -6,12 +7,12 @@ char* argv[6];
|
|||||||
|
|
||||||
void setUp(void)
|
void setUp(void)
|
||||||
{
|
{
|
||||||
argv[0] = "./stuffy.out";
|
argv[0] = "bin/stuffy.out";
|
||||||
argv[1] = "-a";
|
argv[1] = "-a";
|
||||||
argv[2] = "mystuffyarchive";
|
argv[2] = "test/files/mystuffyarchive.test";
|
||||||
argv[3] = "somefile";
|
argv[3] = "test/files/temp.test";
|
||||||
argv[4] = ">";
|
argv[4] = ">";
|
||||||
argv[5] = "someotherfile";
|
argv[5] = "test/files/output.test";
|
||||||
}
|
}
|
||||||
|
|
||||||
void tearDown(void)
|
void tearDown(void)
|
||||||
@ -32,16 +33,30 @@ void Test_StuffyArgument_Should_ReturnCorrectly(void)
|
|||||||
TEST_ASSERT_EQUAL(-1, StuffyArgument(4, argv));
|
TEST_ASSERT_EQUAL(-1, StuffyArgument(4, argv));
|
||||||
}
|
}
|
||||||
|
|
||||||
// void TestAdditionShouldAddCorrectly(void)
|
void Test_AddToArchive_Should_AddCorrectly(void)
|
||||||
// {
|
{
|
||||||
// TEST_ASSERT_EQUAL(10, addition(5, 5));
|
;
|
||||||
// TEST_ASSERT_EQUAL(15, addition(10, 5));
|
}
|
||||||
// TEST_ASSERT_EQUAL(20, addition(10, 10));
|
|
||||||
// }
|
void Test_RemoveFromArchive_Should_RemoveCorrectly(void)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Test_ListArchive_Should_ListCorrectly(void)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Test_ExtractArchive_Should_ExtractCorrectly(void)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
|
remove("test/files/mystuffyarchive.test");
|
||||||
RUN_TEST(Test_StuffyArgument_Should_ReturnCorrectly);
|
RUN_TEST(Test_StuffyArgument_Should_ReturnCorrectly);
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user