From cf6e692289a992032b1e36c012cdac6f4d6aa8af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexe=C3=AF=20KADIR?= <alexei.kadir@gmail.com>
Date: Sun, 18 Feb 2024 14:43:38 +0100
Subject: [PATCH] Fixed a bug and added resetting

---
 src/entry.c   | 13 ++++++--
 src/entry.h   |  6 ++--
 src/sandbox.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 101 insertions(+), 8 deletions(-)

diff --git a/src/entry.c b/src/entry.c
index 496e6da..87c72d2 100644
--- a/src/entry.c
+++ b/src/entry.c
@@ -431,8 +431,16 @@ Status ResetEntryDisk(const char* entry_identifier, const char* backing_identifi
 	}
 
 	// If no backing disk is specified, use the current backing disk
-	if (backing_disk_path == NULL)
-		backing_disk_path = disk_info.backing_file;
+	if (backing_disk_path == NULL) {
+		backing_disk_path = strdup(disk_info.backing_file);
+		if (backing_disk_path == NULL) {
+			Log(LOG_LEVEL_ERROR, "Failed to allocate memory for the backing disk path (%s).", strerror(errno));
+
+			FreeDiskInfo(&disk_info);
+			free(entry_disk_path);
+			return FAILURE;
+		}
+	}
 
 	// Reset the disk
 	if (backing_disk_path != NULL)
@@ -481,4 +489,3 @@ Status TrimEntryDisk(const char* entry_identifier) {
 
 	return status;
 }
-
diff --git a/src/entry.h b/src/entry.h
index 7fdb735..40b9690 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -20,7 +20,5 @@ Status ClearEntries();
 Status AddRootEntryDisk(const char* entry_identifier, uint64_t disk_size);
 Status AddBackedEntryDisk(const char* entry_identifier, const char* backing_identifier);
 Status RemoveEntryDisk(const char* entry_identifier);
-Status ResetEntryDisk(const char* entry_identifier, const char* backing_identifier); // TODO
-Status TrimEntryDisk(const char* entry_identifier);
-
-Status GetEntryBacking(const char* entry_identifier, char** _backing_identifier);
\ No newline at end of file
+Status ResetEntryDisk(const char* entry_identifier, const char* backing_identifier);
+Status TrimEntryDisk(const char* entry_identifier);
\ No newline at end of file
diff --git a/src/sandbox.c b/src/sandbox.c
index 23f6fc6..b4efbc7 100644
--- a/src/sandbox.c
+++ b/src/sandbox.c
@@ -390,7 +390,95 @@ int CommandRemoveDisk(int argc, char* argv[]) {
 }
 
 int CommandResetDisk(int argc, char* argv[]) {
-	return 0;
+	if (argc < 1) {
+		Log(LOG_LEVEL_ERROR, "Too few arguments supplied to command 'reset-disk'.");
+		return EXIT_FAILURE;
+	}
+
+	// Extract the entry identifier
+	const char* entry_id = argv[0];
+
+	// Extract the options
+	bool update = false;
+	bool backed = false;
+	const char* backing_id = NULL;
+
+	for (int i = 1; i < argc; i++) {
+		if (strcmp(argv[i], "--update") == 0 || strcmp(argv[i], "-u") == 0) {
+			// Check if the option is duplicated
+			if (update) {
+				Log(LOG_LEVEL_ERROR, "Duplicate option '--update'.");
+				return EXIT_FAILURE;
+			}
+
+			update = true;
+		} else if (strcmp(argv[i], "--backed") == 0 || strcmp(argv[i], "-b") == 0) {
+			// Check if the option is duplicated
+			if (backed) {
+				Log(LOG_LEVEL_ERROR, "Duplicate option '--backed'.");
+				return EXIT_FAILURE;
+			}
+
+			// Check if the option is the last argument
+			if (i + 1 == argc) {
+				Log(LOG_LEVEL_ERROR, "Missing argument for option '--backed <backing id>'.");
+				return EXIT_FAILURE;
+			}
+
+			// Extract the backing identifier
+			backing_id = argv[i + 1];
+			backed = true;
+
+			// Skip the next argument as it is the backing identifier
+			i++;
+		} else {
+			Log(LOG_LEVEL_ERROR, "Unknown option '%s'.", argv[i]);
+			return EXIT_FAILURE;
+		}
+	}
+
+	// Don't allow both update and backed options
+	if (update && backed) {
+		Log(LOG_LEVEL_ERROR, "Cannot use both '--update' and '--backed' options.");
+		return EXIT_FAILURE;
+	}
+
+	if (update) {
+		char* backing_id;
+		Status status = GetLatestBacking(&backing_id);
+		if (status != SUCCESS) {
+			Log(LOG_LEVEL_ERROR, "Failed to get the latest backing to use as the default backing.");
+			return EXIT_FAILURE;
+		}
+
+		// Reset the disk
+		status = ResetEntryDisk(entry_id, backing_id);
+		if (status != SUCCESS) {
+			free(backing_id);
+			return EXIT_FAILURE;
+		}
+
+		Log(LOG_LEVEL_INFO, "Successfully reset disk from entry '%s' with backing '%s'.", entry_id, backing_id);
+
+		free(backing_id);
+		return EXIT_SUCCESS;
+	} else if (backed) {
+		// Reset the disk with the specified backing
+		Status status = ResetEntryDisk(entry_id, backing_id);
+		if (status != SUCCESS)
+			return EXIT_FAILURE;
+
+		Log(LOG_LEVEL_INFO, "Successfully reset disk from entry '%s' with backing '%s'.", entry_id, backing_id);
+		return EXIT_SUCCESS;
+	} else {
+		// Reset the disk
+		Status status = ResetEntryDisk(entry_id, NULL);
+		if (status != SUCCESS)
+			return EXIT_FAILURE;
+
+		Log(LOG_LEVEL_INFO, "Successfully reset disk from entry '%s'.", entry_id);
+		return EXIT_SUCCESS;
+	}
 }
 int CommandTrimDisk(int argc, char* argv[]) {
 	if (argc < 1) {