From 0d1ae015fef8e15442dafa61b9c8d929ce467969 Mon Sep 17 00:00:00 2001 From: Markus Mittendrein Date: Wed, 15 Aug 2018 22:46:40 +0200 Subject: Refactor code into a library and implement basic file management methods --- examples/c4cat.c | 128 +++++++++++++++++++++++++++++++++++++++++++++ examples/c4cat_dyn.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++ examples/c4copy.c | 36 +++++++++++++ examples/c4info.c | 45 ++++++++++++++++ examples/c4ls.c | 87 +++++++++++++++++++++++++++++++ examples/c4mkdir.c | 49 +++++++++++++++++ examples/c4rm.c | 49 +++++++++++++++++ examples/c4touch.c | 61 ++++++++++++++++++++++ examples/unc4group.c | 46 ++++++++++++++++ 9 files changed, 646 insertions(+) create mode 100644 examples/c4cat.c create mode 100644 examples/c4cat_dyn.c create mode 100644 examples/c4copy.c create mode 100644 examples/c4info.c create mode 100644 examples/c4ls.c create mode 100644 examples/c4mkdir.c create mode 100644 examples/c4rm.c create mode 100644 examples/c4touch.c create mode 100644 examples/unc4group.c (limited to 'examples') diff --git a/examples/c4cat.c b/examples/c4cat.c new file mode 100644 index 0000000..04f51b6 --- /dev/null +++ b/examples/c4cat.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cc4group.h" + +bool catNormalFile(const char* const path, const off_t size) +{ + int file = open(path, O_RDONLY); + if(file == -1) + { + fprintf(stderr, "ERROR: Reading \"%s\": %s\n", path, strerror(errno)); + return false; + } + + void* mappedFile = mmap(NULL, size, PROT_READ, MAP_PRIVATE, file, 0); + + if(close(file) == -1) + { + fprintf(stderr, "ERROR: Closing \"%s\": %s\n", path, strerror(errno)); + } + + if(mappedFile == MAP_FAILED) + { + fprintf(stderr, "ERROR: Mapping \"%s\" for reading: %s\n", path, strerror(errno)); + return false; + } + + if(write(STDOUT_FILENO, mappedFile, size) != size) + { + fprintf(stderr, "ERROR: Writing file contents of \"%s\" to stdout: %s\n", path, strerror(errno)); + } + + if(munmap(mappedFile, size) == -1) + { + fprintf(stderr, "ERROR: Unmapping \"%s\": %s\n", path, strerror(errno)); + } + + return true; +} + +bool catFileWithPathsAndSize(const char* const completePath, const char* const groupPath, off_t fileSize) +{ + if(strcmp(groupPath, completePath) == 0) + { + return catNormalFile(completePath, fileSize); + } + + const char* pathInGroup = completePath + strlen(groupPath) + 1; + CC4Group* group = cc4group.new(); + if(!cc4group.openExisting(group, groupPath)) + { + fprintf(stderr, "ERROR: Can not open group file \"%s\": %s\n", groupPath, cc4group.getErrorMessage(group)); + return false; + } + + const void* data; + size_t size; + bool success = cc4group.getEntryData(group, pathInGroup, &data, &size); + + if(success) + { + if(write(STDOUT_FILENO, data, size) != (ssize_t)size) + { + fprintf(stderr, "ERROR: Writing file contents of \"%s\" to stdout: %s\n", completePath, strerror(errno)); + } + } + else + { + fprintf(stderr, "ERROR: Reading \"%s\" from \"%s\": %s\n", pathInGroup, groupPath, strerror(ENOENT)); + } + + cc4group.delete(group); + + return success; +} + +bool catFile(const char* const completePath) +{ + struct stat st; + + char* groupPath = strdup(completePath); + char* slash; + for(slash = groupPath + strlen(groupPath); slash != NULL; slash = strrchr(groupPath, '/')) + { + *slash = '\0'; + if(stat(groupPath, &st) == 0 && !S_ISDIR(st.st_mode)) + { + break; + } + } + + bool success; + if(slash == NULL) + { + fprintf(stderr, "ERROR: Reading \"%s\": %s\n", completePath, strerror(ENOENT)); + success = false; + } + else + { + success = catFileWithPathsAndSize(completePath, groupPath, st.st_size); + } + + free(groupPath); + return success; +} + +int main(int argc, char* argv[]) +{ + if(argc < 2) + { + fprintf(stderr, "USAGE: %s ...\n", argv[0]); + return EXIT_FAILURE; + } + + bool success = true; + for(int i = 1; i < argc; ++i) + { + success &= catFile(argv[i]); + } + + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/c4cat_dyn.c b/examples/c4cat_dyn.c new file mode 100644 index 0000000..92da979 --- /dev/null +++ b/examples/c4cat_dyn.c @@ -0,0 +1,145 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define CC4GROUP_DYNAMIC_LOAD +#include "cc4group.h" +#undef CC4GROUP_DYNAMIC_LOAD + +CC4Group_API* cc4group_dyn; +#define cc4group (*cc4group_dyn) + +bool catNormalFile(const char* const path, const off_t size) +{ + int file = open(path, O_RDONLY); + if(file == -1) + { + fprintf(stderr, "ERROR: Reading \"%s\": %s\n", path, strerror(errno)); + return false; + } + + void* mappedFile = mmap(NULL, size, PROT_READ, MAP_PRIVATE, file, 0); + + if(close(file) == -1) + { + fprintf(stderr, "ERROR: Closing \"%s\": %s\n", path, strerror(errno)); + } + + if(mappedFile == MAP_FAILED) + { + fprintf(stderr, "ERROR: Mapping \"%s\" for reading: %s\n", path, strerror(errno)); + return false; + } + + if(write(STDOUT_FILENO, mappedFile, size) != size) + { + fprintf(stderr, "ERROR: Writing file contents of \"%s\" to stdout: %s\n", path, strerror(errno)); + } + + if(munmap(mappedFile, size) == -1) + { + fprintf(stderr, "ERROR: Unmapping \"%s\": %s\n", path, strerror(errno)); + } + + return true; +} + +bool catFileWithPathsAndSize(const char* const completePath, const char* const groupPath, off_t fileSize) +{ + if(strcmp(groupPath, completePath) == 0) + { + return catNormalFile(completePath, fileSize); + } + + const char* pathInGroup = completePath + strlen(groupPath) + 1; + CC4Group* group = cc4group.new(); + if(!cc4group.openExisting(group, groupPath)) + { + fprintf(stderr, "ERROR: Can not open group file \"%s\": %s\n", groupPath, cc4group.getErrorMessage(group)); + return false; + } + + const void* data; + size_t size; + bool success = cc4group.getEntryData(group, pathInGroup, &data, &size); + + if(success) + { + if(write(STDOUT_FILENO, data, size) != (ssize_t)size) + { + fprintf(stderr, "ERROR: Writing file contents of \"%s\" to stdout: %s\n", completePath, strerror(errno)); + } + } + else + { + fprintf(stderr, "ERROR: Reading \"%s\" from \"%s\": %s\n", pathInGroup, groupPath, strerror(ENOENT)); + } + + cc4group.delete(group); + + return success; +} + +bool catFile(const char* const completePath) +{ + struct stat st; + + char* groupPath = strdup(completePath); + char* slash; + for(slash = groupPath + strlen(groupPath); slash != NULL; slash = strrchr(groupPath, '/')) + { + *slash = '\0'; + if(stat(groupPath, &st) == 0 && !S_ISDIR(st.st_mode)) + { + break; + } + } + + bool success; + if(slash == NULL) + { + fprintf(stderr, "ERROR: Reading \"%s\": %s\n", completePath, strerror(ENOENT)); + success = false; + } + else + { + success = catFileWithPathsAndSize(completePath, groupPath, st.st_size); + } + + free(groupPath); + return success; +} + +int main(int argc, char* argv[]) +{ + void* dl = dlopen("./libcc4group_dyn.so", RTLD_LAZY); + assert(dl); + + dlerror(); + cc4group_dyn = dlsym(dl, "cc4group"); + assert(!dlerror()); + + if(argc < 2) + { + fprintf(stderr, "USAGE: %s ...\n", argv[0]); + return EXIT_FAILURE; + } + + bool success = true; + for(int i = 1; i < argc; ++i) + { + success &= catFile(argv[i]); + } + + dlclose(dl); + + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/c4copy.c b/examples/c4copy.c new file mode 100644 index 0000000..35e201b --- /dev/null +++ b/examples/c4copy.c @@ -0,0 +1,36 @@ +#include +#include + +#include "cc4group.h" + +int main(int argc, char* argv[]) +{ + if(argc != 3) + { + fprintf(stderr, "USAGE: %s \n", argv[0]); + return EXIT_FAILURE; + } + + bool success = true; + + CC4Group* group = cc4group.new(); + if(!cc4group.openExisting(group, argv[1])) + { + fprintf(stderr, "ERROR: Can not open group file \"%s\": %s\n", argv[1], cc4group.getErrorMessage(group)); + + success = false; + } + else + { + success = cc4group.save(group, argv[2]); + + if(!success) + { + fprintf(stderr, "ERROR: Can not save group file to \"%s\": %s\n", argv[2], cc4group.getErrorMessage(group)); + } + } + + cc4group.delete(group); + + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/c4info.c b/examples/c4info.c new file mode 100644 index 0000000..6fa63fe --- /dev/null +++ b/examples/c4info.c @@ -0,0 +1,45 @@ +#include +#include +#include + +#include "cc4group.h" + +const char* formatTime(int32_t time) +{ + time_t tTime = time; + static char ret[128]; + strftime(ret, sizeof(ret), "%c", localtime(&tTime)); + return ret; +} + +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + fprintf(stderr, "USAGE: %s \n", argv[0]); + return EXIT_FAILURE; + } + + CC4Group* group = cc4group.new(); + bool success = cc4group.openExisting(group, argv[1]); + if(!success) + { + fprintf(stderr, "ERROR: Can not open group file \"%s\": %s\n", argv[1], cc4group.getErrorMessage(group)); + } + else + { + CC4Group_EntryInfo info; + cc4group.getEntryInfo(group, "", &info); + + puts(argv[1]); + printf("Created: %s\n", formatTime(info.modified)); + printf("Author: %s\n", info.author); + if(info.official) + { + puts("Official"); + } + } + cc4group.delete(group); + + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/c4ls.c b/examples/c4ls.c new file mode 100644 index 0000000..4324d9b --- /dev/null +++ b/examples/c4ls.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +#include "cc4group.h" + +const char* formatTime(int32_t time) +{ + time_t tTime = time; + static char ret[128]; + strftime(ret, sizeof(ret), "%c", localtime(&tTime)); + return ret; +} + +const char* formatSize(size_t size) +{ + static char ret[128]; + if(size < 1000) + { + snprintf(ret, 128, "%4zd", size); + return ret; + } + + static const char prefixes[] = " KMGTPE"; + + const char* prefix = prefixes; + size_t fract = 0; + + while(size >= 1000 && *(prefix + 1) != '\0') + { + ++prefix; + fract = size % 1000; + size /= 1000; + } + + if(size < 10) + { + snprintf(ret, 128, "%1.1f%c", (float)size + (float)fract / 1000, *prefix); + } + else + { + snprintf(ret, 128, "%3zd%c", size, *prefix); + } + + return ret; +} + +int main(int argc, char* argv[]) +{ + if(argc != 2 && argc != 3) + { + fprintf(stderr, "USAGE: %s [subgroup]\n", argv[0]); + return EXIT_FAILURE; + } + + CC4Group* group = cc4group.new(); + bool success = cc4group.openExisting(group, argv[1]); + if(!success) + { + fprintf(stderr, "ERROR: Can not open group file \"%s\": %s\n", argv[1], cc4group.getErrorMessage(group)); + } + else + { + CC4Group_EntryInfo* infos; + size_t entries; + + success = cc4group.getEntryInfos(group, argc == 3 ? argv[2] : NULL, &infos, &entries); + + if(!success) + { + fprintf(stderr, "ERROR: Can not list group entries: %s\n", cc4group.getErrorMessage(group)); + } + else + { + for(size_t i = 0; i < entries; ++i) + { + printf("%c %s %s %s\t%s\n", infos[i].directory ? 'd' : infos[i].executable ? 'x' : ' ', formatTime(infos[i].modified), formatSize(infos[i].totalSize), infos[i].fileName, infos[i].author); + } + + free(infos); + } + } + cc4group.delete(group); + + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/c4mkdir.c b/examples/c4mkdir.c new file mode 100644 index 0000000..5677125 --- /dev/null +++ b/examples/c4mkdir.c @@ -0,0 +1,49 @@ +#include +#include +#include + +#include "cc4group.h" + +int main(int argc, char* argv[]) +{ + bool recursive = argc == 4 && strcmp(argv[1], "-r") == 0; + + if(argc != 3 && !recursive) + { + fprintf(stderr, "USAGE: %s [-r] \n", argv[0]); + return EXIT_FAILURE; + } + + if(recursive) + { + ++argv; + } + + CC4Group* group = cc4group.new(); + bool success = cc4group.openExisting(group, argv[1]); + if(!success) + { + fprintf(stderr, "ERROR: Can not open group file \"%s\": %s\n", argv[1], cc4group.getErrorMessage(group)); + } + else + { + success = cc4group.deleteEntry(group, argv[2], recursive); + + if(!success) + { + fprintf(stderr, "ERROR: Can not delete group entry \"%s\": %s\n", argv[2], cc4group.getErrorMessage(group)); + } + else + { + success = cc4group.saveOverwrite(group, argv[1]); + + if(!success) + { + fprintf(stderr, "ERROR: Can not save group file \"%s\": %s\n", argv[2], cc4group.getErrorMessage(group)); + } + } + } + cc4group.delete(group); + + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/c4rm.c b/examples/c4rm.c new file mode 100644 index 0000000..5677125 --- /dev/null +++ b/examples/c4rm.c @@ -0,0 +1,49 @@ +#include +#include +#include + +#include "cc4group.h" + +int main(int argc, char* argv[]) +{ + bool recursive = argc == 4 && strcmp(argv[1], "-r") == 0; + + if(argc != 3 && !recursive) + { + fprintf(stderr, "USAGE: %s [-r] \n", argv[0]); + return EXIT_FAILURE; + } + + if(recursive) + { + ++argv; + } + + CC4Group* group = cc4group.new(); + bool success = cc4group.openExisting(group, argv[1]); + if(!success) + { + fprintf(stderr, "ERROR: Can not open group file \"%s\": %s\n", argv[1], cc4group.getErrorMessage(group)); + } + else + { + success = cc4group.deleteEntry(group, argv[2], recursive); + + if(!success) + { + fprintf(stderr, "ERROR: Can not delete group entry \"%s\": %s\n", argv[2], cc4group.getErrorMessage(group)); + } + else + { + success = cc4group.saveOverwrite(group, argv[1]); + + if(!success) + { + fprintf(stderr, "ERROR: Can not save group file \"%s\": %s\n", argv[2], cc4group.getErrorMessage(group)); + } + } + } + cc4group.delete(group); + + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/c4touch.c b/examples/c4touch.c new file mode 100644 index 0000000..5d0000d --- /dev/null +++ b/examples/c4touch.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include + +#include "cc4group.h" + +int main(int argc, char* argv[]) +{ + if(argc != 2 && argc != 3) + { + fprintf(stderr, "USAGE: %s [author]\n", argv[0]); + return EXIT_FAILURE; + } + + CC4Group* group = cc4group.new(); + bool success, exists; + struct stat st; + if(stat(argv[1], &st) == 0) + { + success = cc4group.openExisting(group, argv[1]); + exists = true; + } + else + { + success = cc4group.create(group); + exists = false; + } + if(!success) + { + const char* error = cc4group.getErrorMessage(group); + if(exists) + { + fprintf(stderr, "ERROR: Can not open group file \"%s\": %s\n", argv[1], error); + } + else + { + fprintf(stderr, "ERROR: Can not initialize empty group file: %s\n", error); + } + } + + if(success) + { + cc4group.setCreation(group, time(NULL), NULL, false); + + if(argc == 3) + { + cc4group.setMaker(group, argv[2], NULL, true); + } + + success = (exists ? cc4group.saveOverwrite : cc4group.save)(group, argv[1]); + + if(!success) + { + fprintf(stderr, "ERROR: Can not save group file to \"%s\": %s\n", argv[1], cc4group.getErrorMessage(group)); + } + } + cc4group.delete(group); + + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/unc4group.c b/examples/unc4group.c new file mode 100644 index 0000000..8d08eb3 --- /dev/null +++ b/examples/unc4group.c @@ -0,0 +1,46 @@ +#include +#include + +#include "cc4group.h" + +int main(int argc, char* argv[]) +{ + if(argc != 3 && argc != 4) + { + fprintf(stderr, "USAGE: %s [group entry] \n", argv[0]); + return EXIT_FAILURE; + } + + CC4Group* group = cc4group.new(); + if(!cc4group.openExisting(group, argv[1])) + { + fprintf(stderr, "ERROR: Can not open group file \"%s\": %s\n", argv[1], cc4group.getErrorMessage(group)); + + cc4group.delete(group); + return EXIT_FAILURE; + } + + bool success; + if(argc == 3) + { + success = cc4group.extractAll(group, argv[2]); + } + else if(argc == 4) + { + success = cc4group.extractSingle(group, argv[2], argv[3]); + } + else + { + fprintf(stderr, "ERROR: Can't get here\n"); + success = false; + } + + if(!success) + { + fprintf(stderr, "ERROR: Extracting the desired file/group: %s\n", cc4group.getErrorMessage(group)); + } + + cc4group.delete(group); + + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} -- cgit v1.2.3-54-g00ecf