diff options
| -rw-r--r-- | src/compress.c | 11 | ||||
| -rw-r--r-- | src/header.c | 3 | ||||
| -rw-r--r-- | src/main.c | 106 | ||||
| -rw-r--r-- | src/table.c | 26 |
4 files changed, 102 insertions, 44 deletions
diff --git a/src/compress.c b/src/compress.c index 3137145..71e0ae3 100644 --- a/src/compress.c +++ b/src/compress.c @@ -65,10 +65,13 @@ struct stream *stream_inflate(struct stream *s, size_t len, /* Deflates `s` into a newly allocated stream structure. */ struct stream *stream_deflate(struct stream *s, size_t len) { struct stream *new = stream_new(len); - z_stream strm; - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; + if (new == NULL) + return NULL; + + z_stream strm; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; if (deflateInit(&strm, LEVEL) != Z_OK) return NULL; diff --git a/src/header.c b/src/header.c index e2f09b2..a5b6477 100644 --- a/src/header.c +++ b/src/header.c @@ -66,7 +66,8 @@ struct header *read_header(struct stream *s) { /* Generates an XP3 header structure readable by Nekopara. */ struct header *create_header(void) { struct header *h = malloc(sizeof(struct header)); - if (h == NULL) return NULL; + if (h == NULL) + return NULL; memcpy(h->magic, XP3_MAGIC, 11); h->info_offset = 17; @@ -103,6 +103,9 @@ void make_dirs(char *path) { static char *get_path(struct params p, char *name) { size_t name_len = strlen(name); char *path = malloc(p.out_len + name_len + 2); + if (path == NULL) + return NULL; + strcpy(path, p.out); strcpy(path + p.out_len, name); return path; @@ -125,6 +128,9 @@ static void extract(struct stream *s, struct table_entry *e, struct params p) { } char *path = get_path(p, e->filename); + if (path == NULL) + return; + make_dirs(path); FILE *fp = fopen(path, "wb+"); @@ -187,7 +193,7 @@ static void map_entries(char *path, struct params p) { fprintf(stderr, "Error allocating memory.\n"); return; } - + struct table_entry *root = read_table(table); if (root == NULL) { fprintf(stderr, "Error allocating memory.\n"); @@ -214,21 +220,36 @@ static void map_entries(char *path, struct params p) { first string in `paths`, and the files at any following paths will be flattened into the archive. */ static void create_archive(char **paths, int argc, struct params p) { + struct stream *table_compressed, *file_compressed, *file; + struct table_entry *cur; + FILE *fp = fopen(paths[0], "wb+"); if (fp == NULL) { perror(paths[0]); return; } - struct table_entry *root = calloc(sizeof(struct table_entry), 1); - struct table_entry *cur; - struct header *h = create_header(); - struct stream *table_compressed, *data_compressed; - struct stream *data = stream_new(1); - struct stream *table = stream_new(1); - struct stream *file; - uint64_t data_size = 0; - uint64_t table_size = 0; + struct table_entry *root = calloc(sizeof(struct table_entry), 1); + if (root == NULL) { + fprintf(stderr, "Error allocating memory.\n"); + return; + } + + struct header *h = create_header(); + if (h == NULL) { + fprintf(stderr, "Error allocating memory.\n"); + return; + } + + struct stream *data = stream_new(1); + struct stream *table = stream_new(1); + if (data == NULL || table == NULL) { + fprintf(stderr, "Error allocating memory.\n"); + return; + } + + uint64_t data_size = 0; + uint64_t table_size = 0; for (int i = 1; i < argc - p.vararg_index; i++) { file = stream_from_file(paths[i]); @@ -237,37 +258,70 @@ static void create_archive(char **paths, int argc, struct params p) { continue; } - data_size += file->len; - stream_concat(data, file, file->len); + file_compressed = stream_deflate(file, file->len); + if (file_compressed == NULL) { + fprintf(stderr, "Unable to compress data.\n"); + return; + } + + data_size += file_compressed->len; + stream_concat(data, file_compressed, file_compressed->len); cur = add_file(root, paths[i]); + if (cur == NULL) { + fprintf(stderr, "Error allocating memory.\n"); + return; + } + /* TODO: Separate into own function. */ table_size += 20 + strlen(cur->filename) * 2; - table_size += 28 * cur->segment_count + 48; - } + table_size += 28 * cur->segment_count + 56; - h->table_size = table_size; - h->table_offset = 40 + data_size; + cur->segments = malloc(sizeof(struct segment *)); + if (cur->segments == NULL) { + fprintf(stderr, "Error allocating memory.\n"); + return; + } + + cur->segments[0] = malloc(sizeof(struct segment)); + if (cur->segments[0] == NULL) { + fprintf(stderr, "Error allocating memory.\n"); + return; + } + + cur->segments[0]->compressed = 1; + cur->segments[0]->offset = 40 + data_size; + cur->segments[0]->decompressed_size = file->len; + cur->segments[0]->compressed_size = file_compressed->len; + + stream_free(file_compressed); + stream_free(file); + } dump_table(table, root); - data_compressed = stream_deflate(data, data_size); + stream_seek(table, 0, SEEK_SET); table_compressed = stream_deflate(table, table_size); - stream_free(data); stream_free(table); + if (table_compressed == NULL) { + fprintf(stderr, "Unable to compress data.\n"); + return; + } + h->table_size = data->len; // This isn't right <:^) + h->table_offset = 40 + data->len; dump_header(fp, h); + /* FIXME: Formatting and this initial seek might not be necessary. */ - stream_seek(data_compressed, 0, SEEK_SET); - stream_dump(fp, data_compressed, data_size); + stream_seek(data, 0, SEEK_SET); + stream_dump(fp, data, data->len); /* FIXME: May be an incompatible value. Also, move this shitty hack. */ - uint8_t compressed = 0x80; - uint64_t len = table_compressed->len, decompressed_len = table_size; - fwrite(&compressed, sizeof(uint8_t), 1, fp); - fwrite(&len, sizeof(uint64_t), 1, fp); - fwrite(&decompressed_len, sizeof(uint64_t), 1, fp); + uint8_t compressed = 1; + fwrite(&compressed, sizeof(uint8_t), 1, fp); + fwrite(&table_compressed->len, sizeof(uint64_t), 1, fp); + fwrite(&table_size, sizeof(uint64_t), 1, fp); - stream_dump(fp, table_compressed, table_size); + stream_dump(fp, table_compressed, table_compressed->len); } diff --git a/src/table.c b/src/table.c index 7e11668..12daff5 100644 --- a/src/table.c +++ b/src/table.c @@ -161,14 +161,9 @@ static void dump_file(struct stream *s, struct table_entry *cur) { uint64_t bytes_written = 28 * cur->segment_count + 48; stream_write(s, &magic, sizeof(uint32_t)); stream_write(s, &bytes_written, sizeof(uint64_t)); - dump_adlr(s, cur->key); dump_time(s, cur->ctime); dump_segm(s, cur); - - stream_seek(s, -bytes_written, SEEK_CUR); - stream_write(s, &bytes_written, sizeof(uint64_t)); - stream_seek(s, bytes_written, SEEK_CUR); } @@ -224,12 +219,14 @@ void read_elif(struct stream *s, struct table_entry *root) { /* Dumps the eliF entry for `cur` into the table at `s`. */ static void dump_elif(struct stream *s, struct table_entry *cur) { - uint32_t magic = ELIF_MAGIC; - uint16_t name_len = strlen(cur->filename); - uint64_t entry_size = name_len * 2 + 8; - char *encoded = malloc(name_len * 2 + 2); + uint16_t name_len = strlen(cur->filename); + char *encoded = malloc(name_len * 2 + 2); + if (encoded == NULL) + return; utf16le_encode(cur->filename, encoded, name_len); + uint32_t magic = ELIF_MAGIC; + uint64_t entry_size = name_len * 2 + 8; stream_write(s, &magic, sizeof(uint32_t)); stream_write(s, &entry_size, sizeof(uint64_t)); stream_write(s, &cur->key, sizeof(uint32_t)); @@ -278,8 +275,6 @@ void dump_table(struct stream *s, struct table_entry *root) { dump_elif(s, cur); dump_file(s, cur); } - /* FIXME: This should be moved. */ - stream_seek(s, 0, SEEK_SET); } @@ -287,13 +282,18 @@ void dump_table(struct stream *s, struct table_entry *root) { specified by `root`. */ struct table_entry *add_file(struct table_entry *root, char *path) { struct table_entry *new = calloc(sizeof(struct table_entry), 1); + if (new == NULL) + return NULL; + size_t name_len = strlen(path); new->filename = malloc(name_len); - strncpy(new->filename, path, name_len); + if (new->filename == NULL) + return NULL; + strncpy(new->filename, path, name_len); new->key = 0xffffffff; new->ctime = 0; - new->segment_count = 0; + new->segment_count = 1; entry_append(root, new); return new; |