Implemented some more functions

This commit is contained in:
2024-02-15 12:50:30 +01:00
parent a059611982
commit f64f39c9c8
8 changed files with 306 additions and 29 deletions

View File

@@ -7,6 +7,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
char* get_backings_path(void) {
@@ -22,10 +24,16 @@ bool is_valid_backing_name(const char* name) {
if (length == 0)
return false;
// Check that the name is a number (the number is the timestamp of the backing disk creation)
// Check that the name starts with a number, corresponding to the timestamp of the backing disk creation
size_t timestamp_length = 0;
for (size_t i = 0; i < length; i++)
if (name[i] < '0' || name[i] > '9')
return false;
if (name[i] >= '0' && name[i] <= '9')
timestamp_length++;
else
break;
if (timestamp_length == 0)
return false;
return true;
}
@@ -65,7 +73,112 @@ bool backing_exists(const char* backing) {
return true;
}
uint64_t get_backing_creation_time(const char* backing) {
// A valid backing name is a number, corresponding to the timestamp of the backing disk creation
return strtoull(backing, NULL, 10);
char** list_backings(void) {
char* path = get_backings_path();
if (path == NULL)
return NULL;
// Open the directory
DIR* dir = opendir(path);
if (dir == NULL) {
log_msg(LOG_ERROR, "Failed to open directory '%s' (%s).", path, strerror(errno));
free(path);
return NULL;
}
free(path);
// Count the number of entries
size_t count = 0;
struct dirent* entry;
while ((entry = readdir(dir)) != NULL)
if (is_valid_backing_name(entry->d_name) && backing_exists(entry->d_name))
count++;
// Allocate the array of strings
char** backings = malloc((count + 1) * sizeof(char*));
if (backings == NULL) {
log_msg(LOG_ERROR, "Failed to allocate memory for the backings array.");
closedir(dir);
return NULL;
}
// Fill the array of strings
rewinddir(dir);
size_t index = 0;
while ((entry = readdir(dir)) != NULL) {
if (is_valid_backing_name(entry->d_name) && backing_exists(entry->d_name)) {
backings[index] = strdup(entry->d_name);
if (backings[index] == NULL) {
log_msg(LOG_ERROR, "Failed to allocate memory for the backing name.");
for (size_t i = 0; i < index; i++)
free(backings[i]);
free(backings);
closedir(dir);
return NULL;
}
index++;
}
}
// Terminate the array of strings
backings[count] = NULL;
// Close the directory
closedir(dir);
return backings;
}
uint64_t get_backing_creation_time(const char* backing) {
size_t length = strlen(backing);
size_t timestamp_length = 0;
// Find the length of the timestamp
for (size_t i = 0; i < length; i++)
if (backing[i] >= '0' && backing[i] <= '9')
timestamp_length++;
else
break;
// Extract the timestamp
char* timestamp = strndup(backing, timestamp_length);
if (timestamp == NULL)
return 0;
// Convert the timestamp to a number
uint64_t creation_time = strtoull(timestamp, NULL, 10);
// Free the timestamp
free(timestamp);
return creation_time;
}
char* find_latest_backing(void) {
char** backings = list_backings();
if (backings == NULL)
return NULL;
// Find the latest backing disk
char* latest_backing = NULL;
uint64_t latest_time = 0;
for (size_t i = 0; backings[i] != NULL; i++) {
uint64_t time = get_backing_creation_time(backings[i]);
if (time >= latest_time) {
latest_time = time;
latest_backing = backings[i];
}
}
// Duplicate the latest backing disk
if (latest_backing != NULL)
latest_backing = strdup(latest_backing);
// Free the backings
for (size_t i = 0; backings[i] != NULL; i++)
free(backings[i]);
free(backings);
return latest_backing;
}