#include "helpers.h"
#include "users.h"
-#define TEMP_FILENAME_CMP "%s%ssimple_archiver_compressed_%zu.tmp"
#define FILE_COUNTS_OUTPUT_FORMAT_STR_0 \
"\nFile %%%zu" PRIu32 " of %%%zu" PRIu32 ".\n"
#define FILE_COUNTS_OUTPUT_FORMAT_STR_1 "[%%%zuzu/%%%zuzu]\n"
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
- // Use temp file to store compressed data.
- char temp_filename[512];
- size_t idx = 0;
- size_t 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 {
- FILE *test_fd = fopen(temp_filename, "rb");
- if (test_fd) {
- // File exists.
- fclose(test_fd);
- snprintf(temp_filename, 512, TEMP_FILENAME_CMP,
- state->parsed->temp_dir,
- state->parsed->temp_dir[temp_dir_end - 1] == '/' ? "" : "/",
- ++idx);
- } else if (idx > 0xFFFF) {
- // Sanity check.
- return 1;
- } else {
- break;
- }
- } while (1);
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
FILE *file_fd = fopen(file_info->filename, "rb");
if (!file_fd) {
// Unable to open file for compressing and archiving.
return 1;
}
+ // Use temp file to store compressed data.
+ __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
+ char *out_temp_filename = NULL;
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
- FILE *tmp_fd = fopen(temp_filename, "wb");
+ FILE *tmp_fd = simple_archiver_helper_temp_dir(state->parsed,
+ &out_temp_filename);
+ fprintf(stderr, "DEBUG: out_temp_filename is %s\n");
__attribute__((cleanup(cleanup_temp_filename_delete))) void **ptrs_array =
malloc(sizeof(void *) * 2);
ptrs_array[0] = NULL;
return 1;
}
} else {
- ptrs_array[0] = temp_filename;
+ ptrs_array[0] = out_temp_filename;
ptrs_array[1] = &tmp_fd;
}
}
} else if (ret == 0) {
read_done = 1;
- simple_archiver_helper_cleanup_FILE(&tmp_fd);
close(pipe_outof_cmd[0]);
pipe_outof_cmd[0] = -1;
// fprintf(stderr, "read_done\n");
// Get compressed file length.
// Compressed file should be at "temp_filename".
- tmp_fd = fopen(temp_filename, "rb");
-
+ clearerr(tmp_fd);
long end;
if (fseek(tmp_fd, 0, SEEK_END) != 0) {
// Error seeking.
if (end == -1L) {
// Error getting end position.
return 1;
- } else if (fseek(tmp_fd, 0, SEEK_SET) != 0) {
- // Error seeking.
- return 1;
}
+ rewind(tmp_fd);
// Write file length.
u64 = (uint64_t)end;
break;
}
} while (1);
-
- // Cleanup.
- simple_archiver_helper_cleanup_FILE(&tmp_fd);
#endif
} else {
uint16_t u16;
if (state->parsed->compressor && state->parsed->decompressor) {
// Is compressing.
- size_t temp_filename_size = strlen(state->parsed->temp_dir) + 1 + 64;
- __attribute__((cleanup(
- simple_archiver_helper_cleanup_c_string))) char *temp_filename =
- malloc(temp_filename_size);
+ __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
+ char *temp_filename = NULL;
__attribute__((cleanup(cleanup_temp_filename_delete))) void **ptrs_array =
malloc(sizeof(void *) * 2);
ptrs_array[1] = NULL;
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
- FILE *temp_fd = NULL;
-
- if (state->parsed->temp_dir) {
- size_t idx = 0;
- size_t temp_dir_len = strlen(state->parsed->temp_dir);
- snprintf(temp_filename, temp_filename_size, TEMP_FILENAME_CMP,
- state->parsed->temp_dir,
- state->parsed->temp_dir[temp_dir_len - 1] == '/' ? "" : "/",
- idx);
- do {
- FILE *test_fd = fopen(temp_filename, "rb");
- if (test_fd) {
- // File exists.
- fclose(test_fd);
- snprintf(
- temp_filename, temp_filename_size, TEMP_FILENAME_CMP,
- state->parsed->temp_dir,
- state->parsed->temp_dir[temp_dir_len - 1] == '/' ? "" : "/",
- ++idx);
- } else if (idx > 0xFFFF) {
- return SDAS_INTERNAL_ERROR;
- } else {
- break;
- }
- } while (1);
- temp_fd = fopen(temp_filename, "w+b");
- if (temp_fd) {
- ptrs_array[0] = temp_filename;
- }
- } else {
- temp_fd = tmpfile();
- }
+ FILE *temp_fd = simple_archiver_helper_temp_dir(state->parsed,
+ &temp_filename);
+
+ ptrs_array[0] = temp_filename;
if (!temp_fd) {
temp_fd = tmpfile();
return SDAS_FAILED_TO_WRITE;
}
- if (fseek(temp_fd, 0, SEEK_SET) != 0) {
- return SDAS_INTERNAL_ERROR;
- }
+ rewind(temp_fd);
size_t written_size = 0;
if (state->parsed->compressor && state->parsed->decompressor) {
// Is compressing.
-
- size_t temp_filename_size = strlen(state->parsed->temp_dir) + 1 + 64;
- __attribute__((cleanup(
- simple_archiver_helper_cleanup_c_string))) char *temp_filename =
- malloc(temp_filename_size);
+ __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
+ char *temp_filename = NULL;
__attribute__((cleanup(cleanup_temp_filename_delete))) void **ptrs_array =
malloc(sizeof(void *) * 2);
ptrs_array[1] = NULL;
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
- FILE *temp_fd = NULL;
-
- if (state->parsed->temp_dir) {
- size_t idx = 0;
- size_t temp_dir_len = strlen(state->parsed->temp_dir);
- snprintf(temp_filename, temp_filename_size, TEMP_FILENAME_CMP,
- state->parsed->temp_dir,
- state->parsed->temp_dir[temp_dir_len - 1] == '/' ? "" : "/",
- idx);
- do {
- FILE *test_fd = fopen(temp_filename, "rb");
- if (test_fd) {
- // File exists.
- fclose(test_fd);
- snprintf(
- temp_filename, temp_filename_size, TEMP_FILENAME_CMP,
- state->parsed->temp_dir,
- state->parsed->temp_dir[temp_dir_len - 1] == '/' ? "" : "/",
- ++idx);
- } else if (idx > 0xFFFF) {
- return SDAS_INTERNAL_ERROR;
- } else {
- break;
- }
- } while (1);
- temp_fd = fopen(temp_filename, "w+b");
- if (temp_fd) {
- ptrs_array[0] = temp_filename;
- }
- } else {
- temp_fd = tmpfile();
- }
+ FILE *temp_fd = simple_archiver_helper_temp_dir(state->parsed,
+ &temp_filename);
+ ptrs_array[0] = temp_filename;
if (!temp_fd) {
temp_fd = tmpfile();
return SDAS_FAILED_TO_WRITE;
}
- if (fseek(temp_fd, 0, SEEK_SET) != 0) {
- return SDAS_INTERNAL_ERROR;
- }
+ rewind(temp_fd);
size_t written_size = 0;
if (state->parsed->compressor && state->parsed->decompressor) {
// Is compressing.
-
- size_t temp_filename_size = strlen(state->parsed->temp_dir) + 1 + 64;
- __attribute__((cleanup(
- simple_archiver_helper_cleanup_c_string))) char *temp_filename =
- malloc(temp_filename_size);
+ __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
+ char *temp_filename = NULL;
__attribute__((cleanup(cleanup_temp_filename_delete))) void **ptrs_array =
malloc(sizeof(void *) * 2);
ptrs_array[1] = NULL;
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
- FILE *temp_fd = NULL;
-
- if (state->parsed->temp_dir) {
- size_t idx = 0;
- size_t temp_dir_len = strlen(state->parsed->temp_dir);
- snprintf(temp_filename, temp_filename_size, TEMP_FILENAME_CMP,
- state->parsed->temp_dir,
- state->parsed->temp_dir[temp_dir_len - 1] == '/' ? "" : "/",
- idx);
- do {
- FILE *test_fd = fopen(temp_filename, "rb");
- if (test_fd) {
- // File exists.
- fclose(test_fd);
- snprintf(
- temp_filename, temp_filename_size, TEMP_FILENAME_CMP,
- state->parsed->temp_dir,
- state->parsed->temp_dir[temp_dir_len - 1] == '/' ? "" : "/",
- ++idx);
- } else if (idx > 0xFFFF) {
- return SDAS_INTERNAL_ERROR;
- } else {
- break;
- }
- } while (1);
- temp_fd = fopen(temp_filename, "w+b");
- if (temp_fd) {
- ptrs_array[0] = temp_filename;
- }
- } else {
- temp_fd = tmpfile();
- }
+ FILE *temp_fd = simple_archiver_helper_temp_dir(state->parsed,
+ &temp_filename);
+ ptrs_array[0] = temp_filename;
if (!temp_fd) {
temp_fd = tmpfile();
return SDAS_FAILED_TO_WRITE;
}
- if (fseek(temp_fd, 0, SEEK_SET) != 0) {
- return SDAS_INTERNAL_ERROR;
- }
+ rewind(temp_fd);
size_t written_size = 0;
}
char *simple_archiver_helper_real_path_to_name(const char *filename) {
+ if (!filename || filename[0] == 0) {
+ return NULL;
+ }
+
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *filename_copy = strdup(filename);
char *filename_dir = dirname(filename_copy);
return 1;
}
+
+FILE *simple_archiver_helper_temp_dir(const SDArchiverParsed *parsed,
+ char **out_temp_filename) {
+ __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
+ char *real_path_to_filename = parsed->temp_dir
+ ? strdup(parsed->temp_dir)
+ : strdup(parsed->filename_full_abs_path);
+
+ if (!real_path_to_filename) {
+ if (out_temp_filename) {
+ *out_temp_filename = NULL;
+ }
+ return tmpfile();
+ }
+
+ char *dir = parsed->temp_dir
+ ? real_path_to_filename
+ : dirname(real_path_to_filename);
+ if (!dir) {
+ if (out_temp_filename) {
+ *out_temp_filename = NULL;
+ }
+ return tmpfile();
+ }
+
+ char temp_filename[512];
+ size_t idx = 0;
+ size_t dir_len = strlen(dir);
+ snprintf(temp_filename,
+ 512,
+ TEMP_FILENAME_CMP,
+ dir,
+ dir[dir_len - 1] == '/' ? "" : "/",
+ idx);
+ do {
+ FILE *test_fd = fopen(temp_filename, "rb");
+ if (test_fd) {
+ // File exists.
+ fclose(test_fd);
+ snprintf(temp_filename,
+ 512,
+ TEMP_FILENAME_CMP,
+ dir,
+ dir[dir_len - 1] == '/' ? "" : "/",
+ ++idx);
+ } else if (idx > 0xFFFF) {
+ // Sanity check.
+ if (out_temp_filename) {
+ *out_temp_filename = NULL;
+ }
+ return tmpfile();
+ } else {
+ break;
+ }
+ } while (1);
+
+ FILE *temp_file = fopen(temp_filename, "w+b");
+
+ if (temp_file) {
+ if (out_temp_filename) {
+ *out_temp_filename = strdup(temp_filename);
+ }
+ return temp_file;
+ } else {
+ if (out_temp_filename) {
+ *out_temp_filename = NULL;
+ }
+ return tmpfile();
+ }
+}
parsed.flags = 0x40;
parsed.filename = NULL;
+ parsed.filename_full_abs_path = NULL;
parsed.compressor = NULL;
parsed.decompressor = NULL;
parsed.working_files = NULL;
free(out->filename);
out->filename = NULL;
}
+ if (out->filename_full_abs_path) {
+ free(out->filename_full_abs_path);
+ out->filename_full_abs_path = NULL;
+ }
if (out->compressor) {
free(out->compressor);
out->compressor = NULL;
if (out->filename) {
free(out->filename);
}
+ if (out->filename_full_abs_path) {
+ free(out->filename_full_abs_path);
+ }
out->filename = NULL;
+ out->filename_full_abs_path = NULL;
} else {
out->flags &= 0xFFFFFFEF;
- size_t size = strlen(argv[1]) + 1;
- out->filename = malloc(size);
- strncpy(out->filename, argv[1], size);
+ out->filename = strdup(argv[1]);
+ out->filename_full_abs_path =
+ simple_archiver_helper_real_path_to_name(argv[1]);
}
--argc;
++argv;
simple_archiver_print_usage();
return 1;
}
- out->temp_dir = argv[1];
+ out->temp_dir = simple_archiver_helper_real_path_to_name(argv[1]);
--argc;
++argv;
} else if (strcmp(argv[0], "--write-version") == 0) {
++argv;
}
- if (!out->temp_dir) {
- out->temp_dir = "./";
- }
-
return 0;
}
free(parsed->filename);
parsed->filename = NULL;
}
+ if (parsed->filename_full_abs_path) {
+ free(parsed->filename_full_abs_path);
+ parsed->filename_full_abs_path = NULL;
+ }
if (parsed->compressor) {
free(parsed->compressor);
parsed->compressor = NULL;
parsed->working_files = NULL;
}
+ if (parsed->temp_dir) {
+ free(parsed->temp_dir);
+ parsed->temp_dir = NULL;
+ }
+
simple_archiver_users_free_users_infos(&parsed->users_infos);
if (parsed->mappings.UidToUname) {