Impl. "-t" command (printing archive info)
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 4s
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:
parent
58daa1130d
commit
2364f53649
3 changed files with 208 additions and 6 deletions
184
src/archiver.c
184
src/archiver.c
|
@ -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) {
|
void free_internal_to_write(void *data) {
|
||||||
SDArchiverInternalToWrite *to_write = data;
|
SDArchiverInternalToWrite *to_write = data;
|
||||||
free(to_write->buf);
|
free(to_write->buf);
|
||||||
|
@ -275,3 +282,180 @@ int simple_archiver_write_all(FILE *out_f, SDArchiverState *state,
|
||||||
fprintf(stderr, "End archiving.\n");
|
fprintf(stderr, "End archiving.\n");
|
||||||
return SDAS_SUCCESS;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -40,7 +40,8 @@ enum SDArchiverStateReturns {
|
||||||
SDAS_FAILED_TO_WRITE,
|
SDAS_FAILED_TO_WRITE,
|
||||||
SDAS_NO_COMPRESSOR,
|
SDAS_NO_COMPRESSOR,
|
||||||
SDAS_NO_DECOMPRESSOR,
|
SDAS_NO_DECOMPRESSOR,
|
||||||
SDAS_INVALID_PARSED_STATE
|
SDAS_INVALID_PARSED_STATE,
|
||||||
|
SDAS_INVALID_FILE
|
||||||
};
|
};
|
||||||
|
|
||||||
SDArchiverState *simple_archiver_init_state(const SDArchiverParsed *parsed);
|
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,
|
int simple_archiver_write_all(FILE *out_f, SDArchiverState *state,
|
||||||
const SDArchiverLinkedList *filenames);
|
const SDArchiverLinkedList *filenames);
|
||||||
|
|
||||||
|
/// Returns zero on success.
|
||||||
|
int simple_archiver_print_archive_info(FILE *in_f);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
20
src/main.c
20
src/main.c
|
@ -39,7 +39,7 @@ int main(int argc, const char **argv) {
|
||||||
|
|
||||||
simple_archiver_parse_args(argc, argv, &parsed);
|
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");
|
FILE *file = fopen(parsed.filename, "r");
|
||||||
if (file != NULL) {
|
if (file != NULL) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
@ -55,10 +55,12 @@ int main(int argc, const char **argv) {
|
||||||
SDArchiverLinkedList *filenames =
|
SDArchiverLinkedList *filenames =
|
||||||
simple_archiver_parsed_to_filenames(&parsed);
|
simple_archiver_parsed_to_filenames(&parsed);
|
||||||
|
|
||||||
|
if (filenames->count > 0) {
|
||||||
fprintf(stderr, "Filenames:\n");
|
fprintf(stderr, "Filenames:\n");
|
||||||
simple_archiver_list_get(filenames, print_list_fn, NULL);
|
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");
|
FILE *file = fopen(parsed.filename, "wb");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
fprintf(stderr, "ERROR: Failed to open \"%s\" for writing!\n",
|
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);
|
SDArchiverState *state = simple_archiver_init_state(&parsed);
|
||||||
|
|
||||||
if (simple_archiver_write_all(file, state, filenames) != SDAS_SUCCESS) {
|
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);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue