Compare commits

...

8 commits

Author SHA1 Message Date
eff2b44f6d Impl. setting stored UID/GID if EUID 0
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 56s
2024-09-28 19:07:37 +09:00
7c4663daf2 "Fix" Linux/Mac/Unix usage 2024-09-28 19:07:37 +09:00
49f6434601 Impl. simple test/extract new file format (WIP)
TODO:
    Extract symlinks in new format (implemented but untested).
    Extract compressed files in new format.
2024-09-28 19:07:37 +09:00
e5acb4d730 Split up handling of archive file based on version 2024-09-28 19:07:37 +09:00
d48d458712 Fix typo 2024-09-28 19:07:37 +09:00
1bbfd8c53d Fix typo in file format specification version 1 2024-09-28 19:07:37 +09:00
b9ed8961a4 Create file format for format version 1
This is in preparation of improving compression by concatenating files
together before compressing them to reduce the per-file overhead.

Discussed in
#18
2024-09-28 19:07:37 +09:00
a81ec4434a Fix potential NULL-ptr dereference
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 5s
2024-09-28 19:07:12 +09:00
4 changed files with 622 additions and 9 deletions

View file

@ -76,3 +76,109 @@ Following the file-count bytes, the following bytes are added for each file:
1. 8 bytes 64-bit unsigned integer "size of filename in this archive file"
in big-endian.
2. X bytes file data (length defined by previous value).
## Format Version 1
File extension is "*.simplearchive" but this isn't really checked.
First 18 bytes of file will be (in ascii):
SIMPLE_ARCHIVE_VER
Next 2 bytes is a 16-bit unsigned integer "version" in big-endian. It will be:
0x00 0x01
Next 4 bytes are bit-flags.
1. The first byte
1. The first bit is set if de/compressor is set for this archive.
The remaining unused flags in the previous bit-flags bytes are reserved for
future revisions and are currently ignored.
If the previous "de/compressor is set" flag is enabled, then the next section is
added:
1. 2 bytes is 16-bit unsigned integer "compressor cmd+args" in big-endian. This
does not include the NULL at the end of the string.
2. X bytes of "compressor cmd+args" (length defined by previous value). Is a
NULL-terminated string.
3. 2 bytes is 16-bit unsigned integer "decompressor cmd+args" in big-endian.
This does not include the NULL at the end of the string.
4. X bytes of "decompressor cmd+args" (length defined by previous value). Is a
NULL-terminated string.
The next 4 bytes is a 32-bit unsigned integer "link count" in big-endian which
will indicate the number of symbolic links in this archive.
Following the link-count bytes, the following bytes are added for each symlink:
1. 2 bytes bit-flags:
1. The first byte.
1. The first bit is UNSET if relative links are preferred, and is SET if
absolute links are preferred.
2. The second byte.
1. Currently unused.
2. 2 bytes 16-bit unsigned integer "link name" in big-endian. This does not
include the NULL at the end of the string. Must not be zero.
3. X bytes of link-name (length defined by previous value). Is a NULL-terminated
string.
4. 2 bytes is 16-bit unsigned integer "link target absolute path" in
big-endian. This does not include the NULL at the end of the string.
5. X bytes of link-target-absolute-path (length defined by previous value).
Is a NULL-terminated string. If the previous "size" value is 0, then
this entry does not exist and should be skipped.
6. 2 bytes is 16-bit unsigned integer "link target relative path" in
big-endian. This does not include the NULL at the end of the string.
7. X bytes of link-target-relative-path (length defined by previous value).
Is a NULL-terminated string. If the previous "size" value is 0, then
this entry does not exist and should be skipped.
After the symlink related data, the next 4 bytes is a 32-bit unsigned integer
"chunk count" in big-endian which will indicate the number of chunks in this
archive.
Following the chunk-count bytes, the following bytes are added for each chunk:
1. 2 bytes that are a 16-bit unsigned integer "file count" in big-endian.
The following bytes are added for each file within the current chunk:
1. 2 bytes that are a 16-bit unsigned integer "filename length" in big-endian.
This does not include the NULL at the end of the string.
2. X bytes of filename (length defined by previous value). Is a NULL-terminated
string.
3. 4 bytes bit-flags.
1. The first byte.
1. The first bit is "user read permission".
2. The second bit is "user write permission".
3. The third bit is "user execute permission".
4. The fourth bit is "group read permission".
5. The fifth bit is "group write permission".
6. The sixth bit is "group execute permission".
7. The seventh bit is "other read permission".
8. The eighth bit is "other write permission".
2. The second byte.
1. The first bit is "other execute permission".
3. The third byte.
1. Currently unused.
4. The fourth byte.
1. Currently unused.
4. Two 4-byte unsigned integers in big-endian for UID and GID.
1. A 32-bit unsigned integer in big endian that specifies the UID of the
file. Note that during extraction, if the user is not root, then this
value will be ignored.
2. A 32-bit unsigned integer in big endian that specifies the GID of the
file. Note that during extraction, if the user is not root, then this
value will be ignored.
5. A 64-bit unsigned integer in big endian for the "size of file".
After the files' metadata are the current chunk's data:
1. A 64-bit unsigned integer in big endian for the "size of chunk".
2. X bytes of data for the current chunk of the previously specified size. If
not using de/compressor, this section is the previously mentioned files
concatenated with each other. If using de/compressor, this section is the
previously mentioned files concatenated and compressed into a single blob of
data.

BIN
file_format_1_example_0 Normal file

Binary file not shown.

View file

@ -60,6 +60,14 @@ typedef struct SDArchiverInternalToWrite {
uint64_t size;
} SDArchiverInternalToWrite;
typedef struct SDArchiverInternalFileInfo {
char *filename;
uint8_t bit_flags[4];
uint32_t uid;
uint32_t gid;
uint64_t file_size;
} SDArchiverInternalFileInfo;
void free_internal_to_write(void *data) {
SDArchiverInternalToWrite *to_write = data;
free(to_write->buf);
@ -977,6 +985,159 @@ int filenames_to_abs_map_fn(void *data, void *ud) {
return 0;
}
int read_buf_full_from_fd(FILE *fd, char *read_buf, const size_t read_buf_size,
const size_t amount_total, char *dst_buf) {
size_t amount = amount_total;
while (amount != 0) {
if (amount >= read_buf_size) {
if (fread(read_buf, 1, read_buf_size, fd) != read_buf_size) {
return SDAS_INVALID_FILE;
}
if (dst_buf) {
memcpy(dst_buf + (amount_total - amount), read_buf, read_buf_size);
}
amount -= read_buf_size;
} else {
if (fread(read_buf, 1, amount, fd) != amount) {
return SDAS_INVALID_FILE;
}
if (dst_buf) {
memcpy(dst_buf + (amount_total - amount), read_buf, amount);
}
amount = 0;
}
}
return SDAS_SUCCESS;
}
int read_fd_to_out_fd(FILE *in_fd, FILE *out_fd, char *read_buf,
const size_t read_buf_size, const size_t amount_total) {
size_t amount = amount_total;
while (amount != 0) {
if (amount >= read_buf_size) {
if (fread(read_buf, 1, read_buf_size, in_fd) != read_buf_size) {
return SDAS_INVALID_FILE;
} else if (fwrite(read_buf, 1, read_buf_size, out_fd) != read_buf_size) {
return SDAS_FAILED_TO_WRITE;
}
amount -= read_buf_size;
} else {
if (fread(read_buf, 1, amount, in_fd) != amount) {
return SDAS_INVALID_FILE;
} else if (fwrite(read_buf, 1, amount, out_fd) != amount) {
return SDAS_FAILED_TO_WRITE;
}
amount = 0;
}
}
return SDAS_SUCCESS;
}
void free_internal_file_info(void *data) {
SDArchiverInternalFileInfo *file_info = data;
if (file_info) {
if (file_info->filename) {
free(file_info->filename);
}
free(file_info);
}
}
void cleanup_internal_file_info(SDArchiverInternalFileInfo **file_info) {
if (file_info && *file_info) {
if ((*file_info)->filename) {
free((*file_info)->filename);
}
free(*file_info);
*file_info = NULL;
}
}
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
mode_t permissions_from_bits_version_1(const uint8_t flags[4],
uint_fast8_t print) {
mode_t permissions = 0;
if ((flags[0] & 1) != 0) {
permissions |= S_IRUSR;
if (print) {
fprintf(stderr, "r");
}
} else if (print) {
fprintf(stderr, "-");
}
if ((flags[0] & 2) != 0) {
permissions |= S_IWUSR;
if (print) {
fprintf(stderr, "w");
}
} else if (print) {
fprintf(stderr, "-");
}
if ((flags[0] & 4) != 0) {
permissions |= S_IXUSR;
if (print) {
fprintf(stderr, "x");
}
} else if (print) {
fprintf(stderr, "-");
}
if ((flags[0] & 8) != 0) {
permissions |= S_IRGRP;
if (print) {
fprintf(stderr, "r");
}
} else if (print) {
fprintf(stderr, "-");
}
if ((flags[0] & 0x10) != 0) {
permissions |= S_IWGRP;
if (print) {
fprintf(stderr, "w");
}
} else if (print) {
fprintf(stderr, "-");
}
if ((flags[0] & 0x20) != 0) {
permissions |= S_IXGRP;
if (print) {
fprintf(stderr, "x");
}
} else if (print) {
fprintf(stderr, "-");
}
if ((flags[0] & 0x40) != 0) {
permissions |= S_IROTH;
if (print) {
fprintf(stderr, "r");
}
} else if (print) {
fprintf(stderr, "-");
}
if ((flags[0] & 0x80) != 0) {
permissions |= S_IWOTH;
if (print) {
fprintf(stderr, "w");
}
} else if (print) {
fprintf(stderr, "-");
}
if ((flags[1] & 1) != 0) {
permissions |= S_IXOTH;
if (print) {
fprintf(stderr, "x");
}
} else if (print) {
fprintf(stderr, "-");
}
return permissions;
}
#endif
char *simple_archiver_error_to_string(enum SDArchiverStateReturns error) {
switch (error) {
case SDAS_SUCCESS:
@ -1173,12 +1334,9 @@ int simple_archiver_write_all(FILE *out_f, SDArchiverState *state,
int simple_archiver_parse_archive_info(FILE *in_f, int_fast8_t do_extract,
const SDArchiverState *state) {
uint8_t buf[1024];
memset(buf, 0, 1024);
uint8_t buf[32];
memset(buf, 0, 32);
uint16_t u16;
uint32_t u32;
uint64_t u64;
int_fast8_t is_compressed = 0;
if (fread(buf, 1, 18, in_f) != 18) {
return SDAS_INVALID_FILE;
@ -1186,10 +1344,31 @@ int simple_archiver_parse_archive_info(FILE *in_f, int_fast8_t do_extract,
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.
}
memcpy(&u16, buf, 2);
simple_archiver_helper_16_bit_be(&u16);
if (u16 == 0) {
return simple_archiver_parse_archive_version_0(in_f, do_extract, state);
} else if (u16 == 1) {
return simple_archiver_parse_archive_version_1(in_f, do_extract, state);
} else {
fprintf(stderr, "ERROR Unsupported archive version %u!\n", u16);
return SDAS_INVALID_FILE;
} else if (fread(buf, 1, 4, in_f) != 4) {
}
}
int simple_archiver_parse_archive_version_0(FILE *in_f, int_fast8_t do_extract,
const SDArchiverState *state) {
uint8_t buf[1024];
memset(buf, 0, 1024);
uint16_t u16;
uint32_t u32;
uint64_t u64;
int_fast8_t is_compressed = 0;
if (fread(buf, 1, 4, in_f) != 4) {
return SDAS_INVALID_FILE;
}
@ -1259,6 +1438,8 @@ int simple_archiver_parse_archive_info(FILE *in_f, int_fast8_t do_extract,
}
uc_heap_buf[u16 - 1] = 0;
fprintf(stderr, "Decompressor cmd: %s\n", uc_heap_buf);
decompressor_cmd = heap_buf;
heap_buf = NULL;
}
} else {
fprintf(stderr, "De/compressor flag is NOT set.\n");
@ -1365,10 +1546,10 @@ int simple_archiver_parse_archive_info(FILE *in_f, int_fast8_t do_extract,
return SDAS_INVALID_FILE;
}
mode_t permissions = 0;
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
mode_t permissions = 0;
if (do_extract == 0) {
fprintf(stderr, " Permissions: ");
@ -1854,6 +2035,324 @@ int simple_archiver_parse_archive_info(FILE *in_f, int_fast8_t do_extract,
return SDAS_SUCCESS;
}
int simple_archiver_parse_archive_version_1(FILE *in_f, int_fast8_t do_extract,
const SDArchiverState *state) {
uint8_t buf[1024];
memset(buf, 0, 1024);
uint16_t u16;
uint32_t u32;
uint64_t u64;
if (fread(buf, 1, 4, in_f) != 4) {
return SDAS_INVALID_FILE;
}
if (do_extract && state->parsed->user_cwd) {
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
if (chdir(state->parsed->user_cwd)) {
return SDAS_FAILED_TO_CHANGE_CWD;
}
#endif
}
const int_fast8_t is_compressed = (buf[0] & 1) ? 1 : 0;
__attribute__((cleanup(
simple_archiver_helper_cleanup_c_string))) char *compressor_cmd = NULL;
__attribute__((cleanup(
simple_archiver_helper_cleanup_c_string))) char *decompressor_cmd = NULL;
if (is_compressed) {
if (fread(buf, 1, 2, in_f) != 2) {
return SDAS_INVALID_FILE;
}
memcpy(&u16, buf, 2);
simple_archiver_helper_16_bit_be(&u16);
compressor_cmd = malloc(u16 + 1);
int ret =
read_buf_full_from_fd(in_f, (char *)buf, 1024, u16 + 1, compressor_cmd);
if (ret != SDAS_SUCCESS) {
return ret;
}
compressor_cmd[u16] = 0;
if (fread(buf, 1, 2, in_f) != 2) {
return SDAS_INVALID_FILE;
}
memcpy(&u16, buf, 2);
simple_archiver_helper_16_bit_be(&u16);
decompressor_cmd = malloc(u16 + 1);
ret = read_buf_full_from_fd(in_f, (char *)buf, 1024, u16 + 1,
decompressor_cmd);
if (ret != SDAS_SUCCESS) {
return ret;
}
decompressor_cmd[u16] = 0;
}
// Link count.
if (fread(buf, 1, 4, in_f) != 4) {
return SDAS_INVALID_FILE;
}
memcpy(&u32, buf, 4);
simple_archiver_helper_32_bit_be(&u32);
for (uint32_t idx = 0; idx < u32; ++idx) {
fprintf(stderr, "SYMLINK %3u of %3u\n", idx + 1, u32);
if (fread(buf, 1, 2, in_f) != 2) {
return SDAS_INVALID_FILE;
}
const uint_fast8_t absolute_preferred = (buf[0] & 1) ? 1 : 0;
uint_fast8_t link_extracted = 0;
if (fread(buf, 1, 2, in_f) != 2) {
return SDAS_INVALID_FILE;
}
memcpy(&u16, buf, 2);
simple_archiver_helper_16_bit_be(&u16);
__attribute__((
cleanup(simple_archiver_helper_cleanup_c_string))) char *link_name =
malloc(u16 + 1);
int ret =
read_buf_full_from_fd(in_f, (char *)buf, 1024, u16 + 1, link_name);
if (ret != SDAS_SUCCESS) {
return ret;
}
if (fread(buf, 1, 2, in_f) != 2) {
return SDAS_INVALID_FILE;
}
memcpy(&u16, buf, 2);
simple_archiver_helper_16_bit_be(&u16);
if (u16 != 0) {
__attribute__((
cleanup(simple_archiver_helper_cleanup_c_string))) char *path =
malloc(u16 + 1);
ret = read_buf_full_from_fd(in_f, (char *)buf, 1024, u16 + 1, path);
if (ret != SDAS_SUCCESS) {
return ret;
}
path[u16] = 0;
if (do_extract && absolute_preferred) {
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
simple_archiver_helper_make_dirs(link_name);
ret = symlink(path, link_name);
if (ret == -1) {
return SDAS_FAILED_TO_EXTRACT_SYMLINK;
}
link_extracted = 1;
fprintf(stderr, " %s -> %s\n", link_name, path);
#endif
}
}
if (fread(buf, 1, 2, in_f) != 2) {
return SDAS_INVALID_FILE;
}
memcpy(&u16, buf, 2);
simple_archiver_helper_16_bit_be(&u16);
if (u16 != 0) {
__attribute__((
cleanup(simple_archiver_helper_cleanup_c_string))) char *path =
malloc(u16 + 1);
ret = read_buf_full_from_fd(in_f, (char *)buf, 1024, u16 + 1, path);
if (ret != SDAS_SUCCESS) {
return ret;
}
path[u16] = 0;
if (do_extract && !absolute_preferred) {
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
simple_archiver_helper_make_dirs(link_name);
ret = symlink(path, link_name);
if (ret == -1) {
return SDAS_FAILED_TO_EXTRACT_SYMLINK;
}
link_extracted = 1;
fprintf(stderr, " %s -> %s\n", link_name, path);
#endif
}
}
if (!link_extracted) {
fprintf(stderr, "WARNING Symlink \"%s\" was not created!\n", link_name);
}
}
if (fread(buf, 1, 4, in_f) != 4) {
return SDAS_INVALID_FILE;
}
memcpy(&u32, buf, 4);
simple_archiver_helper_32_bit_be(&u32);
const uint32_t chunk_count = u32;
for (uint32_t chunk_idx = 0; chunk_idx < chunk_count; ++chunk_idx) {
fprintf(stderr, "CHUNK %3u of %3u\n", chunk_idx + 1, chunk_count);
if (fread(buf, 1, 2, in_f) != 2) {
return SDAS_INVALID_FILE;
}
memcpy(&u16, buf, 2);
simple_archiver_helper_16_bit_be(&u16);
const uint16_t file_count = u16;
__attribute__((cleanup(simple_archiver_list_free)))
SDArchiverLinkedList *file_info_list = simple_archiver_list_init();
__attribute__((cleanup(cleanup_internal_file_info)))
SDArchiverInternalFileInfo *file_info = NULL;
for (uint16_t file_idx = 0; file_idx < file_count; ++file_idx) {
file_info = malloc(sizeof(SDArchiverInternalFileInfo));
memset(file_info, 0, sizeof(SDArchiverInternalFileInfo));
if (fread(buf, 1, 2, in_f) != 2) {
return SDAS_INVALID_FILE;
}
memcpy(&u16, buf, 2);
simple_archiver_helper_16_bit_be(&u16);
file_info->filename = malloc(u16 + 1);
int ret = read_buf_full_from_fd(in_f, (char *)buf, 1024, u16 + 1,
file_info->filename);
if (ret != SDAS_SUCCESS) {
return ret;
}
file_info->filename[u16] = 0;
if (fread(file_info->bit_flags, 1, 4, in_f) != 4) {
return SDAS_INVALID_FILE;
}
if (fread(buf, 1, 4, in_f) != 4) {
return SDAS_INVALID_FILE;
}
memcpy(&u32, buf, 4);
simple_archiver_helper_32_bit_be(&u32);
file_info->uid = u32;
if (fread(buf, 1, 4, in_f) != 4) {
return SDAS_INVALID_FILE;
}
memcpy(&u32, buf, 4);
simple_archiver_helper_32_bit_be(&u32);
file_info->gid = u32;
if (fread(buf, 1, 8, in_f) != 8) {
return SDAS_INVALID_FILE;
}
memcpy(&u64, buf, 8);
simple_archiver_helper_64_bit_be(&u64);
file_info->file_size = u64;
simple_archiver_list_add(file_info_list, file_info,
free_internal_file_info);
file_info = NULL;
}
if (fread(buf, 1, 8, in_f) != 8) {
return SDAS_INVALID_FILE;
}
memcpy(&u64, buf, 8);
simple_archiver_helper_64_bit_be(&u64);
const uint64_t chunk_size = u64;
uint64_t chunk_idx = 0;
SDArchiverLLNode *node = file_info_list->head;
uint16_t file_idx = 0;
if (is_compressed) {
fprintf(stderr, "ERROR Extracting compressed chunks is unimplemented!\n");
return SDAS_INTERNAL_ERROR;
} else {
while (node->next != file_info_list->tail) {
node = node->next;
const SDArchiverInternalFileInfo *file_info = node->data;
fprintf(stderr, " FILE %3u of %3u\n", ++file_idx, file_count);
fprintf(stderr, " Filename: %s\n", file_info->filename);
chunk_idx += file_info->file_size;
if (chunk_idx > chunk_size) {
fprintf(stderr, "ERROR Files in chunk is larger than chunk!\n");
return SDAS_INTERNAL_ERROR;
} else if (do_extract) {
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
mode_t permissions =
permissions_from_bits_version_1(file_info->bit_flags, 0);
#endif
if ((state->parsed->flags & 8) == 0) {
// Check if file already exists.
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
FILE *temp_fd = fopen(file_info->filename, "r");
if (temp_fd) {
fprintf(stderr,
" WARNING: File already exists and "
"\"--overwrite-extract\" is not specified, skipping!\n");
int ret = read_buf_full_from_fd(in_f, (char *)buf, 1024,
file_info->file_size, NULL);
if (ret != SDAS_SUCCESS) {
return ret;
}
continue;
}
}
simple_archiver_helper_make_dirs(file_info->filename);
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
FILE *out_fd = fopen(file_info->filename, "wb");
int ret = read_fd_to_out_fd(in_f, out_fd, (char *)buf, 1024,
file_info->file_size);
if (ret != SDAS_SUCCESS) {
return ret;
}
simple_archiver_helper_cleanup_FILE(&out_fd);
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
if (chmod(file_info->filename, permissions) == -1) {
return SDAS_INTERNAL_ERROR;
} else if (geteuid() == 0 &&
chown(file_info->filename, file_info->uid,
file_info->gid) != 0) {
fprintf(stderr,
"ERROR Failed to set UID/GID as EUID 0 of file \"%s\"!\n",
file_info->filename);
return SDAS_INTERNAL_ERROR;
}
#endif
} else {
fprintf(stderr, " Permissions: ");
permissions_from_bits_version_1(file_info->bit_flags, 1);
fprintf(stderr, "\n UID: %u\n GID: %u\n", file_info->uid,
file_info->gid);
if (is_compressed) {
fprintf(stderr, " File size (compressed): %lu\n",
file_info->file_size);
} else {
fprintf(stderr, " File size: %lu\n", file_info->file_size);
}
int ret = read_buf_full_from_fd(in_f, (char *)buf, 1024,
file_info->file_size, NULL);
if (ret != SDAS_SUCCESS) {
return ret;
}
}
}
}
}
return SDAS_SUCCESS;
}
int simple_archiver_de_compress(int pipe_fd_in[2], int pipe_fd_out[2],
const char *cmd, void *pid_out) {
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \

View file

@ -69,6 +69,14 @@ int simple_archiver_write_all(FILE *out_f, SDArchiverState *state,
int simple_archiver_parse_archive_info(FILE *in_f, int_fast8_t do_extract,
const SDArchiverState *state);
/// Returns zero on success.
int simple_archiver_parse_archive_version_0(FILE *in_f, int_fast8_t do_extract,
const SDArchiverState *state);
/// Returns zero on success.
int simple_archiver_parse_archive_version_1(FILE *in_f, int_fast8_t do_extract,
const SDArchiverState *state);
/// Returns zero on success.
int simple_archiver_de_compress(int pipe_fd_in[2], int pipe_fd_out[2],
const char *cmd, void *pid_out);