diff --git a/otp.c b/otp.c index 21c6c60..723ff17 100644 --- a/otp.c +++ b/otp.c @@ -103,6 +103,9 @@ int handle_file_encrypt(void); // Enhanced input functions int get_filename_with_default(const char* prompt, const char* default_path, char* result, size_t result_size); +// Directory display functions +void get_directory_display(const char* file_path, char* result, size_t result_size); + void print_usage(const char* program_name); int main(int argc, char* argv[]) { @@ -2943,14 +2946,21 @@ int handle_pads_menu(void) { // Display pads with minimal prefixes underlined printf("\nAvailable pads:\n"); - printf("%-20s %-12s %-12s %-8s\n", "ChkSum", "Size", "Used", "% Used"); - printf("%-20s %-12s %-12s %-8s\n", "-------------------", "----------", "----------", "------"); + printf("%-8s %-12s %-12s %-12s %-8s\n", "ChkSum", "Dir", "Size", "Used", "% Used"); + printf("%-8s %-12s %-12s %-12s %-8s\n", "--------", "------------", "----------", "----------", "------"); for (int i = 0; i < pad_count; i++) { - // Display checksum with prefix underlined - printf("\033[4m%.*s\033[0m%-*s %-12s %-12s %.1f%%\n", + // Get directory information for this pad + char full_path[300]; + snprintf(full_path, sizeof(full_path), "%s/%s.pad", PADS_DIR, pads[i].chksum); + char dir_display[13]; // 12 chars + null terminator + get_directory_display(full_path, dir_display, sizeof(dir_display)); + + // Display first 8 characters of checksum with prefix underlined + printf("\033[4m%.*s\033[0m%-*s %-12s %-12s %-12s %.1f%%\n", prefix_lengths[i], pads[i].chksum, // Underlined prefix - 20 - prefix_lengths[i], pads[i].chksum + prefix_lengths[i], // Rest of checksum with padding + 8 - prefix_lengths[i], pads[i].chksum + prefix_lengths[i], // Rest of 8-char checksum + dir_display, pads[i].size_str, pads[i].used_str, pads[i].percentage); @@ -3019,6 +3029,121 @@ int handle_pads_menu(void) { return handle_pads_menu(); } +void get_directory_display(const char* file_path, char* result, size_t result_size) { + // Extract directory path from full file path + char dir_path[512]; + char* last_slash = strrchr(file_path, '/'); + + if (last_slash) { + size_t dir_len = last_slash - file_path; + if (dir_len >= sizeof(dir_path)) { + dir_len = sizeof(dir_path) - 1; + } + strncpy(dir_path, file_path, dir_len); + dir_path[dir_len] = '\0'; + } else { + // No directory separator, assume current directory + strcpy(dir_path, "."); + } + + // USB Drive Detection and Smart Shortening + char* home_dir = getenv("HOME"); + + // Check for USB/removable media mount patterns + if (strstr(dir_path, "/media/") || strstr(dir_path, "/run/media/") || strstr(dir_path, "/mnt/")) { + // Extract USB label/name + char* media_start = NULL; + if (strstr(dir_path, "/media/")) { + media_start = strstr(dir_path, "/media/"); + } else if (strstr(dir_path, "/run/media/")) { + media_start = strstr(dir_path, "/run/media/"); + } else if (strstr(dir_path, "/mnt/")) { + media_start = strstr(dir_path, "/mnt/"); + } + + if (media_start) { + // Find the USB label part + char* path_after_media = strchr(media_start + 1, '/'); + if (path_after_media) { + path_after_media++; // Skip the slash + + // For /run/media/user/LABEL pattern, skip the username + if (strstr(media_start, "/run/media/")) { + char* next_slash = strchr(path_after_media, '/'); + if (next_slash) { + path_after_media = next_slash + 1; + } + } + + // Extract just the USB label (up to next slash or end) + char* label_end = strchr(path_after_media, '/'); + if (label_end) { + size_t label_len = label_end - path_after_media; + if (label_len > 11) label_len = 11; // Max 11 chars for display + strncpy(result, path_after_media, label_len); + result[label_len] = '\0'; + } else { + // USB label is the last part + strncpy(result, path_after_media, result_size - 1); + result[result_size - 1] = '\0'; + } + return; + } + } + } + + // Home directory shortening + if (home_dir && strncmp(dir_path, home_dir, strlen(home_dir)) == 0) { + if (dir_path[strlen(home_dir)] == '/' || dir_path[strlen(home_dir)] == '\0') { + // Replace home directory with ~ + char temp[512]; + snprintf(temp, sizeof(temp), "~%s", dir_path + strlen(home_dir)); + + // If result is too long, truncate intelligently + if (strlen(temp) > 11) { + // Show ~/...end_part + char* last_part = strrchr(temp, '/'); + if (last_part && strlen(last_part) < 8) { + snprintf(result, result_size, "~...%s", last_part); + } else { + strncpy(result, temp, 11); + result[11] = '\0'; + } + } else { + strncpy(result, temp, result_size - 1); + result[result_size - 1] = '\0'; + } + return; + } + } + + // Current working directory + if (strcmp(dir_path, ".") == 0 || strcmp(dir_path, PADS_DIR) == 0) { + strncpy(result, "pads", result_size - 1); + result[result_size - 1] = '\0'; + return; + } + + // System/other paths - smart truncation with ellipsis + if (strlen(dir_path) > 11) { + // Try to show the most meaningful part + char* last_part = strrchr(dir_path, '/'); + if (last_part && strlen(last_part) < 9) { + // Show .../last_part + snprintf(result, result_size, "...%s", last_part); + } else { + // Show first part with ellipsis + strncpy(result, dir_path, 8); + strncpy(result + 8, "...", result_size - 8 - 1); + result[result_size - 1] = '\0'; + } + } else { + // Short enough, use as-is + strncpy(result, dir_path, result_size - 1); + result[result_size - 1] = '\0'; + } +} + void print_usage(const char* program_name) { printf("OTP Cipher - One Time Pad Implementation %s\n", get_version()); printf("%s\n", get_build_info());