summaryrefslogtreecommitdiff
path: root/src/main.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/main.c
parent3b9772a65146afb36e29b5bce082ce5aa1483c22 (diff)
Began inevetable rewrite.
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c137
1 files changed, 3 insertions, 134 deletions
diff --git a/src/main.c b/src/main.c
index 2ba65db..892958e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,7 +1,9 @@
-/* This file is part of Nekopack.
+/* main.c -- Entry point to Nekopack.
Copyright (C) 2017 Jakob Tsar-Fox, All Rights Reserved.
+ This file is part of Nekopack.
+
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
@@ -14,136 +16,3 @@
You should have received a copy of the GNU General Public License
along with Nekopack. If not, see <http://www.gnu.org/licenses/>. */
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "cli.h"
-#include "decompress.h"
-#include "extract.h"
-
-#define XP3_MAGIC "XP3\x0d\x0a\x20\x0a\x1a\x8b\x67\x01"
-#define XP3_TABLE_OFFSET 11
-#define XP3_VERSION_OFFSET 19
-
-void handle_archive(char *path);
-int is_xp3_archive(FILE *archive);
-int get_archive_version(FILE *archive);
-uint64_t get_table_offset(FILE *archive, uint8_t archive_version);
-
-/* Global instance of the command-line configuration structure. */
-struct configuration arguments;
-
-
-int main(int argc, char *argv[]) {
- arguments = parse_args(argc, argv);
- for (int i = arguments.vararg_index; i < argc; i++)
- handle_archive(argv[i]);
- free(arguments.output);
- return 0;
-}
-
-
-/* Extracts the archive at the specified path. */
-void handle_archive(char *path) {
- FILE *archive = fopen(path, "rb");
- if (archive == NULL) {
- /* Including the expanded path in the error message is
- much more useful to the user than `perror("fopen")`. */
- perror(path);
- exit(EXIT_FAILURE);
- } else if (!is_xp3_archive(archive)) {
- fprintf(stderr, "%s is not an XP3 archive.\n", path);
- fclose(archive);
- exit(EXIT_FAILURE);
- }
-
- int archive_version = get_archive_version(archive);
- uint64_t table_offset = get_table_offset(archive, archive_version);
-
- uint8_t compressed;
- uint64_t compressed_size, decompressed_size;
- fseek(archive, table_offset, SEEK_SET);
- fread(&compressed, sizeof(uint8_t), 1, archive);
- fread(&compressed_size, sizeof(uint64_t), 1, archive);
- fread(&decompressed_size, sizeof(uint64_t), 1, archive);
-
- /* Every task that hasn't already been handled needs a
- decompressed instance of the archive table. Decompression
- done in memory because it's $CURRENT_YEAR. */
- memory_stream data_stream;
- memory_stream compressed_data = read_to_stream(archive, compressed_size);
- if (compressed) {
- data_stream = decompress_stream(compressed_data, decompressed_size);
- free(compressed_data.start);
- } else {
- data_stream = compressed_data;
- }
-
- switch (arguments.mode) {
- case EXTRACT:
- extract(data_stream, archive);
- break;
- case LIST:
- list(data_stream);
- }
-
- free(data_stream.start);
- fclose(archive);
-}
-
-
-/* Check of the file's magic number to decide
- whether or not the file a valid XP3 archive. */
-int is_xp3_archive(FILE *archive) {
- int ret = 1;
- char* buffer = malloc(11);
- rewind(archive);
- fread(buffer, 11, 1, archive);
- if (memcmp(buffer, XP3_MAGIC, 11))
- ret = 0;
- free(buffer);
- return ret;
-}
-
-
-/* Returns the version of XP3 used to pack the archive. */
-int get_archive_version(FILE *archive) {
- uint32_t version;
- fseek(archive, XP3_VERSION_OFFSET, SEEK_SET);
- fread(&version, sizeof(uint32_t), 1, archive);
- /* 0x00 indicates version 1, and 0x01 indicates version 2. */
- return version == 1 ? 2 : 1;
-}
-
-
-/* Subroutine for finding the archive's table offset. If
- the minor_version is invalid, the program will exit. */
-uint64_t get_table_offset(FILE *archive, uint8_t archive_version) {
- uint64_t table_offset;
- fseek(archive, XP3_TABLE_OFFSET, SEEK_SET);
- fread(&table_offset, sizeof(uint64_t), 1, archive);
- if (archive_version == 1)
- return table_offset;
-
- /* The minor version is only present in XP3 version 2. */
- uint32_t minor_version;
- fread(&minor_version, sizeof(uint32_t), 1, archive);
- if (minor_version != 1) {
- fprintf(stderr, "Archive version not implemented.\n");
- fclose(archive);
- exit(EXIT_FAILURE);
- }
-
- /* The value initally read as table_offset is actually an offset to
- the real table offset. (Try saying that five times fast.) */
- fseek(archive, table_offset, SEEK_SET);
- /* Table flags and size are ignored in the parsing process,
- but are read anyway to advance the FILE pointer. */
- fseek(archive, sizeof(uint8_t) + sizeof(uint64_t), SEEK_CUR);
- fread(&table_offset, sizeof(uint64_t), 1, archive);
- return table_offset;
-}