2018-09-14 01:02:12 +02:00
|
|
|
#include <getopt.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "decrypt.h"
|
2018-09-14 01:41:35 +02:00
|
|
|
#include "errorAndExit.h"
|
2018-09-14 01:02:12 +02:00
|
|
|
#include "parseArguments.h"
|
|
|
|
|
2018-09-14 01:41:35 +02:00
|
|
|
//Uses GNU's getopt_long_only(), see https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Options.html
|
|
|
|
|
2018-09-14 01:02:12 +02:00
|
|
|
static struct option long_options[] = {
|
|
|
|
{"disk", required_argument, 0, 'd'},
|
|
|
|
{"offset", required_argument, 0, 'o'},
|
|
|
|
{"size", required_argument, 0, 's'},
|
|
|
|
{"keys", required_argument, 0, 'k'},
|
|
|
|
{"prev", required_argument, 0, 'p'},
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct arguments parseArguments(int argc, char *argv[]) {
|
|
|
|
//Stores current state from command line arguments, initialized to zero
|
|
|
|
struct arguments state = {};
|
|
|
|
|
2018-09-14 01:41:35 +02:00
|
|
|
bool hasDisk = false;
|
|
|
|
bool hasOffset = false;
|
|
|
|
bool hasSize = false;
|
2018-09-14 01:02:12 +02:00
|
|
|
|
|
|
|
while (1) {
|
2018-09-14 01:41:35 +02:00
|
|
|
//In this variable, getopt_long stores the current long option that was found. Unused since we don't use flags in our long options
|
|
|
|
int optionIndex = 0;
|
2018-09-14 01:02:12 +02:00
|
|
|
|
2018-09-14 01:41:35 +02:00
|
|
|
int curOption = getopt_long_only(argc, argv, "d:o:s:k:p:", long_options, &optionIndex);
|
2018-09-14 01:02:12 +02:00
|
|
|
|
|
|
|
//end of command line arguments reached
|
|
|
|
if (curOption == -1) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (curOption) {
|
|
|
|
case 'd': //disk name
|
|
|
|
state.diskName = optarg;
|
2018-09-14 01:41:35 +02:00
|
|
|
hasDisk = true;
|
2018-09-14 01:02:12 +02:00
|
|
|
break;
|
|
|
|
case 'o': //offset
|
|
|
|
state.diskOffset = atol(optarg);
|
2018-09-14 01:41:35 +02:00
|
|
|
hasOffset = true;
|
2018-09-14 01:02:12 +02:00
|
|
|
break;
|
|
|
|
case 's': //size
|
|
|
|
state.fileSize = atol(optarg);
|
2018-09-14 01:41:35 +02:00
|
|
|
hasSize = true;
|
2018-09-14 01:02:12 +02:00
|
|
|
break;
|
|
|
|
case 'k': { //decryption keys
|
|
|
|
//TODO: parse from optarg
|
|
|
|
uint32_t key0 = atoi(argv[8]);
|
|
|
|
uint32_t key1 = atoi(argv[9]);
|
|
|
|
uint32_t key2 = atoi(argv[10]);
|
|
|
|
//Initialize decryption (pass decryption keys)
|
|
|
|
initDecryptor(key0, key1, key2);
|
|
|
|
state.isEncrypted = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'p': //prev file for xdelta3
|
|
|
|
//TODO
|
|
|
|
break;
|
2018-09-14 01:41:35 +02:00
|
|
|
case '?':
|
|
|
|
errorAndExit();
|
|
|
|
break;
|
2018-09-14 01:02:12 +02:00
|
|
|
default:
|
2018-09-14 01:41:35 +02:00
|
|
|
fprintf(stderr, "Unknown option '%c'.\n", (char)curOption);
|
|
|
|
errorAndExit();
|
2018-09-14 01:02:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-14 01:41:35 +02:00
|
|
|
if (!hasDisk) {
|
|
|
|
fprintf(stderr, "Missing required argument --disk.\n");
|
|
|
|
errorAndExit();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hasOffset) {
|
|
|
|
fprintf(stderr, "Missing required argument --offset.\n");
|
|
|
|
errorAndExit();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hasSize) {
|
|
|
|
fprintf(stderr, "Missing required argument --size.\n");
|
|
|
|
errorAndExit();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (optind < argc) {
|
|
|
|
fprintf(stderr, "Found %i arguments without an option. All arguments must be preceded by an option.\n", argc - optind);
|
|
|
|
errorAndExit();
|
2018-09-14 01:02:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return state;
|
|
|
|
}
|