22 Commits

Author SHA1 Message Date
Cametendo
cb9b464a99 Added uninstall.sh 2026-04-24 07:58:00 +02:00
cc3bd2a3a5 Update README.md for installation on Arch 2026-04-23 19:57:05 +02:00
Cametendo
9f0338740a Added PKGBUILD for AUR publishing 2026-04-23 19:30:11 +02:00
Cametendo
ae8a44fe76 update gitignore 2026-04-23 18:54:14 +02:00
64985fa2d8 Update README.md for installation 2026-04-23 18:48:29 +02:00
Cametendo
d8b3795b3e test: verify update script 2026-04-23 18:32:36 +02:00
9157b3514a Update README.md 2026-04-23 15:02:57 +02:00
Cametendo
4ed8cdc792 Fixed blocksize and oflag and only supporting number
in both the CLI version aswell as the TUI version
2026-04-23 14:40:36 +02:00
Cametendo
23f5ff77ec Fixed blocksize and oflag and only supporting number
in both the CLI version aswell as the TUI version
2026-04-23 14:26:32 +02:00
Cametendo
ee7c2ba46b Fix 'Program doesnt close when saying i dont want to flash a image' 2026-04-23 11:41:23 +02:00
Cametendo
d0d239e0ca Added tab-completion and cli-arguments 2026-04-22 22:12:33 +02:00
Cametendo
5fd53af017 Removed MacOS and FreeBSD from supported OS
Will add them once they are also supported
2026-04-21 22:04:08 +02:00
Cametendo
48f4093906 Added Library JLINE 2026-04-21 22:00:28 +02:00
Cametendo
0edbc24003 Added file and device verification 2026-04-21 20:54:54 +02:00
Cametendo
ecb1f7be3e Merge branch 'dev' 2026-04-04 19:54:57 +02:00
Cametendo
66e4247199 Added dd 2026-04-04 19:54:18 +02:00
Cametendo
1661e3e060 Merge branch 'working-flasher' into dev 2026-04-03 15:14:23 +02:00
Cametendo
c086bcc2e6 Made flasher show user configuration 2026-04-03 15:12:45 +02:00
Cametendo
68d7520e26 Clarify description in README.md
Removed redundant wording for clarity.
2026-03-20 12:14:57 +01:00
Cametendo
2c076c4c95 Added oflag 2026-03-18 23:03:35 +01:00
Cametendo
4d6e8b975f create devicecheck, filepathcheck and blocksize 2026-02-09 11:58:37 +01:00
Cametendo
baab63f846 create base 2026-02-09 08:26:01 +01:00
18 changed files with 758 additions and 5 deletions

15
.gitignore vendored
View File

@@ -22,3 +22,18 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
target/
*.class
.mtj.tmp/
*.jar
*.war
*.ear
hs_err_pid*
# VS Code specific
.classpath
.project
.settings/
.vscode/
.claude/

35
PKGBUILD Normal file
View File

@@ -0,0 +1,35 @@
# Maintainer: Cametendo cameronmathis08@gmail.com
pkgname=cflash
pkgver=1.0.0
pkgrel=1
pkgdesc="Small and lightweight image and iso flasher build on dd."
arch=('any')
url="https://github.com/cametendo/cflash-git"
license=('MIT')
depends=('java-runtime>=21')
makedepends=('java-environment>=21' 'maven')
source=("cflash::git+https://github.com/cametendo/cflash-git.git")
sha256sums=('SKIP')
build() {
cd "$pkgname"
# using 'package' because pom.xml triggers the assembly plugin during this phase
mvn clean package
}
package() {
cd "$srcdir/cflash"
# for some reason MAKEPKD won't accept my version, using the wildcard for literally anything if may find
install -Dm644 target/cflash-*-jar-with-dependencies.jar \
"$pkgdir/usr/share/java/cflash/cflash.jar"
# Create the executable
install -d "$pkgdir/usr/bin"
cat <<EOF > "$pkgdir/usr/bin/cflash"
#!/bin/sh
exec /usr/bin/java -jar /usr/share/java/cflash/cflash.jar "\$@"
EOF
# makes the program executable
chmod +x "$pkgdir/usr/bin/cflash"
}

View File

@@ -7,12 +7,84 @@ Small and lightweight image and iso flasher build on `dd`.
[![Status](https://img.shields.io/badge/Status-Beta-red.svg)](https://en.wikipedia.org/wiki/Software_release_life_cycle#Beta)
# About
Java program using `dd` to make flashing iso and image files easier on the terminal. This program allows anyone to flash iso and image files without having to search for extra GUI tools and by keeping it simple and resource-friendly.
Java program using `dd` to make flashing iso and image files easier on the terminal. This program allows anyone to flash iso and image files without having to search for extra GUI tools by keeping it simple and resource-friendly.
## Getting Started
# Requirements
- `Java`: 21 (Download [here](https://www.oracle.com/java/technologies/downloads/#java21)
- `Java`: 21 (Download [here](https://www.oracle.com/java/technologies/downloads/#java21))
- `util-linux`: 2.41
- `coreutils`: 9.10
- `maven`: 3.9.15
- Operating System: Linux
### Building and Running Locally
1. Clone the repository:
```bash
git clone https://github.com/cametendo/cflash-git.git
cd cflash-git
```
2. Compile the code:
```bash
mvn clean package
```
3. Run the application:
```bash
java -jar target/cflash-<version>.jar (optionally add arguments here, like with dd)
```
### System-wide Installation
To install cflash globally so that it can be run from any terminal:
1. Clone the repository (if not done already):
```bash
git clone https://github.com/cametendo/cflash-git.git
cd cflash-git
```
2. Make the build and install scripts executable:
```bash
chmod +x build.sh install.sh
```
3. Build the project using the provided build script:
```bash
./build.sh
```
4. Install globally (requires root privileges):
```bash
sudo ./install.sh
```
5. Run cflash from anywhere:
```bash
cflash
```
**Notes:**
* The `build.sh` script compiles all Java source files and creates an executable `cflash.jar`.
* The `install.sh` script copies `cflash.jar` to `/usr/local/lib/cflash` and installs a wrapper script in `/usr/local/bin` for easy execution.
* If you use Arch Linux:
* You can directly install it with `yay` or `paru` via `yay -S cflash` / `paru -S cflash` or
* You can clone the repository from the [AUR](https://aur.archlinux.org/packages/cflash) and manually build it:
```bash
git clone https://aur.archlinux.org/cflash.git
cd cflash
makepkg -si
```
# Usage
- Using the command `cflash` in the terminal, will start the flashing process. You will be asked several question before the flashing begins:
@@ -27,13 +99,13 @@ Java program using `dd` to make flashing iso and image files easier on the termi
- **IMPORTANT**: Since dd needs sudo rights, ensure you have root priviliges.
# Supported OS
- Linux, MacOS, FreeBSD
- Linux
# Installation
1. Clone the repository onto your local device.
1. Clone the repository onto your device and cd into it.
2. Run the `build.sh` file to build the program.
3. Run the `ìnstall.sh`to install the program.
4. Open a terminal and use the program with `cflash`.
4. Open a terminal and use the program with `cflash`, optionally add all the arguments you need.
# License and Credits
**Author**: [Cametendo](https://www.github.com/Cametendo)

86
build.sh Executable file
View File

@@ -0,0 +1,86 @@
#!/usr/bin/env bash
# --- Build script for cflash ---
# Compiles sources and bundles jline via Maven into a single fat JAR.
# If Maven is missing, prompts the user to install it using the detected package manager.
set -e
JAR_FILE="cflash.jar"
# --- Detect package manager ---
detect_package_manager() {
if command -v pacman >/dev/null 2>&1; then
echo "pacman"
elif command -v apt >/dev/null 2>&1; then
echo "apt"
elif command -v dnf >/dev/null 2>&1; then
echo "dnf"
elif command -v yum >/dev/null 2>&1; then
echo "yum"
elif command -v zypper >/dev/null 2>&1; then
echo "zypper"
elif command -v brew >/dev/null 2>&1; then
echo "brew"
elif command -v apk >/dev/null 2>&1; then
echo "apk"
elif command -v emerge >/dev/null 2>&1; then
echo "emerge"
else
echo ""
fi
}
# --- Generate Maven install command ---
maven_install_command() {
local pm="$1"
case "$pm" in
pacman) echo "pacman -Sy --noconfirm maven" ;;
apt) echo "apt update && apt install -y maven" ;;
dnf) echo "dnf install -y maven" ;;
yum) echo "yum install -y maven" ;;
zypper) echo "zypper install -y maven" ;;
brew) echo "brew install maven" ;;
apk) echo "apk add maven" ;;
emerge) echo "emerge dev-java/maven-bin" ;;
*) echo "" ;;
esac
}
# --- Check for mvn ---
if ! command -v mvn >/dev/null 2>&1; then
echo "Maven (mvn) not found."
PM=$(detect_package_manager)
if [[ -z "$PM" ]]; then
echo "Please install Maven manually and rerun this script."
exit 1
fi
CMD=$(maven_install_command "$PM")
if [[ $EUID -ne 0 && "$PM" != "brew" ]]; then
echo "Please run this script as root to install Maven, or install it manually."
exit 1
fi
read -rp "Do you want to run the following command to install Maven? [$CMD] (y/n): " ANSWER
case "$ANSWER" in
y|Y)
echo "Installing Maven..."
eval "$CMD"
echo "Maven installed successfully."
;;
*)
echo "Maven installation cancelled. Please install manually and rerun."
exit 1
;;
esac
fi
# --- Build process ---
echo "Building cflash with Maven..."
mvn package -q
echo "Copying fat JAR to ${JAR_FILE}..."
cp target/cflash-*-jar-with-dependencies.jar "$JAR_FILE"
echo "Build completed successfully: ${JAR_FILE}"

84
cflash.sh Executable file
View File

@@ -0,0 +1,84 @@
#!/usr/bin/env bash
# cflash launcher with self-update via git + rebuild (requires sudo for update)
CFLASH_DIR="/usr/local/lib/cflash"
CFLASH_JAR="$CFLASH_DIR/cflash.jar"
GIT_REPO="https://gitea.cametendo.org/cametendo/cflash.git"
update_cflash() {
# Check for sudo/root
if [[ $EUID -ne 0 ]]; then
echo "cflash --update requires root privileges. Please run with sudo."
exit 1
fi
echo "Updating cflash from repository..."
TMP_DIR=$(mktemp -d)
echo "Cloning repository into $TMP_DIR..."
if ! git clone --depth 1 "$GIT_REPO" "$TMP_DIR"; then
echo "Failed to clone repository."
rm -rf "$TMP_DIR"
exit 1
fi
pushd "$TMP_DIR" >/dev/null
# Logic to handle if the repo contents are nested inside a 'cflash' folder
if [[ ! -f "./build.sh" && -d "cflash" ]]; then
echo "Detected nested directory, moving into cflash/..."
cd cflash
fi
# Ensure build.sh is executable (git usually preserves this, but just in case)
if [[ -f "./build.sh" ]]; then
chmod +x ./build.sh
echo "Building cflash..."
if ! ./build.sh; then
echo "Build failed."
popd >/dev/null
rm -rf "$TMP_DIR"
exit 1
fi
else
echo "Error: build.sh not found in the repository root or cflash/ directory."
popd >/dev/null
rm -rf "$TMP_DIR"
exit 1
fi
echo "Installing new version..."
if [[ -f "./install.sh" ]]; then
chmod +x ./install.sh
if ! ./install.sh; then
echo "Install failed."
popd >/dev/null
rm -rf "$TMP_DIR"
exit 1
fi
else
echo "Error: install.sh not found."
popd >/dev/null
rm -rf "$TMP_DIR"
exit 1
fi
popd >/dev/null
rm -rf "$TMP_DIR"
echo "Update completed successfully!"
exit 0
}
# Handle --update argument
if [[ "$1" == "--update" ]]; then
update_cflash
fi
# Run cflash normally
if [[ -f "$CFLASH_JAR" ]]; then
java --enable-native-access=ALL-UNNAMED -jar "$CFLASH_JAR" "$@"
else
echo "Error: $CFLASH_JAR not found. Please run 'sudo cflash --update' to install."
exit 1
fi

16
install.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# Install script for system-wide usage
# Ensure running as root
if [[ $EUID -ne 0 ]]; then
echo "Please run as root to install globally."
exit 1
fi
# Create installation directories
mkdir -p /usr/local/lib/cflash
cp cflash.jar /usr/local/lib/cflash/
cp cflash.sh /usr/local/bin/cflash
chmod +x /usr/local/bin/cflash
echo "cflash installed successfully! You can now run 'cflash' from anywhere."

55
pom.xml Normal file
View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.cametendo</groupId>
<artifactId>cflash</artifactId>
<version>1.0.1</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.jline</groupId>
<artifactId>jline</artifactId>
<version>3.25.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<archive>
<manifest>
<mainClass>org.cametendo.Main</mainClass>
</manifest>
<manifestEntries>
<Enable-Native-Access>ALL-UNNAMED</Enable-Native-Access>
</manifestEntries>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,31 @@
package org.cametendo;
import java.util.Scanner;
public class BlockSize {
public static String blockSizeString = "4M";
public static String mapBlockSize(String input) {
return switch (input) {
case "1", "512K" -> "512K";
case "2", "1M" -> "1M";
case "3", "2M" -> "2M";
case "4", "4M" -> "4M";
case "5", "8M" -> "8M";
case "6", "16M" -> "16M";
default -> blockSizeString;
};
}
static String blockSize(Scanner UserInput) {
System.out.println("Choose a block size (Default: 4M)");
System.out.println("512KB (1), 1M (2), 2M (3), 4M (4), 8M (5), 16M (6)");
String input = UserInput.nextLine();
blockSizeString = mapBlockSize(input);
System.out.println("Using blocksize of: " + blockSizeString);
return blockSizeString;
}
}

View File

@@ -0,0 +1,28 @@
package org.cametendo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Dd {
public static void dd() {
try {
ProcessBuilder pb = new ProcessBuilder("sudo", "dd", "if=" + FilePathAdd.ImagePath, "of=" + StorageDeviceLister.fullPath, "bs=" + BlockSize.blockSizeString, "status=progress", "oflag=" + OflagHandler.oflagHandleString);
pb.redirectErrorStream(true);
Process process = pb.start();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
int character;
while ((character = reader.read()) != -1) {
char c = (char) character;
System.out.print(c);
System.out.flush();
}
OSDetector.wishWell(FilePathAdd.ImagePath);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,60 @@
package org.cametendo;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.reader.impl.completer.FileNameCompleter;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
public class FilePathAdd {
public static String ImagePath = "";
protected static String filePath() throws IOException {
fileQuestion();
Terminal terminal = TerminalBuilder.terminal();
LineReader reader = LineReaderBuilder.builder().terminal(terminal).completer(new FileNameCompleter()).build();
while (true) {
ImagePath = reader.readLine("Path: ").trim();
if (ImagePath.isBlank()) {
System.out.println("Oops... You didn't specify a file!");
continue;
}
Path path = Path.of(ImagePath);
if (!Files.exists(path) || !Files.isRegularFile(path)) {
System.out.println("Invalid file! Please ensure the path points to an ISO / image file.");
continue;
}
System.out.println("Using File: " + ImagePath);
return ImagePath;
}
}
public static String validateAndGetFile(String ImagePath) {
try {
Path path = Path.of(ImagePath);
if (Files.exists(path) && Files.isRegularFile(path)) {
return path.toRealPath().toString();
} else {
System.out.println("Invalid file! Please ensure the path points to an ISO / image file.");
return null;
}
} catch (IOException e) {
System.out.println("File not found! Invalid Path or no access.");
return null;
}
}
protected static void fileQuestion() {
System.out.println("Please enter the FULL Path of your ISO / Image. (Tab-completion supported)");
}
}

View File

@@ -0,0 +1,23 @@
package org.cametendo;
import java.util.Scanner;
public class Flasher {
public static void flasher(Scanner UserInput) {
String input = "";
System.out.println("The program will use the following configuration, do you want to flash with this? (Y/n)");
System.out.println(" - To be flashed device: " + StorageDeviceLister.fullPath);
System.out.println(" - To be used path: " + FilePathAdd.ImagePath);
System.out.println(" - To be used blocksize: " + BlockSize.blockSizeString);
System.out.println(" - To be used oflag: " + OflagHandler.oflagHandleString);
input = UserInput.nextLine();
if (YesNo.check(input)) {
System.out.println("Starting to flash...");
} else {
System.out.println("Canceling...");
System.exit(0);
}
Dd.dd();
}
}

View File

@@ -0,0 +1,18 @@
package org.cametendo;
import java.util.Scanner;
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

@@ -0,0 +1,34 @@
package org.cametendo;
import java.io.IOException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws InterruptedException, IOException {
Scanner UserInput = new Scanner(System.in);
if (args.length == 4) {
String validatedDevice = StorageDeviceLister.validateAndGetPath(args[0]);
if (validatedDevice == null) {
return;
}
String validatedFile = FilePathAdd.validateAndGetFile(args[1]);
if (validatedFile == null) {
return;
}
StorageDeviceLister.fullPath = validatedDevice;
FilePathAdd.ImagePath = validatedFile;
BlockSize.blockSizeString = BlockSize.mapBlockSize(args[2]);
OflagHandler.oflagHandleString = OflagHandler.mapOflagHandle(args[3]);
} else {
Greeting.greeting(UserInput);
StorageDeviceLister.deviceCheck(UserInput);
FilePathAdd.filePath();
BlockSize.blockSize(UserInput);
OflagHandler.Oflag(UserInput);
}
Flasher.flasher(UserInput);
}
}

View File

@@ -0,0 +1,76 @@
package org.cametendo;
import java.nio.file.Path;
public class OSDetector {
public static void wishWell(String imagePath) {
String fileName = Path.of(imagePath).getFileName().toString().toLowerCase();
String osName;
// Specialized & Advanced Distros
if (fileName.contains("nyarch")) {
osName = "Nyarch Linux (Nyaa~!)";
} else if (fileName.contains("artix")) {
osName = "Artix Linux (Systemd-free Arch!)";
} else if (fileName.contains("gentoo")) {
osName = "Gentoo (Enjoy the compiling...)";
} else if (fileName.contains("nixos")) {
osName = "NixOS (Immutable & Reproducible!)";
} else if (fileName.contains("void")) {
osName = "Void Linux";
} else if (fileName.contains("arch")) {
osName = "Arch Linux (btw)";
} else if (fileName.contains("alpine")) {
osName = "Alpine Linux (Minimalism at its peak)";
} else if (fileName.contains("winux")) {
osName = "Winux (Windows without Windows)";
}
// Mainstream Linux
else if (fileName.contains("fedora")) {
osName = "Fedora (Freehat Linux)";
} else if (fileName.contains("debian")) {
osName = "Debian (Universal OS)";
} else if (fileName.contains("ubuntu")) {
osName = "Ubuntu (Debian but fancy)";
} else if (fileName.contains("mint")) {
osName = "Linux Mint";
} else if (fileName.contains("pop-os") || fileName.contains("pop_os")) {
osName = "Pop!_OS";
}
// The BSD Family
else if (fileName.contains("freebsd")) {
osName = "FreeBSD";
} else if (fileName.contains("openbsd")) {
osName = "OpenBSD (Secure by default)";
} else if (fileName.contains("netbsd")) {
osName = "NetBSD (It runs on everything!)";
}
// Security & Privacy
else if (fileName.contains("kali")) {
osName = "Kali Linux (Happy Hacking)";
} else if (fileName.contains("tails")) {
osName = "Tails (Incognito mode: ON)";
} else if (fileName.contains("qubes")) {
osName = "Qubes OS (Security by Compartmentalization)";
}
// Others & Legacy
else if (fileName.contains("win") && (fileName.contains("10") || fileName.contains("11"))) {
osName = "Windows (Spies... Spies everywhere)";
} else if (fileName.contains("haiku")) {
osName = "Haiku OS";
} else if (fileName.contains("reactos")) {
osName = "ReactOS";
}
// Generic Fallbacks
else if (fileName.contains("linux")) {
osName = "Linux";
} else if (fileName.contains("bsd")) {
osName = "BSD";
} else {
osName = "new OS";
}
System.out.println("\nFlash complete! Have fun with your " + osName + " installation! 🚀");
}
}

View File

@@ -0,0 +1,29 @@
package org.cametendo;
import java.util.Scanner;
public class OflagHandler {
public static String oflagHandleString = "direct";
public static String mapOflagHandle(String input) {
return switch (input) {
case "1", "direct" -> "direct";
case "2", "dsync" -> "dsync";
case "3", "sync" -> "sync";
case "4", "nocache" -> "nocache";
default -> oflagHandleString;
};
}
static String Oflag(Scanner UserInput) {
System.out.println("Choose an Oflag (Default: direct)");
System.out.println("direct (1), dsync (2), sync (3), nocache (4)");
String input = UserInput.nextLine();
oflagHandleString = mapOflagHandle(input);
System.out.println("Using Oflag: " + oflagHandleString);
return oflagHandleString;
}
}

View File

@@ -0,0 +1,62 @@
package org.cametendo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Path;
import java.util.Scanner;
public class StorageDeviceLister {
public static String device = "";
public static String fullPath = "";
protected static String deviceCheck(Scanner UserInput) {
deviceList();
while (true) {
device = UserInput.nextLine();
if (device.isBlank()) {
System.out.println("Oops... Device name is empty. Did you missclick?");
continue;
}
Path path = Path.of("/dev/" + device);
try {
fullPath = path.toRealPath().toString();
System.out.println("Using device: " + fullPath);
return fullPath;
} catch (IOException e) {
System.out.println("Failed to access device! Invalid path or no access. Please try again.");
}
}
}
public static String validateAndGetPath(String deviceName) {
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;
}
}
private static void deviceList() {
try {
ProcessBuilder pb = new ProcessBuilder("lsblk");
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/):");
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,17 @@
package org.cametendo;
public class YesNo {
public static boolean check(String input) {
switch (input) {
case "Y":
return true;
case "y":
return true;
case "":
return true;
case "n":
return false;
default:
return false;
}
}
}

12
uninstall.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
# Uninstall script for cflash
if [[ $EUID -ne 0 ]]; then
echo "Please run as root to uninstall globally."
exit 1
fi
rm -f /usr/local/bin/cflash
rm -rf /usr/local/lib/cflash
echo "cflash uninstalled successfully."