aboutsummaryrefslogtreecommitdiff
path: root/src/proone-unpack.c
diff options
context:
space:
mode:
authorDavid Timber <mieabby@gmail.com>2020-01-19 13:12:29 +1100
committerDavid Timber <mieabby@gmail.com>2020-01-19 13:12:29 +1100
commitd328cbbdc256197d02ec03eef0022b4122d38bb8 (patch)
tree088f711afe755ef99c28955fab716a0752e47029 /src/proone-unpack.c
parenta9762b186c68797c19c61bf0284a80d9bc51a2ca (diff)
bin pack redesign. resolv bug fix
Diffstat (limited to 'src/proone-unpack.c')
-rw-r--r--src/proone-unpack.c202
1 files changed, 100 insertions, 102 deletions
diff --git a/src/proone-unpack.c b/src/proone-unpack.c
index ff08e48..d7787a8 100644
--- a/src/proone-unpack.c
+++ b/src/proone-unpack.c
@@ -5,146 +5,144 @@
#include <unistd.h>
#include <fcntl.h>
-
-#include <zlib.h>
-#include <mbedtls/error.h>
+#include <sys/mman.h>
#include "pack.h"
#include "util_rt.h"
+#define USE_MMAP 1
-static void report_unpack_bin_archive_err (const prne_unpack_bin_archive_result_t *r) {
- const char *err_str, *err_msg = NULL;
- char err_buf[1024];
-
- switch (r->result) {
- case PRNE_UNPACK_BIN_ARCHIVE_OK:
- err_str = "ok";
- break;
- case PRNE_UNPACK_BIN_ARCHIVE_CRYPTO_ERR:
- err_str = "crypto error";
- mbedtls_strerror(r->err, err_buf, 1024);
- err_msg = err_buf;
- break;
- case PRNE_UNPACK_BIN_ARCHIVE_Z_ERR:
- err_str = "zlib error";
- err_msg = zError((int)r->err);
- break;
- case PRNE_UNPACK_BIN_ARCHIVE_ERRNO:
- err_str = "errno";
- err_msg = strerror((int)r->err);
- break;
- case PRNE_UNPACK_BIN_ARCHIVE_MEM_ERR:
- err_str = "memory error";
- err_msg = strerror((int)r->err);
- break;
- case PRNE_UNPACK_BIN_ARCHIVE_FMT_ERR:
- err_str = "format error";
- break;
- default:
- err_str = "* unknown";
- }
-
- if (err_msg == NULL) {
- fprintf(stderr, "%s.\n", err_str);
- }
- else {
- fprintf(stderr, "%s: %s\n", err_str, err_msg);
- }
-}
-static void report_index_bin_archive_err (const prne_index_bin_archive_result_code_t c) {
- const char *msg;
-
- switch (c) {
- case PRNE_INDEX_BIN_ARCHIVE_OK:
- msg = "ok"; break;
- case PRNE_INDEX_BIN_ARCHIVE_FMT_ERR:
- msg = "format error"; break;
- case PRNE_INDEX_BIN_ARCHIVE_MEM_ERR:
- msg = "memory error"; break;
- default:
- msg = "* unknown"; break;
- }
+static void report_pack_ret (const prne_pack_ret_t pr) {
+ char *str = prne_pack_ret_tostr(pr);
- fprintf(stderr, "%s.\n", msg);
+ fprintf(stderr, "%s\n", str);
+ prne_free(str);
}
+
int main (const int argc, const char **args) {
int exit_code = 0;
const char *path_prefix;
size_t path_prefix_len;
- prne_unpack_bin_archive_result_t unpack_ret;
+ prne_stdin_base64_rf_ctx_t rf_ctx;
prne_bin_archive_t bin_archive;
- prne_index_bin_archive_result_code_t index_ret;
+ prne_pack_ret_t pr;
size_t i;
const char *arch_str;
char *path = NULL;
size_t path_size;
void *ny_buf;
int fd = -1;
+ prne_unpack_ctx_pt unpack_ctx = NULL;
+#if USE_MMAP
+ void *addr = NULL;
+#else
+ uint8_t write_buf[512];
+ ssize_t write_len;
+#endif
if (argc <= 1) {
fprintf(stderr, "Usage: %s <prefix>\n", args[0]);
- return 1;
+ return 2;
}
path_prefix = args[1];
path_prefix_len = strlen(path_prefix);
prne_init_bin_archive(&bin_archive);
+ prne_init_stdin_base64_rf_ctx(&rf_ctx);
+
+ pr = prne_index_bin_archive(&rf_ctx, prne_stdin_base64_rf, &bin_archive);
+ if (pr.rc != PRNE_PACK_RC_OK) {
+ report_pack_ret(pr);
+ exit_code = 1;
+ goto END;
+ }
+
+ for (i = 0; i < bin_archive.nb_bin; i += 1) {
+ arch_str = prne_arch_tostr(bin_archive.bin[i].arch);
+ if (arch_str == NULL) {
+ fprintf(stderr, "** unrecognised arch!");
+ exit_code = 1;
+ goto END;
+ }
- do { // fake loop
- unpack_ret = prne_unpack_bin_archive(STDIN_FILENO);
- if (unpack_ret.result != PRNE_UNPACK_BIN_ARCHIVE_OK) {
- report_unpack_bin_archive_err(&unpack_ret);
- exit_code = 2;
- break;
+ unpack_ctx = prne_alloc_unpack_ctx(&bin_archive, bin_archive.bin[i].arch, &pr);
+ if (unpack_ctx == NULL) {
+ report_pack_ret(pr);
+ exit_code = 1;
+ goto END;
+ }
+
+ path_size = 2 + path_prefix_len + strlen(arch_str);
+ ny_buf = prne_realloc(path, 1, path_size);
+ if (ny_buf == NULL) {
+ perror("prne_realloc()");
+ exit_code = 1;
+ goto END;
+ }
+ path = (char*)ny_buf;
+ if (sprintf(path, "%s.%s", path_prefix, arch_str) < 0) {
+ perror("sprintf()");
+ exit_code = 1;
+ goto END;
}
- index_ret = prne_index_bin_archive(&unpack_ret, &bin_archive);
- if (index_ret != PRNE_INDEX_BIN_ARCHIVE_OK) {
- report_index_bin_archive_err(index_ret);
- exit_code = 2;
- break;
+ fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0666);
+ if (fd < 0) {
+ perror("open()");
+ exit_code = 1;
+ goto END;
+ }
+#if USE_MMAP
+ if (ftruncate(fd, bin_archive.bin[i].size) != 0) {
+ perror("ftruncate()");
+ exit_code = 1;
+ goto END;
+ }
+ addr = mmap(NULL, bin_archive.bin[i].size, PROT_WRITE, MAP_SHARED, fd, 0);
+ if (addr == MAP_FAILED) {
+ perror("mmap()");
+ exit_code = 1;
+ goto END;
}
- for (i = 0; i < bin_archive.nb_binaries; i += 1) {
- arch_str = prne_arch_tostr(bin_archive.arch_arr[i]);
- if (arch_str == NULL) {
- fprintf(stderr, "** unrecognised arch!");
- exit_code = 2;
- break;
- }
-
- path_size = 2 + path_prefix_len + strlen(arch_str);
- ny_buf = prne_realloc(path, 1, path_size);
- if (ny_buf == NULL) {
- perror("prne_realloc()");
- exit_code = 2;
- break;
- }
- path = (char*)ny_buf;
- sprintf(path, "%s.%s", path_prefix, arch_str);
-
- fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0666);
- if (fd < 0) {
- perror("open()");
- exit_code = 2;
- break;
- }
- if (write(fd, bin_archive.data + bin_archive.offset_arr[i], bin_archive.size_arr[i]) != (ssize_t)bin_archive.size_arr[i]) {
- perror("write()");
- exit_code = 2;
- break;
- }
- prne_close(fd);
+ if (prne_do_unpack(unpack_ctx, (uint8_t*)addr, bin_archive.bin[i].size, &pr) != (ssize_t)bin_archive.bin[i].size) {
+ report_pack_ret(pr);
+ exit_code = 1;
+ goto END;
}
- } while (false);
+ munmap(addr, bin_archive.bin[i].size);
+ addr = NULL;
+#else
+ do {
+ write_len = prne_do_unpack(unpack_ctx, write_buf, sizeof(write_buf), &pr);
+ if (write_len < 0) {
+ report_pack_ret(pr);
+ exit_code = 1;
+ goto END;
+ }
+ write(fd, write_buf, (size_t)write_len);
+ } while (write_len != 0);
+#endif
+ prne_free_unpack_ctx(unpack_ctx);
+ unpack_ctx = NULL;
+ prne_close(fd);
+ fd = -1;
+ }
+
+END:
+#if USE_MMAP
+ if (addr != NULL) {
+ munmap(addr, bin_archive.bin[i].size);
+ }
+#endif
+ prne_free_unpack_ctx(unpack_ctx);
prne_free(path);
prne_close(fd);
- prne_free_unpack_bin_archive_result(&unpack_ret);
prne_free_bin_archive(&bin_archive);
+ prne_free_stdin_base64_rf_ctx(&rf_ctx);
return exit_code;
}