diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..5a9a397 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "ms-vscode.cpptools" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..bd546be --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "C_Cpp.clang_format_fallbackStyle": "Google", + "files.associations": { + "functional": "c", + "helper.h": "c" + }, + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/Implementierung/.gitignore b/Implementierung/.gitignore new file mode 100644 index 0000000..a811ad3 --- /dev/null +++ b/Implementierung/.gitignore @@ -0,0 +1,5 @@ +Makefile +cmake_install.cmake +CMakeCache.txt +md2 +CMakeFiles \ No newline at end of file diff --git a/Implementierung/CMakeLists.txt b/Implementierung/CMakeLists.txt new file mode 100644 index 0000000..e164800 --- /dev/null +++ b/Implementierung/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.6.0) + +# here we specify that the project is C language only, so the default +# C compiler on the system will be used +project(md2 C) +add_executable(md2 "") + +set(SOURCE_FILES + src/main.c + src/helper.c + src/io.c + src/md2.c +) + +target_sources(md2 PRIVATE ${SOURCE_FILES}) + +target_include_directories(md2 PUBLIC + lib +) \ No newline at end of file diff --git a/Implementierung/Makefile b/Implementierung/Makefile deleted file mode 100644 index d6b448b..0000000 --- a/Implementierung/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -FLAGS=-O3 -std=c11 -g -Wall -Wextra -no-pie - -.PHONY: all - all: main -main: main.c toupper.S - $(CC) $(CFLAGS) -o $@ $^ - -.PHONY: clean - clean: - rm -f main - -.PHONY: run - run: - ./main diff --git a/Implementierung/lib/helper.h b/Implementierung/lib/helper.h new file mode 100644 index 0000000..90ddbc4 --- /dev/null +++ b/Implementierung/lib/helper.h @@ -0,0 +1,34 @@ +#ifndef HELPER_H +#define HELPER_H + +#include +#include +#include +#include +#include + +enum argumentParseResult { + RESULT_OK = 0, + RESULT_EXIT_SUCCESS, + RESULT_EXIT_FAILURE +}; + +struct configuration { + char* filename; + int implementationToUse; + int doBenchmark; + int benchmarkingCycles; +}; + +/** + * @brief parse commandline arguments to config and print errors, if any + * + * @param argc argc + * @param argv argv + * @param c pointer where the configuration should be stored + * @return enum argumentParseResult + */ +enum argumentParseResult parseArguments(int argc, char** argv, + struct configuration* c); + +#endif // HELPER_H \ No newline at end of file diff --git a/Implementierung/lib/io.h b/Implementierung/lib/io.h new file mode 100644 index 0000000..2ed8134 --- /dev/null +++ b/Implementierung/lib/io.h @@ -0,0 +1,19 @@ +#ifndef IO_H +#define IO_H + +#include +#include +#include +#include +#include + +/** + * @brief reads a file at a path + * + * @param path the filepath + * @param size a pointer where the size of the result should be stored + * @return the raw data + */ +static uint8_t* read_file(const char* path, size_t* size); + +#endif // IO_H \ No newline at end of file diff --git a/Implementierung/lib/md2.h b/Implementierung/lib/md2.h new file mode 100644 index 0000000..3880bb7 --- /dev/null +++ b/Implementierung/lib/md2.h @@ -0,0 +1,25 @@ +#ifndef MD2_H +#define MD2_H + +#include +#include + +/** + * @brief Calculates checksum of buf and stores it in out + * + * @param len Length of the data at buf + * @param buf Location of the data + * @param out Destination array of for the checksum + */ +void md2_hash(size_t len, const uint8_t buf[], uint8_t out[16]); + +/** + * @brief Calculates checksum of buf and appends it to buf + * + * @param len Length of data which the checksum should be calculated of + * @param buf Location of the data. Make sure to reserve 16 bytes more so the + * chechsum fits! + */ +void md2_checksum(size_t len, uint8_t* buf); + +#endif // MD2_H \ No newline at end of file diff --git a/Implementierung/main.c b/Implementierung/main.c deleted file mode 100644 index 0eafbf0..0000000 --- a/Implementierung/main.c +++ /dev/null @@ -1,3 +0,0 @@ -int main(int argc, char* argv) { - return 0; -} diff --git a/Implementierung/src/helper.c b/Implementierung/src/helper.c new file mode 100644 index 0000000..fa3043b --- /dev/null +++ b/Implementierung/src/helper.c @@ -0,0 +1,88 @@ +#include "helper.h" + +int stringToInt(char *string) { + char *leftover = ""; + errno = 0; + int x = strtold(string, &leftover); + if (*leftover != '\0' || leftover == string) { + errno = EINVAL; + return -1; + } + if (errno == ERANGE) { + printf("Number is too large or too small!\n"); + errno = EINVAL; + return -1; + } + errno = 0; + return x; +} + +void help(char *progname) { + fprintf( + stderr, + "usage: %s [-V implementation] [-B [repetitons]] [-h] [--help] file\n", + progname); +} + +enum argumentParseResult parseArguments(int argc, char **argv, + struct configuration *c) { + if (c == NULL) { + return RESULT_EXIT_FAILURE; + } + + c->implementationToUse = 0; + c->doBenchmark = 0; + c->benchmarkingCycles = 1; + + int opt; + + while (1) { + static struct option longOptions[] = {{"help", no_argument, NULL, 'h'}, + NULL}; + int longOptionIndex = 0; + + opt = getopt_long(argc, argv, "V:B::h", longOptions, &longOptionIndex); + + if (-1 == opt) break; + + switch (opt) { + case 'B': + c->doBenchmark = 1; + if (optarg != NULL) { + c->benchmarkingCycles = stringToInt(optarg); + if (errno == 0) break; + fprintf(stderr, + "%s: invalid argument, has to be int -- 'B' got '%s'\n", + argv[0], optarg); + help(argv[0]); + return RESULT_EXIT_FAILURE; + } + break; + case 'V': + c->implementationToUse = stringToInt(optarg); + if (errno == 0) break; + fprintf(stderr, "%s: invalid argument, has to be int -- 'V' got '%s'\n", + argv[0], optarg); + help(argv[0]); + return RESULT_EXIT_FAILURE; + + case 'h': + help(argv[0]); + return RESULT_EXIT_SUCCESS; + + default: + help(argv[0]); + return RESULT_EXIT_FAILURE; + } + } + + if (argc > optind) { + c->filename = argv[optind]; + } else { + fprintf(stderr, "%s: missing poisional argument -- 'file'\n", argv[0]); + help(argv[0]); + return RESULT_EXIT_FAILURE; + } + + return RESULT_OK; +} \ No newline at end of file diff --git a/Implementierung/src/io.c b/Implementierung/src/io.c new file mode 100644 index 0000000..ee415ce --- /dev/null +++ b/Implementierung/src/io.c @@ -0,0 +1,42 @@ +#include "io.h" + +static uint8_t* read_file(const char* path, size_t* size) { + // Read the contents of the file specified by path into a heap-allocated + // buffer and return a pointer to that buffer. + FILE* f = fopen(path, "r"); + if (f == NULL) { + printf("Fopen error: %d\n", errno); + fclose(f); + return NULL; + } + + struct stat statOfFile; + int status = fstat(fileno(f), &statOfFile); + if (status == -1) { + printf("Fstat error: %d\n", errno); + fclose(f); + return NULL; + }; + + if ((statOfFile.st_mode & S_IFMT) != S_IFREG) { + printf("File is not a regular file!\n"); + fclose(f); + return NULL; + } + + uint8_t* data = malloc(statOfFile.st_size); + + size_t bytesRead = + fread(data, statOfFile.st_blksize, statOfFile.st_blocks, f); + // Or: size_t bytesRead = fread(data, sizeof(char), statOfFile.st_size, f); + if (bytesRead != 0 && !feof(f)) { + printf("Error reading file!\n"); + fclose(f); + return NULL; + } + + fclose(f); + + (*size) = bytesRead; + return data; +} \ No newline at end of file diff --git a/Implementierung/src/main.c b/Implementierung/src/main.c new file mode 100644 index 0000000..db1527a --- /dev/null +++ b/Implementierung/src/main.c @@ -0,0 +1,24 @@ +#include "helper.h" +#include "io.h" +#include "md2.h" + +int main(int argc, char** argv) { + struct configuration c; + enum argumentParseResult result = parseArguments(argc, argv, &c); + + switch (result) { + case RESULT_EXIT_SUCCESS: + return EXIT_SUCCESS; + case RESULT_EXIT_FAILURE: + return EXIT_FAILURE; + default: + break; + } + + printf( + "Hashing file: %s\nUsing implementation: %d, doing benchmark: %d, " + "benchmark cycles: %d\n", + c.filename, c.implementationToUse, c.doBenchmark, c.benchmarkingCycles); + + return 0; +} diff --git a/Implementierung/src/md2.c b/Implementierung/src/md2.c new file mode 100644 index 0000000..1f30e8d --- /dev/null +++ b/Implementierung/src/md2.c @@ -0,0 +1,8 @@ +#include "io.h" + +// The file "testfile" should lead to this hash: +// fc982e558db259f298b43cd4c1241c66 + +void md2_checksum(size_t len, uint8_t* buf) {} + +void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) {} \ No newline at end of file diff --git a/Implementierung/testfile b/Implementierung/testfile new file mode 100644 index 0000000..d72e1a3 Binary files /dev/null and b/Implementierung/testfile differ diff --git a/README.md b/README.md index ee36483..f69843e 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,8 @@ Beachten Sie, dass die äußere Form und die Einhaltung der Formalitäten wichti - `Implementierung/`: Ihre Implementierung - `Implementierung/Makefile`: Makefile für Ihre Implementierung, welches durch einen Aufruf von `make` Ihre Implementierung kompiliert - `Vortrag/Vortrag.pdf`: Folien für Ihre Abschlusspräsentation + +# Kompilieren + +- CMake ausführen: `cmake .` +- Make ausführen: `make` \ No newline at end of file