diff --git a/output.otp b/files/output.otp similarity index 100% rename from output.otp rename to files/output.otp diff --git a/test_decrypt.txt b/files/test_decrypt.txt similarity index 100% rename from test_decrypt.txt rename to files/test_decrypt.txt diff --git a/test_decrypt.txt.otp b/files/test_decrypt.txt.otp similarity index 100% rename from test_decrypt.txt.otp rename to files/test_decrypt.txt.otp diff --git a/test_file.txt b/files/test_file.txt similarity index 100% rename from test_file.txt rename to files/test_file.txt diff --git a/test_file.txt.otp.asc b/files/test_file.txt.otp.asc similarity index 100% rename from test_file.txt.otp.asc rename to files/test_file.txt.otp.asc diff --git a/test_input.txt b/files/test_input.txt similarity index 100% rename from test_input.txt rename to files/test_input.txt diff --git a/toc.txt b/files/toc.txt similarity index 100% rename from toc.txt rename to files/toc.txt diff --git a/toc.txt.otp b/files/toc.txt.otp similarity index 100% rename from toc.txt.otp rename to files/toc.txt.otp diff --git a/otp.c b/otp.c index 717afb9..d390790 100644 --- a/otp.c +++ b/otp.c @@ -40,6 +40,7 @@ static const int base64_decode_table[256] = { #define MAX_HASH_LENGTH 65 #define PROGRESS_UPDATE_INTERVAL (64 * 1024 * 1024) // 64MB intervals #define PADS_DIR "pads" +#define FILES_DIR "files" #define MAX_ENTROPY_BUFFER 32768 // 32KB entropy buffer // Function prototypes @@ -72,7 +73,10 @@ void simple_entropy_mix(unsigned char* urandom_buffer, size_t buffer_size, // Directory management int ensure_pads_directory(void); +int ensure_files_directory(void); void get_pad_path(const char* chksum, char* pad_path, char* state_path); +const char* get_files_directory(void); +void get_default_file_path(const char* filename, char* result_path, size_t result_size); // Utility functions uint64_t parse_size_string(const char* size_str); @@ -461,14 +465,20 @@ int handle_encrypt_menu(void) { int ascii_armor = (atoi(format_input) == 2) ? 1 : 0; - // Generate default output filename and use enhanced input function + // Generate default output filename with files directory and use enhanced input function char default_output[1024]; // Increased size to prevent truncation warnings + char temp_default[1024]; + + // Generate base filename with appropriate extension if (ascii_armor) { - snprintf(default_output, sizeof(default_output), "%s.otp.asc", input_file); + snprintf(temp_default, sizeof(temp_default), "%s.otp.asc", input_file); } else { - snprintf(default_output, sizeof(default_output), "%s.otp", input_file); + snprintf(temp_default, sizeof(temp_default), "%s.otp", input_file); } + // Apply files directory default path + get_default_file_path(temp_default, default_output, sizeof(default_output)); + char output_file[512]; if (get_filename_with_default("Output filename:", default_output, output_file, sizeof(output_file)) != 0) { printf("Error: Failed to read input\n"); @@ -522,25 +532,29 @@ int handle_decrypt_menu(void) { return 1; } - // Generate smart default output filename and use enhanced input function + // Generate smart default output filename with files directory and use enhanced input function + char temp_default[512]; char default_output[512]; - strncpy(default_output, input_file, sizeof(default_output) - 1); - default_output[sizeof(default_output) - 1] = '\0'; + strncpy(temp_default, input_file, sizeof(temp_default) - 1); + temp_default[sizeof(temp_default) - 1] = '\0'; // Remove common encrypted extensions to get a better default - if (strstr(default_output, ".otp.asc")) { + if (strstr(temp_default, ".otp.asc")) { // Replace .otp.asc with original extension or no extension - char* ext_pos = strstr(default_output, ".otp.asc"); + char* ext_pos = strstr(temp_default, ".otp.asc"); *ext_pos = '\0'; - } else if (strstr(default_output, ".otp")) { + } else if (strstr(temp_default, ".otp")) { // Replace .otp with original extension or no extension - char* ext_pos = strstr(default_output, ".otp"); + char* ext_pos = strstr(temp_default, ".otp"); *ext_pos = '\0'; } else { // No recognized encrypted extension, add .decrypted suffix - strncat(default_output, ".decrypted", sizeof(default_output) - strlen(default_output) - 1); + strncat(temp_default, ".decrypted", sizeof(temp_default) - strlen(temp_default) - 1); } + // Apply files directory default path + get_default_file_path(temp_default, default_output, sizeof(default_output)); + char output_file[512]; if (get_filename_with_default("Output filename:", default_output, output_file, sizeof(output_file)) != 0) { printf("Error: Failed to read input\n"); @@ -2229,6 +2243,38 @@ int ensure_pads_directory(void) { return 0; } +int ensure_files_directory(void) { + struct stat st = {0}; + if (stat(FILES_DIR, &st) == -1) { + if (mkdir(FILES_DIR, 0755) != 0) { + return 1; + } + } + return 0; +} + +const char* get_files_directory(void) { + struct stat st = {0}; + if (stat(FILES_DIR, &st) == 0 && S_ISDIR(st.st_mode)) { + return FILES_DIR; + } + return "."; // Fall back to current directory +} + +void get_default_file_path(const char* filename, char* result_path, size_t result_size) { + const char* files_dir = get_files_directory(); + + // If filename already has a path (contains '/'), use it as-is + if (strchr(filename, '/') != NULL) { + strncpy(result_path, filename, result_size - 1); + result_path[result_size - 1] = '\0'; + return; + } + + // Otherwise, prepend the files directory + snprintf(result_path, result_size, "%s/%s", files_dir, filename); +} + void get_pad_path(const char* chksum, char* pad_path, char* state_path) { snprintf(pad_path, MAX_HASH_LENGTH + 20, "%s/%s.pad", PADS_DIR, chksum); snprintf(state_path, MAX_HASH_LENGTH + 20, "%s/%s.state", PADS_DIR, chksum);