Impl. "-t" command (printing archive info)
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 4s

TODO:
    Write symbolic links into archive when creating.
    Use De/compressor cmds when creating archive.
    Extracting archive.
This commit is contained in:
Stephen Seo 2024-07-17 13:30:05 +09:00
parent 58daa1130d
commit 2364f53649
3 changed files with 208 additions and 6 deletions

View file

@ -36,6 +36,13 @@ void free_FILE_helper(FILE **fd) {
}
}
void free_malloced_memory(void **data) {
if (data && *data) {
free(*data);
*data = NULL;
}
}
void free_internal_to_write(void *data) {
SDArchiverInternalToWrite *to_write = data;
free(to_write->buf);
@ -275,3 +282,180 @@ int simple_archiver_write_all(FILE *out_f, SDArchiverState *state,
fprintf(stderr, "End archiving.\n");
return SDAS_SUCCESS;
}
int simple_archiver_print_archive_info(FILE *in_f) {
unsigned char buf[1024];
memset(buf, 0, 1024);
uint16_t u16;
uint32_t u32;
uint64_t u64;
if (fread(buf, 1, 18, in_f) != 18) {
return SDAS_INVALID_FILE;
} else if (memcmp(buf, "SIMPLE_ARCHIVE_VER", 18) != 0) {
return SDAS_INVALID_FILE;
} else if (fread(buf, 1, 2, in_f) != 2) {
return SDAS_INVALID_FILE;
} else if (buf[0] != 0 || buf[1] != 0) {
// Version is not zero.
return SDAS_INVALID_FILE;
} else if (fread(buf, 1, 4, in_f) != 4) {
return SDAS_INVALID_FILE;
}
if ((buf[0] & 1) != 0) {
fprintf(stderr, "De/compressor flag is set.\n");
// Read compressor data.
if (fread(&u16, 2, 1, in_f) != 1) {
return SDAS_INVALID_FILE;
}
simple_archiver_helper_16_bit_be(&u16);
fprintf(stderr, "Compressor size is %u\n", u16);
if (u16 < 1024) {
if (fread(buf, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
return SDAS_INVALID_FILE;
}
buf[1023] = 0;
fprintf(stderr, "Compressor cmd: %s\n", buf);
} else {
__attribute__((cleanup(free_malloced_memory))) void *heap_buf =
malloc(u16 + 1);
unsigned char *uc_heap_buf = heap_buf;
if (fread(uc_heap_buf, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
return SDAS_INVALID_FILE;
}
uc_heap_buf[u16 - 1] = 0;
fprintf(stderr, "Compressor cmd: %s\n", uc_heap_buf);
}
// Read decompressor data.
if (fread(&u16, 2, 1, in_f) != 1) {
return SDAS_INVALID_FILE;
}
simple_archiver_helper_16_bit_be(&u16);
fprintf(stderr, "Decompressor size is %u\n", u16);
if (u16 < 1024) {
if (fread(buf, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
return SDAS_INVALID_FILE;
}
buf[1023] = 0;
fprintf(stderr, "Decompressor cmd: %s\n", buf);
} else {
__attribute__((cleanup(free_malloced_memory))) void *heap_buf =
malloc(u16 + 1);
unsigned char *uc_heap_buf = heap_buf;
if (fread(uc_heap_buf, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
return SDAS_INVALID_FILE;
}
uc_heap_buf[u16 - 1] = 0;
fprintf(stderr, "Decompressor cmd: %s\n", uc_heap_buf);
}
} else {
fprintf(stderr, "De/compressor flag is NOT set.\n");
}
if (fread(&u32, 1, 4, in_f) != 4) {
return SDAS_INVALID_FILE;
}
simple_archiver_helper_32_bit_be(&u32);
fprintf(stderr, "File count is %u\n", u32);
uint32_t size = u32;
for (uint32_t idx = 0; idx < size; ++idx) {
fprintf(stderr, "File %10u of %10u.\n", idx + 1, size);
if (feof(in_f) || ferror(in_f)) {
return SDAS_INVALID_FILE;
} else if (fread(&u16, 2, 1, in_f) != 1) {
return SDAS_INVALID_FILE;
}
simple_archiver_helper_16_bit_be(&u16);
if (u16 < 1024) {
if (fread(buf, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
return SDAS_INVALID_FILE;
}
buf[1023] = 0;
fprintf(stderr, " Filename: %s\n", buf);
} else {
__attribute__((cleanup(free_malloced_memory))) void *heap_buf =
malloc(u16 + 1);
unsigned char *uc_heap_buf = heap_buf;
if (fread(uc_heap_buf, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
return SDAS_INVALID_FILE;
}
uc_heap_buf[u16 - 1] = 0;
fprintf(stderr, " Filename: %s\n", uc_heap_buf);
}
if (fread(buf, 1, 4, in_f) != 4) {
return SDAS_INVALID_FILE;
}
if ((buf[0] & 1) == 0) {
// Not a sybolic link.
if (fread(&u64, 8, 1, in_f) != 1) {
return SDAS_INVALID_FILE;
}
simple_archiver_helper_64_bit_be(&u64);
fprintf(stderr, " File size: %lu\n", u64);
while (u64 > 0) {
if (u64 > 1024) {
if (fread(buf, 1, 1024, in_f) != 1024) {
return SDAS_INVALID_FILE;
}
u64 -= 1024;
} else {
if (fread(buf, 1, u64, in_f) != u64) {
return SDAS_INVALID_FILE;
}
u64 = 0;
}
}
} else {
// Is a symbolic link.
if (fread(&u16, 2, 1, in_f) != 1) {
return SDAS_INVALID_FILE;
}
simple_archiver_helper_16_bit_be(&u16);
if (u16 < 1024) {
if (fread(buf, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
return SDAS_INVALID_FILE;
}
buf[1023] = 0;
fprintf(stderr, " Link absolute path: %s\n", buf);
} else {
__attribute__((cleanup(free_malloced_memory))) void *heap_buf =
malloc(u16 + 1);
unsigned char *uc_heap_buf = heap_buf;
if (fread(uc_heap_buf, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
return SDAS_INVALID_FILE;
}
uc_heap_buf[u16 - 1] = 0;
fprintf(stderr, " Link absolute path: %s\n", uc_heap_buf);
}
if (fread(&u16, 2, 1, in_f) != 1) {
return SDAS_INVALID_FILE;
}
simple_archiver_helper_16_bit_be(&u16);
if (u16 < 1024) {
if (fread(buf, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
return SDAS_INVALID_FILE;
}
buf[1023] = 0;
fprintf(stderr, " Link relative path: %s\n", buf);
} else {
__attribute__((cleanup(free_malloced_memory))) void *heap_buf =
malloc(u16 + 1);
unsigned char *uc_heap_buf = heap_buf;
if (fread(uc_heap_buf, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
return SDAS_INVALID_FILE;
}
uc_heap_buf[u16 - 1] = 0;
fprintf(stderr, " Link relative path: %s\n", uc_heap_buf);
}
}
}
return 0;
}

View file

@ -40,7 +40,8 @@ enum SDArchiverStateReturns {
SDAS_FAILED_TO_WRITE,
SDAS_NO_COMPRESSOR,
SDAS_NO_DECOMPRESSOR,
SDAS_INVALID_PARSED_STATE
SDAS_INVALID_PARSED_STATE,
SDAS_INVALID_FILE
};
SDArchiverState *simple_archiver_init_state(const SDArchiverParsed *parsed);
@ -51,4 +52,7 @@ void simple_archiver_free_state(SDArchiverState **state);
int simple_archiver_write_all(FILE *out_f, SDArchiverState *state,
const SDArchiverLinkedList *filenames);
/// Returns zero on success.
int simple_archiver_print_archive_info(FILE *in_f);
#endif

View file

@ -39,7 +39,7 @@ int main(int argc, const char **argv) {
simple_archiver_parse_args(argc, argv, &parsed);
if ((parsed.flags & 0x4) == 0) {
if ((parsed.flags & 0x3) == 0 && (parsed.flags & 0x4) == 0) {
FILE *file = fopen(parsed.filename, "r");
if (file != NULL) {
fclose(file);
@ -55,10 +55,12 @@ int main(int argc, const char **argv) {
SDArchiverLinkedList *filenames =
simple_archiver_parsed_to_filenames(&parsed);
fprintf(stderr, "Filenames:\n");
simple_archiver_list_get(filenames, print_list_fn, NULL);
if (filenames->count > 0) {
fprintf(stderr, "Filenames:\n");
simple_archiver_list_get(filenames, print_list_fn, NULL);
}
if ((parsed.flags & 1) == 0) {
if ((parsed.flags & 3) == 0) {
FILE *file = fopen(parsed.filename, "wb");
if (!file) {
fprintf(stderr, "ERROR: Failed to open \"%s\" for writing!\n",
@ -70,7 +72,19 @@ int main(int argc, const char **argv) {
SDArchiverState *state = simple_archiver_init_state(&parsed);
if (simple_archiver_write_all(file, state, filenames) != SDAS_SUCCESS) {
fprintf(stderr, "Error during writing.");
fprintf(stderr, "Error during writing.\n");
}
fclose(file);
} else if ((parsed.flags & 3) == 2) {
FILE *file = fopen(parsed.filename, "rb");
if (!file) {
fprintf(stderr, "ERROR: Failed to open \"%s\" for reading!\n",
parsed.filename);
return 3;
}
if (simple_archiver_print_archive_info(file) != 0) {
fprintf(stderr, "Error during archive checking/examining.\n");
}
fclose(file);
}