diff options
| -rw-r--r-- | other/find_key.py | 1 | ||||
| -rw-r--r-- | src/cli.c | 23 | ||||
| -rw-r--r-- | src/cli.h | 1 | ||||
| -rw-r--r-- | src/main.c | 17 |
4 files changed, 21 insertions, 21 deletions
diff --git a/other/find_key.py b/other/find_key.py index 3371f21..7aa2fd9 100644 --- a/other/find_key.py +++ b/other/find_key.py @@ -18,6 +18,7 @@ KNOWN_MAGICS = [("png", b"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"), ("ogg", b"\x4f\x67\x67\x53"), ("psb", b"\x50\x53\x42\x00"), ("mstand", b"\xff\xfe"), + # ("tjs", b"\xff\xfe"), ("csv", b"\xff\xfe")] @@ -34,8 +34,6 @@ " -e, --extract\tExtract the contents of the archive. " \ "This is the default.\n" \ " -l, --list\t\tList the contents of the archive.\n\n" \ - " -a, --archive\tAlternate way of specifying archive" \ - "to extract.\n" \ " -o, --output\t\tPath to extract files to.\n" \ " -g, --game\t\tGame the archive is from. Required for " \ "file decryption\n" \ @@ -68,14 +66,13 @@ struct configuration parse_args(int argc, char *argv[]) { {"quiet", no_argument, NULL, 'q'}, {"extract", no_argument, NULL, 'e'}, {"list", no_argument, NULL, 'l'}, - {"archive", required_argument, NULL, 'a'}, {"output", required_argument, NULL, 'o'}, {"game", required_argument, NULL, 'g'}, {NULL, 0, NULL, 0} }; do { - current = getopt_long(argc, argv, "hvelqa:o:g:", long_options, + current = getopt_long(argc, argv, "hvelqo:g:", long_options, &option_index); switch (current) { case 'h': @@ -90,10 +87,6 @@ struct configuration parse_args(int argc, char *argv[]) { case 'q': parsed.quiet = 1; break; - case 'a': - count++; - parsed.archive = optarg; - break; case 'o': count++; size_t path_size = strlen(optarg); @@ -128,15 +121,13 @@ struct configuration parse_args(int argc, char *argv[]) { count++; } while (current >= 0); - /* getopt "sorts" the argument array such that all of the flags come - first. argv[count] is the first positional argument encountered. */ - if (parsed.archive == NULL) { - if (argv[count] == NULL) { - fprintf(stderr, "No archive path provided.\n"); - exit(EXIT_FAILURE); - } - parsed.archive = argv[count]; + /* getopt pushes non-flag arguments to the end of argv, and `count` + is only incremented when a flag argument is parsed. */ + if (count == argc) { + fprintf(stderr, "No archive path provided.\n"); + exit(EXIT_FAILURE); } + parsed.vararg_index = count; /* The output path is allocated on the heap to simplify freeing. */ if (parsed.output == NULL) { @@ -38,6 +38,7 @@ typedef enum mode_type { /* Binary structure for storing command-line options. */ struct configuration { int quiet; /* Level of output verbosity. */ + int vararg_index; /* Index of where a variadic list of paths starts. */ game_type game; /* Which decryption key to use. */ mode_type mode; /* What to do after initial sanity checks. */ char *output; /* Path to extract files to. */ @@ -29,6 +29,7 @@ #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); @@ -39,15 +40,23 @@ 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; +} - FILE *archive = fopen(arguments.archive, "rb"); + +/* 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(arguments.archive); + perror(path); exit(EXIT_FAILURE); } else if (!is_xp3_archive(archive)) { - fprintf(stderr, "%s is not an XP3 archive.\n", arguments.archive); + fprintf(stderr, "%s is not an XP3 archive.\n", path); fclose(archive); exit(EXIT_FAILURE); } @@ -82,10 +91,8 @@ int main(int argc, char *argv[]) { list(data_stream); } - free(arguments.output); free(data_stream.start); fclose(archive); - return 0; } |