Fixed bugs
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
package org.cametendo;
|
package org.cametendo;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@@ -11,29 +12,31 @@ import org.jline.terminal.TerminalBuilder;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles file path input and validation for disk image files.
|
* Handles file path input and validation for disk image files.
|
||||||
*
|
* * <p>This class provides functionality to interactively prompt users for image file paths
|
||||||
* <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
|
||||||
* with tab completion support, validate that files exist and are regular files, and
|
* to the user's home directory and validates that paths point to existing regular files.</p>
|
||||||
* validate file paths from command-line arguments.</p>
|
* * @author Cametendo
|
||||||
*
|
* @version 1.1
|
||||||
* @author Cametendo
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
*/
|
||||||
public class FilePathAdd {
|
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 = "";
|
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.
|
* Interactively prompts the user to select an image file path.
|
||||||
*
|
* * <p>Uses JLine for enhanced terminal interaction with {@link FileNameCompleter}.
|
||||||
* <p>Uses JLine for enhanced terminal interaction with tab completion support.
|
* The method expands the tilde (~) character if present at the start of the string
|
||||||
* Validates that the selected path points to an existing regular file.</p>
|
* and validates that the resulting path is a regular file before returning.</p>
|
||||||
*
|
* * @return The validated absolute path to the selected image file
|
||||||
* @return The validated path to the selected image file
|
* @throws IOException If there are I/O errors during terminal setup or file resolution
|
||||||
* @throws IOException If there are I/O errors during terminal setup or file validation
|
|
||||||
*/
|
*/
|
||||||
protected static String filePath() throws IOException {
|
protected static String filePath() throws IOException {
|
||||||
fileQuestion();
|
fileQuestion();
|
||||||
@@ -42,37 +45,48 @@ public class FilePathAdd {
|
|||||||
LineReader reader = LineReaderBuilder.builder().terminal(terminal).completer(new FileNameCompleter()).build();
|
LineReader reader = LineReaderBuilder.builder().terminal(terminal).completer(new FileNameCompleter()).build();
|
||||||
|
|
||||||
while (true) {
|
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!");
|
System.out.println("Oops... You didn't specify a file!");
|
||||||
continue;
|
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)) {
|
if (!Files.exists(path) || !Files.isRegularFile(path)) {
|
||||||
System.out.println("Invalid file! Please ensure the path points to an ISO / image file.");
|
System.out.println("Invalid file! Please ensure the path points to an ISO / image file.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert to a real, absolute path and return
|
||||||
|
ImagePath = path.toRealPath().toString();
|
||||||
System.out.println("Using File: " + ImagePath);
|
System.out.println("Using File: " + ImagePath);
|
||||||
return ImagePath;
|
return ImagePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates and returns the full path to an image file.
|
* 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
|
||||||
* <p>Takes a file path, validates that it exists and is a regular file,
|
* tilde expansion and verifies file existence and type.</p>
|
||||||
* and returns the real path. Used for command-line argument validation.</p>
|
* * @param inputPath Raw path string to validate
|
||||||
*
|
* @return Full validated absolute path, or {@code null} if the path is invalid or inaccessible
|
||||||
* @param ImagePath Path to the image file to validate
|
|
||||||
* @return Full validated path to the file, or null if invalid
|
|
||||||
*/
|
*/
|
||||||
public static String validateAndGetFile(String ImagePath) {
|
public static String validateAndGetFile(String inputPath) {
|
||||||
|
if (inputPath == null) return null;
|
||||||
|
|
||||||
try {
|
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)) {
|
if (Files.exists(path) && Files.isRegularFile(path)) {
|
||||||
return path.toRealPath().toString();
|
return path.toRealPath().toString();
|
||||||
} else {
|
} else {
|
||||||
@@ -86,10 +100,7 @@ public class FilePathAdd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the prompt for file path input.
|
* Displays the prompt for file path input to the standard output.
|
||||||
*
|
|
||||||
* <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>
|
|
||||||
*/
|
*/
|
||||||
protected static void fileQuestion() {
|
protected static void fileQuestion() {
|
||||||
System.out.println("Please enter the FULL Path of your ISO / Image. (Tab-completion supported)");
|
System.out.println("Please enter the FULL Path of your ISO / Image. (Tab-completion supported)");
|
||||||
|
|||||||
1
src/main/java/org/cametendo/GetHome.java
Normal file
1
src/main/java/org/cametendo/GetHome.java
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -23,14 +23,5 @@ public class Greeting {
|
|||||||
*/
|
*/
|
||||||
public static void greeting(Scanner UserInput) {
|
public static void greeting(Scanner UserInput) {
|
||||||
System.out.println("Welcome to cflash!");
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ public class OSDetector {
|
|||||||
osName = "Haiku OS";
|
osName = "Haiku OS";
|
||||||
} else if (fileName.contains("reactos")) {
|
} else if (fileName.contains("reactos")) {
|
||||||
osName = "ReactOS";
|
osName = "ReactOS";
|
||||||
|
} else if (fileName.contains("jgh")) {
|
||||||
|
osName = "JGH OS (Sauerkraut juice)";
|
||||||
}
|
}
|
||||||
// Generic Fallbacks
|
// Generic Fallbacks
|
||||||
else if (fileName.contains("linux")) {
|
else if (fileName.contains("linux")) {
|
||||||
@@ -90,6 +92,6 @@ public class OSDetector {
|
|||||||
osName = "new OS";
|
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!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
package org.cametendo;
|
package org.cametendo;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@@ -7,99 +8,127 @@ import java.util.Scanner;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles storage device detection, listing, and validation for the flashing process.
|
* Handles storage device detection, listing, and validation for the flashing process.
|
||||||
*
|
* * <p>Includes safety checks to ensure we don't nuke a partition that's currently in use.
|
||||||
* <p>This class provides functionality to list available storage devices using lsblk,
|
* Keeps the user in the loop with a more personal touch.</p>
|
||||||
* validate device paths, and interactively prompt users to select a target device
|
* * @author Cametendo
|
||||||
* for flashing operations.</p>
|
* @version 1.1
|
||||||
*
|
|
||||||
* @author Cametendo
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
*/
|
||||||
public class StorageDeviceLister {
|
public class StorageDeviceLister {
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores the selected device name (without /dev/ prefix).
|
|
||||||
*/
|
|
||||||
public static String device = "";
|
public static String device = "";
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores the full validated path to the selected device.
|
|
||||||
*/
|
|
||||||
public static String fullPath = "";
|
public static String fullPath = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interactively prompts the user to select a storage device.
|
* Guides the user through selecting a safe, unmounted 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
|
|
||||||
*/
|
*/
|
||||||
protected static String deviceCheck(Scanner UserInput) {
|
protected static String deviceCheck(Scanner UserInput) {
|
||||||
deviceList();
|
deviceList();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
device = UserInput.nextLine();
|
System.out.print("Target device: ");
|
||||||
|
device = UserInput.nextLine().trim();
|
||||||
|
|
||||||
if (device.isBlank()) {
|
if (device.isBlank()) {
|
||||||
System.out.println("Oops... Device name is empty. Did you missclick?");
|
System.out.println("Oops... Device name is empty. Did you missclick?");
|
||||||
continue;
|
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 {
|
try {
|
||||||
fullPath = path.toRealPath().toString();
|
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;
|
return fullPath;
|
||||||
|
|
||||||
} catch (IOException e) {
|
} 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.
|
* Asks lsblk if the device or its children have an active mount point.
|
||||||
*
|
|
||||||
* <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
|
|
||||||
*/
|
*/
|
||||||
public static String validateAndGetPath(String deviceName) {
|
private static boolean isMounted(String devicePath) {
|
||||||
try {
|
try {
|
||||||
Path path = Path.of("/dev/" + deviceName);
|
ProcessBuilder pb = new ProcessBuilder("lsblk", "-no", "MOUNTPOINT", devicePath);
|
||||||
return path.toRealPath().toString();
|
Process process = pb.start();
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("Device not found. Invalid Path or no access.");
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||||
return null;
|
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.
|
* Lists devices with enough info for the user to make a smart decision.
|
||||||
*
|
|
||||||
* <p>Executes the lsblk command to show block devices and their properties,
|
|
||||||
* then prompts the user to enter a device name for selection.</p>
|
|
||||||
*/
|
*/
|
||||||
private static void deviceList() {
|
private static void deviceList() {
|
||||||
try {
|
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();
|
Process process = pb.start();
|
||||||
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
System.out.println(line);
|
System.out.println(line);
|
||||||
}
|
}
|
||||||
process.waitFor();
|
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) {
|
} 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user