summaryrefslogtreecommitdiff
path: root/src/write.c
diff options
context:
space:
mode:
authorjakob <jakob@memeware.net>2017-02-13 16:53:11 -0500
committerjakob <jakob@memeware.net>2017-02-13 16:53:11 -0500
commit01d185f31ff7194773342881fa0e0a550b5d5c5a (patch)
treee708be1001500e0932f77f82483e6c90a3e4e24d /src/write.c
parent3b9772a65146afb36e29b5bce082ce5aa1483c22 (diff)
Began inevetable rewrite.
Diffstat (limited to 'src/write.c')
-rw-r--r--src/write.c201
1 files changed, 0 insertions, 201 deletions
diff --git a/src/write.c b/src/write.c
deleted file mode 100644
index 7a0d90e..0000000
--- a/src/write.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/* This file is part of Nekopack.
-
- Copyright (C) 2017 Jakob Tsar-Fox, All Rights Reserved.
-
- Nekopack is free software: you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- Nekopack is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Nekopack. If not, see <http://www.gnu.org/licenses/>. */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "crypto.h"
-#include "decompress.h"
-#include "defs.h"
-#include "extract.h"
-#include "file.h"
-#include "write.h"
-
-/* Global instance of the command-line configuration structure. */
-extern struct configuration arguments;
-
-
-/* Finds an eliF entry with the given key in a linked list and returns
- the associated filename, removing it from the linked list. */
-char *pop_file_name(uint32_t key, elif_node *root) {
- char *file_name = NULL;
- elif_node *current = root->next, *last = root;
- for (;;) {
- if (current->key == key) {
- file_name = current->file_name;
- last->next = current->next;
- free(current);
- break;
- } else if (current->next == NULL) {
- break;
- } else {
- last = current;
- current = current->next;
- }
- }
- return file_name;
-}
-
-
-/* Creates all of the paths in a filename. */
-void make_paths(char *file_name) {
- /* This structure is only used for the stat call. */
- struct stat temp = {0};
-
- /* Max filename size. */
- char *buffer = calloc(0x100, 1);
- char *buffer_start = buffer;
- for (int i = 0; i < 0x100 && file_name[i] != '\0'; i++) {
- if (file_name[i] == '/') {
- *buffer++ = PATH_DELIMITER;
- *buffer = '\0';
- if (stat(buffer_start, &temp) == -1) {
- if (!arguments.quiet)
- printf("Creating directory %s\n", buffer_start);
- mkdir(buffer_start, 0777);
- }
- } else {
- *buffer++ = file_name[i];
- }
- }
- free(buffer_start);
-}
-
-
-/* Iterates through the linked list of file entries and writes every
- entry to disk, according to information specified by the node. */
-void write_files(file_node *file_root, elif_node *elif_root, FILE *archive) {
- file_node *current;
- key encryption_key = get_encryption_key(arguments.game);
- Bytef *compressed_buffer, *decompressed_buffer, *out_buffer, *out_start;
- for (current = file_root->next; current != NULL; current = current->next) {
- char *file_name = pop_file_name(current->key, elif_root);
- if (file_name == NULL)
- continue;
-
- /* strcpy is used rather than strcat to prevent the file
- name from being appended after garbage data. */
- size_t file_name_size = strlen(file_name);
- size_t path_size = strlen(arguments.output);
- char *output_path = malloc(path_size + file_name_size + 1);
- if (output_path == NULL) {
- fprintf(stderr, "Insufficient memory.\n");
- return;
- }
- strcpy(output_path, arguments.output);
- strcpy(output_path + path_size, file_name);
-
- if (!arguments.quiet) {
- printf("Inflating %s (%" PRIu64 " bytes)\n",
- file_name, current->file_size);
- }
-
- out_buffer = malloc(current->file_size);
- if (out_buffer == NULL) {
- fprintf(stderr, "Insufficient memory to decompress.\n");
- return;
- }
-
- /* out_start is kept so out_buffer can be incremented. */
- out_start = out_buffer;
- for (uint64_t i = 0; i < current->segment_count; i++) {
- segment *chunk = current->segments[i];
- fseek(archive, chunk->offset, SEEK_SET);
- compressed_buffer = malloc(chunk->compressed_size);
- fread(compressed_buffer, chunk->compressed_size, 1, archive);
-
- if (chunk->compressed) {
- decompressed_buffer = inflate_chunk(compressed_buffer,
- chunk->compressed_size,
- chunk->decompressed_size);
- free(compressed_buffer);
- } else {
- decompressed_buffer = compressed_buffer;
- }
- memcpy(out_buffer, decompressed_buffer, chunk->decompressed_size);
- out_buffer += chunk->decompressed_size;
- free(decompressed_buffer);
- }
-
- if (arguments.game != NO_CRYPTO) {
- decrypt_buffer(out_start, current->file_size,
- encryption_key, current->key);
- }
-
- make_paths(output_path);
- FILE *output = fopen(output_path, "wb+");
- if (output == NULL) {
- perror(output_path);
- break;
- }
- fwrite(out_start, current->file_size, 1, output);
- fclose(output);
- free(output_path);
- free(file_name);
- free(out_start);
- }
-}
-
-
-/* Inserts an eliF entry at the end of a linked list. */
-void defer_elif_node(elif_node *new, elif_node *root) {
- elif_node *current = root;
- for (;;) {
- if (current->next == NULL) {
- current->next = new;
- break;
- } else {
- current = current->next;
- }
- }
-}
-
-
-/* Inserts a File entry node at the end of a linked list. */
-void defer_file_node(file_node *new, file_node *root) {
- file_node *current = root;
- for (;;) {
- if (current->next == NULL) {
- current->next = new;
- break;
- } else {
- current = current->next;
- }
- }
-}
-
-
-/* Iterates through the linked list and frees all entries. */
-void free_elif_nodes(elif_node *base) {
- if (base->next != NULL) {
- free_elif_nodes(base->next);
- }
- free(base->file_name);
- free(base);
-}
-
-
-/* Iterates through the linked list and frees all entries. */
-void free_file_nodes(file_node *base) {
- if (base->next != NULL)
- free_file_nodes(base->next);
- free(base);
-}