2018-09-14 01:02:12 +02:00
|
|
|
#include <getopt.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2018-09-14 01:51:48 +02:00
|
|
|
#include <string.h>
|
2018-09-14 01:02:12 +02:00
|
|
|
|
|
|
|
#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-10-08 23:08:02 +02:00
|
|
|
#include "rateLimiter.h"
|
2018-09-14 01:02:12 +02:00
|
|
|
|
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-30 16:09:51 +02:00
|
|
|
//For a description of these arguments, see errorAndExit.c
|
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'},
|
2018-09-14 02:01:15 +02:00
|
|
|
{"previous", required_argument, 0, 'p'},
|
2018-09-16 02:33:30 +02:00
|
|
|
{"target", required_argument, 0, 't'},
|
2018-10-08 23:08:02 +02:00
|
|
|
{"limit", required_argument, 0, 'l'},
|
2018-09-14 01:57:49 +02:00
|
|
|
{NULL, 0, 0, 0},
|
2018-09-14 01:02:12 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
2019-07-21 23:18:00 +02:00
|
|
|
int curOption = getopt_long_only(argc, argv, "", 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;
|
2018-09-14 01:51:48 +02:00
|
|
|
case 'k': { //decryption keys (12345,12345,12345)
|
|
|
|
//Split argument by comma into three integers
|
|
|
|
char* token = strtok(optarg, ",");
|
|
|
|
uint32_t keys[3] = { 0UL, 0UL, 0UL };
|
|
|
|
int index = 0;
|
|
|
|
while (token != NULL) {
|
|
|
|
if (index > 2) {
|
|
|
|
fprintf(stderr, "Too many decryption keys specified with --keys; only 3 are allowed.\n");
|
|
|
|
errorAndExit();
|
|
|
|
}
|
|
|
|
keys[index] = atoi(token);
|
|
|
|
index += 1;
|
|
|
|
token = strtok(NULL, ",");
|
|
|
|
}
|
|
|
|
if (index < 3) {
|
|
|
|
fprintf(stderr, "Not enough decryption keys specified with --keys; 3 are required but only found %i.\n", index);
|
|
|
|
errorAndExit();
|
|
|
|
}
|
2018-09-14 01:02:12 +02:00
|
|
|
//Initialize decryption (pass decryption keys)
|
2018-09-14 01:51:48 +02:00
|
|
|
initDecryptor(keys[0], keys[1], keys[2]);
|
2018-09-14 01:02:12 +02:00
|
|
|
state.isEncrypted = true;
|
|
|
|
break;
|
|
|
|
}
|
2018-09-14 02:06:02 +02:00
|
|
|
case 'p': //previous file for xdelta3
|
2018-09-14 01:57:49 +02:00
|
|
|
state.prevFile = optarg;
|
2018-09-14 01:02:12 +02:00
|
|
|
break;
|
2018-09-16 02:33:30 +02:00
|
|
|
case 't': //target file path where extracted file is saved to
|
|
|
|
state.target = optarg;
|
|
|
|
break;
|
2018-10-08 23:08:02 +02:00
|
|
|
case 'l': //disk write limit
|
|
|
|
setDiskSpeed(atol(optarg));
|
|
|
|
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) {
|
2018-09-14 01:57:49 +02:00
|
|
|
fprintf(stderr, "Found %i argument(s) without an option. All arguments must be preceded by an option.\n", argc - optind);
|
2018-09-14 01:41:35 +02:00
|
|
|
errorAndExit();
|
2018-09-14 01:02:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return state;
|
|
|
|
}
|