From 948a65cf39c8ce31c5adc0f24979e0cb55bc33c3 Mon Sep 17 00:00:00 2001 From: Jan Sucan Date: Sat, 18 Jun 2022 08:50:45 +0200 Subject: Refactor the command line interface Select operation by its name instead of by number of the arguments. --- src/resources.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 165 insertions(+), 22 deletions(-) (limited to 'src/resources.c') diff --git a/src/resources.c b/src/resources.c index 65b7f71..0829c7c 100644 --- a/src/resources.c +++ b/src/resources.c @@ -26,45 +26,188 @@ #include "resources.h" +#include "print.h" + +#include #include #include +#include -void -resources_init(resources_t *const res) +static void +resources_init_for_backup(resources_backup_t *const res) { res->in_file = NULL; res->ref_file = NULL; res->out_file = NULL; + res->in_buffer = NULL; res->ref_buffer = NULL; res->out_buffer = NULL; } -void -resources_free(resources_t *const res) +static int +resources_allocate_for_backup(const options_backup_t *const opts, + resources_backup_t *const res) { - if (res->in_file != NULL) { - fclose(res->in_file); - res->in_file = NULL; + if ((res->in_file = fopen(opts->in_file_path, "r")) == NULL) { + print_error("cannot open input file: %s", strerror(errno)); + return 1; } - if (res->ref_file != NULL) { - fclose(res->ref_file); - res->ref_file = NULL; + + if ((res->ref_file = fopen(opts->ref_file_path, "r")) == NULL) { + print_error("cannot open reference file: %s", strerror(errno)); + return 1; } - if (res->out_file != NULL) { - fclose(res->out_file); - res->out_file = NULL; + + /* When backing up, the output file is truncated to hold the + * new data + */ + if ((res->out_file = fopen(opts->out_file_path, "w+")) == NULL) { + print_error("cannot open output file: %s", strerror(errno)); + return 1; } - if (res->in_buffer != NULL) { - free(res->in_buffer); - res->in_buffer = NULL; + + /* The output buffer contains also the offsets */ + res->out_buffer_size = + ((opts->buffer_size / opts->sector_size) * sizeof(uint64_t)) + + opts->buffer_size; + + // TODO: separate function + if ((res->in_buffer = (char *)malloc(opts->buffer_size)) == NULL) { + print_error("cannot allocate buffer for input file data"); + return 1; + } else if ((res->ref_buffer = (char *)malloc(opts->buffer_size)) == NULL) { + print_error("cannot allocate buffer for reference file data"); + return 1; + } else if ((res->out_buffer = (char *)malloc(res->out_buffer_size)) == + NULL) { + print_error("cannot allocate buffer for output file data"); + return 1; } - if (res->ref_buffer != NULL) { - free(res->ref_buffer); - res->ref_buffer = NULL; + + return 0; +} + +static void +resources_init_for_restore(resources_restore_t *const res) +{ + res->in_file = NULL; + res->out_file = NULL; + + res->in_buffer = NULL; + res->out_buffer = NULL; +} + +static int +resources_allocate_for_restore(const options_restore_t *const opts, + resources_restore_t *const res) +{ + if ((res->in_file = fopen(opts->in_file_path, "r")) == NULL) { + print_error("cannot open input file: %s", strerror(errno)); + return 1; } - if (res->out_buffer != NULL) { - free(res->out_buffer); - res->out_buffer = NULL; + + /* When restoring, the file must be opened for writing and not + * truncated + */ + if ((res->out_file = fopen(opts->out_file_path, "r+")) == NULL) { + print_error("cannot open output file: %s", strerror(errno)); + return 1; } + + /* Allocate the buffer for data from the input file */ + /* The input buffer contains also the offsets */ + res->in_sector_size = sizeof(uint64_t) + opts->sector_size; + const size_t in_buffer_sector_count = + opts->buffer_size / res->in_sector_size; + res->in_buffer_size = in_buffer_sector_count * res->in_sector_size; + + if ((res->in_buffer = (char *)malloc(res->in_buffer_size)) == NULL) { + print_error("cannot allocate buffer for input file data"); + return 1; + } + + return 0; +} + +static void +resources_close_file(FILE **const file) +{ + if (*file != NULL) { + fclose(*file); + *file = NULL; + } +} + +static void +resources_close_buffer(char **const buffer) +{ + if (*buffer != NULL) { + free(*buffer); + *buffer = NULL; + } +} + +static void +resources_free_backup(resources_backup_t *const res) +{ + resources_close_file(&(res->in_file)); + resources_close_file(&(res->ref_file)); + resources_close_file(&(res->out_file)); + + resources_close_buffer(&(res->in_buffer)); + resources_close_buffer(&(res->ref_buffer)); + resources_close_buffer(&(res->out_buffer)); +} + +static void +resources_free_restore(resources_restore_t *const res) +{ + resources_close_file(&(res->in_file)); + resources_close_file(&(res->out_file)); + + resources_close_buffer(&(res->in_buffer)); + resources_close_buffer(&(res->out_buffer)); +} + +int +resources_allocate(const options_t *const opts, resources_t *const res) +{ + res->operation_id = opts->operation_id; + + if (res->operation_id == OPERATION_ID_BACKUP) { + resources_init_for_backup(&(res->res.backup)); + return resources_allocate_for_backup(&(opts->op.backup), + &(res->res.backup)); + } else if (res->operation_id == OPERATION_ID_RESTORE) { + resources_init_for_restore(&(res->res.restore)); + return resources_allocate_for_restore(&(opts->op.restore), + &(res->res.restore)); + } + + return 0; +} + +const resources_backup_t * +resources_get_for_backup(const resources_t *const res) +{ + return &(res->res.backup); +} + +const resources_restore_t * +resources_get_for_restore(const resources_t *const res) +{ + return &(res->res.restore); +} + +void +resources_free(resources_t *const res) +{ + if (res->operation_id == OPERATION_ID_BACKUP) { + resources_free_backup(&(res->res.backup)); + } else if (res->operation_id == OPERATION_ID_RESTORE) { + resources_free_restore(&(res->res.restore)); + } + + res->operation_id = OPERATION_ID_UNKNOWN; } -- cgit v1.2.3