diff --git a/extractor/cum_xct.c b/extractor/cum_xct.c index 07da0ad..b331017 100644 --- a/extractor/cum_xct.c +++ b/extractor/cum_xct.c @@ -6,12 +6,14 @@ * Author: Chloe M. */ +#include #include #include #include #include #include #include +#include #define REF_MAGIC "CUMHOLE" #define REF_MAGIC_LEN 8 @@ -36,6 +38,32 @@ struct hole_ref { /* Globals */ static char *input_path = NULL; +static void +mkdir_recurse(const char *path) +{ + char buf[256]; + char *p = NULL; + size_t len; + + snprintf(buf, sizeof(buf), "%s", path); + len = strlen(buf); + + /* Strip trailing slash */ + if (buf[len - 1] == '/') + buf[len - 1] = '\0'; + + /* Make directory of each component */ + for (p = buf; *p != '\0'; ++p) { + if (*p == '/') { + *p = '\0'; + mkdir(buf, S_IRWXU); + *p = '/'; + } + } + + mkdir(buf, S_IRWXU); +} + static void help(void) { @@ -44,9 +72,35 @@ help(void) printf("[-i] Input CUMHOLE bundle\n"); } +static int +push_file(const char *path, void *data, size_t size) +{ + int fd; + + if (path == NULL || data == NULL) { + return -1; + } + + fd = open(path, O_RDWR | O_CREAT, 0777); + if (fd < 0) { + printf("fatal: failed to open '%s'\n", path); + perror("open"); + return -1; + } + + write(fd, data, size); + close(fd); + return 0; +} + static void do_parse(struct hole_ref *ref) { + const char *directory_name; + struct hole_ref *ref_base = ref; + char *path; + void *data; + if (ref == NULL) { return; } @@ -56,7 +110,19 @@ do_parse(struct hole_ref *ref) break; } - printf("found '%s' with size %ld\n", ref->path, ref->size); + path = strdup(ref->path); + directory_name = dirname(path); + mkdir_recurse(directory_name); + + printf("creating %s\n", ref->path); + data = (void *)((char *)ref_base + ref->data_off); + + if (push_file(ref->path, data, ref->size) < 0) { + free(path); + return; + } + + free(path); ++ref; } }