Compare commits

...

2 commits

Author SHA1 Message Date
0b63dd12ee Impl. being able to set dir for temporary files
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 11s
2024-07-25 10:42:31 +09:00
c55864a51b Refactor parser, setup for different temp dir 2024-07-25 10:26:34 +09:00
4 changed files with 58 additions and 12 deletions

View file

@ -39,7 +39,7 @@
#include "helpers.h" #include "helpers.h"
#define TEMP_FILENAME_CMP "simple_archiver_compressed_%u.tmp" #define TEMP_FILENAME_CMP "%s%ssimple_archiver_compressed_%u.tmp"
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \ #if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \ SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
@ -168,15 +168,21 @@ int write_files_fn(void *data, void *ud) {
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \ SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
// Use temp file to store compressed data. // Use temp file to store compressed data.
char temp_filename[128]; char temp_filename[512];
unsigned int idx = 0; unsigned int idx = 0;
snprintf(temp_filename, 128, TEMP_FILENAME_CMP, idx); unsigned int temp_dir_end = strlen(state->parsed->temp_dir);
snprintf(temp_filename, 512, TEMP_FILENAME_CMP, state->parsed->temp_dir,
state->parsed->temp_dir[temp_dir_end - 1] == '/' ? "" : "/",
idx);
do { do {
FILE *test_fd = fopen(temp_filename, "rb"); FILE *test_fd = fopen(temp_filename, "rb");
if (test_fd) { if (test_fd) {
// File exists. // File exists.
fclose(test_fd); fclose(test_fd);
snprintf(temp_filename, 128, TEMP_FILENAME_CMP, ++idx); snprintf(temp_filename, 512, TEMP_FILENAME_CMP,
state->parsed->temp_dir,
state->parsed->temp_dir[temp_dir_end - 1] == '/' ? "" : "/",
++idx);
} else if (idx > 0xFFFF) { } else if (idx > 0xFFFF) {
// Sanity check. // Sanity check.
return 1; return 1;
@ -192,14 +198,14 @@ int write_files_fn(void *data, void *ud) {
} }
__attribute__((cleanup(free_FILE_helper))) FILE *tmp_fd = __attribute__((cleanup(free_FILE_helper))) FILE *tmp_fd =
fopen(temp_filename, "wb"); fopen(temp_filename, "wb");
if (!tmp_fd) {
fprintf(stderr, "ERROR: Unable to create temp file for compressing!\n");
return 1;
}
__attribute__((cleanup(cleanup_temp_filename_delete))) void **ptrs_array = __attribute__((cleanup(cleanup_temp_filename_delete))) void **ptrs_array =
malloc(sizeof(void *) * 2); malloc(sizeof(void *) * 2);
ptrs_array[0] = temp_filename; ptrs_array[0] = temp_filename;
ptrs_array[1] = &tmp_fd; ptrs_array[1] = &tmp_fd;
if (!tmp_fd) {
// Unable to create temp file.
return 1;
}
// Handle SIGPIPE. // Handle SIGPIPE.
signal(SIGPIPE, handle_sig_pipe); signal(SIGPIPE, handle_sig_pipe);

View file

@ -44,7 +44,10 @@ int main(int argc, const char **argv) {
cleanup(simple_archiver_free_parsed))) SDArchiverParsed parsed = cleanup(simple_archiver_free_parsed))) SDArchiverParsed parsed =
simple_archiver_create_parsed(); simple_archiver_create_parsed();
simple_archiver_parse_args(argc, argv, &parsed); if (simple_archiver_parse_args(argc, argv, &parsed)) {
fprintf(stderr, "Failed to parse args.\n");
return 7;
}
if (!parsed.filename && (parsed.flags & 0x10) == 0) { if (!parsed.filename && (parsed.flags & 0x10) == 0) {
fprintf(stderr, "ERROR: Filename not specified!\n"); fprintf(stderr, "ERROR: Filename not specified!\n");

View file

@ -153,6 +153,9 @@ void simple_archiver_print_usage(void) {
fprintf(stderr, "--overwrite-extract : allows overwriting when extracting\n"); fprintf(stderr, "--overwrite-extract : allows overwriting when extracting\n");
fprintf(stderr, fprintf(stderr,
"--no-abs-symlink : do not store absolute paths for symlinks\n"); "--no-abs-symlink : do not store absolute paths for symlinks\n");
fprintf(stderr,
"--temp-files-dir <dir> : where to store temporary files created "
"when compressing (defaults to current working directory)\n");
fprintf(stderr, fprintf(stderr,
"-- : specifies remaining arguments are files to archive/extract\n"); "-- : specifies remaining arguments are files to archive/extract\n");
fprintf( fprintf(
@ -171,6 +174,7 @@ SDArchiverParsed simple_archiver_create_parsed(void) {
parsed.compressor = NULL; parsed.compressor = NULL;
parsed.decompressor = NULL; parsed.decompressor = NULL;
parsed.working_files = NULL; parsed.working_files = NULL;
parsed.temp_dir = NULL;
return parsed; return parsed;
} }
@ -199,6 +203,7 @@ int simple_archiver_parse_args(int argc, const char **argv,
while (argc > 0) { while (argc > 0) {
if (!is_remaining_args) { if (!is_remaining_args) {
if (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0) { if (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0) {
simple_archiver_free_parsed(out);
simple_archiver_print_usage(); simple_archiver_print_usage();
exit(0); exit(0);
} else if (strcmp(argv[0], "-c") == 0) { } else if (strcmp(argv[0], "-c") == 0) {
@ -214,7 +219,12 @@ int simple_archiver_parse_args(int argc, const char **argv,
out->flags &= 0xFFFFFFFC; out->flags &= 0xFFFFFFFC;
// set second bit. // set second bit.
out->flags |= 0x2; out->flags |= 0x2;
} else if (strcmp(argv[0], "-f") == 0 && argc > 1) { } else if (strcmp(argv[0], "-f") == 0) {
if (argc < 2) {
fprintf(stderr, "ERROR: -f specified but missing argument!\n");
simple_archiver_print_usage();
return 1;
}
if (strcmp(argv[1], "-") == 0) { if (strcmp(argv[1], "-") == 0) {
out->flags |= 0x10; out->flags |= 0x10;
if (out->filename) { if (out->filename) {
@ -229,13 +239,23 @@ int simple_archiver_parse_args(int argc, const char **argv,
} }
--argc; --argc;
++argv; ++argv;
} else if (strcmp(argv[0], "--compressor") == 0 && argc > 1) { } else if (strcmp(argv[0], "--compressor") == 0) {
if (argc < 2) {
fprintf(stderr, "--compressor specfied but missing argument!\n");
simple_archiver_print_usage();
return 1;
}
int size = strlen(argv[1]) + 1; int size = strlen(argv[1]) + 1;
out->compressor = malloc(size); out->compressor = malloc(size);
strncpy(out->compressor, argv[1], size); strncpy(out->compressor, argv[1], size);
--argc; --argc;
++argv; ++argv;
} else if (strcmp(argv[0], "--decompressor") == 0 && argc > 1) { } else if (strcmp(argv[0], "--decompressor") == 0) {
if (argc < 2) {
fprintf(stderr, "--decompressor specfied but missing argument!\n");
simple_archiver_print_usage();
return 1;
}
int size = strlen(argv[1]) + 1; int size = strlen(argv[1]) + 1;
out->decompressor = malloc(size); out->decompressor = malloc(size);
strncpy(out->decompressor, argv[1], size); strncpy(out->decompressor, argv[1], size);
@ -247,6 +267,15 @@ int simple_archiver_parse_args(int argc, const char **argv,
out->flags |= 0x8; out->flags |= 0x8;
} else if (strcmp(argv[0], "--no-abs-symlink") == 0) { } else if (strcmp(argv[0], "--no-abs-symlink") == 0) {
out->flags |= 0x20; out->flags |= 0x20;
} else if (strcmp(argv[0], "--temp-files-dir") == 0) {
if (argc < 2) {
fprintf(stderr, "ERROR: --temp-files-dir is missing an argument!\n");
simple_archiver_print_usage();
return 1;
}
out->temp_dir = argv[1];
--argc;
++argv;
} else if (argv[0][0] == '-' && argv[0][1] == '-' && argv[0][2] == 0) { } else if (argv[0][0] == '-' && argv[0][1] == '-' && argv[0][2] == 0) {
is_remaining_args = 1; is_remaining_args = 1;
} else if (argv[0][0] != '-') { } else if (argv[0][0] != '-') {
@ -292,6 +321,10 @@ int simple_archiver_parse_args(int argc, const char **argv,
++argv; ++argv;
} }
if (!out->temp_dir) {
out->temp_dir = "./";
}
return 0; return 0;
} }

View file

@ -42,6 +42,9 @@ typedef struct SDArchiverParsed {
/// Last entry should be NULL. /// Last entry should be NULL.
/// Determines a "white-list" of files to extract when extracting. /// Determines a "white-list" of files to extract when extracting.
char **working_files; char **working_files;
/// Determines where to place temporary files. If NULL, temporary files are
/// created in the current working directory.
const char *temp_dir;
} SDArchiverParsed; } SDArchiverParsed;
typedef struct SDArchiverFileInfo { typedef struct SDArchiverFileInfo {
@ -57,6 +60,7 @@ SDArchiverParsed simple_archiver_create_parsed(void);
/// Expects the user to pass a pointer to an SDArchiverParsed. /// Expects the user to pass a pointer to an SDArchiverParsed.
/// This means the user should have a SDArchiverParsed variable /// This means the user should have a SDArchiverParsed variable
/// and it should be passed with e.g. "&var". /// and it should be passed with e.g. "&var".
/// Returns 0 on success.
int simple_archiver_parse_args(int argc, const char **argv, int simple_archiver_parse_args(int argc, const char **argv,
SDArchiverParsed *out); SDArchiverParsed *out);