Fixed bugs

This commit is contained in:
Cametendo
2026-04-28 11:49:35 +02:00
parent e15e7f26d5
commit 063cbbd568
5 changed files with 123 additions and 89 deletions

View File

@@ -1,4 +1,5 @@
package org.cametendo;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -11,29 +12,31 @@ import org.jline.terminal.TerminalBuilder;
/**
* Handles file path input and validation for disk image files.
*
* <p>This class provides functionality to interactively prompt users for image file paths
* with tab completion support, validate that files exist and are regular files, and
* validate file paths from command-line arguments.</p>
*
* @author Cametendo
* @version 1.0
* * <p>This class provides functionality to interactively prompt users for image file paths
* with tab completion support via JLine. It handles Unix-style tilde (~) expansion
* to the user's home directory and validates that paths point to existing regular files.</p>
* * @author Cametendo
* @version 1.1
*/
public class FilePathAdd {
/**
* Stores the validated path to the selected image file.
* Stores the validated absolute path to the selected image file.
*/
public static String ImagePath = "";
/**
* Constant representing the current user's home directory path.
*/
public static final String Home = System.getProperty("user.home");
/**
* Interactively prompts the user to select an image file path.
*
* <p>Uses JLine for enhanced terminal interaction with tab completion support.
* Validates that the selected path points to an existing regular file.</p>
*
* @return The validated path to the selected image file
* @throws IOException If there are I/O errors during terminal setup or file validation
* * <p>Uses JLine for enhanced terminal interaction with {@link FileNameCompleter}.
* The method expands the tilde (~) character if present at the start of the string
* and validates that the resulting path is a regular file before returning.</p>
* * @return The validated absolute path to the selected image file
* @throws IOException If there are I/O errors during terminal setup or file resolution
*/
protected static String filePath() throws IOException {
fileQuestion();
@@ -42,37 +45,48 @@ public class FilePathAdd {
LineReader reader = LineReaderBuilder.builder().terminal(terminal).completer(new FileNameCompleter()).build();
while (true) {
ImagePath = reader.readLine("Path: ").trim();
String input = reader.readLine("Path: ").trim();
if (ImagePath.isBlank()) {
if (input.isBlank()) {
System.out.println("Oops... You didn't specify a file!");
continue;
}
Path path = Path.of(ImagePath);
// Expand tilde to the full home directory path
if (input.startsWith("~")) {
input = Home + input.substring(1);
}
Path path = Path.of(input);
if (!Files.exists(path) || !Files.isRegularFile(path)) {
System.out.println("Invalid file! Please ensure the path points to an ISO / image file.");
continue;
}
// Convert to a real, absolute path and return
ImagePath = path.toRealPath().toString();
System.out.println("Using File: " + ImagePath);
return ImagePath;
}
}
/**
* Validates and returns the full path to an image file.
*
* <p>Takes a file path, validates that it exists and is a regular file,
* and returns the real path. Used for command-line argument validation.</p>
*
* @param ImagePath Path to the image file to validate
* @return Full validated path to the file, or null if invalid
* Validates and returns the full path to an image file from a provided string.
* * <p>This is primarily used for validating command-line arguments. It supports
* tilde expansion and verifies file existence and type.</p>
* * @param inputPath Raw path string to validate
* @return Full validated absolute path, or {@code null} if the path is invalid or inaccessible
*/
public static String validateAndGetFile(String ImagePath) {
public static String validateAndGetFile(String inputPath) {
if (inputPath == null) return null;
try {
Path path = Path.of(ImagePath);
if (inputPath.startsWith("~")) {
inputPath = Home + inputPath.substring(1);
}
Path path = Path.of(inputPath);
if (Files.exists(path) && Files.isRegularFile(path)) {
return path.toRealPath().toString();
} else {
@@ -86,10 +100,7 @@ public class FilePathAdd {
}
/**
* Displays the prompt for file path input.
*
* <p>Informs the user that they should enter the full path to their ISO/image file
* and mentions that tab completion is supported for convenience.</p>
* Displays the prompt for file path input to the standard output.
*/
protected static void fileQuestion() {
System.out.println("Please enter the FULL Path of your ISO / Image. (Tab-completion supported)");

View File

@@ -0,0 +1 @@

View File

@@ -23,14 +23,5 @@ public class Greeting {
*/
public static void greeting(Scanner UserInput) {
System.out.println("Welcome to cflash!");
System.out.println("Would you like to flash an image (Y/n)");
String input = UserInput.nextLine();
if (YesNo.check(input)) {
System.out.println("Please choose the to be flashed device (f. e. sda)");
} else {
System.out.println("Canceling...");
System.exit(0);
}
}
}

View File

@@ -80,6 +80,8 @@ public class OSDetector {
osName = "Haiku OS";
} else if (fileName.contains("reactos")) {
osName = "ReactOS";
} else if (fileName.contains("jgh")) {
osName = "JGH OS (Sauerkraut juice)";
}
// Generic Fallbacks
else if (fileName.contains("linux")) {
@@ -90,6 +92,6 @@ public class OSDetector {
osName = "new OS";
}
System.out.println("\nFlash complete! Have fun with your " + osName + " installation! 🚀");
System.out.println("\nFlash complete! Have fun with your " + osName + " installation!");
}
}

View File

@@ -1,4 +1,5 @@
package org.cametendo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
@@ -7,99 +8,127 @@ import java.util.Scanner;
/**
* Handles storage device detection, listing, and validation for the flashing process.
*
* <p>This class provides functionality to list available storage devices using lsblk,
* validate device paths, and interactively prompt users to select a target device
* for flashing operations.</p>
*
* @author Cametendo
* @version 1.0
* * <p>Includes safety checks to ensure we don't nuke a partition that's currently in use.
* Keeps the user in the loop with a more personal touch.</p>
* * @author Cametendo
* @version 1.1
*/
public class StorageDeviceLister {
/**
* Stores the selected device name (without /dev/ prefix).
*/
public static String device = "";
/**
* Stores the full validated path to the selected device.
*/
public static String fullPath = "";
/**
* Interactively prompts the user to select a storage device.
*
* <p>Displays a list of available storage devices using the lsblk command,
* then prompts the user to enter a device name. Validates the device path
* and continues prompting until a valid device is selected.</p>
*
* @param UserInput Scanner object for reading user input
* @return The full validated path to the selected device
* Guides the user through selecting a safe, unmounted storage device.
*/
protected static String deviceCheck(Scanner UserInput) {
deviceList();
while (true) {
device = UserInput.nextLine();
System.out.print("Target device: ");
device = UserInput.nextLine().trim();
if (device.isBlank()) {
System.out.println("Oops... Device name is empty. Did you missclick?");
continue;
}
Path path = Path.of("/dev/" + device);
// Standardize path - allows entering 'sda' or '/dev/sda'
String checkPath = device.startsWith("/dev/") ? device : "/dev/" + device;
Path path = Path.of(checkPath);
try {
fullPath = path.toRealPath().toString();
System.out.println("Using device: " + fullPath);
// Check if the user is about to break their system
if (isMounted(fullPath)) {
System.out.println("Wait a second! " + fullPath + " is currently mounted.");
System.out.println("I can't flash to a device that's in use. Unmount it and try again!");
continue;
}
System.out.println("Solid choice. Using device: " + fullPath);
return fullPath;
} catch (IOException e) {
System.out.println("Failed to access device! Invalid path or no access. Please try again.");
System.out.println("Hmm... I can't seem to find or access that device. Are you sure you have access to it?");
}
}
}
/**
* Validates and returns the full path to a storage device.
*
* <p>Takes a device name (without /dev/ prefix), constructs the full path,
* and validates that the device exists and is accessible. Used for command-line
* argument validation.</p>
*
* @param deviceName Device name without /dev/ prefix (e.g., "sda")
* @return Full validated path to the device, or null if invalid
* Asks lsblk if the device or its children have an active mount point.
*/
public static String validateAndGetPath(String deviceName) {
private static boolean isMounted(String devicePath) {
try {
Path path = Path.of("/dev/" + deviceName);
return path.toRealPath().toString();
} catch (IOException e) {
System.out.println("Device not found. Invalid Path or no access.");
return null;
ProcessBuilder pb = new ProcessBuilder("lsblk", "-no", "MOUNTPOINT", devicePath);
Process process = pb.start();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
if (!line.trim().isEmpty()) {
return true;
}
}
}
process.waitFor();
} catch (IOException | InterruptedException e) {
System.out.println("Warning: Mountstatus couldn't be verified");
return true;
}
return false;
}
/**
* Displays a list of available storage devices using the lsblk command.
*
* <p>Executes the lsblk command to show block devices and their properties,
* then prompts the user to enter a device name for selection.</p>
* Lists devices with enough info for the user to make a smart decision.
*/
private static void deviceList() {
try {
ProcessBuilder pb = new ProcessBuilder("lsblk");
System.out.println("Scanning for block devices...");
ProcessBuilder pb = new ProcessBuilder("lsblk", "-o", "NAME,SIZE,TYPE,RM,MOUNTPOINT");
Process process = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
process.waitFor();
System.out.println("Please enter the name of your device (without /dev/):");
System.out.println("Enter the name of your device (e.g., sdb or nvme1n1):");
} catch (IOException | InterruptedException e) {
e.printStackTrace();
System.out.println("Failed to run lsblk. Do you have it installed.");
}
}
/**
* Validates a device path (e.g., from a CLI argument).
* * <p>Checks if the device exists, resolves the real path, and ensures
* it isn't currently mounted before giving the green light.</p>
* * @param deviceName Device name (e.g., "sda" or "/dev/sda")
* @return Full validated path, or null if it's a bad idea to use it
*/
public static String validateAndGetPath(String deviceName) {
if (deviceName == null || deviceName.isBlank()) return null;
try {
// Support both "sda" and "/dev/sda"
String checkPath = deviceName.startsWith("/dev/") ? deviceName : "/dev/" + deviceName;
Path path = Path.of(checkPath);
String resolvedPath = path.toRealPath().toString();
// Safety check for CLI arguments too!
if (isMounted(resolvedPath)) {
System.out.println("Hold up! " + resolvedPath + " is mounted. I won't let you flash it like that.");
return null;
}
return resolvedPath;
} catch (IOException e) {
System.out.println("Hmm... I couldn't find a device at '" + deviceName + "'. Is it plugged in?");
return null;
}
}
}