Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f0a258c21 |
18
TODO.md
18
TODO.md
@@ -1,19 +1,3 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
## The pad menu in interactive encrypt mode gives numbers instead of checksum selection
|
||||||
## Change technique for adding keyboard entropy.
|
|
||||||
|
|
||||||
|
|
||||||
## There is the problem of the location of the pad revealing metadata about how many messages have been sent in the past, or at least the size of the messsages.
|
|
||||||
|
|
||||||
One solution could be to start the pad at a random location, and then wrap around, so an attacker could never tell the size of the past text sent. This helps. But then you have to store the start location, which you could do within the header of the pad along with the pad?
|
|
||||||
|
|
||||||
Or, better yet, assume the offset is a very large size, and use the pad itself to encrypt the offset.
|
|
||||||
|
|
||||||
## Take a look at how the file header is being handled.
|
|
||||||
|
|
||||||
|
|
||||||
## Setup for multiple USB drives
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
674
otp.c
674
otp.c
@@ -125,7 +125,6 @@ int add_entropy_to_pad(const char* pad_chksum, const unsigned char* entropy_data
|
|||||||
int handle_add_entropy_to_pad(const char* pad_chksum);
|
int handle_add_entropy_to_pad(const char* pad_chksum);
|
||||||
|
|
||||||
// Enhanced entropy system helper functions
|
// Enhanced entropy system helper functions
|
||||||
int filter_unused_pads(char unused_pads[][65], int max_pads);
|
|
||||||
int update_pad_checksum_after_entropy(const char* old_chksum, char* new_chksum);
|
int update_pad_checksum_after_entropy(const char* old_chksum, char* new_chksum);
|
||||||
int rename_pad_files_safely(const char* old_chksum, const char* new_chksum);
|
int rename_pad_files_safely(const char* old_chksum, const char* new_chksum);
|
||||||
int is_pad_unused(const char* pad_chksum);
|
int is_pad_unused(const char* pad_chksum);
|
||||||
@@ -139,7 +138,6 @@ void get_default_file_path(const char* filename, char* result_path, size_t resul
|
|||||||
// Utility functions
|
// Utility functions
|
||||||
uint64_t parse_size_string(const char* size_str);
|
uint64_t parse_size_string(const char* size_str);
|
||||||
char* find_pad_by_prefix(const char* prefix);
|
char* find_pad_by_prefix(const char* prefix);
|
||||||
int list_available_pads(void);
|
|
||||||
int show_pad_info(const char* chksum);
|
int show_pad_info(const char* chksum);
|
||||||
void show_progress(uint64_t current, uint64_t total, time_t start_time);
|
void show_progress(uint64_t current, uint64_t total, time_t start_time);
|
||||||
|
|
||||||
@@ -177,6 +175,14 @@ int get_filename_with_default(const char* prompt, const char* default_path, char
|
|||||||
// Directory display functions
|
// Directory display functions
|
||||||
void get_directory_display(const char* file_path, char* result, size_t result_size);
|
void get_directory_display(const char* file_path, char* result, size_t result_size);
|
||||||
|
|
||||||
|
// Unified pad selection function
|
||||||
|
typedef enum {
|
||||||
|
PAD_FILTER_ALL, // Show all pads
|
||||||
|
PAD_FILTER_UNUSED_ONLY // Show only unused pads (0% usage)
|
||||||
|
} pad_filter_type_t;
|
||||||
|
|
||||||
|
char* select_pad_interactive(const char* title, const char* prompt, pad_filter_type_t filter_type, int allow_cancel);
|
||||||
|
|
||||||
void print_usage(const char* program_name);
|
void print_usage(const char* program_name);
|
||||||
|
|
||||||
|
|
||||||
@@ -397,7 +403,12 @@ int command_line_mode(int argc, char* argv[]) {
|
|||||||
return encrypt_file(pad_prefix, input_file, output_file, ascii_armor);
|
return encrypt_file(pad_prefix, input_file, output_file, ascii_armor);
|
||||||
}
|
}
|
||||||
else if (strcmp(argv[1], "list") == 0 || strcmp(argv[1], "-l") == 0) {
|
else if (strcmp(argv[1], "list") == 0 || strcmp(argv[1], "-l") == 0) {
|
||||||
return list_available_pads();
|
printf("Available pads:\n");
|
||||||
|
char* selected = select_pad_interactive("Available pads:", "Select pad (or press Enter to exit)", PAD_FILTER_ALL, 0);
|
||||||
|
if (selected) {
|
||||||
|
free(selected);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print_usage(argv[0]);
|
print_usage(argv[0]);
|
||||||
@@ -415,7 +426,7 @@ int command_line_mode(int argc, char* argv[]) {
|
|||||||
|
|
||||||
int interactive_mode(void) {
|
int interactive_mode(void) {
|
||||||
char input[10];
|
char input[10];
|
||||||
|
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||||
while (1) {
|
while (1) {
|
||||||
show_main_menu();
|
show_main_menu();
|
||||||
|
|
||||||
@@ -455,7 +466,8 @@ int interactive_mode(void) {
|
|||||||
|
|
||||||
void show_main_menu(void) {
|
void show_main_menu(void) {
|
||||||
|
|
||||||
printf("\n\n\n\n=========================== Main Menu - OTP v1.0.0 ===========================\n\n");
|
|
||||||
|
printf("\n=========================== Main Menu - OTP v1.0.0 ===========================\n\n");
|
||||||
|
|
||||||
printf(" \033[4mT\033[0mext encrypt\n"); //TEXT ENCRYPT
|
printf(" \033[4mT\033[0mext encrypt\n"); //TEXT ENCRYPT
|
||||||
printf(" \033[4mF\033[0mile encrypt\n"); //FILE ENCRYPT
|
printf(" \033[4mF\033[0mile encrypt\n"); //FILE ENCRYPT
|
||||||
@@ -493,7 +505,14 @@ int handle_generate_menu(void) {
|
|||||||
int handle_encrypt_menu(void) {
|
int handle_encrypt_menu(void) {
|
||||||
printf("\n=== Encrypt Data ===\n");
|
printf("\n=== Encrypt Data ===\n");
|
||||||
|
|
||||||
int pad_count = list_available_pads();
|
printf("Available pads:\n");
|
||||||
|
char* selected = select_pad_interactive("Available pads:", "Select pad (or press Enter to continue)", PAD_FILTER_ALL, 0);
|
||||||
|
int pad_count = 1; // Assume at least 1 pad if function returned
|
||||||
|
if (selected) {
|
||||||
|
free(selected);
|
||||||
|
} else {
|
||||||
|
pad_count = 0;
|
||||||
|
}
|
||||||
if (pad_count == 0) {
|
if (pad_count == 0) {
|
||||||
printf("No pads available. Generate a pad first.\n");
|
printf("No pads available. Generate a pad first.\n");
|
||||||
return 1;
|
return 1;
|
||||||
@@ -514,57 +533,18 @@ int handle_encrypt_menu(void) {
|
|||||||
int choice = atoi(choice_input);
|
int choice = atoi(choice_input);
|
||||||
|
|
||||||
if (choice == 1) {
|
if (choice == 1) {
|
||||||
// Text encryption
|
// Text encryption - use unified pad selection
|
||||||
printf("\nPad selection options:\n");
|
char* selected_pad = select_pad_interactive("=== Select Pad for Text Encryption ===",
|
||||||
printf(" 1. Select from numbered list\n");
|
"Select pad (by prefix or number)",
|
||||||
printf(" 2. Enter checksum/prefix manually\n");
|
PAD_FILTER_ALL, 1);
|
||||||
printf(" 3. Browse pad files\n");
|
if (!selected_pad) {
|
||||||
printf("Enter choice (1-3): ");
|
printf("Text encryption cancelled.\n");
|
||||||
|
|
||||||
char pad_choice[10];
|
|
||||||
if (!fgets(pad_choice, sizeof(pad_choice), stdin)) {
|
|
||||||
printf("Error: Failed to read input\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char input[MAX_HASH_LENGTH];
|
int result = encrypt_text(selected_pad, NULL); // NULL for interactive mode
|
||||||
if (atoi(pad_choice) == 3) {
|
free(selected_pad);
|
||||||
// Use file manager to browse pads directory
|
return result;
|
||||||
char selected_pad[512];
|
|
||||||
if (launch_file_manager("pads", selected_pad, sizeof(selected_pad)) == 0) {
|
|
||||||
// Extract checksum from selected .pad file
|
|
||||||
char* filename = strrchr(selected_pad, '/');
|
|
||||||
if (!filename) filename = selected_pad;
|
|
||||||
else filename++; // Skip the '/'
|
|
||||||
|
|
||||||
// Remove .pad extension to get checksum
|
|
||||||
if (strlen(filename) == 68 && strstr(filename, ".pad")) {
|
|
||||||
strncpy(input, filename, 64);
|
|
||||||
input[64] = '\0';
|
|
||||||
} else {
|
|
||||||
printf("Invalid pad file selected.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("Falling back to manual pad selection.\n");
|
|
||||||
printf("Enter pad selection (number, chksum, or prefix): ");
|
|
||||||
if (!fgets(input, sizeof(input), stdin)) {
|
|
||||||
printf("Error: Failed to read input\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
input[strcspn(input, "\n")] = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Manual pad selection
|
|
||||||
printf("Enter pad selection (number, chksum, or prefix): ");
|
|
||||||
if (!fgets(input, sizeof(input), stdin)) {
|
|
||||||
printf("Error: Failed to read input\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
input[strcspn(input, "\n")] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return encrypt_text(input, NULL); // NULL for interactive mode
|
|
||||||
}
|
}
|
||||||
else if (choice == 2) {
|
else if (choice == 2) {
|
||||||
// File encryption
|
// File encryption
|
||||||
@@ -608,13 +588,14 @@ int handle_encrypt_menu(void) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nEnter pad selection (number, chksum, or prefix): ");
|
// Use unified pad selection
|
||||||
char pad_input[MAX_HASH_LENGTH];
|
char* selected_pad = select_pad_interactive("=== Select Pad for File Encryption ===",
|
||||||
if (!fgets(pad_input, sizeof(pad_input), stdin)) {
|
"Select pad (by prefix)",
|
||||||
printf("Error: Failed to read input\n");
|
PAD_FILTER_ALL, 1);
|
||||||
|
if (!selected_pad) {
|
||||||
|
printf("File encryption cancelled.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
pad_input[strcspn(pad_input, "\n")] = 0;
|
|
||||||
|
|
||||||
// Ask for output format
|
// Ask for output format
|
||||||
printf("\nSelect output format:\n");
|
printf("\nSelect output format:\n");
|
||||||
@@ -652,7 +633,9 @@ int handle_encrypt_menu(void) {
|
|||||||
|
|
||||||
const char* output_filename = output_file;
|
const char* output_filename = output_file;
|
||||||
|
|
||||||
return encrypt_file(pad_input, input_file, output_filename, ascii_armor);
|
int result = encrypt_file(selected_pad, input_file, output_filename, ascii_armor);
|
||||||
|
free(selected_pad);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("Invalid choice. Please enter 1 or 2.\n");
|
printf("Invalid choice. Please enter 1 or 2.\n");
|
||||||
@@ -870,7 +853,10 @@ char* find_pad_by_prefix(const char* prefix) {
|
|||||||
if (match_count == 0) {
|
if (match_count == 0) {
|
||||||
printf("No pads found matching '%s'\n", prefix);
|
printf("No pads found matching '%s'\n", prefix);
|
||||||
printf("Available pads:\n");
|
printf("Available pads:\n");
|
||||||
list_available_pads();
|
char* selected = select_pad_interactive("Available pads:", "Available pads (press Enter to continue)", PAD_FILTER_ALL, 0);
|
||||||
|
if (selected) {
|
||||||
|
free(selected);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (match_count == 1) {
|
} else if (match_count == 1) {
|
||||||
char* result = matches[0];
|
char* result = matches[0];
|
||||||
@@ -911,99 +897,14 @@ char* find_pad_by_prefix(const char* prefix) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_available_pads(void) {
|
|
||||||
DIR* dir = opendir(current_pads_dir);
|
|
||||||
if (!dir) {
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
printf("Error: Cannot open pads directory %s\n", current_pads_dir);
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
return 0;
|
// PADS MENU
|
||||||
}
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
struct dirent* entry;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
// Get current default pad path for comparison
|
|
||||||
char* current_default = get_default_pad_path();
|
|
||||||
char default_pad_checksum[65] = "";
|
|
||||||
|
|
||||||
if (current_default) {
|
|
||||||
// Extract checksum from default pad path
|
|
||||||
char* filename = strrchr(current_default, '/');
|
|
||||||
if (!filename) filename = current_default;
|
|
||||||
else filename++; // Skip the '/'
|
|
||||||
|
|
||||||
// Extract checksum (remove .pad extension)
|
|
||||||
if (strlen(filename) >= 68 && strstr(filename, ".pad")) {
|
|
||||||
strncpy(default_pad_checksum, filename, 64);
|
|
||||||
default_pad_checksum[64] = '\0';
|
|
||||||
}
|
|
||||||
free(current_default);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\nAvailable pads:\n");
|
|
||||||
printf("%-4s %-7s %-20s %-12s %-12s %-8s\n", "No.", "Default", "ChkSum", "Size", "Used", "% Used");
|
|
||||||
printf("%-4s %-7s %-20s %-12s %-12s %-8s\n", "---", "-------", "-------------------", "----------", "----------", "------");
|
|
||||||
|
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
|
||||||
if (strstr(entry->d_name, ".pad") && strlen(entry->d_name) == 68) {
|
|
||||||
count++;
|
|
||||||
char chksum[65];
|
|
||||||
strncpy(chksum, entry->d_name, 64);
|
|
||||||
chksum[64] = '\0';
|
|
||||||
|
|
||||||
// Check if this is the default pad
|
|
||||||
int is_default = (strlen(default_pad_checksum) > 0 &&
|
|
||||||
strncmp(chksum, default_pad_checksum, 64) == 0);
|
|
||||||
|
|
||||||
// Get pad file size
|
|
||||||
char full_path[1024]; // Increased buffer size to accommodate longer paths
|
|
||||||
snprintf(full_path, sizeof(full_path), "%s/%s", current_pads_dir, entry->d_name);
|
|
||||||
struct stat st;
|
|
||||||
if (stat(full_path, &st) == 0) {
|
|
||||||
// Get used bytes from state
|
|
||||||
uint64_t used_bytes;
|
|
||||||
read_state_offset(chksum, &used_bytes);
|
|
||||||
|
|
||||||
// Format sizes
|
|
||||||
char size_str[32], used_str[32];
|
|
||||||
|
|
||||||
// Format total size
|
|
||||||
if (st.st_size < 1024) {
|
|
||||||
snprintf(size_str, sizeof(size_str), "%luB", st.st_size);
|
|
||||||
} else if (st.st_size < 1024 * 1024) {
|
|
||||||
snprintf(size_str, sizeof(size_str), "%.1fKB", (double)st.st_size / 1024.0);
|
|
||||||
} else if (st.st_size < 1024 * 1024 * 1024) {
|
|
||||||
snprintf(size_str, sizeof(size_str), "%.1fMB", (double)st.st_size / (1024.0 * 1024.0));
|
|
||||||
} else {
|
|
||||||
snprintf(size_str, sizeof(size_str), "%.2fGB", (double)st.st_size / (1024.0 * 1024.0 * 1024.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format used size
|
|
||||||
if (used_bytes < 1024) {
|
|
||||||
snprintf(used_str, sizeof(used_str), "%luB", used_bytes);
|
|
||||||
} else if (used_bytes < 1024 * 1024) {
|
|
||||||
snprintf(used_str, sizeof(used_str), "%.1fKB", (double)used_bytes / 1024.0);
|
|
||||||
} else if (used_bytes < 1024 * 1024 * 1024) {
|
|
||||||
snprintf(used_str, sizeof(used_str), "%.1fMB", (double)used_bytes / (1024.0 * 1024.0));
|
|
||||||
} else {
|
|
||||||
snprintf(used_str, sizeof(used_str), "%.2fGB", (double)used_bytes / (1024.0 * 1024.0 * 1024.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate percentage
|
|
||||||
double percentage = (double)used_bytes / st.st_size * 100.0;
|
|
||||||
|
|
||||||
printf("%-4d %-7s %-20.16s %-12s %-12s %.1f%%\n", count, is_default ? "*" : "", chksum, size_str, used_str, percentage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
|
|
||||||
if (count == 0) {
|
|
||||||
printf("No pads found.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
int show_pad_info(const char* chksum) {
|
int show_pad_info(const char* chksum) {
|
||||||
char pad_filename[MAX_HASH_LENGTH + 10];
|
char pad_filename[MAX_HASH_LENGTH + 10];
|
||||||
@@ -1526,7 +1427,7 @@ int encrypt_text(const char* pad_identifier, const char* input_text) {
|
|||||||
int is_interactive = (input_text == NULL); // Interactive if no input_text provided
|
int is_interactive = (input_text == NULL); // Interactive if no input_text provided
|
||||||
|
|
||||||
if (is_interactive) {
|
if (is_interactive) {
|
||||||
printf("\n\n%s\n\n", ascii_output);
|
printf("\n\n\n%s\n\n", ascii_output);
|
||||||
} else {
|
} else {
|
||||||
printf("%s\n", ascii_output); // Add newline for proper piping with tee
|
printf("%s\n", ascii_output); // Add newline for proper piping with tee
|
||||||
}
|
}
|
||||||
@@ -1891,7 +1792,10 @@ int decrypt_binary_file(FILE* input_fp, const char* output_file) {
|
|||||||
if (access(pad_path, R_OK) != 0) {
|
if (access(pad_path, R_OK) != 0) {
|
||||||
printf("Error: Required pad not found: %s\n", pad_chksum_hex);
|
printf("Error: Required pad not found: %s\n", pad_chksum_hex);
|
||||||
printf("Available pads:\n");
|
printf("Available pads:\n");
|
||||||
list_available_pads();
|
char* selected = select_pad_interactive("Available pads:", "Available pads (press Enter to continue)", PAD_FILTER_ALL, 0);
|
||||||
|
if (selected) {
|
||||||
|
free(selected);
|
||||||
|
}
|
||||||
fclose(input_fp);
|
fclose(input_fp);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -2904,34 +2808,6 @@ int is_pad_unused(const char* pad_chksum) {
|
|||||||
return (used_bytes <= 32); // Only reserved bytes used (32 bytes for checksum encryption)
|
return (used_bytes <= 32); // Only reserved bytes used (32 bytes for checksum encryption)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter pads to only return unused ones
|
|
||||||
int filter_unused_pads(char unused_pads[][65], int max_pads) {
|
|
||||||
DIR* dir = opendir(current_pads_dir);
|
|
||||||
if (!dir) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dirent* entry;
|
|
||||||
int unused_count = 0;
|
|
||||||
|
|
||||||
while ((entry = readdir(dir)) != NULL && unused_count < max_pads) {
|
|
||||||
if (strstr(entry->d_name, ".pad") && strlen(entry->d_name) == 68) {
|
|
||||||
// Extract checksum from filename
|
|
||||||
char chksum[65];
|
|
||||||
strncpy(chksum, entry->d_name, 64);
|
|
||||||
chksum[64] = '\0';
|
|
||||||
|
|
||||||
// Check if pad is unused
|
|
||||||
if (is_pad_unused(chksum)) {
|
|
||||||
strcpy(unused_pads[unused_count], chksum);
|
|
||||||
unused_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
return unused_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Safely rename pad files (pad and state) from old to new checksum
|
// Safely rename pad files (pad and state) from old to new checksum
|
||||||
int rename_pad_files_safely(const char* old_chksum, const char* new_chksum) {
|
int rename_pad_files_safely(const char* old_chksum, const char* new_chksum) {
|
||||||
@@ -3319,7 +3195,10 @@ int universal_decrypt(const char* input_data, const char* output_target, decrypt
|
|||||||
printf("Error: Required pad not found: %s\n", stored_chksum);
|
printf("Error: Required pad not found: %s\n", stored_chksum);
|
||||||
if (mode == DECRYPT_MODE_INTERACTIVE || mode == DECRYPT_MODE_FILE_TO_TEXT) {
|
if (mode == DECRYPT_MODE_INTERACTIVE || mode == DECRYPT_MODE_FILE_TO_TEXT) {
|
||||||
printf("Available pads:\n");
|
printf("Available pads:\n");
|
||||||
list_available_pads();
|
char* selected = select_pad_interactive("Available pads:", "Available pads (press Enter to continue)", PAD_FILTER_ALL, 0);
|
||||||
|
if (selected) {
|
||||||
|
free(selected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -3842,22 +3721,18 @@ int handle_text_encrypt(void) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// List available pads and get selection
|
// Use unified pad selection
|
||||||
int pad_count = list_available_pads();
|
char* selected_pad = select_pad_interactive("=== Select Pad for Text Encryption ===",
|
||||||
if (pad_count == 0) {
|
"Select pad (by prefix)",
|
||||||
printf("No pads available. Generate a pad first.\n");
|
PAD_FILTER_ALL, 1);
|
||||||
|
if (!selected_pad) {
|
||||||
|
printf("Text encryption cancelled.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nEnter pad selection (number, checksum, or prefix): ");
|
int result = encrypt_text(selected_pad, text_buffer);
|
||||||
char pad_input[MAX_HASH_LENGTH];
|
free(selected_pad);
|
||||||
if (!fgets(pad_input, sizeof(pad_input), stdin)) {
|
return result;
|
||||||
printf("Error: Failed to read pad selection\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
pad_input[strcspn(pad_input, "\n")] = 0;
|
|
||||||
|
|
||||||
return encrypt_text(pad_input, text_buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int handle_file_encrypt(void) {
|
int handle_file_encrypt(void) {
|
||||||
@@ -3876,21 +3751,15 @@ int handle_file_encrypt(void) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// List available pads
|
// Use unified pad selection
|
||||||
int pad_count = list_available_pads();
|
char* selected_pad = select_pad_interactive("=== Select Pad for File Encryption ===",
|
||||||
if (pad_count == 0) {
|
"Select pad (by prefix)",
|
||||||
printf("No pads available. Generate a pad first.\n");
|
PAD_FILTER_ALL, 1);
|
||||||
|
if (!selected_pad) {
|
||||||
|
printf("File encryption cancelled.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nEnter pad selection (number, checksum, or prefix): ");
|
|
||||||
char pad_input[MAX_HASH_LENGTH];
|
|
||||||
if (!fgets(pad_input, sizeof(pad_input), stdin)) {
|
|
||||||
printf("Error: Failed to read pad selection\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
pad_input[strcspn(pad_input, "\n")] = 0;
|
|
||||||
|
|
||||||
// Ask for output format
|
// Ask for output format
|
||||||
printf("\nSelect output format:\n");
|
printf("\nSelect output format:\n");
|
||||||
printf("1. Binary (.otp) - preserves file permissions\n");
|
printf("1. Binary (.otp) - preserves file permissions\n");
|
||||||
@@ -3922,10 +3791,258 @@ int handle_file_encrypt(void) {
|
|||||||
|
|
||||||
const char* output_filename = output_file;
|
const char* output_filename = output_file;
|
||||||
|
|
||||||
return encrypt_file(pad_input, input_file, output_filename, ascii_armor);
|
int result = encrypt_file(selected_pad, input_file, output_filename, ascii_armor);
|
||||||
|
free(selected_pad);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Unified pad selection function - extracts the best UI from handle_pads_menu()
|
||||||
|
char* select_pad_interactive(const char* title, const char* prompt, pad_filter_type_t filter_type, int allow_cancel) {
|
||||||
|
// Get list of pads from current directory
|
||||||
|
DIR* dir = opendir(current_pads_dir);
|
||||||
|
if (!dir) {
|
||||||
|
printf("Error: Cannot open pads directory %s\n", current_pads_dir);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Structure to store pad information
|
||||||
|
struct PadInfo {
|
||||||
|
char chksum[65];
|
||||||
|
char size_str[32];
|
||||||
|
char used_str[32];
|
||||||
|
double percentage;
|
||||||
|
char location[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PadInfo pads[100]; // Support up to 100 pads
|
||||||
|
int pad_count = 0;
|
||||||
|
|
||||||
|
// Collect all pad information
|
||||||
|
struct dirent* entry;
|
||||||
|
while ((entry = readdir(dir)) != NULL && pad_count < 100) {
|
||||||
|
if (strstr(entry->d_name, ".pad") && strlen(entry->d_name) == 68) {
|
||||||
|
strncpy(pads[pad_count].chksum, entry->d_name, 64);
|
||||||
|
pads[pad_count].chksum[64] = '\0';
|
||||||
|
|
||||||
|
// Get pad file size and usage info
|
||||||
|
char full_path[1024];
|
||||||
|
snprintf(full_path, sizeof(full_path), "%s/%s", current_pads_dir, entry->d_name);
|
||||||
|
struct stat st;
|
||||||
|
if (stat(full_path, &st) == 0) {
|
||||||
|
// Get used bytes from state
|
||||||
|
uint64_t used_bytes;
|
||||||
|
read_state_offset(pads[pad_count].chksum, &used_bytes);
|
||||||
|
|
||||||
|
// Apply filter
|
||||||
|
if (filter_type == PAD_FILTER_UNUSED_ONLY && used_bytes > 32) {
|
||||||
|
continue; // Skip used pads when filtering for unused only
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format total size
|
||||||
|
if (st.st_size < 1024) {
|
||||||
|
snprintf(pads[pad_count].size_str, sizeof(pads[pad_count].size_str), "%luB", st.st_size);
|
||||||
|
} else if (st.st_size < 1024 * 1024) {
|
||||||
|
snprintf(pads[pad_count].size_str, sizeof(pads[pad_count].size_str), "%.1fKB", (double)st.st_size / 1024.0);
|
||||||
|
} else if (st.st_size < 1024 * 1024 * 1024) {
|
||||||
|
snprintf(pads[pad_count].size_str, sizeof(pads[pad_count].size_str), "%.1fMB", (double)st.st_size / (1024.0 * 1024.0));
|
||||||
|
} else {
|
||||||
|
snprintf(pads[pad_count].size_str, sizeof(pads[pad_count].size_str), "%.2fGB", (double)st.st_size / (1024.0 * 1024.0 * 1024.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format used size
|
||||||
|
if (used_bytes < 1024) {
|
||||||
|
snprintf(pads[pad_count].used_str, sizeof(pads[pad_count].used_str), "%luB", used_bytes);
|
||||||
|
} else if (used_bytes < 1024 * 1024) {
|
||||||
|
snprintf(pads[pad_count].used_str, sizeof(pads[pad_count].used_str), "%.1fKB", (double)used_bytes / 1024.0);
|
||||||
|
} else if (used_bytes < 1024 * 1024 * 1024) {
|
||||||
|
snprintf(pads[pad_count].used_str, sizeof(pads[pad_count].used_str), "%.1fMB", (double)used_bytes / (1024.0 * 1024.0));
|
||||||
|
} else {
|
||||||
|
snprintf(pads[pad_count].used_str, sizeof(pads[pad_count].used_str), "%.2fGB", (double)used_bytes / (1024.0 * 1024.0 * 1024.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate percentage
|
||||||
|
pads[pad_count].percentage = (double)used_bytes / st.st_size * 100.0;
|
||||||
|
|
||||||
|
// Set location info using directory display
|
||||||
|
get_directory_display(full_path, pads[pad_count].location, sizeof(pads[pad_count].location));
|
||||||
|
|
||||||
|
pad_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
if (pad_count == 0) {
|
||||||
|
printf("\n%s\n", title);
|
||||||
|
if (filter_type == PAD_FILTER_UNUSED_ONLY) {
|
||||||
|
printf("No unused pads found.\n");
|
||||||
|
printf("Entropy can only be added to pads with 0%% usage (only reserved bytes used).\n");
|
||||||
|
} else {
|
||||||
|
printf("No pads found.\n");
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate minimal unique prefixes for each pad
|
||||||
|
char prefixes[100][65];
|
||||||
|
int prefix_lengths[100];
|
||||||
|
|
||||||
|
for (int i = 0; i < pad_count; i++) {
|
||||||
|
prefix_lengths[i] = 1;
|
||||||
|
|
||||||
|
// Find minimal unique prefix
|
||||||
|
while (prefix_lengths[i] <= 64) {
|
||||||
|
int unique = 1;
|
||||||
|
|
||||||
|
// Check if current prefix is unique among all other pads
|
||||||
|
for (int j = 0; j < pad_count; j++) {
|
||||||
|
if (i != j && strncmp(pads[i].chksum, pads[j].chksum, prefix_lengths[i]) == 0) {
|
||||||
|
unique = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unique) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prefix_lengths[i]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the minimal prefix
|
||||||
|
strncpy(prefixes[i], pads[i].chksum, prefix_lengths[i]);
|
||||||
|
prefixes[i][prefix_lengths[i]] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display title and pads table
|
||||||
|
printf("\n%s\n", title);
|
||||||
|
printf("%-8s %-2s %-12s %-12s %-12s %-8s\n", "ChkSum", "D", "Dir", "Size", "Used", "% Used");
|
||||||
|
printf("%-8s %-2s %-12s %-12s %-12s %-8s\n", "--------", "--", "------------", "----------", "----------", "------");
|
||||||
|
|
||||||
|
// Get current default pad path for comparison
|
||||||
|
char* current_default = get_default_pad_path();
|
||||||
|
char default_pad_checksum[65] = "";
|
||||||
|
|
||||||
|
if (current_default) {
|
||||||
|
// Extract checksum from default pad path
|
||||||
|
char* filename = strrchr(current_default, '/');
|
||||||
|
if (!filename) filename = current_default;
|
||||||
|
else filename++; // Skip the '/'
|
||||||
|
|
||||||
|
// Extract checksum (remove .pad extension)
|
||||||
|
if (strlen(filename) >= 68 && strstr(filename, ".pad")) {
|
||||||
|
strncpy(default_pad_checksum, filename, 64);
|
||||||
|
default_pad_checksum[64] = '\0';
|
||||||
|
}
|
||||||
|
free(current_default);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < pad_count; i++) {
|
||||||
|
// Check if this is the default pad
|
||||||
|
int is_default = (strlen(default_pad_checksum) > 0 &&
|
||||||
|
strncmp(pads[i].chksum, default_pad_checksum, 64) == 0);
|
||||||
|
|
||||||
|
// Display first 8 characters of checksum with prefix underlined
|
||||||
|
char checksum_8char[9];
|
||||||
|
strncpy(checksum_8char, pads[i].chksum, 8);
|
||||||
|
checksum_8char[8] = '\0';
|
||||||
|
|
||||||
|
printf("\033[4m%.*s\033[0m%s %-2s %-12s %-12s %-12s %.1f%%\n",
|
||||||
|
prefix_lengths[i], checksum_8char, // Underlined prefix
|
||||||
|
checksum_8char + prefix_lengths[i], // Rest of 8-char checksum
|
||||||
|
is_default ? "*" : "", // Default indicator
|
||||||
|
pads[i].location,
|
||||||
|
pads[i].size_str,
|
||||||
|
pads[i].used_str,
|
||||||
|
pads[i].percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display prompt
|
||||||
|
printf("\n%s", prompt);
|
||||||
|
if (allow_cancel) {
|
||||||
|
printf(" (or 'x' to cancel)");
|
||||||
|
}
|
||||||
|
printf(": ");
|
||||||
|
|
||||||
|
char input[MAX_HASH_LENGTH];
|
||||||
|
if (!fgets(input, sizeof(input), stdin)) {
|
||||||
|
printf("Error: Failed to read input\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
input[strcspn(input, "\n")] = 0;
|
||||||
|
|
||||||
|
// Handle empty input - select default pad if available
|
||||||
|
if (strlen(input) == 0) {
|
||||||
|
// Get current default pad path
|
||||||
|
char* current_default = get_default_pad_path();
|
||||||
|
if (current_default) {
|
||||||
|
// Extract checksum from default pad path
|
||||||
|
char* filename = strrchr(current_default, '/');
|
||||||
|
if (!filename) filename = current_default;
|
||||||
|
else filename++; // Skip the '/'
|
||||||
|
|
||||||
|
// Extract checksum (remove .pad extension)
|
||||||
|
if (strlen(filename) >= 68 && strstr(filename, ".pad")) {
|
||||||
|
char default_checksum[65];
|
||||||
|
strncpy(default_checksum, filename, 64);
|
||||||
|
default_checksum[64] = '\0';
|
||||||
|
|
||||||
|
// Verify this default pad is in our current list
|
||||||
|
for (int i = 0; i < pad_count; i++) {
|
||||||
|
if (strncmp(pads[i].chksum, default_checksum, 64) == 0) {
|
||||||
|
free(current_default);
|
||||||
|
printf("Selected default pad: %.16s...\n", default_checksum);
|
||||||
|
return strdup(default_checksum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(current_default);
|
||||||
|
}
|
||||||
|
// No default pad or default pad not in current list
|
||||||
|
printf("No default pad available or default pad not in current list\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle cancel
|
||||||
|
if (allow_cancel && (toupper(input[0]) == 'X' && strlen(input) == 1)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find matching pad by prefix or number
|
||||||
|
int selected_pad = -1;
|
||||||
|
int match_count = 0;
|
||||||
|
|
||||||
|
// Check if input is a number first
|
||||||
|
char* endptr;
|
||||||
|
int selection = strtol(input, &endptr, 10);
|
||||||
|
if (*endptr == '\0' && selection >= 1 && selection <= pad_count) {
|
||||||
|
// Valid number selection
|
||||||
|
selected_pad = selection - 1;
|
||||||
|
match_count = 1;
|
||||||
|
} else {
|
||||||
|
// Try prefix matching
|
||||||
|
for (int i = 0; i < pad_count; i++) {
|
||||||
|
if (strncmp(input, pads[i].chksum, strlen(input)) == 0) {
|
||||||
|
if (match_count == 0) {
|
||||||
|
selected_pad = i;
|
||||||
|
}
|
||||||
|
match_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_count == 0) {
|
||||||
|
printf("No pad found matching '%s'\n", input);
|
||||||
|
return NULL;
|
||||||
|
} else if (match_count > 1) {
|
||||||
|
printf("Ambiguous prefix. Multiple matches found.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return selected pad checksum (caller must free)
|
||||||
|
return strdup(pads[selected_pad].chksum);
|
||||||
|
}
|
||||||
|
|
||||||
int handle_pads_menu(void) {
|
int handle_pads_menu(void) {
|
||||||
printf("\n=== Pad Management ===\n");
|
printf("\n=== Pad Management ===\n");
|
||||||
|
|
||||||
@@ -4052,8 +4169,8 @@ int handle_pads_menu(void) {
|
|||||||
|
|
||||||
// Display pads with minimal prefixes underlined and default indicator
|
// Display pads with minimal prefixes underlined and default indicator
|
||||||
printf("\nAvailable pads:\n");
|
printf("\nAvailable pads:\n");
|
||||||
printf("%-7s %-8s %-12s %-12s %-12s %-8s\n", "Default", "ChkSum", "Dir", "Size", "Used", "% Used");
|
printf("%-8s %-2s %-12s %-12s %-12s %-8s\n", "ChkSum", "D", "Dir", "Size", "Used", "% Used");
|
||||||
printf("%-7s %-8s %-12s %-12s %-12s %-8s\n", "-------", "--------", "------------", "----------", "----------", "------");
|
printf("%-8s %-2s %-12s %-12s %-12s %-8s\n", "--------", "--", "------------", "----------", "----------", "------");
|
||||||
|
|
||||||
// Get current default pad path for comparison
|
// Get current default pad path for comparison
|
||||||
char* current_default = get_default_pad_path();
|
char* current_default = get_default_pad_path();
|
||||||
@@ -4083,10 +4200,10 @@ int handle_pads_menu(void) {
|
|||||||
strncpy(checksum_8char, pads[i].chksum, 8);
|
strncpy(checksum_8char, pads[i].chksum, 8);
|
||||||
checksum_8char[8] = '\0';
|
checksum_8char[8] = '\0';
|
||||||
|
|
||||||
printf("%-7s \033[4m%.*s\033[0m%s %-12s %-12s %-12s %.1f%%\n",
|
printf("\033[4m%.*s\033[0m%s %-2s %-12s %-12s %-12s %.1f%%\n",
|
||||||
is_default ? "*" : "", // Default indicator
|
|
||||||
prefix_lengths[i], checksum_8char, // Underlined prefix
|
prefix_lengths[i], checksum_8char, // Underlined prefix
|
||||||
checksum_8char + prefix_lengths[i], // Rest of 8-char checksum
|
checksum_8char + prefix_lengths[i], // Rest of 8-char checksum
|
||||||
|
is_default ? "*" : "", // Default indicator
|
||||||
pads[i].location, // Use the stored location info
|
pads[i].location, // Use the stored location info
|
||||||
pads[i].size_str,
|
pads[i].size_str,
|
||||||
pads[i].used_str,
|
pads[i].used_str,
|
||||||
@@ -4098,7 +4215,7 @@ int handle_pads_menu(void) {
|
|||||||
printf(" \033[4mA\033[0mdd entropy to pad\n");
|
printf(" \033[4mA\033[0mdd entropy to pad\n");
|
||||||
printf(" \033[4mS\033[0met default pad\n");
|
printf(" \033[4mS\033[0met default pad\n");
|
||||||
printf(" E\033[4mx\033[0mit\n");
|
printf(" E\033[4mx\033[0mit\n");
|
||||||
printf("\nSelect pad (by prefix) or action: ");
|
printf("\nSelect pad (by prefix): ");
|
||||||
|
|
||||||
char input[MAX_HASH_LENGTH];
|
char input[MAX_HASH_LENGTH];
|
||||||
if (!fgets(input, sizeof(input), stdin)) {
|
if (!fgets(input, sizeof(input), stdin)) {
|
||||||
@@ -4116,113 +4233,30 @@ int handle_pads_menu(void) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else if (toupper(input[0]) == 'A') {
|
} else if (toupper(input[0]) == 'A') {
|
||||||
// Add entropy to pad - filter for unused pads only
|
// Add entropy to pad - use unified function with unused pads filter
|
||||||
char unused_pads[100][65];
|
char* selected_pad = select_pad_interactive("=== Select Unused Pad for Entropy Addition ===",
|
||||||
int unused_count = filter_unused_pads(unused_pads, 100);
|
"Select unused pad (by prefix or number)",
|
||||||
|
PAD_FILTER_UNUSED_ONLY, 1);
|
||||||
if (unused_count == 0) {
|
if (!selected_pad) {
|
||||||
printf("\nNo unused pads available for entropy addition.\n");
|
printf("Entropy addition cancelled.\n");
|
||||||
printf("Entropy can only be added to pads with 0%% usage (only reserved bytes used).\n");
|
|
||||||
printf("Use existing pads for encryption/decryption or generate new pads.\n");
|
|
||||||
printf("\nPress Enter to continue...");
|
|
||||||
getchar();
|
|
||||||
return handle_pads_menu();
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\nUnused pads available for entropy addition:\n");
|
|
||||||
printf("%-4s %-20s %-12s %-12s\n", "No.", "ChkSum", "Size", "Location");
|
|
||||||
printf("%-4s %-20s %-12s %-12s\n", "---", "-------------------", "----------", "----------");
|
|
||||||
|
|
||||||
// Display unused pads with their details
|
|
||||||
for (int i = 0; i < unused_count; i++) {
|
|
||||||
// Find the pad info from our main list
|
|
||||||
for (int j = 0; j < pad_count; j++) {
|
|
||||||
if (strcmp(unused_pads[i], pads[j].chksum) == 0) {
|
|
||||||
printf("%-4d %-20.16s %-12s %-12s\n",
|
|
||||||
i + 1,
|
|
||||||
pads[j].chksum,
|
|
||||||
pads[j].size_str,
|
|
||||||
pads[j].location);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\nSelect pad to add entropy to (by number or prefix): ");
|
|
||||||
char pad_input[MAX_HASH_LENGTH];
|
|
||||||
if (!fgets(pad_input, sizeof(pad_input), stdin)) {
|
|
||||||
printf("Error: Failed to read input\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
pad_input[strcspn(pad_input, "\n")] = 0;
|
|
||||||
|
|
||||||
// Find matching pad by number or prefix (from unused pads only)
|
|
||||||
char* selected_chksum = NULL;
|
|
||||||
|
|
||||||
// Check if input is a number
|
|
||||||
char* endptr;
|
|
||||||
int selection = strtol(pad_input, &endptr, 10);
|
|
||||||
if (*endptr == '\0' && selection >= 1 && selection <= unused_count) {
|
|
||||||
// Valid number selection
|
|
||||||
selected_chksum = unused_pads[selection - 1];
|
|
||||||
} else {
|
|
||||||
// Try prefix matching in unused pads
|
|
||||||
int match_count = 0;
|
|
||||||
char* matched_chksum = NULL;
|
|
||||||
|
|
||||||
for (int i = 0; i < unused_count; i++) {
|
|
||||||
if (strncmp(pad_input, unused_pads[i], strlen(pad_input)) == 0) {
|
|
||||||
matched_chksum = unused_pads[i];
|
|
||||||
match_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match_count == 1) {
|
|
||||||
selected_chksum = matched_chksum;
|
|
||||||
} else if (match_count > 1) {
|
|
||||||
printf("Ambiguous prefix. Multiple matches found in unused pads.\n");
|
|
||||||
return handle_pads_menu();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!selected_chksum) {
|
|
||||||
printf("No unused pad found matching '%s'\n", pad_input);
|
|
||||||
return handle_pads_menu();
|
return handle_pads_menu();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add entropy to the selected unused pad
|
// Add entropy to the selected unused pad
|
||||||
int result = handle_add_entropy_to_pad(selected_chksum);
|
int result = handle_add_entropy_to_pad(selected_pad);
|
||||||
|
free(selected_pad);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
// Return to pads menu after successful entropy addition
|
// Return to pads menu after successful entropy addition
|
||||||
return handle_pads_menu();
|
return handle_pads_menu();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else if (toupper(input[0]) == 'S') {
|
} else if (toupper(input[0]) == 'S') {
|
||||||
// Set default pad
|
// Set default pad - use unified function
|
||||||
printf("\nSelect pad to set as default (by prefix): ");
|
char* selected_pad = select_pad_interactive("=== Select Default Pad ===",
|
||||||
char pad_input[MAX_HASH_LENGTH];
|
"Select pad to set as default (by prefix)",
|
||||||
if (!fgets(pad_input, sizeof(pad_input), stdin)) {
|
PAD_FILTER_ALL, 1);
|
||||||
printf("Error: Failed to read input\n");
|
if (!selected_pad) {
|
||||||
return 1;
|
printf("Default pad selection cancelled.\n");
|
||||||
}
|
|
||||||
pad_input[strcspn(pad_input, "\n")] = 0;
|
|
||||||
|
|
||||||
// Find matching pad by prefix using the same logic as pad selection
|
|
||||||
int matched_pad = -1;
|
|
||||||
int match_count = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < pad_count; i++) {
|
|
||||||
if (strncmp(pad_input, pads[i].chksum, strlen(pad_input)) == 0) {
|
|
||||||
matched_pad = i;
|
|
||||||
match_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match_count == 0) {
|
|
||||||
printf("No pad found matching prefix '%s'\n", pad_input);
|
|
||||||
return handle_pads_menu();
|
|
||||||
} else if (match_count > 1) {
|
|
||||||
printf("Ambiguous prefix. Multiple matches found.\n");
|
|
||||||
return handle_pads_menu();
|
return handle_pads_menu();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4230,41 +4264,45 @@ int handle_pads_menu(void) {
|
|||||||
char new_default_path[1024];
|
char new_default_path[1024];
|
||||||
if (current_pads_dir[0] == '/') {
|
if (current_pads_dir[0] == '/') {
|
||||||
// Already absolute path
|
// Already absolute path
|
||||||
int ret = snprintf(new_default_path, sizeof(new_default_path), "%s/%s.pad", current_pads_dir, pads[matched_pad].chksum);
|
int ret = snprintf(new_default_path, sizeof(new_default_path), "%s/%s.pad", current_pads_dir, selected_pad);
|
||||||
if (ret >= (int)sizeof(new_default_path)) {
|
if (ret >= (int)sizeof(new_default_path)) {
|
||||||
printf("Error: Path too long for default pad setting\n");
|
printf("Error: Path too long for default pad setting\n");
|
||||||
|
free(selected_pad);
|
||||||
return handle_pads_menu();
|
return handle_pads_menu();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Relative path - make it absolute
|
// Relative path - make it absolute
|
||||||
char current_dir[512];
|
char current_dir[512];
|
||||||
if (getcwd(current_dir, sizeof(current_dir))) {
|
if (getcwd(current_dir, sizeof(current_dir))) {
|
||||||
int ret = snprintf(new_default_path, sizeof(new_default_path), "%s/%s/%s.pad", current_dir, current_pads_dir, pads[matched_pad].chksum);
|
int ret = snprintf(new_default_path, sizeof(new_default_path), "%s/%s/%s.pad", current_dir, current_pads_dir, selected_pad);
|
||||||
if (ret >= (int)sizeof(new_default_path)) {
|
if (ret >= (int)sizeof(new_default_path)) {
|
||||||
// Path was truncated, fall back to relative path
|
// Path was truncated, fall back to relative path
|
||||||
int ret2 = snprintf(new_default_path, sizeof(new_default_path), "%s/%s.pad", current_pads_dir, pads[matched_pad].chksum);
|
int ret2 = snprintf(new_default_path, sizeof(new_default_path), "%s/%s.pad", current_pads_dir, selected_pad);
|
||||||
if (ret2 >= (int)sizeof(new_default_path)) {
|
if (ret2 >= (int)sizeof(new_default_path)) {
|
||||||
printf("Error: Path too long for default pad setting\n");
|
printf("Error: Path too long for default pad setting\n");
|
||||||
|
free(selected_pad);
|
||||||
return handle_pads_menu();
|
return handle_pads_menu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fallback to relative path
|
// Fallback to relative path
|
||||||
int ret = snprintf(new_default_path, sizeof(new_default_path), "%s/%s.pad", current_pads_dir, pads[matched_pad].chksum);
|
int ret = snprintf(new_default_path, sizeof(new_default_path), "%s/%s.pad", current_pads_dir, selected_pad);
|
||||||
if (ret >= (int)sizeof(new_default_path)) {
|
if (ret >= (int)sizeof(new_default_path)) {
|
||||||
printf("Error: Path too long for default pad setting\n");
|
printf("Error: Path too long for default pad setting\n");
|
||||||
|
free(selected_pad);
|
||||||
return handle_pads_menu();
|
return handle_pads_menu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set_default_pad_path(new_default_path) == 0) {
|
if (set_default_pad_path(new_default_path) == 0) {
|
||||||
printf("Default pad set to: %.16s...\n", pads[matched_pad].chksum);
|
printf("Default pad set to: %.16s...\n", selected_pad);
|
||||||
printf("Full path: %s\n", new_default_path);
|
printf("Full path: %s\n", new_default_path);
|
||||||
} else {
|
} else {
|
||||||
printf("Error: Failed to update default pad preference\n");
|
printf("Error: Failed to update default pad preference\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(selected_pad);
|
||||||
return handle_pads_menu();
|
return handle_pads_menu();
|
||||||
} else if (toupper(input[0]) == 'X') {
|
} else if (toupper(input[0]) == 'X') {
|
||||||
return 0; // Exit to main menu
|
return 0; // Exit to main menu
|
||||||
|
|||||||
Reference in New Issue
Block a user