From c86c90748c51c1f4ec3cf90af48d40f09607d768 Mon Sep 17 00:00:00 2001 From: saurav Date: Wed, 12 Nov 2025 07:21:46 +0100 Subject: [PATCH 1/7] Added functionality for creation of MyCMD-GUI.exe --- mvnw | 1 - mvnw.cmd | 1 - pom.xml | 56 ++++++++--------- scripts/build-windows.bat | 129 +++++++++++++++++++++++++++++++++++--- 4 files changed, 148 insertions(+), 39 deletions(-) delete mode 100644 mvnw delete mode 100644 mvnw.cmd diff --git a/mvnw b/mvnw deleted file mode 100644 index 8b13789..0000000 --- a/mvnw +++ /dev/null @@ -1 +0,0 @@ - diff --git a/mvnw.cmd b/mvnw.cmd deleted file mode 100644 index 8b13789..0000000 --- a/mvnw.cmd +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pom.xml b/pom.xml index 4a7bd63..2363e7a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.mycmd MyCMD-GUI 1.0.0 @@ -16,11 +15,10 @@ 17 17 21 - 2.43.0 - + org.openjfx javafx-controls @@ -35,64 +33,62 @@ - + + org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.11.0 ${maven.compiler.source} ${maven.compiler.target} - + org.openjfx javafx-maven-plugin - ${javafx.version} + 0.0.8 com.mycmd.gui.MainApp - + org.apache.maven.plugins - maven-shade-plugin + maven-jar-plugin 3.3.0 - - - package - - shade - - - - - com.mycmd.gui.MainApp - - - - - + + + + true + com.mycmd.gui.MainApp + + + - + com.diffplug.spotless spotless-maven-plugin - ${spotless.version} + 2.43.0 - - + + 2.38.0 + + + + - - validate + spotless-check + verify check diff --git a/scripts/build-windows.bat b/scripts/build-windows.bat index 278cf79..ae13569 100644 --- a/scripts/build-windows.bat +++ b/scripts/build-windows.bat @@ -1,12 +1,127 @@ @echo off -echo 🏗️ Building MyCMD for Windows... +setlocal -REM Clean and package using Maven Wrapper -call mvnw.cmd clean package +echo ::Info:: Building MyCMD for Windows... -REM Move output JARs to /dist folder -if not exist dist mkdir dist -copy target\MyCMD-GUI*.jar dist\MyCMD-GUI.jar +REM --- Get absolute path of this script and move to project root --- +set "SCRIPT_DIR=%~dp0" +cd /d "%SCRIPT_DIR%\.." -echo ✅ Build complete! File located in dist\MyCMD-GUI.jar +REM --- Check if Maven is available --- +where mvn >nul 2>&1 +if errorlevel 1 ( + echo ::Error:: Maven not found in PATH. Please install Maven first. + pause + exit /b 1 +) + +REM --- Run the Maven build --- +echo ::Info:: Building with Maven... +call mvn clean package +if errorlevel 1 ( + echo ::Error:: Maven build failed. + pause + exit /b 1 +) + +REM --- Ensure dist/dependencies directory exists --- +set "DIST_DIR=%SCRIPT_DIR%dist\dependencies" +if not exist "%DIST_DIR%" mkdir "%DIST_DIR%" + +REM --- Copy the generated JAR to output folder --- +copy /y "target\MyCMD-GUI*.jar" "%DIST_DIR%\MyCMD-GUI.jar" >nul +if errorlevel 1 ( + echo ::Error:: Copy failed. Check if target JAR exists. + dir /b target\*.jar + pause + exit /b 1 +) + +REM --- Ensure dist/icon directory exists --- +set "ICO_DIR=%SCRIPT_DIR%dist\icon" +if not exist "%ICO_DIR%" mkdir "%ICO_DIR%" + +REM --- Copy the ico file to output folder --- +copy /y "icons\mycmd.ico" "%ICO_DIR%" >nul +if errorlevel 1 ( + echo ::Error:: Copy failed. Check if target ico file exists. + echo Available icons: + dir /b icons\*.ico + pause + exit /b 1 +) + +REM --- Ensure bin output directory exists --- +set "BIN_DIR=%SCRIPT_DIR%dist\bin" +if not exist "%BIN_DIR%" mkdir "%BIN_DIR%" + +REM ================================================================== +REM === Launch4j silent EXE creation section ========================= +REM ================================================================== + +echo ::Info:: Creating Windows EXE using Launch4j... + +REM --- Launch4j exe path (modify if installed elsewhere) --- +set "LAUNCH4J_EXE=C:\Program Files (x86)\Launch4j\launch4j.exe" + +REM --- Paths for config and output --- +set "CONFIG_FILE=%DIST_DIR%\launch4jConfig.xml" +set "JAR_FILE=%DIST_DIR%\MyCMD-GUI.jar" +set "ICO_FILE=%ICO_DIR%\mycmd.ico" +set "EXE_FILE=%BIN_DIR%\MyCMD-GUI.exe" + +REM --- Verify Launch4j executable exists --- +if not exist "%LAUNCH4J_EXE%" ( + echo ::Error:: Launch4j executable not found at "%LAUNCH4J_EXE%". + echo Please install Launch4j or update LAUNCH4J_EXE path in this script. + pause + exit /b 1 +) + +REM --- Regenerate Launch4j config XML dynamically --- +( + echo ^ + echo ^ + echo ^false^ + echo ^gui^ + echo ^%JAR_FILE%^ + echo ^%EXE_FILE%^ + echo ^MyCMD-GUI Error^ + echo ^^ + echo ^.^ + echo ^normal^ + echo ^^ + echo ^^ + echo ^false^ + echo ^false^ + echo ^^ + echo ^%ICO_FILE%^ + echo ^ + echo ^%%JAVA_HOME%%;%%PATH%%^ + echo ^false^ + echo ^false^ + echo ^^ + echo ^^ + echo ^ + echo ^ +) > "%CONFIG_FILE%" + +REM --- Run Launch4j executable silently --- +"%LAUNCH4J_EXE%" "%CONFIG_FILE%" >nul 2>&1 +if errorlevel 1 ( + echo ::Error:: Launch4j build failed! + echo If Launch4j prints no console output, run the command manually to see details: + echo "%LAUNCH4J_EXE%" "%CONFIG_FILE%" + pause + exit /b %errorlevel% +) + +echo. +echo ::Success:: Build complete! +echo ::Info:: Files located at: +echo - JAR: scripts\dist\dependencies\MyCMD-GUI.jar +echo - ICO: scripts\dist\icon\mycmd.ico +echo - EXE: scripts\dist\bin\MyCMD-GUI.exe +echo. pause +endlocal From 95a5cbd6d0c47a60d8b6995d3bdfed95d89c2396 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 12 Nov 2025 06:22:40 +0000 Subject: [PATCH 2/7] Apply Spotless formatting --- src/main/java/com/mycmd/App.java | 22 +- src/main/java/com/mycmd/Command.java | 6 +- src/main/java/com/mycmd/CommandRegistry.java | 20 +- src/main/java/com/mycmd/ConsoleShell.java | 28 +- src/main/java/com/mycmd/ShellContext.java | 314 ++++----- src/main/java/com/mycmd/ShellEngine.java | 42 +- src/main/java/com/mycmd/StringUtils.java | 20 +- .../java/com/mycmd/commands/AliasCommand.java | 108 +-- .../java/com/mycmd/commands/ArpCommand.java | 81 ++- .../java/com/mycmd/commands/AssocCommand.java | 150 ++--- .../com/mycmd/commands/AttribCommand.java | 113 ++-- .../java/com/mycmd/commands/CdCommand.java | 74 +- .../com/mycmd/commands/ChkdskCommand.java | 95 ++- .../com/mycmd/commands/ChoiceCommand.java | 96 +-- .../mycmd/commands/ClearHistoryCommand.java | 26 +- .../java/com/mycmd/commands/ClipCommand.java | 49 +- .../java/com/mycmd/commands/ClsCommand.java | 46 +- .../java/com/mycmd/commands/ColorCommand.java | 104 ++- .../com/mycmd/commands/CompactCommand.java | 92 +-- .../java/com/mycmd/commands/CopyCommand.java | 62 +- .../java/com/mycmd/commands/DateCommand.java | 36 +- .../java/com/mycmd/commands/DelCommand.java | 48 +- .../java/com/mycmd/commands/DirCommand.java | 36 +- .../mycmd/commands/DriverqueryCommand.java | 140 ++-- .../java/com/mycmd/commands/EchoCommand.java | 30 +- .../java/com/mycmd/commands/ExitCommand.java | 26 +- .../java/com/mycmd/commands/FcCommand.java | 253 ++++--- .../java/com/mycmd/commands/FindCommand.java | 196 +++--- .../com/mycmd/commands/FindstrCommand.java | 201 +++--- .../com/mycmd/commands/ForfilesCommand.java | 107 ++- .../com/mycmd/commands/FsutilCommand.java | 89 ++- .../java/com/mycmd/commands/FtypeCommand.java | 70 +- .../com/mycmd/commands/GetmacCommand.java | 92 +-- .../java/com/mycmd/commands/HelpCommand.java | 87 ++- .../com/mycmd/commands/HistoryCommand.java | 40 +- .../com/mycmd/commands/HostnameCommand.java | 38 +- .../commands/InteractiveSearchCommand.java | 197 +++--- .../java/com/mycmd/commands/IpConfig.java | 50 +- .../java/com/mycmd/commands/LabelCommand.java | 46 +- .../java/com/mycmd/commands/LsCommand.java | 38 +- .../java/com/mycmd/commands/MkdirCommand.java | 44 +- .../java/com/mycmd/commands/MoreCommand.java | 92 +-- .../java/com/mycmd/commands/MoveCommand.java | 54 +- .../java/com/mycmd/commands/MsgCommand.java | 118 ++-- .../java/com/mycmd/commands/NetCommand.java | 112 +-- .../java/com/mycmd/commands/NetshCommand.java | 93 ++- .../com/mycmd/commands/NetstatCommand.java | 76 +-- .../com/mycmd/commands/NslookupCommand.java | 83 ++- .../java/com/mycmd/commands/PathCommand.java | 75 +-- .../java/com/mycmd/commands/PauseCommand.java | 52 +- .../java/com/mycmd/commands/PingCommand.java | 635 +++++++++--------- .../java/com/mycmd/commands/PwdCommand.java | 24 +- .../java/com/mycmd/commands/RemCommand.java | 26 +- .../com/mycmd/commands/RenameCommand.java | 54 +- .../com/mycmd/commands/ReplaceCommand.java | 62 +- .../java/com/mycmd/commands/RmdirCommand.java | 48 +- .../com/mycmd/commands/RobocopyCommand.java | 99 ++- .../java/com/mycmd/commands/RouteCommand.java | 108 ++- .../mycmd/commands/SearchHistoryCommand.java | 171 ++--- .../java/com/mycmd/commands/SetCommand.java | 64 +- .../java/com/mycmd/commands/SfcCommand.java | 93 ++- .../com/mycmd/commands/ShutdownCommand.java | 183 +++-- .../java/com/mycmd/commands/SortCommand.java | 128 ++-- .../java/com/mycmd/commands/StartCommand.java | 96 +-- .../com/mycmd/commands/SysteminfoCommand.java | 103 ++- .../com/mycmd/commands/TaskkillCommand.java | 96 ++- .../com/mycmd/commands/TasklistCommand.java | 97 ++- .../com/mycmd/commands/TelnetCommand.java | 141 ++-- .../java/com/mycmd/commands/TimeCommand.java | 42 +- .../com/mycmd/commands/TimeoutCommand.java | 307 ++++----- .../java/com/mycmd/commands/TitleCommand.java | 32 +- .../java/com/mycmd/commands/TouchCommand.java | 44 +- .../com/mycmd/commands/TracertCommand.java | 92 +-- .../java/com/mycmd/commands/TreeCommand.java | 60 +- .../java/com/mycmd/commands/TypeCommand.java | 54 +- .../com/mycmd/commands/UnaliasCommand.java | 46 +- .../com/mycmd/commands/UptimeCommand.java | 48 +- .../com/mycmd/commands/VerifyCommand.java | 54 +- .../com/mycmd/commands/VersionCommand.java | 24 +- .../java/com/mycmd/commands/VolCommand.java | 81 ++- .../com/mycmd/commands/WhoamiCommand.java | 24 +- .../java/com/mycmd/commands/WmicCommand.java | 91 ++- .../java/com/mycmd/commands/XcopyCommand.java | 102 ++- src/main/java/com/mycmd/gui/MainApp.java | 77 +-- .../com/mycmd/gui/TerminalController.java | 58 +- 85 files changed, 3782 insertions(+), 3849 deletions(-) diff --git a/src/main/java/com/mycmd/App.java b/src/main/java/com/mycmd/App.java index 5ed7a41..780d2e6 100644 --- a/src/main/java/com/mycmd/App.java +++ b/src/main/java/com/mycmd/App.java @@ -5,16 +5,16 @@ /** Entry point for MyCMD-GUI. */ public class App { - public static void main(String[] args) { - // Security check to prevent CMD access - String launchedFrom = System.getenv("MYCMD_LAUNCHED"); - if (launchedFrom == null || !launchedFrom.equalsIgnoreCase("true")) { - System.out.println("❌ MyCMD-GUI cannot be run directly from CMD."); - System.out.println("➡️ Please use the official launcher (MyCMD.bat)."); - return; - } + public static void main(String[] args) { + // Security check to prevent CMD access + String launchedFrom = System.getenv("MYCMD_LAUNCHED"); + if (launchedFrom == null || !launchedFrom.equalsIgnoreCase("true")) { + System.out.println("❌ MyCMD-GUI cannot be run directly from CMD."); + System.out.println("➡️ Please use the official launcher (MyCMD.bat)."); + return; + } - // Launch JavaFX GUI - Application.launch(MainApp.class, args); - } + // Launch JavaFX GUI + Application.launch(MainApp.class, args); + } } diff --git a/src/main/java/com/mycmd/Command.java b/src/main/java/com/mycmd/Command.java index a971823..0add84c 100644 --- a/src/main/java/com/mycmd/Command.java +++ b/src/main/java/com/mycmd/Command.java @@ -4,9 +4,9 @@ /** Interfaace for all commands. Every command impleements this */ public interface Command { - void execute(String[] args, ShellContext context) throws IOException; + void execute(String[] args, ShellContext context) throws IOException; - String description(); + String description(); - String usage(); + String usage(); } diff --git a/src/main/java/com/mycmd/CommandRegistry.java b/src/main/java/com/mycmd/CommandRegistry.java index caa211b..8c73f47 100644 --- a/src/main/java/com/mycmd/CommandRegistry.java +++ b/src/main/java/com/mycmd/CommandRegistry.java @@ -5,17 +5,17 @@ /** Registers and retrieves commands by name. */ public class CommandRegistry { - private final Map commands = new HashMap<>(); + private final Map commands = new HashMap<>(); - public void register(String name, Command cmd) { - commands.put(name.toLowerCase(), cmd); - } + public void register(String name, Command cmd) { + commands.put(name.toLowerCase(), cmd); + } - public Command get(String name) { - return commands.get(name.toLowerCase()); - } + public Command get(String name) { + return commands.get(name.toLowerCase()); + } - public Map getAll() { - return commands; - } + public Map getAll() { + return commands; + } } diff --git a/src/main/java/com/mycmd/ConsoleShell.java b/src/main/java/com/mycmd/ConsoleShell.java index 3d32b3c..47fc3b9 100644 --- a/src/main/java/com/mycmd/ConsoleShell.java +++ b/src/main/java/com/mycmd/ConsoleShell.java @@ -5,21 +5,21 @@ /** Developer console mode for debugging. */ public class ConsoleShell { - public static void main(String[] args) { - CommandRegistry registry = new CommandRegistry(); - ShellContext context = new ShellContext(); - ShellEngine engine = new ShellEngine(registry, context); + public static void main(String[] args) { + CommandRegistry registry = new CommandRegistry(); + ShellContext context = new ShellContext(); + ShellEngine engine = new ShellEngine(registry, context); - Scanner sc = new Scanner(System.in); - System.out.println("MyCMD Developer Console Mode\n(Type 'exit' to quit)"); + Scanner sc = new Scanner(System.in); + System.out.println("MyCMD Developer Console Mode\n(Type 'exit' to quit)"); - while (true) { - System.out.print("> "); - String input = sc.nextLine(); - if (input.equalsIgnoreCase("exit")) break; - engine.execute(input); - } + while (true) { + System.out.print("> "); + String input = sc.nextLine(); + if (input.equalsIgnoreCase("exit")) break; + engine.execute(input); + } - sc.close(); - } + sc.close(); + } } diff --git a/src/main/java/com/mycmd/ShellContext.java b/src/main/java/com/mycmd/ShellContext.java index 75fb541..9a6764f 100644 --- a/src/main/java/com/mycmd/ShellContext.java +++ b/src/main/java/com/mycmd/ShellContext.java @@ -9,161 +9,161 @@ * command history, aliases, and shared Scanner. */ public class ShellContext { - private File currentDir; - private final Map environment; - private final List history; - private final Map aliases; - private Scanner scanner; - private Instant startTime; - - public ShellContext() { - this.currentDir = new File(System.getProperty("user.dir")); - this.environment = new HashMap<>(System.getenv()); - this.history = new ArrayList<>(); - this.aliases = new HashMap<>(); - this.scanner = null; - this.startTime = Instant.now(); - } - - // ==================== Scanner Management ==================== - - /** - * Set the shared Scanner instance for all commands to use. Should only be called once by App.java - * during initialization. - */ - public void setScanner(Scanner scanner) { - this.scanner = scanner; - } - - /** - * Get the shared Scanner instance. All commands should use this instead of creating their own - * Scanner. - * - * @return the shared Scanner instance - * @throws IllegalStateException if Scanner hasn't been initialized - */ - public Scanner getScanner() { - if (scanner == null) { - throw new IllegalStateException("Scanner not initialized in ShellContext"); - } - return scanner; - } - - // ==================== Directory Management ==================== - - public File getCurrentDir() { - return currentDir; - } - - public void setCurrentDir(File dir) { - if (dir == null || !dir.exists()) { - throw new IllegalArgumentException("Directory does not exist: " + dir); - } - if (!dir.isDirectory()) { - throw new IllegalArgumentException("Not a directory: " + dir); - } - this.currentDir = dir; - } - - /** - * Resolve a path relative to the current directory. If the path is absolute, return it as-is. If - * relative, resolve it against the current directory. - */ - public File resolvePath(String path) { - File file = new File(path); - if (file.isAbsolute()) { - return file; - } - return new File(currentDir, path); - } - - // ==================== Environment Variables ==================== - - public String getEnvVar(String key) { - return environment.get(key); - } - - public void setEnvVar(String key, String value) { - environment.put(key, value); - } - - public Map getAllEnvVars() { - return new HashMap<>(environment); - } - - /** Legacy method name support for compatibility. */ - public Map getEnvVars() { - return getAllEnvVars(); - } - - // ==================== Command History ==================== - - public void addToHistory(String command) { - history.add(command); - } - - public List getHistory() { - return new ArrayList<>(history); - } - - /** Legacy method name support for compatibility. */ - public List getCommandHistory() { - return getHistory(); - } - - public void clearHistory() { - history.clear(); - } - - // ==================== Aliases ==================== - - /** Get all aliases (for compatibility with existing code). */ - public Map getAliases() { - return new HashMap<>(aliases); - } - - /** Add an alias (for compatibility with existing code). */ - public void addAlias(String name, String command) { - aliases.put(name, command); - } - - /** Resolve an alias (for compatibility with existing code). */ - public String resolveAlias(String cmd) { - return aliases.getOrDefault(cmd, cmd); - } - - /** Set an alias. */ - public void setAlias(String alias, String command) { - aliases.put(alias, command); - } - - /** Get alias command. */ - public String getAlias(String alias) { - return aliases.get(alias); - } - - /** Check if alias exists. */ - public boolean hasAlias(String alias) { - return aliases.containsKey(alias); - } - - /** Remove an alias. */ - public void removeAlias(String alias) { - aliases.remove(alias); - } - - /** Get all aliases. */ - public Map getAllAliases() { - return new HashMap<>(aliases); - } - - // ==================== Start Time (for uptime command) ==================== - - public Instant getStartTime() { - return startTime; - } - - public void setStartTime(Instant startTime) { - this.startTime = startTime; - } + private File currentDir; + private final Map environment; + private final List history; + private final Map aliases; + private Scanner scanner; + private Instant startTime; + + public ShellContext() { + this.currentDir = new File(System.getProperty("user.dir")); + this.environment = new HashMap<>(System.getenv()); + this.history = new ArrayList<>(); + this.aliases = new HashMap<>(); + this.scanner = null; + this.startTime = Instant.now(); + } + + // ==================== Scanner Management ==================== + + /** + * Set the shared Scanner instance for all commands to use. Should only be called once by App.java + * during initialization. + */ + public void setScanner(Scanner scanner) { + this.scanner = scanner; + } + + /** + * Get the shared Scanner instance. All commands should use this instead of creating their own + * Scanner. + * + * @return the shared Scanner instance + * @throws IllegalStateException if Scanner hasn't been initialized + */ + public Scanner getScanner() { + if (scanner == null) { + throw new IllegalStateException("Scanner not initialized in ShellContext"); + } + return scanner; + } + + // ==================== Directory Management ==================== + + public File getCurrentDir() { + return currentDir; + } + + public void setCurrentDir(File dir) { + if (dir == null || !dir.exists()) { + throw new IllegalArgumentException("Directory does not exist: " + dir); + } + if (!dir.isDirectory()) { + throw new IllegalArgumentException("Not a directory: " + dir); + } + this.currentDir = dir; + } + + /** + * Resolve a path relative to the current directory. If the path is absolute, return it as-is. If + * relative, resolve it against the current directory. + */ + public File resolvePath(String path) { + File file = new File(path); + if (file.isAbsolute()) { + return file; + } + return new File(currentDir, path); + } + + // ==================== Environment Variables ==================== + + public String getEnvVar(String key) { + return environment.get(key); + } + + public void setEnvVar(String key, String value) { + environment.put(key, value); + } + + public Map getAllEnvVars() { + return new HashMap<>(environment); + } + + /** Legacy method name support for compatibility. */ + public Map getEnvVars() { + return getAllEnvVars(); + } + + // ==================== Command History ==================== + + public void addToHistory(String command) { + history.add(command); + } + + public List getHistory() { + return new ArrayList<>(history); + } + + /** Legacy method name support for compatibility. */ + public List getCommandHistory() { + return getHistory(); + } + + public void clearHistory() { + history.clear(); + } + + // ==================== Aliases ==================== + + /** Get all aliases (for compatibility with existing code). */ + public Map getAliases() { + return new HashMap<>(aliases); + } + + /** Add an alias (for compatibility with existing code). */ + public void addAlias(String name, String command) { + aliases.put(name, command); + } + + /** Resolve an alias (for compatibility with existing code). */ + public String resolveAlias(String cmd) { + return aliases.getOrDefault(cmd, cmd); + } + + /** Set an alias. */ + public void setAlias(String alias, String command) { + aliases.put(alias, command); + } + + /** Get alias command. */ + public String getAlias(String alias) { + return aliases.get(alias); + } + + /** Check if alias exists. */ + public boolean hasAlias(String alias) { + return aliases.containsKey(alias); + } + + /** Remove an alias. */ + public void removeAlias(String alias) { + aliases.remove(alias); + } + + /** Get all aliases. */ + public Map getAllAliases() { + return new HashMap<>(aliases); + } + + // ==================== Start Time (for uptime command) ==================== + + public Instant getStartTime() { + return startTime; + } + + public void setStartTime(Instant startTime) { + this.startTime = startTime; + } } diff --git a/src/main/java/com/mycmd/ShellEngine.java b/src/main/java/com/mycmd/ShellEngine.java index acb8e7e..8730b8d 100644 --- a/src/main/java/com/mycmd/ShellEngine.java +++ b/src/main/java/com/mycmd/ShellEngine.java @@ -6,31 +6,31 @@ /** Central execution engine. */ public class ShellEngine { - private final CommandRegistry registry; - private final ShellContext context; + private final CommandRegistry registry; + private final ShellContext context; - public ShellEngine(CommandRegistry registry, ShellContext context) { - this.registry = registry; - this.context = context; - } + public ShellEngine(CommandRegistry registry, ShellContext context) { + this.registry = registry; + this.context = context; + } - public void execute(String input) { - if (input == null || input.trim().isEmpty()) return; + public void execute(String input) { + if (input == null || input.trim().isEmpty()) return; - String[] parts = input.trim().split("\\s+"); - String cmdName = context.resolveAlias(parts[0]); - String[] args = Arrays.copyOfRange(parts, 1, parts.length); + String[] parts = input.trim().split("\\s+"); + String cmdName = context.resolveAlias(parts[0]); + String[] args = Arrays.copyOfRange(parts, 1, parts.length); - Command cmd = registry.get(cmdName); - if (cmd == null) { - System.out.println("❌ Unknown command: " + cmdName); - return; - } + Command cmd = registry.get(cmdName); + if (cmd == null) { + System.out.println("❌ Unknown command: " + cmdName); + return; + } - try { - cmd.execute(args, context); - } catch (IOException e) { - System.out.println("⚠️ Error executing command: " + e.getMessage()); + try { + cmd.execute(args, context); + } catch (IOException e) { + System.out.println("⚠️ Error executing command: " + e.getMessage()); + } } - } } diff --git a/src/main/java/com/mycmd/StringUtils.java b/src/main/java/com/mycmd/StringUtils.java index fa5aa70..ecb2887 100644 --- a/src/main/java/com/mycmd/StringUtils.java +++ b/src/main/java/com/mycmd/StringUtils.java @@ -2,16 +2,16 @@ /** String helper functions for commands. */ public class StringUtils { - public static boolean isEmpty(String s) { - return s == null || s.trim().isEmpty(); - } + public static boolean isEmpty(String s) { + return s == null || s.trim().isEmpty(); + } - public static String join(String[] arr, int start) { - StringBuilder sb = new StringBuilder(); - for (int i = start; i < arr.length; i++) { - if (i > start) sb.append(' '); - sb.append(arr[i]); + public static String join(String[] arr, int start) { + StringBuilder sb = new StringBuilder(); + for (int i = start; i < arr.length; i++) { + if (i > start) sb.append(' '); + sb.append(arr[i]); + } + return sb.toString(); } - return sb.toString(); - } } diff --git a/src/main/java/com/mycmd/commands/AliasCommand.java b/src/main/java/com/mycmd/commands/AliasCommand.java index 46fe226..c9bf37d 100644 --- a/src/main/java/com/mycmd/commands/AliasCommand.java +++ b/src/main/java/com/mycmd/commands/AliasCommand.java @@ -6,63 +6,63 @@ import java.util.Map; public class AliasCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - // no args: list aliases - if (args == null || args.length == 0) { - Map aliases = context.getAliases(); - if (aliases.isEmpty()) { - System.out.println("No aliases defined."); - } else { - aliases.forEach((k, v) -> System.out.println(k + "=" + v)); - } - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + // no args: list aliases + if (args == null || args.length == 0) { + Map aliases = context.getAliases(); + if (aliases.isEmpty()) { + System.out.println("No aliases defined."); + } else { + aliases.forEach((k, v) -> System.out.println(k + "=" + v)); + } + return; + } - // single arg of form name=command - if (args.length == 1 && args[0].contains("=")) { - String[] parts = args[0].split("=", 2); - String name = parts[0].trim(); - String cmd = parts[1].trim(); - if (name.isEmpty() || cmd.isEmpty()) { - System.out.println("Invalid alias format. Usage: \n" + usage()); - return; - } - context.addAlias(name, cmd); - System.out.println("Alias added: " + name + "=" + cmd); - return; - } + // single arg of form name=command + if (args.length == 1 && args[0].contains("=")) { + String[] parts = args[0].split("=", 2); + String name = parts[0].trim(); + String cmd = parts[1].trim(); + if (name.isEmpty() || cmd.isEmpty()) { + System.out.println("Invalid alias format. Usage: \n" + usage()); + return; + } + context.addAlias(name, cmd); + System.out.println("Alias added: " + name + "=" + cmd); + return; + } - // multiple args: first is name, rest form command - if (args.length >= 2) { - String name = args[0]; - StringBuilder sb = new StringBuilder(); - for (int i = 1; i < args.length; i++) { - if (i > 1) sb.append(' '); - sb.append(args[i]); - } - String cmd = sb.toString(); - if (name.trim().isEmpty() || cmd.trim().isEmpty()) { - System.out.println("Invalid alias. Usage: \n" + usage()); - return; - } - context.addAlias(name, cmd); - System.out.println("Alias added: " + name + "=" + cmd); - return; - } + // multiple args: first is name, rest form command + if (args.length >= 2) { + String name = args[0]; + StringBuilder sb = new StringBuilder(); + for (int i = 1; i < args.length; i++) { + if (i > 1) sb.append(' '); + sb.append(args[i]); + } + String cmd = sb.toString(); + if (name.trim().isEmpty() || cmd.trim().isEmpty()) { + System.out.println("Invalid alias. Usage: \n" + usage()); + return; + } + context.addAlias(name, cmd); + System.out.println("Alias added: " + name + "=" + cmd); + return; + } - System.out.println("Invalid usage. Usage: " + usage()); - } + System.out.println("Invalid usage. Usage: " + usage()); + } - @Override - public String description() { - return "Create or list command aliases."; - } + @Override + public String description() { + return "Create or list command aliases."; + } - @Override - public String usage() { - return "alias # list aliases\n" - + "alias name=command # create alias\n" - + "alias name command... # create alias"; - } + @Override + public String usage() { + return "alias # list aliases\n" + + "alias name=command # create alias\n" + + "alias name command... # create alias"; + } } diff --git a/src/main/java/com/mycmd/commands/ArpCommand.java b/src/main/java/com/mycmd/commands/ArpCommand.java index 29e0bd7..e725f86 100644 --- a/src/main/java/com/mycmd/commands/ArpCommand.java +++ b/src/main/java/com/mycmd/commands/ArpCommand.java @@ -13,56 +13,55 @@ */ public class ArpCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - try { - StringBuilder cmdBuilder = new StringBuilder("arp"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + try { + StringBuilder cmdBuilder = new StringBuilder("arp"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - // Default to -a if no args provided - if (args.length == 0) { - cmdBuilder.append(" -a"); - } + // Default to -a if no args provided + if (args.length == 0) { + cmdBuilder.append(" -a"); + } - ProcessBuilder pb = new ProcessBuilder(); - String os = System.getProperty("os.name").toLowerCase(); + ProcessBuilder pb = new ProcessBuilder(); + String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - pb.command("cmd.exe", "/c", cmdBuilder.toString()); - } else { - pb.command("sh", "-c", cmdBuilder.toString()); - } + if (os.contains("win")) { + pb.command("cmd.exe", "/c", cmdBuilder.toString()); + } else { + pb.command("sh", "-c", cmdBuilder.toString()); + } - Process process = pb.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + Process process = pb.start(); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing arp: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error executing arp: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Displays and modifies the IP-to-Physical address translation tables."; - } + @Override + public String description() { + return "Displays and modifies the IP-to-Physical address translation tables."; + } - @Override - public String usage() { - return "arp [-a] [-d ip_addr] [-s ip_addr eth_addr]"; - } + @Override + public String usage() { + return "arp [-a] [-d ip_addr] [-s ip_addr eth_addr]"; + } } diff --git a/src/main/java/com/mycmd/commands/AssocCommand.java b/src/main/java/com/mycmd/commands/AssocCommand.java index 331978f..7a5d288 100644 --- a/src/main/java/com/mycmd/commands/AssocCommand.java +++ b/src/main/java/com/mycmd/commands/AssocCommand.java @@ -17,87 +17,85 @@ */ public class AssocCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - String os = System.getProperty("os.name").toLowerCase(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + String os = System.getProperty("os.name").toLowerCase(); - if (!os.contains("win")) { - System.out.println("ASSOC is only available on Windows systems."); - return; - } + if (!os.contains("win")) { + System.out.println("ASSOC is only available on Windows systems."); + return; + } - try { - - List command = new ArrayList<>(); - command.add("cmd.exe"); - command.add("/c"); - command.add("assoc"); - if (args != null && args.length > 0) { - command.addAll(Arrays.asList(args)); - } - - ProcessBuilder pb = new ProcessBuilder(command); - Process process = pb.start(); - - Thread errorGobbler = - new Thread( - () -> { - try (BufferedReader errReader = - new BufferedReader(new InputStreamReader(process.getErrorStream()))) { - String errLine; - while ((errLine = errReader.readLine()) != null) { - System.err.println(errLine); - } - } catch (IOException e) { - - System.err.println("Error reading process error stream: " + e.getMessage()); + try { + + List command = new ArrayList<>(); + command.add("cmd.exe"); + command.add("/c"); + command.add("assoc"); + if (args != null && args.length > 0) { + command.addAll(Arrays.asList(args)); + } + + ProcessBuilder pb = new ProcessBuilder(command); + Process process = pb.start(); + + Thread errorGobbler = new Thread( + () -> { + try (BufferedReader errReader = + new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + String errLine; + while ((errLine = errReader.readLine()) != null) { + System.err.println(errLine); + } + } catch (IOException e) { + + System.err.println("Error reading process error stream: " + e.getMessage()); + } + }, + "assoc-error-gobbler"); + errorGobbler.setDaemon(true); + errorGobbler.start(); + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); } - }, - "assoc-error-gobbler"); - errorGobbler.setDaemon(true); - errorGobbler.start(); - - try (BufferedReader reader = - new BufferedReader(new InputStreamReader(process.getInputStream()))) { - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); + } + + boolean finished; + try { + finished = process.waitFor(30, TimeUnit.SECONDS); + } catch (InterruptedException ie) { + + Thread.currentThread().interrupt(); + process.destroyForcibly(); + throw new IOException("Interrupted while waiting for assoc process", ie); + } + + if (!finished) { + process.destroyForcibly(); + System.out.println("Command timed out."); + } + + try { + errorGobbler.join(1000); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + + } catch (Exception e) { + System.out.println("Error executing assoc: " + e.getMessage()); } - } - - boolean finished; - try { - finished = process.waitFor(30, TimeUnit.SECONDS); - } catch (InterruptedException ie) { - - Thread.currentThread().interrupt(); - process.destroyForcibly(); - throw new IOException("Interrupted while waiting for assoc process", ie); - } - - if (!finished) { - process.destroyForcibly(); - System.out.println("Command timed out."); - } - - try { - errorGobbler.join(1000); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } - - } catch (Exception e) { - System.out.println("Error executing assoc: " + e.getMessage()); } - } - @Override - public String description() { - return "Displays or modifies file extension associations."; - } + @Override + public String description() { + return "Displays or modifies file extension associations."; + } - @Override - public String usage() { - return "assoc [.ext[=[fileType]]]"; - } + @Override + public String usage() { + return "assoc [.ext[=[fileType]]]"; + } } diff --git a/src/main/java/com/mycmd/commands/AttribCommand.java b/src/main/java/com/mycmd/commands/AttribCommand.java index abb9d9d..f701664 100644 --- a/src/main/java/com/mycmd/commands/AttribCommand.java +++ b/src/main/java/com/mycmd/commands/AttribCommand.java @@ -14,72 +14,71 @@ */ public class AttribCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("Displays or changes file attributes."); - System.out.println( - "\nATTRIB [+R | -R] [+A | -A] [+S | -S] [+H | -H] [[drive:][path]filename] [/S [/D]]"); - System.out.println("\n + Sets an attribute"); - System.out.println(" - Clears an attribute"); - System.out.println(" R Read-only file attribute"); - System.out.println(" A Archive file attribute"); - System.out.println(" S System file attribute"); - System.out.println(" H Hidden file attribute"); - System.out.println(" /S Processes matching files in the current folder and all subfolders"); - System.out.println(" /D Processes folders as well"); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("Displays or changes file attributes."); + System.out.println("\nATTRIB [+R | -R] [+A | -A] [+S | -S] [+H | -H] [[drive:][path]filename] [/S [/D]]"); + System.out.println("\n + Sets an attribute"); + System.out.println(" - Clears an attribute"); + System.out.println(" R Read-only file attribute"); + System.out.println(" A Archive file attribute"); + System.out.println(" S System file attribute"); + System.out.println(" H Hidden file attribute"); + System.out.println(" /S Processes matching files in the current folder and all subfolders"); + System.out.println(" /D Processes folders as well"); + return; + } - String os = System.getProperty("os.name").toLowerCase(); + String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - try { - StringBuilder cmdBuilder = new StringBuilder("attrib"); - for (String arg : args) { - cmdBuilder.append(" \"").append(arg).append("\""); - } + if (os.contains("win")) { + try { + StringBuilder cmdBuilder = new StringBuilder("attrib"); + for (String arg : args) { + cmdBuilder.append(" \"").append(arg).append("\""); + } - ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); - pb.directory(context.getCurrentDir()); - Process process = pb.start(); + ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); + pb.directory(context.getCurrentDir()); + Process process = pb.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing attrib: " + e.getMessage()); - } - } else { - // Unix-like system - use ls -l to show permissions - if (args.length > 0) { - File file = new File(args[args.length - 1]); - if (!file.isAbsolute()) { - file = new File(context.getCurrentDir(), args[args.length - 1]); - } + } catch (Exception e) { + System.out.println("Error executing attrib: " + e.getMessage()); + } + } else { + // Unix-like system - use ls -l to show permissions + if (args.length > 0) { + File file = new File(args[args.length - 1]); + if (!file.isAbsolute()) { + file = new File(context.getCurrentDir(), args[args.length - 1]); + } - System.out.println("File: " + file.getName()); - System.out.println("Readable: " + file.canRead()); - System.out.println("Writable: " + file.canWrite()); - System.out.println("Executable: " + file.canExecute()); - System.out.println("Hidden: " + file.isHidden()); - } + System.out.println("File: " + file.getName()); + System.out.println("Readable: " + file.canRead()); + System.out.println("Writable: " + file.canWrite()); + System.out.println("Executable: " + file.canExecute()); + System.out.println("Hidden: " + file.isHidden()); + } + } } - } - @Override - public String description() { - return "Displays or changes file attributes."; - } + @Override + public String description() { + return "Displays or changes file attributes."; + } - @Override - public String usage() { - return "attrib [+R | -R] [+A | -A] [+S | -S] [+H | -H] filename"; - } + @Override + public String usage() { + return "attrib [+R | -R] [+A | -A] [+S | -S] [+H | -H] filename"; + } } diff --git a/src/main/java/com/mycmd/commands/CdCommand.java b/src/main/java/com/mycmd/commands/CdCommand.java index 2b8ccd1..0c81563 100644 --- a/src/main/java/com/mycmd/commands/CdCommand.java +++ b/src/main/java/com/mycmd/commands/CdCommand.java @@ -18,47 +18,47 @@ * current working directory stored in ShellContext. */ public class CdCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - // If no argument, print current directory - if (args.length == 0) { - System.out.println(context.getCurrentDir().getAbsolutePath()); - return; - } + @Override + public void execute(String[] args, ShellContext context) { + // If no argument, print current directory + if (args.length == 0) { + System.out.println(context.getCurrentDir().getAbsolutePath()); + return; + } - String dir = args[0]; - File newDir; + String dir = args[0]; + File newDir; - // Handle "cd .." (go to parent directory) - if (dir.equals("..")) { - File parent = context.getCurrentDir().getParentFile(); - if (parent == null) { - System.out.println("Already at the root directory."); - return; - } - newDir = parent; - } else { - newDir = new File(dir); - if (!newDir.isAbsolute()) { - newDir = new File(context.getCurrentDir(), dir); - } - } + // Handle "cd .." (go to parent directory) + if (dir.equals("..")) { + File parent = context.getCurrentDir().getParentFile(); + if (parent == null) { + System.out.println("Already at the root directory."); + return; + } + newDir = parent; + } else { + newDir = new File(dir); + if (!newDir.isAbsolute()) { + newDir = new File(context.getCurrentDir(), dir); + } + } - // Change directory if valid - if (newDir.exists() && newDir.isDirectory()) { - context.setCurrentDir(newDir); - } else { - System.out.println("The system cannot find the path specified."); + // Change directory if valid + if (newDir.exists() && newDir.isDirectory()) { + context.setCurrentDir(newDir); + } else { + System.out.println("The system cannot find the path specified."); + } } - } - @Override - public String description() { - return "Change the current working directory or display it."; - } + @Override + public String description() { + return "Change the current working directory or display it."; + } - @Override - public String usage() { - return "cd [path]"; - } + @Override + public String usage() { + return "cd [path]"; + } } diff --git a/src/main/java/com/mycmd/commands/ChkdskCommand.java b/src/main/java/com/mycmd/commands/ChkdskCommand.java index 6ea6c9d..0cb9714 100644 --- a/src/main/java/com/mycmd/commands/ChkdskCommand.java +++ b/src/main/java/com/mycmd/commands/ChkdskCommand.java @@ -13,63 +13,62 @@ */ public class ChkdskCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - String os = System.getProperty("os.name").toLowerCase(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + String os = System.getProperty("os.name").toLowerCase(); - if (!os.contains("win")) { - System.out.println("CHKDSK is only available on Windows systems."); - System.out.println("On Unix-like systems, use 'fsck' instead."); - return; - } + if (!os.contains("win")) { + System.out.println("CHKDSK is only available on Windows systems."); + System.out.println("On Unix-like systems, use 'fsck' instead."); + return; + } - if (args.length == 0) { - System.out.println("Checks a disk and displays a status report."); - System.out.println("\nCHKDSK [volume[[path]filename]]] [/F] [/V] [/R] [/X]"); - System.out.println("\n volume Specifies the drive letter (followed by a colon)"); - System.out.println(" /F Fixes errors on the disk"); - System.out.println(" /V Displays the full path of every file"); - System.out.println(" /R Locates bad sectors and recovers readable information"); - System.out.println(" /X Forces the volume to dismount first if necessary"); - System.out.println("\nNote: Administrator privileges required."); - return; - } + if (args.length == 0) { + System.out.println("Checks a disk and displays a status report."); + System.out.println("\nCHKDSK [volume[[path]filename]]] [/F] [/V] [/R] [/X]"); + System.out.println("\n volume Specifies the drive letter (followed by a colon)"); + System.out.println(" /F Fixes errors on the disk"); + System.out.println(" /V Displays the full path of every file"); + System.out.println(" /R Locates bad sectors and recovers readable information"); + System.out.println(" /X Forces the volume to dismount first if necessary"); + System.out.println("\nNote: Administrator privileges required."); + return; + } - try { - StringBuilder cmdBuilder = new StringBuilder("chkdsk"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + try { + StringBuilder cmdBuilder = new StringBuilder("chkdsk"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing chkdsk: " + e.getMessage()); - System.out.println("Administrator privileges may be required."); + } catch (Exception e) { + System.out.println("Error executing chkdsk: " + e.getMessage()); + System.out.println("Administrator privileges may be required."); + } } - } - @Override - public String description() { - return "Checks a disk and displays a status report."; - } + @Override + public String description() { + return "Checks a disk and displays a status report."; + } - @Override - public String usage() { - return "chkdsk [volume] [/F] [/V] [/R] [/X]"; - } + @Override + public String usage() { + return "chkdsk [volume] [/F] [/V] [/R] [/X]"; + } } diff --git a/src/main/java/com/mycmd/commands/ChoiceCommand.java b/src/main/java/com/mycmd/commands/ChoiceCommand.java index fd7ff72..7a8626f 100644 --- a/src/main/java/com/mycmd/commands/ChoiceCommand.java +++ b/src/main/java/com/mycmd/commands/ChoiceCommand.java @@ -12,62 +12,62 @@ */ public class ChoiceCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - String choices = "YN"; - String message = "Y/N?"; - boolean caseInsensitive = false; - int defaultChoice = 0; + @Override + public void execute(String[] args, ShellContext context) throws IOException { + String choices = "YN"; + String message = "Y/N?"; + boolean caseInsensitive = false; + int defaultChoice = 0; - // Parse arguments - for (int i = 0; i < args.length; i++) { - String arg = args[i].toUpperCase(); + // Parse arguments + for (int i = 0; i < args.length; i++) { + String arg = args[i].toUpperCase(); - if (arg.equals("/C") && i + 1 < args.length) { - choices = args[++i].toUpperCase(); - } else if (arg.equals("/M") && i + 1 < args.length) { - message = args[++i]; - } else if (arg.equals("/CS")) { - caseInsensitive = false; - } else if (arg.equals("/N")) { - // No display of choices - } else if (arg.equals("/D") && i + 1 < args.length) { - char defChar = args[++i].charAt(0); - defaultChoice = choices.indexOf(Character.toUpperCase(defChar)); - } - } + if (arg.equals("/C") && i + 1 < args.length) { + choices = args[++i].toUpperCase(); + } else if (arg.equals("/M") && i + 1 < args.length) { + message = args[++i]; + } else if (arg.equals("/CS")) { + caseInsensitive = false; + } else if (arg.equals("/N")) { + // No display of choices + } else if (arg.equals("/D") && i + 1 < args.length) { + char defChar = args[++i].charAt(0); + defaultChoice = choices.indexOf(Character.toUpperCase(defChar)); + } + } - System.out.print(message + " [" + String.join(",", choices.split("")) + "]? "); + System.out.print(message + " [" + String.join(",", choices.split("")) + "]? "); - Scanner scanner = new Scanner(System.in); - String input = scanner.nextLine().trim(); + Scanner scanner = new Scanner(System.in); + String input = scanner.nextLine().trim(); - if (input.isEmpty() && defaultChoice >= 0) { - System.out.println(choices.charAt(defaultChoice)); - return; - } + if (input.isEmpty() && defaultChoice >= 0) { + System.out.println(choices.charAt(defaultChoice)); + return; + } - if (input.length() > 0) { - char inputChar = caseInsensitive ? Character.toUpperCase(input.charAt(0)) : input.charAt(0); - int index = choices.indexOf(inputChar); + if (input.length() > 0) { + char inputChar = caseInsensitive ? Character.toUpperCase(input.charAt(0)) : input.charAt(0); + int index = choices.indexOf(inputChar); - if (index >= 0) { - System.out.println(inputChar); - // Set errorlevel (simulated) - System.setProperty("ERRORLEVEL", String.valueOf(index + 1)); - } else { - System.out.println("Invalid choice."); - } + if (index >= 0) { + System.out.println(inputChar); + // Set errorlevel (simulated) + System.setProperty("ERRORLEVEL", String.valueOf(index + 1)); + } else { + System.out.println("Invalid choice."); + } + } } - } - @Override - public String description() { - return "Prompts the user to select from a set of choices."; - } + @Override + public String description() { + return "Prompts the user to select from a set of choices."; + } - @Override - public String usage() { - return "choice [/C choices] [/M text] [/CS] [/N] [/D choice]"; - } + @Override + public String usage() { + return "choice [/C choices] [/M text] [/CS] [/N] [/D choice]"; + } } diff --git a/src/main/java/com/mycmd/commands/ClearHistoryCommand.java b/src/main/java/com/mycmd/commands/ClearHistoryCommand.java index 782823c..af17746 100644 --- a/src/main/java/com/mycmd/commands/ClearHistoryCommand.java +++ b/src/main/java/com/mycmd/commands/ClearHistoryCommand.java @@ -15,19 +15,19 @@ * history. The history is cleared immediately and cannot be recovered. */ public class ClearHistoryCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - context.clearHistory(); - System.out.println("Command history cleared."); - } + @Override + public void execute(String[] args, ShellContext context) { + context.clearHistory(); + System.out.println("Command history cleared."); + } - @Override - public String description() { - return "Clear the stored command history."; - } + @Override + public String description() { + return "Clear the stored command history."; + } - @Override - public String usage() { - return "clearhistory"; - } + @Override + public String usage() { + return "clearhistory"; + } } diff --git a/src/main/java/com/mycmd/commands/ClipCommand.java b/src/main/java/com/mycmd/commands/ClipCommand.java index 4745526..92190f8 100644 --- a/src/main/java/com/mycmd/commands/ClipCommand.java +++ b/src/main/java/com/mycmd/commands/ClipCommand.java @@ -12,34 +12,31 @@ */ public class ClipCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - String os = System.getProperty("os.name").toLowerCase(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + String os = System.getProperty("os.name").toLowerCase(); - if (!os.contains("win")) { - System.out.println("CLIP command is only available on Windows systems."); - System.out.println("On Unix-like systems, use 'xclip' or 'pbcopy' instead."); - return; - } + if (!os.contains("win")) { + System.out.println("CLIP command is only available on Windows systems."); + System.out.println("On Unix-like systems, use 'xclip' or 'pbcopy' instead."); + return; + } - System.out.println("Redirects command output to the Windows clipboard."); - System.out.println("\nUsage:"); - System.out.println( - " DIR | CLIP Places a copy of the DIR output on the clipboard."); - System.out.println( - " CLIP < README.TXT Places a copy of the text in README.TXT on the clipboard."); - System.out.println("\nNote: Direct clipboard manipulation from MyCMD is limited."); - System.out.println( - "Use the actual Windows CLIP command with piping in CMD for full functionality."); - } + System.out.println("Redirects command output to the Windows clipboard."); + System.out.println("\nUsage:"); + System.out.println(" DIR | CLIP Places a copy of the DIR output on the clipboard."); + System.out.println(" CLIP < README.TXT Places a copy of the text in README.TXT on the clipboard."); + System.out.println("\nNote: Direct clipboard manipulation from MyCMD is limited."); + System.out.println("Use the actual Windows CLIP command with piping in CMD for full functionality."); + } - @Override - public String description() { - return "Copies text to the Windows clipboard."; - } + @Override + public String description() { + return "Copies text to the Windows clipboard."; + } - @Override - public String usage() { - return "command | clip"; - } + @Override + public String usage() { + return "command | clip"; + } } diff --git a/src/main/java/com/mycmd/commands/ClsCommand.java b/src/main/java/com/mycmd/commands/ClsCommand.java index 76586b1..d5148b7 100644 --- a/src/main/java/com/mycmd/commands/ClsCommand.java +++ b/src/main/java/com/mycmd/commands/ClsCommand.java @@ -17,30 +17,30 @@ */ public class ClsCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - try { - String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { // For Windows Users - new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); - } else { // For other Operation Systems - new ProcessBuilder("clear").inheritIO().start().waitFor(); - } - } catch (InterruptedException e) { // Restore the interrupted status - Thread.currentThread().interrupt(); - System.out.println("Error while clearing the screen: " + e.getMessage()); - } catch (IOException e) { - System.out.println("Error while clearing the screen: " + e.getMessage()); + @Override + public void execute(String[] args, ShellContext context) { + try { + String os = System.getProperty("os.name").toLowerCase(); + if (os.contains("win")) { // For Windows Users + new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); + } else { // For other Operation Systems + new ProcessBuilder("clear").inheritIO().start().waitFor(); + } + } catch (InterruptedException e) { // Restore the interrupted status + Thread.currentThread().interrupt(); + System.out.println("Error while clearing the screen: " + e.getMessage()); + } catch (IOException e) { + System.out.println("Error while clearing the screen: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Clear the console screen."; - } + @Override + public String description() { + return "Clear the console screen."; + } - @Override - public String usage() { - return "cls"; - } + @Override + public String usage() { + return "cls"; + } } diff --git a/src/main/java/com/mycmd/commands/ColorCommand.java b/src/main/java/com/mycmd/commands/ColorCommand.java index f99ff2b..42865a1 100644 --- a/src/main/java/com/mycmd/commands/ColorCommand.java +++ b/src/main/java/com/mycmd/commands/ColorCommand.java @@ -18,68 +18,66 @@ *

Note: Background and text colors cannot be the same value. */ public class ColorCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - if (args.length == 1) { - String color = args[0]; + @Override + public void execute(String[] args, ShellContext context) { + if (args.length == 1) { + String color = args[0]; - if (color.length() != 2) { - System.out.println("Usage: " + usage()); - return; - } + if (color.length() != 2) { + System.out.println("Usage: " + usage()); + return; + } - String background = String.valueOf(color.charAt(0)); - String text = String.valueOf(color.charAt(1)); + String background = String.valueOf(color.charAt(0)); + String text = String.valueOf(color.charAt(1)); - if (background.equals(text)) { - return; - } + if (background.equals(text)) { + return; + } - int bgIndex, fgIndex; - try { - bgIndex = Integer.parseInt(background, 16); - fgIndex = Integer.parseInt(text, 16); - } catch (NumberFormatException e) { - System.out.println("Invalid color code. must use two hexadecimal digits."); - System.out.println("Example: color 0A"); - return; - } + int bgIndex, fgIndex; + try { + bgIndex = Integer.parseInt(background, 16); + fgIndex = Integer.parseInt(text, 16); + } catch (NumberFormatException e) { + System.out.println("Invalid color code. must use two hexadecimal digits."); + System.out.println("Example: color 0A"); + return; + } - String[] ansiForeground = { - "30", "34", "32", "36", "31", "35", "33", "37", "90", "94", "92", "96", "91", "95", "93", - "97" - }; - String[] ansiBackground = { - "40", "44", "42", "46", "41", "45", "43", "47", "100", "104", "102", "106", "101", "105", - "103", "107" - }; + String[] ansiForeground = { + "30", "34", "32", "36", "31", "35", "33", "37", "90", "94", "92", "96", "91", "95", "93", "97" + }; + String[] ansiBackground = { + "40", "44", "42", "46", "41", "45", "43", "47", "100", "104", "102", "106", "101", "105", "103", "107" + }; - if (bgIndex >= ansiBackground.length || fgIndex >= ansiForeground.length) { - System.out.println("Invalid color code. must use two hexadecimal digits."); - System.out.println("Example: color 0A"); - return; - } + if (bgIndex >= ansiBackground.length || fgIndex >= ansiForeground.length) { + System.out.println("Invalid color code. must use two hexadecimal digits."); + System.out.println("Example: color 0A"); + return; + } - String bg = "\033[" + ansiBackground[bgIndex] + "m"; - String fg = "\033[" + ansiForeground[fgIndex] + "m"; + String bg = "\033[" + ansiBackground[bgIndex] + "m"; + String fg = "\033[" + ansiForeground[fgIndex] + "m"; - System.out.println(bg + fg); - } else { - // set default color - System.out.println("\033[0m"); + System.out.println(bg + fg); + } else { + // set default color + System.out.println("\033[0m"); + } } - } - @Override - public String description() { - return "Change console text and background colors."; - } + @Override + public String description() { + return "Change console text and background colors."; + } - @Override - public String usage() { - return "color []\n" - + " and are hexadecimal digits (0-9, A-F).\n" - + " Example: color 0A sets black background with bright green text.\n" - + " Call without arguments to reset to default colors."; - } + @Override + public String usage() { + return "color []\n" + + " and are hexadecimal digits (0-9, A-F).\n" + + " Example: color 0A sets black background with bright green text.\n" + + " Call without arguments to reset to default colors."; + } } diff --git a/src/main/java/com/mycmd/commands/CompactCommand.java b/src/main/java/com/mycmd/commands/CompactCommand.java index 159e635..a0b3a80 100644 --- a/src/main/java/com/mycmd/commands/CompactCommand.java +++ b/src/main/java/com/mycmd/commands/CompactCommand.java @@ -14,61 +14,61 @@ */ public class CompactCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - String os = System.getProperty("os.name").toLowerCase(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + String os = System.getProperty("os.name").toLowerCase(); - if (!os.contains("win")) { - System.out.println("COMPACT is only available on Windows NTFS systems."); - return; - } + if (!os.contains("win")) { + System.out.println("COMPACT is only available on Windows NTFS systems."); + return; + } - if (args.length == 0) { - System.out.println("Displays or alters the compression of files on NTFS partitions."); - System.out.println("\nCOMPACT [/C | /U] [/S[:dir]] [/A] [/I] [/F] [/Q] [filename [...]]"); - System.out.println("\n /C Compresses the specified files."); - System.out.println(" /U Uncompresses the specified files."); - System.out.println(" /S Performs the specified operation on files in the given"); - System.out.println(" directory and all subdirectories."); - System.out.println(" /A Displays files with the hidden or system attributes."); - System.out.println(" /I Continues performing the specified operation even after"); - System.out.println(" errors have occurred."); - System.out.println(" /F Forces the compress operation on all specified files."); - System.out.println(" /Q Reports only the most essential information."); - return; - } + if (args.length == 0) { + System.out.println("Displays or alters the compression of files on NTFS partitions."); + System.out.println("\nCOMPACT [/C | /U] [/S[:dir]] [/A] [/I] [/F] [/Q] [filename [...]]"); + System.out.println("\n /C Compresses the specified files."); + System.out.println(" /U Uncompresses the specified files."); + System.out.println(" /S Performs the specified operation on files in the given"); + System.out.println(" directory and all subdirectories."); + System.out.println(" /A Displays files with the hidden or system attributes."); + System.out.println(" /I Continues performing the specified operation even after"); + System.out.println(" errors have occurred."); + System.out.println(" /F Forces the compress operation on all specified files."); + System.out.println(" /Q Reports only the most essential information."); + return; + } - try { - StringBuilder cmdBuilder = new StringBuilder("compact"); - for (String arg : args) { - cmdBuilder.append(" \"").append(arg).append("\""); - } + try { + StringBuilder cmdBuilder = new StringBuilder("compact"); + for (String arg : args) { + cmdBuilder.append(" \"").append(arg).append("\""); + } - ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); - pb.directory(context.getCurrentDir()); - Process process = pb.start(); + ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); + pb.directory(context.getCurrentDir()); + Process process = pb.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing compact: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error executing compact: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Displays or alters the compression of files on NTFS partitions."; - } + @Override + public String description() { + return "Displays or alters the compression of files on NTFS partitions."; + } - @Override - public String usage() { - return "compact [/C | /U] [filename]"; - } + @Override + public String usage() { + return "compact [/C | /U] [filename]"; + } } diff --git a/src/main/java/com/mycmd/commands/CopyCommand.java b/src/main/java/com/mycmd/commands/CopyCommand.java index 93d8889..ba01c40 100644 --- a/src/main/java/com/mycmd/commands/CopyCommand.java +++ b/src/main/java/com/mycmd/commands/CopyCommand.java @@ -17,38 +17,38 @@ * operation. If the destination file already exists, it will be overwritten. */ public class CopyCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - if (args.length < 2) { - System.out.println("Usage: " + usage()); - return; + @Override + public void execute(String[] args, ShellContext context) { + if (args.length < 2) { + System.out.println("Usage: " + usage()); + return; + } + File src = new File(context.getCurrentDir(), args[0]); + File dest = new File(context.getCurrentDir(), args[1]); + if (!src.exists() || !src.isFile()) { + System.out.println("Source file does not exist."); + return; + } + try (InputStream in = new FileInputStream(src); + OutputStream out = new FileOutputStream(dest)) { + byte[] buf = new byte[8192]; + int len; + while ((len = in.read(buf)) != -1) { + out.write(buf, 0, len); + } + System.out.println("File copied."); + } catch (IOException e) { + System.out.println("Error copying file: " + e.getMessage()); + } } - File src = new File(context.getCurrentDir(), args[0]); - File dest = new File(context.getCurrentDir(), args[1]); - if (!src.exists() || !src.isFile()) { - System.out.println("Source file does not exist."); - return; - } - try (InputStream in = new FileInputStream(src); - OutputStream out = new FileOutputStream(dest)) { - byte[] buf = new byte[8192]; - int len; - while ((len = in.read(buf)) != -1) { - out.write(buf, 0, len); - } - System.out.println("File copied."); - } catch (IOException e) { - System.out.println("Error copying file: " + e.getMessage()); - } - } - @Override - public String description() { - return "Copy a file from source to destination."; - } + @Override + public String description() { + return "Copy a file from source to destination."; + } - @Override - public String usage() { - return "copy "; - } + @Override + public String usage() { + return "copy "; + } } diff --git a/src/main/java/com/mycmd/commands/DateCommand.java b/src/main/java/com/mycmd/commands/DateCommand.java index 42b0df4..ea60bba 100644 --- a/src/main/java/com/mycmd/commands/DateCommand.java +++ b/src/main/java/com/mycmd/commands/DateCommand.java @@ -12,24 +12,24 @@ * in ISO-8601 format (yyyy-MM-dd). */ public class DateCommand implements Command { - /** - * Print the current date. - * - * @param args ignored for this command; may be empty or contain unused tokens. - * @param context the current shell context; not used by this command. - */ - @Override - public void execute(String[] args, ShellContext context) { - System.out.println("The current date is: " + java.time.LocalDate.now()); - } + /** + * Print the current date. + * + * @param args ignored for this command; may be empty or contain unused tokens. + * @param context the current shell context; not used by this command. + */ + @Override + public void execute(String[] args, ShellContext context) { + System.out.println("The current date is: " + java.time.LocalDate.now()); + } - @Override - public String description() { - return "Display current date."; - } + @Override + public String description() { + return "Display current date."; + } - @Override - public String usage() { - return "date"; - } + @Override + public String usage() { + return "date"; + } } diff --git a/src/main/java/com/mycmd/commands/DelCommand.java b/src/main/java/com/mycmd/commands/DelCommand.java index 144c822..d2c37bb 100644 --- a/src/main/java/com/mycmd/commands/DelCommand.java +++ b/src/main/java/com/mycmd/commands/DelCommand.java @@ -16,31 +16,31 @@ *

Note: This command only deletes files, not directories. Use rmdir for directory removal. */ public class DelCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - if (args.length == 0) { - System.out.println("Usage: " + usage()); - return; + @Override + public void execute(String[] args, ShellContext context) { + if (args.length == 0) { + System.out.println("Usage: " + usage()); + return; + } + for (String name : args) { + File file = new File(context.getCurrentDir(), name); + if (!file.exists() || !file.isFile()) { + System.out.println("File not found: " + name); + } else if (file.delete()) { + System.out.println("Deleted: " + name); + } else { + System.out.println("Failed to delete: " + name); + } + } } - for (String name : args) { - File file = new File(context.getCurrentDir(), name); - if (!file.exists() || !file.isFile()) { - System.out.println("File not found: " + name); - } else if (file.delete()) { - System.out.println("Deleted: " + name); - } else { - System.out.println("Failed to delete: " + name); - } - } - } - @Override - public String description() { - return "Delete one or more files."; - } + @Override + public String description() { + return "Delete one or more files."; + } - @Override - public String usage() { - return "del [file2 ...]"; - } + @Override + public String usage() { + return "del [file2 ...]"; + } } diff --git a/src/main/java/com/mycmd/commands/DirCommand.java b/src/main/java/com/mycmd/commands/DirCommand.java index 68d4ab9..bb57fa8 100644 --- a/src/main/java/com/mycmd/commands/DirCommand.java +++ b/src/main/java/com/mycmd/commands/DirCommand.java @@ -19,25 +19,25 @@ *

If the directory is empty or cannot be read, an appropriate message is displayed. */ public class DirCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - File[] files = context.getCurrentDir().listFiles(); - if (files == null || files.length == 0) { - System.out.println("No files found."); - return; + @Override + public void execute(String[] args, ShellContext context) { + File[] files = context.getCurrentDir().listFiles(); + if (files == null || files.length == 0) { + System.out.println("No files found."); + return; + } + for (File f : files) { + System.out.println((f.isDirectory() ? "

" : " ") + f.getName()); + } } - for (File f : files) { - System.out.println((f.isDirectory() ? " " : " ") + f.getName()); - } - } - @Override - public String description() { - return "Display the contents of working directory."; - } + @Override + public String description() { + return "Display the contents of working directory."; + } - @Override - public String usage() { - return "dir"; - } + @Override + public String usage() { + return "dir"; + } } diff --git a/src/main/java/com/mycmd/commands/DriverqueryCommand.java b/src/main/java/com/mycmd/commands/DriverqueryCommand.java index c9ce2d0..c8137e5 100644 --- a/src/main/java/com/mycmd/commands/DriverqueryCommand.java +++ b/src/main/java/com/mycmd/commands/DriverqueryCommand.java @@ -17,88 +17,86 @@ */ public class DriverqueryCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - String os = System.getProperty("os.name").toLowerCase(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + String os = System.getProperty("os.name").toLowerCase(); - if (!os.contains("win")) { - System.out.println("driverquery is only available on Windows systems."); - return; - } + if (!os.contains("win")) { + System.out.println("driverquery is only available on Windows systems."); + return; + } - try { + try { - List command = new ArrayList<>(); - command.add("driverquery"); - if (args != null && args.length > 0) { - command.addAll(Arrays.asList(args)); - } + List command = new ArrayList<>(); + command.add("driverquery"); + if (args != null && args.length > 0) { + command.addAll(Arrays.asList(args)); + } - ProcessBuilder pb = new ProcessBuilder(command); - Process process = pb.start(); + ProcessBuilder pb = new ProcessBuilder(command); + Process process = pb.start(); - Thread errorGobbler = - new Thread( - () -> { - try (BufferedReader errReader = - new BufferedReader(new InputStreamReader(process.getErrorStream()))) { - String errLine; - while ((errLine = errReader.readLine()) != null) { - System.err.println(errLine); - } - } catch (IOException e) { - System.err.println("Error reading process error stream: " + e.getMessage()); - } - }, - "driverquery-error-gobbler"); - errorGobbler.setDaemon(true); - errorGobbler.start(); + Thread errorGobbler = new Thread( + () -> { + try (BufferedReader errReader = + new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + String errLine; + while ((errLine = errReader.readLine()) != null) { + System.err.println(errLine); + } + } catch (IOException e) { + System.err.println("Error reading process error stream: " + e.getMessage()); + } + }, + "driverquery-error-gobbler"); + errorGobbler.setDaemon(true); + errorGobbler.start(); - try (BufferedReader reader = - new BufferedReader(new InputStreamReader(process.getInputStream()))) { - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } - } + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + } - boolean finished; - try { - finished = process.waitFor(30, TimeUnit.SECONDS); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - process.destroyForcibly(); - throw new IOException("Interrupted while waiting for driverquery process", ie); - } + boolean finished; + try { + finished = process.waitFor(30, TimeUnit.SECONDS); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + process.destroyForcibly(); + throw new IOException("Interrupted while waiting for driverquery process", ie); + } - if (!finished) { - process.destroyForcibly(); - System.out.println("Command timed out."); - } else { - int exitCode = process.exitValue(); - if (exitCode != 0) { - System.out.println("Command exited with code: " + exitCode); - } - } + if (!finished) { + process.destroyForcibly(); + System.out.println("Command timed out."); + } else { + int exitCode = process.exitValue(); + if (exitCode != 0) { + System.out.println("Command exited with code: " + exitCode); + } + } - try { - errorGobbler.join(1000); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } + try { + errorGobbler.join(1000); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } - } catch (Exception e) { - System.out.println("Error executing driverquery: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error executing driverquery: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Displays a list of all installed device drivers."; - } + @Override + public String description() { + return "Displays a list of all installed device drivers."; + } - @Override - public String usage() { - return "driverquery [/v]"; - } + @Override + public String usage() { + return "driverquery [/v]"; + } } diff --git a/src/main/java/com/mycmd/commands/EchoCommand.java b/src/main/java/com/mycmd/commands/EchoCommand.java index 5948f01..87dad81 100644 --- a/src/main/java/com/mycmd/commands/EchoCommand.java +++ b/src/main/java/com/mycmd/commands/EchoCommand.java @@ -14,22 +14,22 @@ *

Multiple words are automatically joined with spaces between them. */ public class EchoCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - if (args.length == 0) { - System.out.println(); - } else { - System.out.println(String.join(" ", args)); + @Override + public void execute(String[] args, ShellContext context) { + if (args.length == 0) { + System.out.println(); + } else { + System.out.println(String.join(" ", args)); + } } - } - @Override - public String description() { - return "Display a line of text"; - } + @Override + public String description() { + return "Display a line of text"; + } - @Override - public String usage() { - return "echo "; - } + @Override + public String usage() { + return "echo "; + } } diff --git a/src/main/java/com/mycmd/commands/ExitCommand.java b/src/main/java/com/mycmd/commands/ExitCommand.java index f0dca8f..f18dc54 100644 --- a/src/main/java/com/mycmd/commands/ExitCommand.java +++ b/src/main/java/com/mycmd/commands/ExitCommand.java @@ -15,19 +15,19 @@ * confirmation. */ public class ExitCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - System.out.println("Exiting MyCMD..."); - System.exit(0); - } + @Override + public void execute(String[] args, ShellContext context) { + System.out.println("Exiting MyCMD..."); + System.exit(0); + } - @Override - public String description() { - return "Exit the program."; - } + @Override + public String description() { + return "Exit the program."; + } - @Override - public String usage() { - return "exit"; - } + @Override + public String usage() { + return "exit"; + } } diff --git a/src/main/java/com/mycmd/commands/FcCommand.java b/src/main/java/com/mycmd/commands/FcCommand.java index ca61072..e9937a7 100644 --- a/src/main/java/com/mycmd/commands/FcCommand.java +++ b/src/main/java/com/mycmd/commands/FcCommand.java @@ -13,149 +13,148 @@ */ public class FcCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length < 2) { - System.out.println("Compares two files or sets of files and displays the differences."); - System.out.println("\nFC [/B] [/C] [/N]"); - System.out.println(" [drive1:][path1]filename1 [drive2:][path2]filename2"); - System.out.println(""); - System.out.println(" /B Performs a binary comparison."); - System.out.println(" /C Disregards the case of letters."); - System.out.println(" /N Displays the line numbers on an ASCII comparison."); - return; - } - - boolean binary = false; - boolean ignoreCase = false; - boolean showLineNumbers = false; - int argIndex = 0; - - // Parse flags - while (argIndex < args.length && args[argIndex].startsWith("/")) { - String flag = args[argIndex].toUpperCase(); - if (flag.equals("/B")) binary = true; - else if (flag.equals("/C")) ignoreCase = true; - else if (flag.equals("/N")) showLineNumbers = true; - argIndex++; - } - - if (argIndex + 1 >= args.length) { - System.out.println("Insufficient parameters."); - return; - } - - String file1Name = args[argIndex]; - String file2Name = args[argIndex + 1]; - - java.io.File file1 = new java.io.File(file1Name); - java.io.File file2 = new java.io.File(file2Name); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length < 2) { + System.out.println("Compares two files or sets of files and displays the differences."); + System.out.println("\nFC [/B] [/C] [/N]"); + System.out.println(" [drive1:][path1]filename1 [drive2:][path2]filename2"); + System.out.println(""); + System.out.println(" /B Performs a binary comparison."); + System.out.println(" /C Disregards the case of letters."); + System.out.println(" /N Displays the line numbers on an ASCII comparison."); + return; + } - if (!file1.isAbsolute()) { - file1 = new java.io.File(context.getCurrentDir(), file1Name); - } - if (!file2.isAbsolute()) { - file2 = new java.io.File(context.getCurrentDir(), file2Name); - } + boolean binary = false; + boolean ignoreCase = false; + boolean showLineNumbers = false; + int argIndex = 0; + + // Parse flags + while (argIndex < args.length && args[argIndex].startsWith("/")) { + String flag = args[argIndex].toUpperCase(); + if (flag.equals("/B")) binary = true; + else if (flag.equals("/C")) ignoreCase = true; + else if (flag.equals("/N")) showLineNumbers = true; + argIndex++; + } - if (!file1.exists()) { - System.out.println("Cannot find " + file1Name); - return; - } - if (!file2.exists()) { - System.out.println("Cannot find " + file2Name); - return; - } + if (argIndex + 1 >= args.length) { + System.out.println("Insufficient parameters."); + return; + } - System.out.println("Comparing files " + file1.getName() + " and " + file2.getName()); + String file1Name = args[argIndex]; + String file2Name = args[argIndex + 1]; - if (binary) { - compareBinary(file1, file2); - } else { - compareText(file1, file2, ignoreCase, showLineNumbers); - } - } + java.io.File file1 = new java.io.File(file1Name); + java.io.File file2 = new java.io.File(file2Name); - private void compareBinary(java.io.File file1, java.io.File file2) throws IOException { - if (file1.length() != file2.length()) { - System.out.println("Files are different sizes."); - return; - } + if (!file1.isAbsolute()) { + file1 = new java.io.File(context.getCurrentDir(), file1Name); + } + if (!file2.isAbsolute()) { + file2 = new java.io.File(context.getCurrentDir(), file2Name); + } - try (java.io.FileInputStream fis1 = new java.io.FileInputStream(file1); - java.io.FileInputStream fis2 = new java.io.FileInputStream(file2)) { + if (!file1.exists()) { + System.out.println("Cannot find " + file1Name); + return; + } + if (!file2.exists()) { + System.out.println("Cannot find " + file2Name); + return; + } - int b1, b2; - long position = 0; - boolean different = false; + System.out.println("Comparing files " + file1.getName() + " and " + file2.getName()); - while ((b1 = fis1.read()) != -1) { - b2 = fis2.read(); - if (b1 != b2) { - System.out.println("Files differ at position " + position); - different = true; - break; + if (binary) { + compareBinary(file1, file2); + } else { + compareText(file1, file2, ignoreCase, showLineNumbers); } - position++; - } - - if (!different) { - System.out.println("FC: no differences encountered"); - } } - } - - private void compareText( - java.io.File file1, java.io.File file2, boolean ignoreCase, boolean showLineNumbers) - throws IOException { - try (BufferedReader reader1 = new BufferedReader(new FileReader(file1)); - BufferedReader reader2 = new BufferedReader(new FileReader(file2))) { - String line1, line2; - int lineNum = 0; - boolean different = false; - - while (true) { - line1 = reader1.readLine(); - line2 = reader2.readLine(); - lineNum++; - - if (line1 == null && line2 == null) break; - - if (line1 == null || line2 == null) { - System.out.println("Files are different lengths."); - different = true; - break; + private void compareBinary(java.io.File file1, java.io.File file2) throws IOException { + if (file1.length() != file2.length()) { + System.out.println("Files are different sizes."); + return; } - String compare1 = ignoreCase ? line1.toLowerCase() : line1; - String compare2 = ignoreCase ? line2.toLowerCase() : line2; - - if (!compare1.equals(compare2)) { - System.out.println("***** " + file1.getName()); - if (showLineNumbers) System.out.print(lineNum + ": "); - System.out.println(line1); - System.out.println("***** " + file2.getName()); - if (showLineNumbers) System.out.print(lineNum + ": "); - System.out.println(line2); - System.out.println("*****\n"); - different = true; + try (java.io.FileInputStream fis1 = new java.io.FileInputStream(file1); + java.io.FileInputStream fis2 = new java.io.FileInputStream(file2)) { + + int b1, b2; + long position = 0; + boolean different = false; + + while ((b1 = fis1.read()) != -1) { + b2 = fis2.read(); + if (b1 != b2) { + System.out.println("Files differ at position " + position); + different = true; + break; + } + position++; + } + + if (!different) { + System.out.println("FC: no differences encountered"); + } } - } + } - if (!different) { - System.out.println("FC: no differences encountered"); - } + private void compareText(java.io.File file1, java.io.File file2, boolean ignoreCase, boolean showLineNumbers) + throws IOException { + try (BufferedReader reader1 = new BufferedReader(new FileReader(file1)); + BufferedReader reader2 = new BufferedReader(new FileReader(file2))) { + + String line1, line2; + int lineNum = 0; + boolean different = false; + + while (true) { + line1 = reader1.readLine(); + line2 = reader2.readLine(); + lineNum++; + + if (line1 == null && line2 == null) break; + + if (line1 == null || line2 == null) { + System.out.println("Files are different lengths."); + different = true; + break; + } + + String compare1 = ignoreCase ? line1.toLowerCase() : line1; + String compare2 = ignoreCase ? line2.toLowerCase() : line2; + + if (!compare1.equals(compare2)) { + System.out.println("***** " + file1.getName()); + if (showLineNumbers) System.out.print(lineNum + ": "); + System.out.println(line1); + System.out.println("***** " + file2.getName()); + if (showLineNumbers) System.out.print(lineNum + ": "); + System.out.println(line2); + System.out.println("*****\n"); + different = true; + } + } + + if (!different) { + System.out.println("FC: no differences encountered"); + } + } } - } - @Override - public String description() { - return "Compares two files or sets of files and displays the differences."; - } + @Override + public String description() { + return "Compares two files or sets of files and displays the differences."; + } - @Override - public String usage() { - return "fc [/B] [/C] [/N] file1 file2"; - } + @Override + public String usage() { + return "fc [/B] [/C] [/N] file1 file2"; + } } diff --git a/src/main/java/com/mycmd/commands/FindCommand.java b/src/main/java/com/mycmd/commands/FindCommand.java index ad511d8..4aafa25 100644 --- a/src/main/java/com/mycmd/commands/FindCommand.java +++ b/src/main/java/com/mycmd/commands/FindCommand.java @@ -14,117 +14,115 @@ */ public class FindCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length < 2) { - System.out.println("Searches for a text string in a file or files."); - System.out.println( - "\nFIND [/V] [/C] [/N] [/I] [/OFF[LINE]] \"string\" [[drive:][path]filename[ ...]]"); - System.out.println("\n /V Displays all lines NOT containing the specified string."); - System.out.println(" /C Displays only the count of lines containing the string."); - System.out.println(" /N Displays line numbers with the displayed lines."); - System.out.println( - " /I Ignores the case of characters when searching for the string."); - System.out.println(" \"string\" Specifies the text string to find."); - System.out.println(" [drive:][path]filename"); - System.out.println(" Specifies a file or files to search."); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length < 2) { + System.out.println("Searches for a text string in a file or files."); + System.out.println("\nFIND [/V] [/C] [/N] [/I] [/OFF[LINE]] \"string\" [[drive:][path]filename[ ...]]"); + System.out.println("\n /V Displays all lines NOT containing the specified string."); + System.out.println(" /C Displays only the count of lines containing the string."); + System.out.println(" /N Displays line numbers with the displayed lines."); + System.out.println(" /I Ignores the case of characters when searching for the string."); + System.out.println(" \"string\" Specifies the text string to find."); + System.out.println(" [drive:][path]filename"); + System.out.println(" Specifies a file or files to search."); + return; + } - boolean caseInsensitive = false; - boolean showLineNumbers = false; - boolean countOnly = false; - boolean invertMatch = false; - int argIndex = 0; - - // Parse flags - while (argIndex < args.length && args[argIndex].startsWith("/")) { - String flag = args[argIndex].toUpperCase(); - if (flag.equals("/I")) caseInsensitive = true; - else if (flag.equals("/N")) showLineNumbers = true; - else if (flag.equals("/C")) countOnly = true; - else if (flag.equals("/V")) invertMatch = true; - argIndex++; - } + boolean caseInsensitive = false; + boolean showLineNumbers = false; + boolean countOnly = false; + boolean invertMatch = false; + int argIndex = 0; + + // Parse flags + while (argIndex < args.length && args[argIndex].startsWith("/")) { + String flag = args[argIndex].toUpperCase(); + if (flag.equals("/I")) caseInsensitive = true; + else if (flag.equals("/N")) showLineNumbers = true; + else if (flag.equals("/C")) countOnly = true; + else if (flag.equals("/V")) invertMatch = true; + argIndex++; + } - if (argIndex >= args.length) { - System.out.println("Missing search string."); - return; - } + if (argIndex >= args.length) { + System.out.println("Missing search string."); + return; + } - String searchString = args[argIndex++].replace("\"", ""); + String searchString = args[argIndex++].replace("\"", ""); - if (argIndex >= args.length) { - System.out.println("Missing filename."); - return; - } + if (argIndex >= args.length) { + System.out.println("Missing filename."); + return; + } - // Process files - for (int i = argIndex; i < args.length; i++) { - String filename = args[i]; - java.io.File file = new java.io.File(filename); + // Process files + for (int i = argIndex; i < args.length; i++) { + String filename = args[i]; + java.io.File file = new java.io.File(filename); - if (!file.isAbsolute()) { - file = new java.io.File(context.getCurrentDir(), filename); - } + if (!file.isAbsolute()) { + file = new java.io.File(context.getCurrentDir(), filename); + } - if (!file.exists()) { - System.out.println("File not found - " + filename); - continue; - } + if (!file.exists()) { + System.out.println("File not found - " + filename); + continue; + } - searchInFile(file, searchString, caseInsensitive, showLineNumbers, countOnly, invertMatch); + searchInFile(file, searchString, caseInsensitive, showLineNumbers, countOnly, invertMatch); + } } - } - - private void searchInFile( - java.io.File file, - String searchString, - boolean caseInsensitive, - boolean showLineNumbers, - boolean countOnly, - boolean invertMatch) - throws IOException { - System.out.println("\n---------- " + file.getName().toUpperCase()); - - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { - String line; - int lineNumber = 0; - int matchCount = 0; - - while ((line = reader.readLine()) != null) { - lineNumber++; - String compareLine = caseInsensitive ? line.toLowerCase() : line; - String compareString = caseInsensitive ? searchString.toLowerCase() : searchString; - - boolean matches = compareLine.contains(compareString); - if (invertMatch) matches = !matches; - - if (matches) { - matchCount++; - if (!countOnly) { - if (showLineNumbers) { - System.out.println("[" + lineNumber + "]" + line); - } else { - System.out.println(line); + + private void searchInFile( + java.io.File file, + String searchString, + boolean caseInsensitive, + boolean showLineNumbers, + boolean countOnly, + boolean invertMatch) + throws IOException { + System.out.println("\n---------- " + file.getName().toUpperCase()); + + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + int lineNumber = 0; + int matchCount = 0; + + while ((line = reader.readLine()) != null) { + lineNumber++; + String compareLine = caseInsensitive ? line.toLowerCase() : line; + String compareString = caseInsensitive ? searchString.toLowerCase() : searchString; + + boolean matches = compareLine.contains(compareString); + if (invertMatch) matches = !matches; + + if (matches) { + matchCount++; + if (!countOnly) { + if (showLineNumbers) { + System.out.println("[" + lineNumber + "]" + line); + } else { + System.out.println(line); + } + } + } } - } - } - } - if (countOnly) { - System.out.println("Count: " + matchCount); - } + if (countOnly) { + System.out.println("Count: " + matchCount); + } + } } - } - @Override - public String description() { - return "Searches for a text string in a file or files."; - } + @Override + public String description() { + return "Searches for a text string in a file or files."; + } - @Override - public String usage() { - return "find [/I] [/N] [/C] \"string\" filename"; - } + @Override + public String usage() { + return "find [/I] [/N] [/C] \"string\" filename"; + } } diff --git a/src/main/java/com/mycmd/commands/FindstrCommand.java b/src/main/java/com/mycmd/commands/FindstrCommand.java index ac1240f..354b994 100644 --- a/src/main/java/com/mycmd/commands/FindstrCommand.java +++ b/src/main/java/com/mycmd/commands/FindstrCommand.java @@ -16,120 +16,119 @@ */ public class FindstrCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length < 2) { - System.out.println("Searches for strings in files."); - System.out.println("\nFINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P]"); - System.out.println(" [/F:file] [/C:string] [/G:file] [/D:dir list] [strings]"); - System.out.println(" [[drive:][path]filename[ ...]]"); - System.out.println("\n /I Specifies that the search is not to be case-sensitive."); - System.out.println(" /N Prints the line number before each line that matches."); - System.out.println(" /R Uses search strings as regular expressions."); - System.out.println( - " /S Searches for matching files in the current directory and all"); - System.out.println(" subdirectories."); - System.out.println(" strings Text to be searched for."); - System.out.println(" [drive:][path]filename"); - System.out.println(" Specifies a file or files to search."); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length < 2) { + System.out.println("Searches for strings in files."); + System.out.println("\nFINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P]"); + System.out.println(" [/F:file] [/C:string] [/G:file] [/D:dir list] [strings]"); + System.out.println(" [[drive:][path]filename[ ...]]"); + System.out.println("\n /I Specifies that the search is not to be case-sensitive."); + System.out.println(" /N Prints the line number before each line that matches."); + System.out.println(" /R Uses search strings as regular expressions."); + System.out.println(" /S Searches for matching files in the current directory and all"); + System.out.println(" subdirectories."); + System.out.println(" strings Text to be searched for."); + System.out.println(" [drive:][path]filename"); + System.out.println(" Specifies a file or files to search."); + return; + } - boolean caseInsensitive = false; - boolean showLineNumbers = false; - boolean useRegex = false; - boolean recursive = false; - int argIndex = 0; - - // Parse flags - while (argIndex < args.length && args[argIndex].startsWith("/")) { - String flag = args[argIndex].toUpperCase(); - if (flag.equals("/I")) caseInsensitive = true; - else if (flag.equals("/N")) showLineNumbers = true; - else if (flag.equals("/R")) useRegex = true; - else if (flag.equals("/S")) recursive = true; - argIndex++; - } + boolean caseInsensitive = false; + boolean showLineNumbers = false; + boolean useRegex = false; + boolean recursive = false; + int argIndex = 0; + + // Parse flags + while (argIndex < args.length && args[argIndex].startsWith("/")) { + String flag = args[argIndex].toUpperCase(); + if (flag.equals("/I")) caseInsensitive = true; + else if (flag.equals("/N")) showLineNumbers = true; + else if (flag.equals("/R")) useRegex = true; + else if (flag.equals("/S")) recursive = true; + argIndex++; + } - if (argIndex >= args.length) { - System.out.println("Missing search string."); - return; - } + if (argIndex >= args.length) { + System.out.println("Missing search string."); + return; + } - String searchString = args[argIndex++].replace("\"", ""); + String searchString = args[argIndex++].replace("\"", ""); - if (argIndex >= args.length) { - System.out.println("Missing filename."); - return; - } + if (argIndex >= args.length) { + System.out.println("Missing filename."); + return; + } - Pattern pattern = null; - if (useRegex) { - int flags = caseInsensitive ? Pattern.CASE_INSENSITIVE : 0; - pattern = Pattern.compile(searchString, flags); - } + Pattern pattern = null; + if (useRegex) { + int flags = caseInsensitive ? Pattern.CASE_INSENSITIVE : 0; + pattern = Pattern.compile(searchString, flags); + } - // Process files - for (int i = argIndex; i < args.length; i++) { - String filename = args[i]; - java.io.File file = new java.io.File(filename); + // Process files + for (int i = argIndex; i < args.length; i++) { + String filename = args[i]; + java.io.File file = new java.io.File(filename); - if (!file.isAbsolute()) { - file = new java.io.File(context.getCurrentDir(), filename); - } + if (!file.isAbsolute()) { + file = new java.io.File(context.getCurrentDir(), filename); + } - if (!file.exists()) { - System.out.println("File not found - " + filename); - continue; - } + if (!file.exists()) { + System.out.println("File not found - " + filename); + continue; + } - searchInFile(file, searchString, pattern, caseInsensitive, showLineNumbers, useRegex); - } - } - - private void searchInFile( - java.io.File file, - String searchString, - Pattern pattern, - boolean caseInsensitive, - boolean showLineNumbers, - boolean useRegex) - throws IOException { - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { - String line; - int lineNumber = 0; - - while ((line = reader.readLine()) != null) { - lineNumber++; - boolean matches = false; - - if (useRegex && pattern != null) { - Matcher matcher = pattern.matcher(line); - matches = matcher.find(); - } else { - String compareLine = caseInsensitive ? line.toLowerCase() : line; - String compareString = caseInsensitive ? searchString.toLowerCase() : searchString; - matches = compareLine.contains(compareString); + searchInFile(file, searchString, pattern, caseInsensitive, showLineNumbers, useRegex); } + } - if (matches) { - if (showLineNumbers) { - System.out.println(file.getName() + ":" + lineNumber + ":" + line); - } else { - System.out.println(file.getName() + ":" + line); - } + private void searchInFile( + java.io.File file, + String searchString, + Pattern pattern, + boolean caseInsensitive, + boolean showLineNumbers, + boolean useRegex) + throws IOException { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + int lineNumber = 0; + + while ((line = reader.readLine()) != null) { + lineNumber++; + boolean matches = false; + + if (useRegex && pattern != null) { + Matcher matcher = pattern.matcher(line); + matches = matcher.find(); + } else { + String compareLine = caseInsensitive ? line.toLowerCase() : line; + String compareString = caseInsensitive ? searchString.toLowerCase() : searchString; + matches = compareLine.contains(compareString); + } + + if (matches) { + if (showLineNumbers) { + System.out.println(file.getName() + ":" + lineNumber + ":" + line); + } else { + System.out.println(file.getName() + ":" + line); + } + } + } } - } } - } - @Override - public String description() { - return "Searches for strings in files using regular expressions."; - } + @Override + public String description() { + return "Searches for strings in files using regular expressions."; + } - @Override - public String usage() { - return "findstr [/I] [/N] [/R] \"pattern\" filename"; - } + @Override + public String usage() { + return "findstr [/I] [/N] [/R] \"pattern\" filename"; + } } diff --git a/src/main/java/com/mycmd/commands/ForfilesCommand.java b/src/main/java/com/mycmd/commands/ForfilesCommand.java index 9d31526..fc02c8c 100644 --- a/src/main/java/com/mycmd/commands/ForfilesCommand.java +++ b/src/main/java/com/mycmd/commands/ForfilesCommand.java @@ -13,71 +13,70 @@ */ public class ForfilesCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - System.out.println("FORFILES [/P pathname] [/M searchmask] [/S]"); - System.out.println(" [/C command] [/D [+ | -] {MM/dd/yyyy | dd}]"); - System.out.println("\nDescription:"); - System.out.println(" Selects a file (or set of files) and executes a"); - System.out.println(" command on that file. This is helpful for batch jobs."); - System.out.println("\nParameter List:"); - System.out.println(" /P pathname Indicates the path to start searching."); - System.out.println(" /M searchmask Searches files according to a searchmask."); - System.out.println(" /S Recurses into subdirectories."); - System.out.println(" /C command Indicates the command to execute for each file."); - System.out.println(" /D date Selects files with a last modified date greater"); - System.out.println(" than or equal to (+), or less than or equal to"); - System.out.println(" (-), the specified date."); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + System.out.println("FORFILES [/P pathname] [/M searchmask] [/S]"); + System.out.println(" [/C command] [/D [+ | -] {MM/dd/yyyy | dd}]"); + System.out.println("\nDescription:"); + System.out.println(" Selects a file (or set of files) and executes a"); + System.out.println(" command on that file. This is helpful for batch jobs."); + System.out.println("\nParameter List:"); + System.out.println(" /P pathname Indicates the path to start searching."); + System.out.println(" /M searchmask Searches files according to a searchmask."); + System.out.println(" /S Recurses into subdirectories."); + System.out.println(" /C command Indicates the command to execute for each file."); + System.out.println(" /D date Selects files with a last modified date greater"); + System.out.println(" than or equal to (+), or less than or equal to"); + System.out.println(" (-), the specified date."); - if (args.length == 0) { - return; - } + if (args.length == 0) { + return; + } - String os = System.getProperty("os.name").toLowerCase(); + String os = System.getProperty("os.name").toLowerCase(); - if (!os.contains("win")) { - System.out.println("\nFORFILES is only available on Windows systems."); - System.out.println("On Unix-like systems, use 'find' with '-exec' instead."); - return; - } + if (!os.contains("win")) { + System.out.println("\nFORFILES is only available on Windows systems."); + System.out.println("On Unix-like systems, use 'find' with '-exec' instead."); + return; + } - try { - StringBuilder cmdBuilder = new StringBuilder("forfiles"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + try { + StringBuilder cmdBuilder = new StringBuilder("forfiles"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); - pb.directory(context.getCurrentDir()); - Process process = pb.start(); + ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); + pb.directory(context.getCurrentDir()); + Process process = pb.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing forfiles: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error executing forfiles: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Selects files in a directory and runs a command on each file."; - } + @Override + public String description() { + return "Selects files in a directory and runs a command on each file."; + } - @Override - public String usage() { - return "forfiles [/P pathname] [/M searchmask] [/S] [/C command]"; - } + @Override + public String usage() { + return "forfiles [/P pathname] [/M searchmask] [/S] [/C command]"; + } } diff --git a/src/main/java/com/mycmd/commands/FsutilCommand.java b/src/main/java/com/mycmd/commands/FsutilCommand.java index 4a1732e..7e6034b 100644 --- a/src/main/java/com/mycmd/commands/FsutilCommand.java +++ b/src/main/java/com/mycmd/commands/FsutilCommand.java @@ -13,60 +13,59 @@ */ public class FsutilCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - String os = System.getProperty("os.name").toLowerCase(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + String os = System.getProperty("os.name").toLowerCase(); - if (!os.contains("win")) { - System.out.println("FSUTIL is only available on Windows systems."); - return; - } + if (!os.contains("win")) { + System.out.println("FSUTIL is only available on Windows systems."); + return; + } - if (args.length == 0) { - System.out.println("---- FSUTIL Commands Supported ----"); - System.out.println("\nfsinfo File System Information"); - System.out.println("volume Volume management"); - System.out.println("file File specific commands"); - System.out.println("hardlink Hardlink management"); - System.out.println("usn USN management"); - System.out.println("\nNote: Administrator privileges required for most operations."); - return; - } + if (args.length == 0) { + System.out.println("---- FSUTIL Commands Supported ----"); + System.out.println("\nfsinfo File System Information"); + System.out.println("volume Volume management"); + System.out.println("file File specific commands"); + System.out.println("hardlink Hardlink management"); + System.out.println("usn USN management"); + System.out.println("\nNote: Administrator privileges required for most operations."); + return; + } - try { - StringBuilder cmdBuilder = new StringBuilder("fsutil"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + try { + StringBuilder cmdBuilder = new StringBuilder("fsutil"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing fsutil: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error executing fsutil: " + e.getMessage()); + } } - } - @Override - public String description() { - return "File System Utility - Performs file system operations."; - } + @Override + public String description() { + return "File System Utility - Performs file system operations."; + } - @Override - public String usage() { - return "fsutil [command] [options]"; - } + @Override + public String usage() { + return "fsutil [command] [options]"; + } } diff --git a/src/main/java/com/mycmd/commands/FtypeCommand.java b/src/main/java/com/mycmd/commands/FtypeCommand.java index 7344856..c0b0f5e 100644 --- a/src/main/java/com/mycmd/commands/FtypeCommand.java +++ b/src/main/java/com/mycmd/commands/FtypeCommand.java @@ -13,43 +13,43 @@ */ public class FtypeCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - String os = System.getProperty("os.name").toLowerCase(); - - if (!os.contains("win")) { - System.out.println("FTYPE is only available on Windows systems."); - return; + @Override + public void execute(String[] args, ShellContext context) throws IOException { + String os = System.getProperty("os.name").toLowerCase(); + + if (!os.contains("win")) { + System.out.println("FTYPE is only available on Windows systems."); + return; + } + + try { + StringBuilder cmdBuilder = new StringBuilder("ftype"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } + + Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + + process.waitFor(); + + } catch (Exception e) { + System.out.println("Error executing ftype: " + e.getMessage()); + } } - try { - StringBuilder cmdBuilder = new StringBuilder("ftype"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } - - Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } - - process.waitFor(); - - } catch (Exception e) { - System.out.println("Error executing ftype: " + e.getMessage()); + @Override + public String description() { + return "Displays or modifies file types used in file extension associations."; } - } - - @Override - public String description() { - return "Displays or modifies file types used in file extension associations."; - } - @Override - public String usage() { - return "ftype [fileType[=[openCommandString]]]"; - } + @Override + public String usage() { + return "ftype [fileType[=[openCommandString]]]"; + } } diff --git a/src/main/java/com/mycmd/commands/GetmacCommand.java b/src/main/java/com/mycmd/commands/GetmacCommand.java index 156ae91..641fc04 100644 --- a/src/main/java/com/mycmd/commands/GetmacCommand.java +++ b/src/main/java/com/mycmd/commands/GetmacCommand.java @@ -15,62 +15,62 @@ */ public class GetmacCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - String os = System.getProperty("os.name").toLowerCase(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - try { - StringBuilder cmdBuilder = new StringBuilder("getmac"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + if (os.contains("win")) { + try { + StringBuilder cmdBuilder = new StringBuilder("getmac"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); - Process process = pb.start(); + ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); + Process process = pb.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing getmac: " + e.getMessage()); - } - } else { - // Cross-platform implementation - System.out.println("Network Adapter MAC Addresses:\n"); - try { - Enumeration networks = NetworkInterface.getNetworkInterfaces(); - while (networks.hasMoreElements()) { - NetworkInterface network = networks.nextElement(); - byte[] mac = network.getHardwareAddress(); + } catch (Exception e) { + System.out.println("Error executing getmac: " + e.getMessage()); + } + } else { + // Cross-platform implementation + System.out.println("Network Adapter MAC Addresses:\n"); + try { + Enumeration networks = NetworkInterface.getNetworkInterfaces(); + while (networks.hasMoreElements()) { + NetworkInterface network = networks.nextElement(); + byte[] mac = network.getHardwareAddress(); - if (mac != null) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < mac.length; i++) { - sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : "")); + if (mac != null) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < mac.length; i++) { + sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : "")); + } + System.out.printf("%-20s %s%n", network.getName(), sb.toString()); + } + } + } catch (Exception e) { + System.out.println("Error retrieving MAC addresses: " + e.getMessage()); } - System.out.printf("%-20s %s%n", network.getName(), sb.toString()); - } } - } catch (Exception e) { - System.out.println("Error retrieving MAC addresses: " + e.getMessage()); - } } - } - @Override - public String description() { - return "Displays MAC addresses for all network adapters."; - } + @Override + public String description() { + return "Displays MAC addresses for all network adapters."; + } - @Override - public String usage() { - return "getmac [/V]"; - } + @Override + public String usage() { + return "getmac [/V]"; + } } diff --git a/src/main/java/com/mycmd/commands/HelpCommand.java b/src/main/java/com/mycmd/commands/HelpCommand.java index ab8701b..4e1e211 100644 --- a/src/main/java/com/mycmd/commands/HelpCommand.java +++ b/src/main/java/com/mycmd/commands/HelpCommand.java @@ -9,51 +9,50 @@ * descriptions. Supports detailed help for individual commands using 'help '. */ public class HelpCommand implements Command { - private final Map commands; - - public HelpCommand(Map commands) { - this.commands = commands; - } - - @Override - public void execute(String[] args, ShellContext context) { - // Detailed help for a specific command - if (args.length > 0) { - String cmdName = args[0]; - Command cmd = commands.get(cmdName); - - if (cmd != null) { - System.out.println("\nCommand: " + cmdName); - System.out.println("Description: " + cmd.description()); - System.out.println( - "Usage: " + (cmd.usage() != null ? cmd.usage() : cmdName + " [options]")); - } else { - System.out.println("No such command: " + cmdName); - } - return; + private final Map commands; + + public HelpCommand(Map commands) { + this.commands = commands; + } + + @Override + public void execute(String[] args, ShellContext context) { + // Detailed help for a specific command + if (args.length > 0) { + String cmdName = args[0]; + Command cmd = commands.get(cmdName); + + if (cmd != null) { + System.out.println("\nCommand: " + cmdName); + System.out.println("Description: " + cmd.description()); + System.out.println("Usage: " + (cmd.usage() != null ? cmd.usage() : cmdName + " [options]")); + } else { + System.out.println("No such command: " + cmdName); + } + return; + } + + // General help listing all commands + System.out.println("\nMyCMD — Available Commands:\n"); + for (Map.Entry entry : commands.entrySet()) { + String name = entry.getKey(); + Command cmd = entry.getValue(); + String description = + (cmd.description() != null && !cmd.description().isEmpty()) + ? cmd.description() + : "No description available"; + System.out.printf(" %-12s : %s%n", name, description); + } + System.out.println("\nType 'help ' for detailed info about a specific command.\n"); + } + + @Override + public String description() { + return "Show list of available commands and their descriptions."; } - // General help listing all commands - System.out.println("\nMyCMD — Available Commands:\n"); - for (Map.Entry entry : commands.entrySet()) { - String name = entry.getKey(); - Command cmd = entry.getValue(); - String description = - (cmd.description() != null && !cmd.description().isEmpty()) - ? cmd.description() - : "No description available"; - System.out.printf(" %-12s : %s%n", name, description); + @Override + public String usage() { + return "help [command]"; } - System.out.println("\nType 'help ' for detailed info about a specific command.\n"); - } - - @Override - public String description() { - return "Show list of available commands and their descriptions."; - } - - @Override - public String usage() { - return "help [command]"; - } } diff --git a/src/main/java/com/mycmd/commands/HistoryCommand.java b/src/main/java/com/mycmd/commands/HistoryCommand.java index 155e432..b0a1270 100644 --- a/src/main/java/com/mycmd/commands/HistoryCommand.java +++ b/src/main/java/com/mycmd/commands/HistoryCommand.java @@ -5,29 +5,29 @@ public class HistoryCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - // Get the command history from the context - var history = context.getCommandHistory(); + @Override + public void execute(String[] args, ShellContext context) { + // Get the command history from the context + var history = context.getCommandHistory(); - if (history.isEmpty()) { - System.out.println("No commands in history."); - return; - } + if (history.isEmpty()) { + System.out.println("No commands in history."); + return; + } - // Display the history with numbers - for (int i = 0; i < history.size(); i++) { - System.out.println((i + 1) + ". " + history.get(i)); + // Display the history with numbers + for (int i = 0; i < history.size(); i++) { + System.out.println((i + 1) + ". " + history.get(i)); + } } - } - @Override - public String description() { - return "Display the list of previously executed commands."; - } + @Override + public String description() { + return "Display the list of previously executed commands."; + } - @Override - public String usage() { - return "history"; - } + @Override + public String usage() { + return "history"; + } } diff --git a/src/main/java/com/mycmd/commands/HostnameCommand.java b/src/main/java/com/mycmd/commands/HostnameCommand.java index 0a7911c..306688a 100644 --- a/src/main/java/com/mycmd/commands/HostnameCommand.java +++ b/src/main/java/com/mycmd/commands/HostnameCommand.java @@ -17,26 +17,26 @@ * is typically set. */ public class HostnameCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - String hostname = System.getenv("COMPUTERNAME"); - if (hostname == null) { - try { - hostname = InetAddress.getLocalHost().getHostName(); - } catch (Exception e) { - hostname = "Unknown Host"; - } + @Override + public void execute(String[] args, ShellContext context) { + String hostname = System.getenv("COMPUTERNAME"); + if (hostname == null) { + try { + hostname = InetAddress.getLocalHost().getHostName(); + } catch (Exception e) { + hostname = "Unknown Host"; + } + } + System.out.println(hostname); } - System.out.println(hostname); - } - @Override - public String description() { - return "Display the hostname of the current computer."; - } + @Override + public String description() { + return "Display the hostname of the current computer."; + } - @Override - public String usage() { - return "hostname"; - } + @Override + public String usage() { + return "hostname"; + } } diff --git a/src/main/java/com/mycmd/commands/InteractiveSearchCommand.java b/src/main/java/com/mycmd/commands/InteractiveSearchCommand.java index 3fc88cb..cb624a5 100644 --- a/src/main/java/com/mycmd/commands/InteractiveSearchCommand.java +++ b/src/main/java/com/mycmd/commands/InteractiveSearchCommand.java @@ -14,113 +14,108 @@ */ public class InteractiveSearchCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - List history = context.getHistory(); + @Override + public void execute(String[] args, ShellContext context) { + List history = context.getHistory(); - if (history.isEmpty()) { - System.out.println("No command history available."); - return; - } - - // ✅ Use shared scanner from ShellContext instead of creating a new one - Scanner scanner = context.getScanner(); - - System.out.println("=== Interactive History Search ==="); - System.out.println("Type to search, 'q' to quit"); - System.out.println(); + if (history.isEmpty()) { + System.out.println("No command history available."); + return; + } - while (true) { - System.out.print("search> "); - String searchTerm = scanner.nextLine().trim(); + // ✅ Use shared scanner from ShellContext instead of creating a new one + Scanner scanner = context.getScanner(); - if (searchTerm.equalsIgnoreCase("q") || searchTerm.equalsIgnoreCase("quit")) { - System.out.println("Search cancelled."); - break; - } + System.out.println("=== Interactive History Search ==="); + System.out.println("Type to search, 'q' to quit"); + System.out.println(); - if (searchTerm.isEmpty()) { - System.out.println("Enter a search term or 'q' to quit."); - continue; - } + while (true) { + System.out.print("search> "); + String searchTerm = scanner.nextLine().trim(); + + if (searchTerm.equalsIgnoreCase("q") || searchTerm.equalsIgnoreCase("quit")) { + System.out.println("Search cancelled."); + break; + } + + if (searchTerm.isEmpty()) { + System.out.println("Enter a search term or 'q' to quit."); + continue; + } + + // Search and display results + List matches = searchHistory(history, searchTerm); + + if (matches.isEmpty()) { + System.out.println("No matches found for: '" + searchTerm + "'"); + System.out.println(); + continue; + } + + // Display matches with numbers + System.out.println("\nMatches for '" + searchTerm + "':"); + for (int i = 0; i < Math.min(matches.size(), 10); i++) { + System.out.println(" " + (i + 1) + ". " + matches.get(i)); + } + + if (matches.size() > 10) { + System.out.println(" ... and " + (matches.size() - 10) + " more"); + } + + // Ask user to select or refine + System.out.println(); + System.out.print( + "Select number to copy (1-" + Math.min(matches.size(), 10) + "), or press Enter to search again: "); + String selection = scanner.nextLine().trim(); + + if (selection.isEmpty()) { + continue; + } + + try { + int index = Integer.parseInt(selection) - 1; + if (index >= 0 && index < Math.min(matches.size(), 10)) { + String selectedCommand = matches.get(index); + System.out.println("\nSelected command: " + selectedCommand); + System.out.println("(You can now run this command by typing it at the prompt)"); + break; + } else { + System.out.println("Invalid selection. Try again."); + } + } catch (NumberFormatException e) { + System.out.println("Invalid input. Enter a number or press Enter."); + } + + System.out.println(); + } + } - // Search and display results - List matches = searchHistory(history, searchTerm); + /** + * Search history for commands containing the search term. Returns matches in reverse order (most + * recent first). + */ + private List searchHistory(List history, String searchTerm) { + String lowerSearch = searchTerm.toLowerCase(); + + // Search in reverse order (most recent first) + return history.stream() + .filter(cmd -> cmd.toLowerCase().contains(lowerSearch)) + .collect(Collectors.collectingAndThen(Collectors.toList(), list -> { + java.util.Collections.reverse(list); + return list; + })); + } - if (matches.isEmpty()) { - System.out.println("No matches found for: '" + searchTerm + "'"); - System.out.println(); - continue; - } - - // Display matches with numbers - System.out.println("\nMatches for '" + searchTerm + "':"); - for (int i = 0; i < Math.min(matches.size(), 10); i++) { - System.out.println(" " + (i + 1) + ". " + matches.get(i)); - } - - if (matches.size() > 10) { - System.out.println(" ... and " + (matches.size() - 10) + " more"); - } - - // Ask user to select or refine - System.out.println(); - System.out.print( - "Select number to copy (1-" - + Math.min(matches.size(), 10) - + "), or press Enter to search again: "); - String selection = scanner.nextLine().trim(); - - if (selection.isEmpty()) { - continue; - } - - try { - int index = Integer.parseInt(selection) - 1; - if (index >= 0 && index < Math.min(matches.size(), 10)) { - String selectedCommand = matches.get(index); - System.out.println("\nSelected command: " + selectedCommand); - System.out.println("(You can now run this command by typing it at the prompt)"); - break; - } else { - System.out.println("Invalid selection. Try again."); - } - } catch (NumberFormatException e) { - System.out.println("Invalid input. Enter a number or press Enter."); - } + @Override + public String description() { + return "Interactive history search (like Ctrl+R)"; + } - System.out.println(); + @Override + public String usage() { + return "isearch\n" + + " Opens an interactive prompt to search command history.\n" + + " Type your search term and select from matching commands."; } - } - - /** - * Search history for commands containing the search term. Returns matches in reverse order (most - * recent first). - */ - private List searchHistory(List history, String searchTerm) { - String lowerSearch = searchTerm.toLowerCase(); - - // Search in reverse order (most recent first) - return history.stream() - .filter(cmd -> cmd.toLowerCase().contains(lowerSearch)) - .collect( - Collectors.collectingAndThen( - Collectors.toList(), - list -> { - java.util.Collections.reverse(list); - return list; - })); - } - - @Override - public String description() { - return "Interactive history search (like Ctrl+R)"; - } - - @Override - public String usage() { - return "isearch\n" - + " Opens an interactive prompt to search command history.\n" - + " Type your search term and select from matching commands."; - } } diff --git a/src/main/java/com/mycmd/commands/IpConfig.java b/src/main/java/com/mycmd/commands/IpConfig.java index 272c82d..09d9f50 100644 --- a/src/main/java/com/mycmd/commands/IpConfig.java +++ b/src/main/java/com/mycmd/commands/IpConfig.java @@ -11,34 +11,34 @@ /** Implements the "ipconfig" command for MyCMD. */ public class IpConfig implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - try { - Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); - while (interfaces.hasMoreElements()) { - NetworkInterface ni = interfaces.nextElement(); - System.out.println("Interface: " + ni.getDisplayName()); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + try { + Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); + while (interfaces.hasMoreElements()) { + NetworkInterface ni = interfaces.nextElement(); + System.out.println("Interface: " + ni.getDisplayName()); - Enumeration addresses = ni.getInetAddresses(); - while (addresses.hasMoreElements()) { - InetAddress addr = addresses.nextElement(); - System.out.println(" IP Address: " + addr.getHostAddress()); - } + Enumeration addresses = ni.getInetAddresses(); + while (addresses.hasMoreElements()) { + InetAddress addr = addresses.nextElement(); + System.out.println(" IP Address: " + addr.getHostAddress()); + } - System.out.println(); // blank line between interfaces - } - } catch (SocketException e) { - throw new IOException("Failed to get network interfaces", e); + System.out.println(); // blank line between interfaces + } + } catch (SocketException e) { + throw new IOException("Failed to get network interfaces", e); + } } - } - @Override - public String description() { - return "Displays all network interfaces and their IP addresses"; - } + @Override + public String description() { + return "Displays all network interfaces and their IP addresses"; + } - @Override - public String usage() { - return "ipconfig"; - } + @Override + public String usage() { + return "ipconfig"; + } } diff --git a/src/main/java/com/mycmd/commands/LabelCommand.java b/src/main/java/com/mycmd/commands/LabelCommand.java index 8507a66..3391e54 100644 --- a/src/main/java/com/mycmd/commands/LabelCommand.java +++ b/src/main/java/com/mycmd/commands/LabelCommand.java @@ -12,31 +12,31 @@ */ public class LabelCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - System.out.println("LABEL - Creates, changes, or deletes the volume label of a disk."); - System.out.println("\nNote: This is a read-only simulation."); - System.out.println("Actual volume label modification requires system-level permissions."); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + System.out.println("LABEL - Creates, changes, or deletes the volume label of a disk."); + System.out.println("\nNote: This is a read-only simulation."); + System.out.println("Actual volume label modification requires system-level permissions."); - if (args.length == 0) { - // Show current drive label - String currentPath = context.getCurrentDir().getAbsolutePath(); - String driveLetter = currentPath.substring(0, Math.min(2, currentPath.length())); - System.out.println("\nVolume in drive " + driveLetter + " has no label."); - System.out.println("Volume label (11 characters, ENTER for none)? "); - } else { - System.out.println("\nSpecified drive: " + args[0]); - System.out.println("Volume label change requires administrator privileges."); + if (args.length == 0) { + // Show current drive label + String currentPath = context.getCurrentDir().getAbsolutePath(); + String driveLetter = currentPath.substring(0, Math.min(2, currentPath.length())); + System.out.println("\nVolume in drive " + driveLetter + " has no label."); + System.out.println("Volume label (11 characters, ENTER for none)? "); + } else { + System.out.println("\nSpecified drive: " + args[0]); + System.out.println("Volume label change requires administrator privileges."); + } } - } - @Override - public String description() { - return "Creates, changes, or deletes the volume label of a disk."; - } + @Override + public String description() { + return "Creates, changes, or deletes the volume label of a disk."; + } - @Override - public String usage() { - return "label [drive:][label]"; - } + @Override + public String usage() { + return "label [drive:][label]"; + } } diff --git a/src/main/java/com/mycmd/commands/LsCommand.java b/src/main/java/com/mycmd/commands/LsCommand.java index bfca1e7..e8605f9 100644 --- a/src/main/java/com/mycmd/commands/LsCommand.java +++ b/src/main/java/com/mycmd/commands/LsCommand.java @@ -8,28 +8,28 @@ /** LsCommand - lists files and directories in the shell's current directory. */ public class LsCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - Path dir = context.getCurrentDir().toPath(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + Path dir = context.getCurrentDir().toPath(); - try (DirectoryStream stream = Files.newDirectoryStream(dir)) { - for (Path path : stream) { - if (Files.isDirectory(path)) { - System.out.println("[DIR] " + path.getFileName()); - } else { - System.out.println(" " + path.getFileName()); + try (DirectoryStream stream = Files.newDirectoryStream(dir)) { + for (Path path : stream) { + if (Files.isDirectory(path)) { + System.out.println("[DIR] " + path.getFileName()); + } else { + System.out.println(" " + path.getFileName()); + } + } } - } } - } - @Override - public String description() { - return "List files and directories in the current directory."; - } + @Override + public String description() { + return "List files and directories in the current directory."; + } - @Override - public String usage() { - return "ls"; - } + @Override + public String usage() { + return "ls"; + } } diff --git a/src/main/java/com/mycmd/commands/MkdirCommand.java b/src/main/java/com/mycmd/commands/MkdirCommand.java index 3b98198..1530ea7 100644 --- a/src/main/java/com/mycmd/commands/MkdirCommand.java +++ b/src/main/java/com/mycmd/commands/MkdirCommand.java @@ -16,29 +16,29 @@ * appropriate feedback for success or failure conditions. */ public class MkdirCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - if (args.length == 0) { - System.out.println("Usage: " + usage()); - return; + @Override + public void execute(String[] args, ShellContext context) { + if (args.length == 0) { + System.out.println("Usage: " + usage()); + return; + } + File dir = new File(context.getCurrentDir(), args[0]); + if (dir.exists()) { + System.out.println("Directory already exists."); + } else if (dir.mkdirs()) { + System.out.println("Directory created."); + } else { + System.out.println("Failed to create directory."); + } } - File dir = new File(context.getCurrentDir(), args[0]); - if (dir.exists()) { - System.out.println("Directory already exists."); - } else if (dir.mkdirs()) { - System.out.println("Directory created."); - } else { - System.out.println("Failed to create directory."); - } - } - @Override - public String description() { - return "Create a new directory."; - } + @Override + public String description() { + return "Create a new directory."; + } - @Override - public String usage() { - return "mkdir "; - } + @Override + public String usage() { + return "mkdir "; + } } diff --git a/src/main/java/com/mycmd/commands/MoreCommand.java b/src/main/java/com/mycmd/commands/MoreCommand.java index 895264f..e4bde80 100644 --- a/src/main/java/com/mycmd/commands/MoreCommand.java +++ b/src/main/java/com/mycmd/commands/MoreCommand.java @@ -14,62 +14,62 @@ */ public class MoreCommand implements Command { - private static final int LINES_PER_PAGE = 20; + private static final int LINES_PER_PAGE = 20; - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("Displays output one screen at a time."); - System.out.println("\nMORE [/E [/C] [/P] [/S] [/Tn] [+n]] < [drive:][path]filename"); - System.out.println("command-name | MORE [/E [/C] [/P] [/S] [/Tn] [+n]]"); - System.out.println("\nExample: more filename.txt"); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("Displays output one screen at a time."); + System.out.println("\nMORE [/E [/C] [/P] [/S] [/Tn] [+n]] < [drive:][path]filename"); + System.out.println("command-name | MORE [/E [/C] [/P] [/S] [/Tn] [+n]]"); + System.out.println("\nExample: more filename.txt"); + return; + } - String filename = args[0]; - java.io.File file = new java.io.File(filename); + String filename = args[0]; + java.io.File file = new java.io.File(filename); - if (!file.isAbsolute()) { - file = new java.io.File(context.getCurrentDir(), filename); - } + if (!file.isAbsolute()) { + file = new java.io.File(context.getCurrentDir(), filename); + } - if (!file.exists()) { - System.out.println("Cannot access " + filename); - return; - } + if (!file.exists()) { + System.out.println("Cannot access " + filename); + return; + } - if (!file.isFile()) { - System.out.println(filename + " is not a file."); - return; - } + if (!file.isFile()) { + System.out.println(filename + " is not a file."); + return; + } - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { - String line; - int lineCount = 0; + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + int lineCount = 0; - while ((line = reader.readLine()) != null) { - System.out.println(line); - lineCount++; + while ((line = reader.readLine()) != null) { + System.out.println(line); + lineCount++; - if (lineCount % LINES_PER_PAGE == 0) { - System.out.print("-- More -- "); - System.in.read(); // Wait for user input - // Clear the input buffer - while (System.in.available() > 0) { - System.in.read(); - } + if (lineCount % LINES_PER_PAGE == 0) { + System.out.print("-- More -- "); + System.in.read(); // Wait for user input + // Clear the input buffer + while (System.in.available() > 0) { + System.in.read(); + } + } + } } - } } - } - @Override - public String description() { - return "Displays output one screen at a time."; - } + @Override + public String description() { + return "Displays output one screen at a time."; + } - @Override - public String usage() { - return "more [filename]"; - } + @Override + public String usage() { + return "more [filename]"; + } } diff --git a/src/main/java/com/mycmd/commands/MoveCommand.java b/src/main/java/com/mycmd/commands/MoveCommand.java index 3ab207e..eafb054 100644 --- a/src/main/java/com/mycmd/commands/MoveCommand.java +++ b/src/main/java/com/mycmd/commands/MoveCommand.java @@ -20,36 +20,36 @@ */ public class MoveCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length < 2) { - System.out.println("Usage: " + usage()); - return; + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length < 2) { + System.out.println("Usage: " + usage()); + return; + } + + Path source = context.resolvePath(args[0]).toPath(); + Path destination = context.resolvePath(args[1]).toPath(); + + if (!Files.exists(source)) { + System.out.println("The system cannot find the file specified."); + return; + } + + try { + Files.move(source, destination, StandardCopyOption.REPLACE_EXISTING); + System.out.println("Moved: " + source.getFileName() + " -> " + destination); + } catch (IOException e) { + System.out.println("Error moving file: " + e.getMessage()); + } } - Path source = context.resolvePath(args[0]).toPath(); - Path destination = context.resolvePath(args[1]).toPath(); - - if (!Files.exists(source)) { - System.out.println("The system cannot find the file specified."); - return; + @Override + public String description() { + return "Move or rename files and directories"; } - try { - Files.move(source, destination, StandardCopyOption.REPLACE_EXISTING); - System.out.println("Moved: " + source.getFileName() + " -> " + destination); - } catch (IOException e) { - System.out.println("Error moving file: " + e.getMessage()); + @Override + public String usage() { + return "move "; } - } - - @Override - public String description() { - return "Move or rename files and directories"; - } - - @Override - public String usage() { - return "move "; - } } diff --git a/src/main/java/com/mycmd/commands/MsgCommand.java b/src/main/java/com/mycmd/commands/MsgCommand.java index 353e8c3..796bb7b 100644 --- a/src/main/java/com/mycmd/commands/MsgCommand.java +++ b/src/main/java/com/mycmd/commands/MsgCommand.java @@ -11,76 +11,74 @@ */ public class MsgCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length < 2) { - System.out.println("Send a message to a user."); - System.out.println("\nMSG {username | sessionname | sessionid | @filename | *}"); - System.out.println(" [/SERVER:servername] [/TIME:seconds] [/V] [/W] [message]"); - System.out.println("\n username Identifies the specified username."); - System.out.println(" sessionname The name of the session."); - System.out.println(" sessionid The ID of the session."); - System.out.println(" @filename Identifies a file containing a list of usernames."); - System.out.println( - " * Sends message to all sessions on specified server."); - System.out.println(" /SERVER:servername Server to contact (default is current)."); - System.out.println(" /TIME:seconds Time to wait for receiver to acknowledge msg."); - System.out.println( - " /V Display information about actions being performed."); - System.out.println(" /W Wait for response from user, useful with /V."); - System.out.println(" message Message to send."); - return; - } - - String os = System.getProperty("os.name").toLowerCase(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length < 2) { + System.out.println("Send a message to a user."); + System.out.println("\nMSG {username | sessionname | sessionid | @filename | *}"); + System.out.println(" [/SERVER:servername] [/TIME:seconds] [/V] [/W] [message]"); + System.out.println("\n username Identifies the specified username."); + System.out.println(" sessionname The name of the session."); + System.out.println(" sessionid The ID of the session."); + System.out.println(" @filename Identifies a file containing a list of usernames."); + System.out.println(" * Sends message to all sessions on specified server."); + System.out.println(" /SERVER:servername Server to contact (default is current)."); + System.out.println(" /TIME:seconds Time to wait for receiver to acknowledge msg."); + System.out.println(" /V Display information about actions being performed."); + System.out.println(" /W Wait for response from user, useful with /V."); + System.out.println(" message Message to send."); + return; + } - if (!os.contains("win")) { - System.out.println("MSG command is primarily for Windows systems."); - System.out.println("On Unix-like systems, use 'write' or 'wall' instead."); - return; - } + String os = System.getProperty("os.name").toLowerCase(); - try { - StringBuilder cmdBuilder = new StringBuilder("msg"); - for (String arg : args) { - if (arg.contains(" ")) { - cmdBuilder.append(" \"").append(arg).append("\""); - } else { - cmdBuilder.append(" ").append(arg); + if (!os.contains("win")) { + System.out.println("MSG command is primarily for Windows systems."); + System.out.println("On Unix-like systems, use 'write' or 'wall' instead."); + return; } - } - ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); - Process process = pb.start(); + try { + StringBuilder cmdBuilder = new StringBuilder("msg"); + for (String arg : args) { + if (arg.contains(" ")) { + cmdBuilder.append(" \"").append(arg).append("\""); + } else { + cmdBuilder.append(" ").append(arg); + } + } - java.io.BufferedReader reader = - new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream())); - java.io.BufferedReader errorReader = - new java.io.BufferedReader(new java.io.InputStreamReader(process.getErrorStream())); + ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); + Process process = pb.start(); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + java.io.BufferedReader reader = + new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream())); + java.io.BufferedReader errorReader = + new java.io.BufferedReader(new java.io.InputStreamReader(process.getErrorStream())); - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - process.waitFor(); + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - } catch (Exception e) { - System.out.println("Error executing msg: " + e.getMessage()); + process.waitFor(); + + } catch (Exception e) { + System.out.println("Error executing msg: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Sends a message to a user."; - } + @Override + public String description() { + return "Sends a message to a user."; + } - @Override - public String usage() { - return "msg username [message]"; - } + @Override + public String usage() { + return "msg username [message]"; + } } diff --git a/src/main/java/com/mycmd/commands/NetCommand.java b/src/main/java/com/mycmd/commands/NetCommand.java index 17386fc..43b980a 100644 --- a/src/main/java/com/mycmd/commands/NetCommand.java +++ b/src/main/java/com/mycmd/commands/NetCommand.java @@ -12,72 +12,72 @@ */ public class NetCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("The syntax of this command is:"); - System.out.println("\nNET"); - System.out.println(" [ ACCOUNTS | COMPUTER | CONFIG | CONTINUE | FILE | GROUP | HELP |"); - System.out.println(" HELPMSG | LOCALGROUP | PAUSE | SESSION | SHARE | START |"); - System.out.println(" STATISTICS | STOP | TIME | USE | USER | VIEW ]"); - System.out.println("\nCommon commands:"); - System.out.println(" NET USER - Displays user account information"); - System.out.println(" NET USE - Connects/disconnects network resources"); - System.out.println(" NET START - Lists or starts network services"); - System.out.println(" NET STOP - Stops network services"); - System.out.println(" NET SHARE - Displays shared resources"); - System.out.println(" NET SESSION - Lists or disconnects sessions"); - System.out.println("\nNote: Most NET commands require administrator privileges."); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("The syntax of this command is:"); + System.out.println("\nNET"); + System.out.println(" [ ACCOUNTS | COMPUTER | CONFIG | CONTINUE | FILE | GROUP | HELP |"); + System.out.println(" HELPMSG | LOCALGROUP | PAUSE | SESSION | SHARE | START |"); + System.out.println(" STATISTICS | STOP | TIME | USE | USER | VIEW ]"); + System.out.println("\nCommon commands:"); + System.out.println(" NET USER - Displays user account information"); + System.out.println(" NET USE - Connects/disconnects network resources"); + System.out.println(" NET START - Lists or starts network services"); + System.out.println(" NET STOP - Stops network services"); + System.out.println(" NET SHARE - Displays shared resources"); + System.out.println(" NET SESSION - Lists or disconnects sessions"); + System.out.println("\nNote: Most NET commands require administrator privileges."); + return; + } - String subCommand = args[0].toLowerCase(); + String subCommand = args[0].toLowerCase(); - try { - StringBuilder cmdBuilder = new StringBuilder("net ").append(subCommand); - for (int i = 1; i < args.length; i++) { - cmdBuilder.append(" ").append(args[i]); - } + try { + StringBuilder cmdBuilder = new StringBuilder("net ").append(subCommand); + for (int i = 1; i < args.length; i++) { + cmdBuilder.append(" ").append(args[i]); + } - ProcessBuilder pb = new ProcessBuilder(); - String os = System.getProperty("os.name").toLowerCase(); + ProcessBuilder pb = new ProcessBuilder(); + String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - pb.command("cmd.exe", "/c", cmdBuilder.toString()); - } else { - System.out.println("NET command is primarily for Windows systems."); - return; - } + if (os.contains("win")) { + pb.command("cmd.exe", "/c", cmdBuilder.toString()); + } else { + System.out.println("NET command is primarily for Windows systems."); + return; + } - Process process = pb.start(); - java.io.BufferedReader reader = - new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream())); - java.io.BufferedReader errorReader = - new java.io.BufferedReader(new java.io.InputStreamReader(process.getErrorStream())); + Process process = pb.start(); + java.io.BufferedReader reader = + new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream())); + java.io.BufferedReader errorReader = + new java.io.BufferedReader(new java.io.InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing net command: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error executing net command: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Network command - manages network resources and connections."; - } + @Override + public String description() { + return "Network command - manages network resources and connections."; + } - @Override - public String usage() { - return "net [user | use | start | stop | share | session] [options]"; - } + @Override + public String usage() { + return "net [user | use | start | stop | share | session] [options]"; + } } diff --git a/src/main/java/com/mycmd/commands/NetshCommand.java b/src/main/java/com/mycmd/commands/NetshCommand.java index b1436f8..2ee34f2 100644 --- a/src/main/java/com/mycmd/commands/NetshCommand.java +++ b/src/main/java/com/mycmd/commands/NetshCommand.java @@ -14,63 +14,62 @@ */ public class NetshCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - String os = System.getProperty("os.name").toLowerCase(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + String os = System.getProperty("os.name").toLowerCase(); - if (!os.contains("win")) { - System.out.println("NETSH is only available on Windows systems."); - return; - } + if (!os.contains("win")) { + System.out.println("NETSH is only available on Windows systems."); + return; + } - if (args.length == 0) { - System.out.println("Network Shell - command-line scripting utility."); - System.out.println("\nCommon commands:"); - System.out.println(" netsh interface show interface"); - System.out.println(" netsh interface ip show config"); - System.out.println(" netsh wlan show profiles"); - System.out.println(" netsh wlan show networks"); - System.out.println(" netsh firewall show state"); - System.out.println("\nNote: Some commands require administrator privileges."); - return; - } + if (args.length == 0) { + System.out.println("Network Shell - command-line scripting utility."); + System.out.println("\nCommon commands:"); + System.out.println(" netsh interface show interface"); + System.out.println(" netsh interface ip show config"); + System.out.println(" netsh wlan show profiles"); + System.out.println(" netsh wlan show networks"); + System.out.println(" netsh firewall show state"); + System.out.println("\nNote: Some commands require administrator privileges."); + return; + } - try { - StringBuilder cmdBuilder = new StringBuilder("netsh"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + try { + StringBuilder cmdBuilder = new StringBuilder("netsh"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); - Process process = pb.start(); + ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); + Process process = pb.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing netsh: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error executing netsh: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Network Shell - command-line scripting utility for network components."; - } + @Override + public String description() { + return "Network Shell - command-line scripting utility for network components."; + } - @Override - public String usage() { - return "netsh [context] [command]"; - } + @Override + public String usage() { + return "netsh [context] [command]"; + } } diff --git a/src/main/java/com/mycmd/commands/NetstatCommand.java b/src/main/java/com/mycmd/commands/NetstatCommand.java index afdc90c..7abb166 100644 --- a/src/main/java/com/mycmd/commands/NetstatCommand.java +++ b/src/main/java/com/mycmd/commands/NetstatCommand.java @@ -14,45 +14,45 @@ */ public class NetstatCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - try { - StringBuilder cmdBuilder = new StringBuilder("netstat"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } - - ProcessBuilder pb = new ProcessBuilder(); - String os = System.getProperty("os.name").toLowerCase(); - - if (os.contains("win")) { - pb.command("cmd.exe", "/c", cmdBuilder.toString()); - } else { - pb.command("sh", "-c", cmdBuilder.toString()); - } - - 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(); - - } catch (Exception e) { - System.out.println("Error executing netstat: " + e.getMessage()); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + try { + StringBuilder cmdBuilder = new StringBuilder("netstat"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } + + ProcessBuilder pb = new ProcessBuilder(); + String os = System.getProperty("os.name").toLowerCase(); + + if (os.contains("win")) { + pb.command("cmd.exe", "/c", cmdBuilder.toString()); + } else { + pb.command("sh", "-c", cmdBuilder.toString()); + } + + 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(); + + } catch (Exception e) { + System.out.println("Error executing netstat: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Displays active TCP connections and listening ports."; - } + @Override + public String description() { + return "Displays active TCP connections and listening ports."; + } - @Override - public String usage() { - return "netstat [-a] [-n] [-o] [-p protocol]"; - } + @Override + public String usage() { + return "netstat [-a] [-n] [-o] [-p protocol]"; + } } diff --git a/src/main/java/com/mycmd/commands/NslookupCommand.java b/src/main/java/com/mycmd/commands/NslookupCommand.java index 843fe72..626cc5c 100644 --- a/src/main/java/com/mycmd/commands/NslookupCommand.java +++ b/src/main/java/com/mycmd/commands/NslookupCommand.java @@ -13,57 +13,56 @@ */ public class NslookupCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("Usage: nslookup [hostname|IP]"); - System.out.println("\nQueries DNS to obtain domain name or IP address mapping."); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("Usage: nslookup [hostname|IP]"); + System.out.println("\nQueries DNS to obtain domain name or IP address mapping."); + return; + } - try { - StringBuilder cmdBuilder = new StringBuilder("nslookup"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + try { + StringBuilder cmdBuilder = new StringBuilder("nslookup"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - ProcessBuilder pb = new ProcessBuilder(); - String os = System.getProperty("os.name").toLowerCase(); + ProcessBuilder pb = new ProcessBuilder(); + String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - pb.command("cmd.exe", "/c", cmdBuilder.toString()); - } else { - pb.command("sh", "-c", cmdBuilder.toString()); - } + if (os.contains("win")) { + pb.command("cmd.exe", "/c", cmdBuilder.toString()); + } else { + pb.command("sh", "-c", cmdBuilder.toString()); + } - Process process = pb.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + Process process = pb.start(); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing nslookup: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error executing nslookup: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Queries DNS to obtain domain name or IP address mapping."; - } + @Override + public String description() { + return "Queries DNS to obtain domain name or IP address mapping."; + } - @Override - public String usage() { - return "nslookup [hostname|IP]"; - } + @Override + public String usage() { + return "nslookup [hostname|IP]"; + } } diff --git a/src/main/java/com/mycmd/commands/PathCommand.java b/src/main/java/com/mycmd/commands/PathCommand.java index 7e2e91c..d3aa5f2 100644 --- a/src/main/java/com/mycmd/commands/PathCommand.java +++ b/src/main/java/com/mycmd/commands/PathCommand.java @@ -11,49 +11,48 @@ */ public class PathCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - // Display current PATH - String path = context.getEnvVar("PATH"); - if (path == null) { - path = System.getenv("PATH"); - } - - if (path != null) { - if (path.isEmpty()) { - System.out.println("PATH is cleared (session only)"); - } else { - System.out.println("PATH=" + path); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + // Display current PATH + String path = context.getEnvVar("PATH"); + if (path == null) { + path = System.getenv("PATH"); + } + + if (path != null) { + if (path.isEmpty()) { + System.out.println("PATH is cleared (session only)"); + } else { + System.out.println("PATH=" + path); + } + } else { + System.out.println("No Path"); + } + return; } - } else { - System.out.println("No Path"); - } - return; - } - System.out.println("Note: Modifying PATH in MyCMD only affects the current shell session."); - System.out.println( - "To permanently modify PATH, use Windows System Properties or setx command."); + System.out.println("Note: Modifying PATH in MyCMD only affects the current shell session."); + System.out.println("To permanently modify PATH, use Windows System Properties or setx command."); - String newPath = String.join(" ", args); + String newPath = String.join(" ", args); - if (newPath.equalsIgnoreCase(";")) { - context.setEnvVar("PATH", ""); - System.out.println("PATH cleared (session only)"); - } else { - context.setEnvVar("PATH", newPath); - System.out.println("PATH set to: " + newPath + " (session only)"); + if (newPath.equalsIgnoreCase(";")) { + context.setEnvVar("PATH", ""); + System.out.println("PATH cleared (session only)"); + } else { + context.setEnvVar("PATH", newPath); + System.out.println("PATH set to: " + newPath + " (session only)"); + } } - } - @Override - public String description() { - return "Displays or sets the command path."; - } + @Override + public String description() { + return "Displays or sets the command path."; + } - @Override - public String usage() { - return "path [path]"; - } + @Override + public String usage() { + return "path [path]"; + } } diff --git a/src/main/java/com/mycmd/commands/PauseCommand.java b/src/main/java/com/mycmd/commands/PauseCommand.java index 03ba65a..48c477d 100644 --- a/src/main/java/com/mycmd/commands/PauseCommand.java +++ b/src/main/java/com/mycmd/commands/PauseCommand.java @@ -4,33 +4,33 @@ import com.mycmd.ShellContext; public class PauseCommand implements Command { - /** - * Execute the pause command. - * - *

Prints "Press Enter to continue..." and waits for the user to press Enter before continuing. - * - *

If an exception occurs during the pause, it is ignored. - * - * @param args The arguments to the command. - * @param context The context of the shell. - */ - @Override - public void execute(String[] args, ShellContext context) { - System.out.println("Press Enter to continue..."); - try { - System.in.read(); - } catch (Exception e) { - // Ignore exceptions during pause + /** + * Execute the pause command. + * + *

Prints "Press Enter to continue..." and waits for the user to press Enter before continuing. + * + *

If an exception occurs during the pause, it is ignored. + * + * @param args The arguments to the command. + * @param context The context of the shell. + */ + @Override + public void execute(String[] args, ShellContext context) { + System.out.println("Press Enter to continue..."); + try { + System.in.read(); + } catch (Exception e) { + // Ignore exceptions during pause + } } - } - @Override - public String description() { - return "Pause execution until user presses Enter."; - } + @Override + public String description() { + return "Pause execution until user presses Enter."; + } - @Override - public String usage() { - return "pause"; - } + @Override + public String usage() { + return "pause"; + } } diff --git a/src/main/java/com/mycmd/commands/PingCommand.java b/src/main/java/com/mycmd/commands/PingCommand.java index 5a13a14..48730b6 100644 --- a/src/main/java/com/mycmd/commands/PingCommand.java +++ b/src/main/java/com/mycmd/commands/PingCommand.java @@ -52,378 +52,369 @@ */ public class PingCommand implements Command { - private static final Pattern TIME_PATTERN_WINDOWS = - Pattern.compile("time[=<]\\s*(\\d+)\\s*ms", Pattern.CASE_INSENSITIVE); - private static final Pattern TIME_PATTERN_UNIX = - Pattern.compile("time=(\\d+\\.?\\d*)\\s*ms", Pattern.CASE_INSENSITIVE); - - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - displayHelp(); - return; - } + private static final Pattern TIME_PATTERN_WINDOWS = + Pattern.compile("time[=<]\\s*(\\d+)\\s*ms", Pattern.CASE_INSENSITIVE); + private static final Pattern TIME_PATTERN_UNIX = + Pattern.compile("time=(\\d+\\.?\\d*)\\s*ms", Pattern.CASE_INSENSITIVE); + + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + displayHelp(); + return; + } - int hostIndex = -1; - for (int i = 0; i < args.length; i++) { - if (!args[i].startsWith("-")) { - hostIndex = i; - break; - } - // Skip option payload when present - if ((args[i].equalsIgnoreCase("-n") - || args[i].equalsIgnoreCase("-c") - || args[i].equalsIgnoreCase("-w") - || args[i].equalsIgnoreCase("-l") - || args[i].equalsIgnoreCase("-i")) - && i + 1 < args.length) { - i++; - } - } - if (hostIndex == -1) { - System.out.println("Error: target host is required."); - return; - } - String host = args[hostIndex]; + int hostIndex = -1; + for (int i = 0; i < args.length; i++) { + if (!args[i].startsWith("-")) { + hostIndex = i; + break; + } + // Skip option payload when present + if ((args[i].equalsIgnoreCase("-n") + || args[i].equalsIgnoreCase("-c") + || args[i].equalsIgnoreCase("-w") + || args[i].equalsIgnoreCase("-l") + || args[i].equalsIgnoreCase("-i")) + && i + 1 < args.length) { + i++; + } + } + if (hostIndex == -1) { + System.out.println("Error: target host is required."); + return; + } + String host = args[hostIndex]; - // Validate hostname/IP - if (!validateHost(host)) { - System.out.println( - "Ping request could not find host " + host + ". Please check the name and try again."); - return; - } + // Validate hostname/IP + if (!validateHost(host)) { + System.out.println("Ping request could not find host " + host + ". Please check the name and try again."); + return; + } - // Resolve hostname to IP - String resolvedIP = resolveHost(host); - if (resolvedIP == null) { - System.out.println( - "Ping request could not find host " + host + ". Please check the name and try again."); - return; - } + // Resolve hostname to IP + String resolvedIP = resolveHost(host); + if (resolvedIP == null) { + System.out.println("Ping request could not find host " + host + ". Please check the name and try again."); + return; + } - // Build ping command based on operating system - String[] command = buildPingCommand(host, args); + // Build ping command based on operating system + String[] command = buildPingCommand(host, args); - try { - executePing(command, host, resolvedIP); - } catch (InterruptedException e) { - System.out.println("\nPing command was interrupted."); - Thread.currentThread().interrupt(); - } - } - - /** Displays usage help for the ping command. */ - private void displayHelp() { - String os = System.getProperty("os.name").toLowerCase(); - - System.out.println("\nUsage: ping [-t] [-n count] [-l size] [-w timeout] target_name\n"); - System.out.println("Options:"); - System.out.println(" -t Ping the specified host until stopped."); - System.out.println(" To stop - press Control-C."); - System.out.println(" -n count Number of echo requests to send (default: 4)."); - - if (os.contains("win")) { - System.out.println(" -l size Send buffer size (default: 32 bytes)."); - System.out.println(" -w timeout Timeout in milliseconds to wait for each reply."); - } else { - System.out.println(" -c count Number of echo requests to send (Unix-style)."); - System.out.println(" -i interval Wait interval seconds between sending each packet."); + try { + executePing(command, host, resolvedIP); + } catch (InterruptedException e) { + System.out.println("\nPing command was interrupted."); + Thread.currentThread().interrupt(); + } } - System.out.println("\nExamples:"); - System.out.println(" ping google.com"); - System.out.println(" ping 8.8.8.8"); - System.out.println(" ping google.com -n 10"); - System.out.println(" ping 1.1.1.1 -t"); - } - - /** Validates if the host string is a valid hostname or IP address format. */ - private boolean validateHost(String host) { - if (host == null || host.trim().isEmpty()) { - return false; - } + /** Displays usage help for the ping command. */ + private void displayHelp() { + String os = System.getProperty("os.name").toLowerCase(); + + System.out.println("\nUsage: ping [-t] [-n count] [-l size] [-w timeout] target_name\n"); + System.out.println("Options:"); + System.out.println(" -t Ping the specified host until stopped."); + System.out.println(" To stop - press Control-C."); + System.out.println(" -n count Number of echo requests to send (default: 4)."); + + if (os.contains("win")) { + System.out.println(" -l size Send buffer size (default: 32 bytes)."); + System.out.println(" -w timeout Timeout in milliseconds to wait for each reply."); + } else { + System.out.println(" -c count Number of echo requests to send (Unix-style)."); + System.out.println(" -i interval Wait interval seconds between sending each packet."); + } - // Basic validation - allow alphanumeric, dots, hyphens for hostnames - // More complex validation will happen during resolution - return host.matches("^[a-zA-Z0-9._:-]+$"); - } - - /** Resolves hostname to IP address. */ - private String resolveHost(String host) { - try { - InetAddress address = InetAddress.getByName(host); - return address.getHostAddress(); - } catch (UnknownHostException e) { - return null; + System.out.println("\nExamples:"); + System.out.println(" ping google.com"); + System.out.println(" ping 8.8.8.8"); + System.out.println(" ping google.com -n 10"); + System.out.println(" ping 1.1.1.1 -t"); } - } - /** Executes the ping command and displays results with statistics. */ - private void executePing(String[] command, String host, String resolvedIP) - throws IOException, InterruptedException { + /** Validates if the host string is a valid hostname or IP address format. */ + private boolean validateHost(String host) { + if (host == null || host.trim().isEmpty()) { + return false; + } - String os = System.getProperty("os.name").toLowerCase(); + // Basic validation - allow alphanumeric, dots, hyphens for hostnames + // More complex validation will happen during resolution + return host.matches("^[a-zA-Z0-9._:-]+$"); + } - // Display initial message - System.out.println("\nPinging " + host + " [" + resolvedIP + "] with 32 bytes of data:"); + /** Resolves hostname to IP address. */ + private String resolveHost(String host) { + try { + InetAddress address = InetAddress.getByName(host); + return address.getHostAddress(); + } catch (UnknownHostException e) { + return null; + } + } - ProcessBuilder pb = new ProcessBuilder(command); - Process process = pb.start(); + /** Executes the ping command and displays results with statistics. */ + private void executePing(String[] command, String host, String resolvedIP) + throws IOException, InterruptedException { - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + String os = System.getProperty("os.name").toLowerCase(); - // Statistics tracking - PingStatistics stats = new PingStatistics(); + // Display initial message + System.out.println("\nPinging " + host + " [" + resolvedIP + "] with 32 bytes of data:"); - String line; - boolean statsSection = false; + ProcessBuilder pb = new ProcessBuilder(command); + Process process = pb.start(); - // Read and display output in real-time - while ((line = reader.readLine()) != null) { - System.out.println(line); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - // Parse statistics from output - if (line.contains("Packets: Sent") || line.contains("packets transmitted")) { - statsSection = true; - } + // Statistics tracking + PingStatistics stats = new PingStatistics(); - // Extract time values for custom statistics - if (!statsSection) { - extractTimeFromLine(line, stats, os); - } - } + String line; + boolean statsSection = false; - // Display error output if any - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + // Read and display output in real-time + while ((line = reader.readLine()) != null) { + System.out.println(line); - int exitCode = process.waitFor(); + // Parse statistics from output + if (line.contains("Packets: Sent") || line.contains("packets transmitted")) { + statsSection = true; + } - // If statistics weren't displayed by the native command, show custom stats - if (!statsSection && stats.received > 0) { - displayCustomStatistics(stats, resolvedIP); - } + // Extract time values for custom statistics + if (!statsSection) { + extractTimeFromLine(line, stats, os); + } + } - if (exitCode != 0 && stats.received == 0) { - System.out.println("\nPing command failed. Host may be unreachable."); - } - } - - /** Extracts time values from ping output lines for statistics. */ - private void extractTimeFromLine(String line, PingStatistics stats, String os) { - Pattern pattern = os.contains("win") ? TIME_PATTERN_WINDOWS : TIME_PATTERN_UNIX; - Matcher matcher = pattern.matcher(line); - - if (matcher.find()) { - try { - double time = Double.parseDouble(matcher.group(1)); - stats.addTime(time); - } catch (NumberFormatException e) { - // Ignore parsing errors - } - } + // Display error output if any + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - // Count sent/received packets - if (line.toLowerCase().contains("reply from") || line.toLowerCase().contains("bytes from")) { - stats.received++; - stats.sent++; - } else if (line.toLowerCase().contains("request timed out") - || line.toLowerCase().contains("destination host unreachable")) { - stats.sent++; - stats.lost++; - } - } - - /** Displays custom ping statistics when native command doesn't provide them. */ - private void displayCustomStatistics(PingStatistics stats, String ip) { - System.out.println("\nPing statistics for " + ip + ":"); - System.out.println( - " Packets: Sent = " - + stats.sent - + ", Received = " - + stats.received - + ", Lost = " - + stats.lost - + " (" - + stats.getLossPercentage() - + "% loss),"); - - if (stats.received > 0) { - System.out.println("Approximate round trip times in milli-seconds:"); - System.out.println( - " Minimum = " - + String.format("%.0f", stats.minTime) - + "ms" - + ", Maximum = " - + String.format("%.0f", stats.maxTime) - + "ms" - + ", Average = " - + String.format("%.0f", stats.getAverageTime()) - + "ms"); - } - } + int exitCode = process.waitFor(); - /** Builds the appropriate ping command based on the operating system and arguments. */ - private String[] buildPingCommand(String host, String[] args) { - String os = System.getProperty("os.name").toLowerCase(); + // If statistics weren't displayed by the native command, show custom stats + if (!statsSection && stats.received > 0) { + displayCustomStatistics(stats, resolvedIP); + } - if (os.contains("win")) { - return buildWindowsPingCommand(host, args); - } else { - return buildUnixPingCommand(host, args); + if (exitCode != 0 && stats.received == 0) { + System.out.println("\nPing command failed. Host may be unreachable."); + } } - } - - /** Builds ping command for Windows systems. */ - private String[] buildWindowsPingCommand(String host, String[] args) { - List command = new ArrayList<>(); - command.add("ping"); - - boolean continuous = false; - Integer count = null; - Integer timeout = null; - Integer bufferSize = null; - - // Parse arguments - for (int i = 1; i < args.length; i++) { - String arg = args[i].toLowerCase(); - if ("-t".equals(arg)) { - continuous = true; - } else if (("-n".equals(arg) || "-c".equals(arg)) && i + 1 < args.length) { - try { - count = Integer.parseInt(args[i + 1]); - i++; // Skip next argument - } catch (NumberFormatException e) { - System.out.println( - "Warning: Invalid count value '" + args[i + 1] + "', using default (4)"); - } - } else if ("-w".equals(arg) && i + 1 < args.length) { - try { - timeout = Integer.parseInt(args[i + 1]); - i++; // Skip next argument - } catch (NumberFormatException e) { - System.out.println("Warning: Invalid timeout value '" + args[i + 1] + "', using default"); + /** Extracts time values from ping output lines for statistics. */ + private void extractTimeFromLine(String line, PingStatistics stats, String os) { + Pattern pattern = os.contains("win") ? TIME_PATTERN_WINDOWS : TIME_PATTERN_UNIX; + Matcher matcher = pattern.matcher(line); + + if (matcher.find()) { + try { + double time = Double.parseDouble(matcher.group(1)); + stats.addTime(time); + } catch (NumberFormatException e) { + // Ignore parsing errors + } } - } else if ("-l".equals(arg) && i + 1 < args.length) { - try { - bufferSize = Integer.parseInt(args[i + 1]); - i++; // Skip next argument - } catch (NumberFormatException e) { - System.out.println( - "Warning: Invalid buffer size '" + args[i + 1] + "', using default (32)"); + + // Count sent/received packets + if (line.toLowerCase().contains("reply from") || line.toLowerCase().contains("bytes from")) { + stats.received++; + stats.sent++; + } else if (line.toLowerCase().contains("request timed out") + || line.toLowerCase().contains("destination host unreachable")) { + stats.sent++; + stats.lost++; } - } } - // Add options to command - if (continuous) { - command.add("-t"); - } else if (count != null && count > 0) { - command.add("-n"); - command.add(String.valueOf(count)); - } else { - command.add("-n"); - command.add("4"); // Default count + /** Displays custom ping statistics when native command doesn't provide them. */ + private void displayCustomStatistics(PingStatistics stats, String ip) { + System.out.println("\nPing statistics for " + ip + ":"); + System.out.println(" Packets: Sent = " + + stats.sent + + ", Received = " + + stats.received + + ", Lost = " + + stats.lost + + " (" + + stats.getLossPercentage() + + "% loss),"); + + if (stats.received > 0) { + System.out.println("Approximate round trip times in milli-seconds:"); + System.out.println(" Minimum = " + + String.format("%.0f", stats.minTime) + + "ms" + + ", Maximum = " + + String.format("%.0f", stats.maxTime) + + "ms" + + ", Average = " + + String.format("%.0f", stats.getAverageTime()) + + "ms"); + } } - if (timeout != null && timeout > 0) { - command.add("-w"); - command.add(String.valueOf(timeout)); - } + /** Builds the appropriate ping command based on the operating system and arguments. */ + private String[] buildPingCommand(String host, String[] args) { + String os = System.getProperty("os.name").toLowerCase(); - if (bufferSize != null && bufferSize > 0) { - command.add("-l"); - command.add(String.valueOf(bufferSize)); + if (os.contains("win")) { + return buildWindowsPingCommand(host, args); + } else { + return buildUnixPingCommand(host, args); + } } - command.add(host); - return command.toArray(new String[0]); - } + /** Builds ping command for Windows systems. */ + private String[] buildWindowsPingCommand(String host, String[] args) { + List command = new ArrayList<>(); + command.add("ping"); + + boolean continuous = false; + Integer count = null; + Integer timeout = null; + Integer bufferSize = null; + + // Parse arguments + for (int i = 1; i < args.length; i++) { + String arg = args[i].toLowerCase(); + + if ("-t".equals(arg)) { + continuous = true; + } else if (("-n".equals(arg) || "-c".equals(arg)) && i + 1 < args.length) { + try { + count = Integer.parseInt(args[i + 1]); + i++; // Skip next argument + } catch (NumberFormatException e) { + System.out.println("Warning: Invalid count value '" + args[i + 1] + "', using default (4)"); + } + } else if ("-w".equals(arg) && i + 1 < args.length) { + try { + timeout = Integer.parseInt(args[i + 1]); + i++; // Skip next argument + } catch (NumberFormatException e) { + System.out.println("Warning: Invalid timeout value '" + args[i + 1] + "', using default"); + } + } else if ("-l".equals(arg) && i + 1 < args.length) { + try { + bufferSize = Integer.parseInt(args[i + 1]); + i++; // Skip next argument + } catch (NumberFormatException e) { + System.out.println("Warning: Invalid buffer size '" + args[i + 1] + "', using default (32)"); + } + } + } - /** Builds ping command for Unix-like systems (Linux, macOS). */ - private String[] buildUnixPingCommand(String host, String[] args) { - List command = new ArrayList<>(); - command.add("ping"); + // Add options to command + if (continuous) { + command.add("-t"); + } else if (count != null && count > 0) { + command.add("-n"); + command.add(String.valueOf(count)); + } else { + command.add("-n"); + command.add("4"); // Default count + } - boolean continuous = false; - Integer count = null; - Integer interval = null; + if (timeout != null && timeout > 0) { + command.add("-w"); + command.add(String.valueOf(timeout)); + } - // Parse arguments - for (int i = 1; i < args.length; i++) { - String arg = args[i].toLowerCase(); + if (bufferSize != null && bufferSize > 0) { + command.add("-l"); + command.add(String.valueOf(bufferSize)); + } - if ("-t".equals(arg)) { - continuous = true; - } else if (("-n".equals(arg) || "-c".equals(arg)) && i + 1 < args.length) { - try { - count = Integer.parseInt(args[i + 1]); - i++; // Skip next argument - } catch (NumberFormatException e) { - System.out.println( - "Warning: Invalid count value '" + args[i + 1] + "', using default (4)"); + command.add(host); + return command.toArray(new String[0]); + } + + /** Builds ping command for Unix-like systems (Linux, macOS). */ + private String[] buildUnixPingCommand(String host, String[] args) { + List command = new ArrayList<>(); + command.add("ping"); + + boolean continuous = false; + Integer count = null; + Integer interval = null; + + // Parse arguments + for (int i = 1; i < args.length; i++) { + String arg = args[i].toLowerCase(); + + if ("-t".equals(arg)) { + continuous = true; + } else if (("-n".equals(arg) || "-c".equals(arg)) && i + 1 < args.length) { + try { + count = Integer.parseInt(args[i + 1]); + i++; // Skip next argument + } catch (NumberFormatException e) { + System.out.println("Warning: Invalid count value '" + args[i + 1] + "', using default (4)"); + } + } else if ("-i".equals(arg) && i + 1 < args.length) { + try { + interval = Integer.parseInt(args[i + 1]); + i++; // Skip next argument + } catch (NumberFormatException e) { + System.out.println("Warning: Invalid interval value '" + args[i + 1] + "', using default"); + } + } } - } else if ("-i".equals(arg) && i + 1 < args.length) { - try { - interval = Integer.parseInt(args[i + 1]); - i++; // Skip next argument - } catch (NumberFormatException e) { - System.out.println( - "Warning: Invalid interval value '" + args[i + 1] + "', using default"); + + // Add options to command + if (!continuous) { + command.add("-c"); + command.add(count != null && count > 0 ? String.valueOf(count) : "4"); } - } - } - // Add options to command - if (!continuous) { - command.add("-c"); - command.add(count != null && count > 0 ? String.valueOf(count) : "4"); - } + if (interval != null && interval > 0) { + command.add("-i"); + command.add(String.valueOf(interval)); + } - if (interval != null && interval > 0) { - command.add("-i"); - command.add(String.valueOf(interval)); + command.add(host); + return command.toArray(new String[0]); } - command.add(host); - return command.toArray(new String[0]); - } - - @Override - public String description() { - return "Tests network connectivity to a hostname or IP address."; - } - - @Override - public String usage() { - return "ping [-t] [-n count] [-w timeout] [-l size] "; - } - - /** Helper class to track ping statistics. */ - private static class PingStatistics { - int sent = 0; - int received = 0; - int lost = 0; - double minTime = Double.MAX_VALUE; - double maxTime = 0; - double totalTime = 0; - - void addTime(double time) { - if (time < minTime) minTime = time; - if (time > maxTime) maxTime = time; - totalTime += time; + @Override + public String description() { + return "Tests network connectivity to a hostname or IP address."; } - double getAverageTime() { - return received > 0 ? totalTime / received : 0; + @Override + public String usage() { + return "ping [-t] [-n count] [-w timeout] [-l size] "; } - int getLossPercentage() { - return sent > 0 ? (lost * 100) / sent : 0; + /** Helper class to track ping statistics. */ + private static class PingStatistics { + int sent = 0; + int received = 0; + int lost = 0; + double minTime = Double.MAX_VALUE; + double maxTime = 0; + double totalTime = 0; + + void addTime(double time) { + if (time < minTime) minTime = time; + if (time > maxTime) maxTime = time; + totalTime += time; + } + + double getAverageTime() { + return received > 0 ? totalTime / received : 0; + } + + int getLossPercentage() { + return sent > 0 ? (lost * 100) / sent : 0; + } } - } } diff --git a/src/main/java/com/mycmd/commands/PwdCommand.java b/src/main/java/com/mycmd/commands/PwdCommand.java index df874b2..dc0c721 100644 --- a/src/main/java/com/mycmd/commands/PwdCommand.java +++ b/src/main/java/com/mycmd/commands/PwdCommand.java @@ -16,18 +16,18 @@ * scripts and when you need to know your exact location in the file system. */ public class PwdCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - System.out.println(context.getCurrentDir().getAbsolutePath()); - } + @Override + public void execute(String[] args, ShellContext context) { + System.out.println(context.getCurrentDir().getAbsolutePath()); + } - @Override - public String description() { - return "Print the current working directory path."; - } + @Override + public String description() { + return "Print the current working directory path."; + } - @Override - public String usage() { - return "pwd"; - } + @Override + public String usage() { + return "pwd"; + } } diff --git a/src/main/java/com/mycmd/commands/RemCommand.java b/src/main/java/com/mycmd/commands/RemCommand.java index 082442e..1281997 100644 --- a/src/main/java/com/mycmd/commands/RemCommand.java +++ b/src/main/java/com/mycmd/commands/RemCommand.java @@ -11,19 +11,19 @@ */ public class RemCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - // REM command does nothing - it's just for comments - // Silently ignore the comment - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + // REM command does nothing - it's just for comments + // Silently ignore the comment + } - @Override - public String description() { - return "Records comments (remarks) in batch files or scripts."; - } + @Override + public String description() { + return "Records comments (remarks) in batch files or scripts."; + } - @Override - public String usage() { - return "rem [comment]"; - } + @Override + public String usage() { + return "rem [comment]"; + } } diff --git a/src/main/java/com/mycmd/commands/RenameCommand.java b/src/main/java/com/mycmd/commands/RenameCommand.java index 98126a9..1a9c4f9 100644 --- a/src/main/java/com/mycmd/commands/RenameCommand.java +++ b/src/main/java/com/mycmd/commands/RenameCommand.java @@ -10,36 +10,36 @@ /** Implements the "rename" (or "ren") command for MyCMD. Usage: rename */ public class RenameCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length != 2) { - System.out.println("Usage: " + usage()); - return; + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length != 2) { + System.out.println("Usage: " + usage()); + return; + } + + File oldFile = context.resolvePath(args[0]); + File newFile = context.resolvePath(args[1]); + + if (!oldFile.exists()) { + System.out.println("The system cannot find the file specified: " + args[0]); + return; + } + + try { + Files.move(oldFile.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + System.out.println("File renamed from " + oldFile.getName() + " to " + newFile.getName()); + } catch (IOException e) { + throw new IOException("Failed to rename file: " + e.getMessage(), e); + } } - File oldFile = context.resolvePath(args[0]); - File newFile = context.resolvePath(args[1]); - - if (!oldFile.exists()) { - System.out.println("The system cannot find the file specified: " + args[0]); - return; + @Override + public String description() { + return "Renames a file or directory."; } - try { - Files.move(oldFile.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - System.out.println("File renamed from " + oldFile.getName() + " to " + newFile.getName()); - } catch (IOException e) { - throw new IOException("Failed to rename file: " + e.getMessage(), e); + @Override + public String usage() { + return "rename "; } - } - - @Override - public String description() { - return "Renames a file or directory."; - } - - @Override - public String usage() { - return "rename "; - } } diff --git a/src/main/java/com/mycmd/commands/ReplaceCommand.java b/src/main/java/com/mycmd/commands/ReplaceCommand.java index adecba4..f4e322e 100644 --- a/src/main/java/com/mycmd/commands/ReplaceCommand.java +++ b/src/main/java/com/mycmd/commands/ReplaceCommand.java @@ -11,39 +11,37 @@ */ public class ReplaceCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length < 2) { - System.out.println("Replaces files."); - System.out.println("\nREPLACE [drive1:][path1]filename [drive2:][path2] [/A] [/P] [/R] [/W]"); - System.out.println( - "REPLACE [drive1:][path1]filename [drive2:][path2] [/P] [/R] [/S] [/W] [/U]"); - System.out.println("\n [drive1:][path1]filename Specifies the source file or files."); - System.out.println(" [drive2:][path2] Specifies the directory where files"); - System.out.println(" are to be replaced."); - System.out.println(" /A Adds new files to destination directory."); - System.out.println(" /P Prompts for confirmation."); - System.out.println(" /R Replaces read-only files as well."); - System.out.println(" /S Replaces files in all subdirectories."); - System.out.println(" /W Waits for you to insert a disk."); - System.out.println(" /U Replaces only files that are older."); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length < 2) { + System.out.println("Replaces files."); + System.out.println("\nREPLACE [drive1:][path1]filename [drive2:][path2] [/A] [/P] [/R] [/W]"); + System.out.println("REPLACE [drive1:][path1]filename [drive2:][path2] [/P] [/R] [/S] [/W] [/U]"); + System.out.println("\n [drive1:][path1]filename Specifies the source file or files."); + System.out.println(" [drive2:][path2] Specifies the directory where files"); + System.out.println(" are to be replaced."); + System.out.println(" /A Adds new files to destination directory."); + System.out.println(" /P Prompts for confirmation."); + System.out.println(" /R Replaces read-only files as well."); + System.out.println(" /S Replaces files in all subdirectories."); + System.out.println(" /W Waits for you to insert a disk."); + System.out.println(" /U Replaces only files that are older."); + return; + } - System.out.println("REPLACE command simulation."); - System.out.println( - "This is a simplified version. Use COPY or XCOPY for similar functionality."); - System.out.println("Source: " + args[0]); - System.out.println("Destination: " + args[1]); - } + System.out.println("REPLACE command simulation."); + System.out.println("This is a simplified version. Use COPY or XCOPY for similar functionality."); + System.out.println("Source: " + args[0]); + System.out.println("Destination: " + args[1]); + } - @Override - public String description() { - return "Replaces files in a directory."; - } + @Override + public String description() { + return "Replaces files in a directory."; + } - @Override - public String usage() { - return "replace [source] [destination] [/A] [/P] [/R] [/S]"; - } + @Override + public String usage() { + return "replace [source] [destination] [/A] [/P] [/R] [/S]"; + } } diff --git a/src/main/java/com/mycmd/commands/RmdirCommand.java b/src/main/java/com/mycmd/commands/RmdirCommand.java index 775c860..106b636 100644 --- a/src/main/java/com/mycmd/commands/RmdirCommand.java +++ b/src/main/java/com/mycmd/commands/RmdirCommand.java @@ -17,31 +17,31 @@ * directory before deletion - Provides clear error messages for each failure condition */ public class RmdirCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - if (args.length == 0) { - System.out.println("Usage: " + usage()); - return; + @Override + public void execute(String[] args, ShellContext context) { + if (args.length == 0) { + System.out.println("Usage: " + usage()); + return; + } + File dir = new File(context.getCurrentDir(), args[0]); + if (!dir.exists() || !dir.isDirectory()) { + System.out.println("Directory not found."); + } else if (dir.list().length > 0) { + System.out.println("Directory is not empty."); + } else if (dir.delete()) { + System.out.println("Directory deleted."); + } else { + System.out.println("Failed to delete directory."); + } } - File dir = new File(context.getCurrentDir(), args[0]); - if (!dir.exists() || !dir.isDirectory()) { - System.out.println("Directory not found."); - } else if (dir.list().length > 0) { - System.out.println("Directory is not empty."); - } else if (dir.delete()) { - System.out.println("Directory deleted."); - } else { - System.out.println("Failed to delete directory."); - } - } - @Override - public String description() { - return "Remove an empty directory."; - } + @Override + public String description() { + return "Remove an empty directory."; + } - @Override - public String usage() { - return "rmdir "; - } + @Override + public String usage() { + return "rmdir "; + } } diff --git a/src/main/java/com/mycmd/commands/RobocopyCommand.java b/src/main/java/com/mycmd/commands/RobocopyCommand.java index 564261e..57e5ea7 100644 --- a/src/main/java/com/mycmd/commands/RobocopyCommand.java +++ b/src/main/java/com/mycmd/commands/RobocopyCommand.java @@ -13,65 +13,64 @@ */ public class RobocopyCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("ROBOCOPY :: Robust File Copy"); - System.out.println("\nUsage: robocopy [[ ...]] []"); - System.out.println("\nCommon Options:"); - System.out.println(" /S Copy subdirectories (excluding empty ones)"); - System.out.println(" /E Copy subdirectories (including empty ones)"); - System.out.println(" /MIR Mirror a directory tree"); - System.out.println(" /PURGE Delete dest files/dirs that no longer exist in source"); - System.out.println(" /COPYALL Copy all file info"); - System.out.println(" /R:n Number of retries on failed copies"); - System.out.println(" /W:n Wait time between retries"); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("ROBOCOPY :: Robust File Copy"); + System.out.println("\nUsage: robocopy [[ ...]] []"); + System.out.println("\nCommon Options:"); + System.out.println(" /S Copy subdirectories (excluding empty ones)"); + System.out.println(" /E Copy subdirectories (including empty ones)"); + System.out.println(" /MIR Mirror a directory tree"); + System.out.println(" /PURGE Delete dest files/dirs that no longer exist in source"); + System.out.println(" /COPYALL Copy all file info"); + System.out.println(" /R:n Number of retries on failed copies"); + System.out.println(" /W:n Wait time between retries"); + return; + } - String os = System.getProperty("os.name").toLowerCase(); + String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - try { - StringBuilder cmdBuilder = new StringBuilder("robocopy"); - for (String arg : args) { - cmdBuilder.append(" \"").append(arg).append("\""); - } + if (os.contains("win")) { + try { + StringBuilder cmdBuilder = new StringBuilder("robocopy"); + for (String arg : args) { + cmdBuilder.append(" \"").append(arg).append("\""); + } - ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); - pb.directory(context.getCurrentDir()); - Process process = pb.start(); + ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); + pb.directory(context.getCurrentDir()); + Process process = pb.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing robocopy: " + e.getMessage()); - } - } else { - System.out.println("ROBOCOPY is not available on this system. Use 'rsync' instead."); + } catch (Exception e) { + System.out.println("Error executing robocopy: " + e.getMessage()); + } + } else { + System.out.println("ROBOCOPY is not available on this system. Use 'rsync' instead."); + } } - } - @Override - public String description() { - return "Robust File Copy - Advanced file copy utility."; - } + @Override + public String description() { + return "Robust File Copy - Advanced file copy utility."; + } - @Override - public String usage() { - return "robocopy [/S] [/E] [/MIR]"; - } + @Override + public String usage() { + return "robocopy [/S] [/E] [/MIR]"; + } } diff --git a/src/main/java/com/mycmd/commands/RouteCommand.java b/src/main/java/com/mycmd/commands/RouteCommand.java index 46ac477..9aed48a 100644 --- a/src/main/java/com/mycmd/commands/RouteCommand.java +++ b/src/main/java/com/mycmd/commands/RouteCommand.java @@ -14,69 +14,67 @@ */ public class RouteCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("Manipulates network routing tables."); - System.out.println("\nROUTE [-f] [-p] [command [destination] [MASK netmask] [gateway]]"); - System.out.println("\n -f Clears the routing tables of all gateway entries."); - System.out.println(" -p Makes a route persistent across boots."); - System.out.println(" command One of these:"); - System.out.println(" PRINT Prints a route"); - System.out.println(" ADD Adds a route"); - System.out.println(" DELETE Deletes a route"); - System.out.println(" CHANGE Modifies an existing route"); - System.out.println("\nNote: Administrator privileges required for modification."); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("Manipulates network routing tables."); + System.out.println("\nROUTE [-f] [-p] [command [destination] [MASK netmask] [gateway]]"); + System.out.println("\n -f Clears the routing tables of all gateway entries."); + System.out.println(" -p Makes a route persistent across boots."); + System.out.println(" command One of these:"); + System.out.println(" PRINT Prints a route"); + System.out.println(" ADD Adds a route"); + System.out.println(" DELETE Deletes a route"); + System.out.println(" CHANGE Modifies an existing route"); + System.out.println("\nNote: Administrator privileges required for modification."); + return; + } - try { - StringBuilder cmdBuilder = new StringBuilder("route"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + try { + StringBuilder cmdBuilder = new StringBuilder("route"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - ProcessBuilder pb = new ProcessBuilder(); - String os = System.getProperty("os.name").toLowerCase(); + ProcessBuilder pb = new ProcessBuilder(); + String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - pb.command("cmd.exe", "/c", cmdBuilder.toString()); - } else { - pb.command("sh", "-c", cmdBuilder.toString()); - } + if (os.contains("win")) { + pb.command("cmd.exe", "/c", cmdBuilder.toString()); + } else { + pb.command("sh", "-c", cmdBuilder.toString()); + } - Process process = pb.start(); - try (BufferedReader reader = - new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream()))) { - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + Process process = pb.start(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } + } - if (!process.waitFor(30, TimeUnit.SECONDS)) { - process.destroyForcibly(); - System.out.println("Command timed out."); - } + if (!process.waitFor(30, TimeUnit.SECONDS)) { + process.destroyForcibly(); + System.out.println("Command timed out."); + } - } catch (Exception e) { - System.out.println("Error executing route: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error executing route: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Displays and modifies entries in the local IP routing table."; - } + @Override + public String description() { + return "Displays and modifies entries in the local IP routing table."; + } - @Override - public String usage() { - return "route [print | add | delete | change] [options]"; - } + @Override + public String usage() { + return "route [print | add | delete | change] [options]"; + } } diff --git a/src/main/java/com/mycmd/commands/SearchHistoryCommand.java b/src/main/java/com/mycmd/commands/SearchHistoryCommand.java index a5044bb..fd60064 100644 --- a/src/main/java/com/mycmd/commands/SearchHistoryCommand.java +++ b/src/main/java/com/mycmd/commands/SearchHistoryCommand.java @@ -12,100 +12,101 @@ */ public class SearchHistoryCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - List history = context.getHistory(); - - if (history.isEmpty()) { - System.out.println("No command history available."); - return; - } - - // If no search term provided, show all history - if (args.length == 0) { - System.out.println("Command History (use 'searchhistory ' to filter):"); - displayHistory(history, null); - return; + @Override + public void execute(String[] args, ShellContext context) { + List history = context.getHistory(); + + if (history.isEmpty()) { + System.out.println("No command history available."); + return; + } + + // If no search term provided, show all history + if (args.length == 0) { + System.out.println("Command History (use 'searchhistory ' to filter):"); + displayHistory(history, null); + return; + } + + // Join all args as the search term (supports multi-word searches) + String searchTerm = String.join(" ", args).toLowerCase(); + + System.out.println("Searching history for: '" + searchTerm + "'"); + System.out.println(); + + // Filter history + List matches = history.stream() + .filter(cmd -> cmd.toLowerCase().contains(searchTerm)) + .toList(); + + if (matches.isEmpty()) { + System.out.println("No matching commands found."); + System.out.println("Tip: Search is case-insensitive and matches partial text."); + } else { + displayHistory(matches, searchTerm); + System.out.println(); + System.out.println("Found " + matches.size() + " matching command(s)."); + } } - // Join all args as the search term (supports multi-word searches) - String searchTerm = String.join(" ", args).toLowerCase(); + /** + * Display history entries with line numbers. Optionally highlights the search term if provided. + */ + private void displayHistory(List commands, String searchTerm) { + int maxDigits = String.valueOf(commands.size()).length(); - System.out.println("Searching history for: '" + searchTerm + "'"); - System.out.println(); + for (int i = 0; i < commands.size(); i++) { + String lineNum = String.format("%" + maxDigits + "d", i + 1); + String command = commands.get(i); - // Filter history - List matches = - history.stream().filter(cmd -> cmd.toLowerCase().contains(searchTerm)).toList(); + // Highlight search term if provided (simple uppercase for visibility) + if (searchTerm != null && !searchTerm.isEmpty()) { + command = highlightTerm(command, searchTerm); + } - if (matches.isEmpty()) { - System.out.println("No matching commands found."); - System.out.println("Tip: Search is case-insensitive and matches partial text."); - } else { - displayHistory(matches, searchTerm); - System.out.println(); - System.out.println("Found " + matches.size() + " matching command(s)."); + System.out.println(" " + lineNum + " " + command); + } } - } - - /** - * Display history entries with line numbers. Optionally highlights the search term if provided. - */ - private void displayHistory(List commands, String searchTerm) { - int maxDigits = String.valueOf(commands.size()).length(); - - for (int i = 0; i < commands.size(); i++) { - String lineNum = String.format("%" + maxDigits + "d", i + 1); - String command = commands.get(i); - // Highlight search term if provided (simple uppercase for visibility) - if (searchTerm != null && !searchTerm.isEmpty()) { - command = highlightTerm(command, searchTerm); - } - - System.out.println(" " + lineNum + " " + command); - } - } - - /** - * Simple highlighting by surrounding the search term with markers. For terminal with color - * support, you could use ANSI codes instead. - */ - private String highlightTerm(String text, String term) { - // Case-insensitive highlight - int index = text.toLowerCase().indexOf(term.toLowerCase()); - if (index == -1) { - return text; + /** + * Simple highlighting by surrounding the search term with markers. For terminal with color + * support, you could use ANSI codes instead. + */ + private String highlightTerm(String text, String term) { + // Case-insensitive highlight + int index = text.toLowerCase().indexOf(term.toLowerCase()); + if (index == -1) { + return text; + } + + StringBuilder result = new StringBuilder(); + int lastIndex = 0; + + while (index >= 0) { + result.append(text, lastIndex, index); + result.append("["); + result.append(text, index, index + term.length()); + result.append("]"); + + lastIndex = index + term.length(); + index = text.toLowerCase().indexOf(term.toLowerCase(), lastIndex); + } + + result.append(text.substring(lastIndex)); + return result.toString(); } - StringBuilder result = new StringBuilder(); - int lastIndex = 0; - - while (index >= 0) { - result.append(text, lastIndex, index); - result.append("["); - result.append(text, index, index + term.length()); - result.append("]"); - - lastIndex = index + term.length(); - index = text.toLowerCase().indexOf(term.toLowerCase(), lastIndex); + @Override + public String description() { + return "Search through command history"; } - result.append(text.substring(lastIndex)); - return result.toString(); - } - - @Override - public String description() { - return "Search through command history"; - } - - @Override - public String usage() { - return "searchhistory [search_term]\n" - + " Examples:\n" - + " searchhistory - Show all history\n" - + " searchhistory dir - Find all 'dir' commands\n" - + " searchhistory cd .. - Find all 'cd ..' commands"; - } + @Override + public String usage() { + return "searchhistory [search_term]\n" + + " Examples:\n" + + " searchhistory - Show all history\n" + + " searchhistory dir - Find all 'dir' commands\n" + + " searchhistory cd .. - Find all 'cd ..' commands"; + } } diff --git a/src/main/java/com/mycmd/commands/SetCommand.java b/src/main/java/com/mycmd/commands/SetCommand.java index 38135be..a011d3c 100644 --- a/src/main/java/com/mycmd/commands/SetCommand.java +++ b/src/main/java/com/mycmd/commands/SetCommand.java @@ -6,40 +6,40 @@ public class SetCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - // Print all environment variables - for (Map.Entry entry : context.getEnvVars().entrySet()) { - System.out.println(entry.getKey() + "=" + entry.getValue()); - } - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + // Print all environment variables + for (Map.Entry entry : context.getEnvVars().entrySet()) { + System.out.println(entry.getKey() + "=" + entry.getValue()); + } + return; + } - String arg = args[0]; - if (arg.contains("=")) { - String[] parts = arg.split("=", 2); - String key = parts[0].trim(); - String value = parts[1].trim(); - context.setEnvVar(key, value); - System.out.println("Variable set: " + key + "=" + value); - } else { - String value = context.getEnvVar(arg); - if (value != null) { - System.out.println(arg + "=" + value); - } else { - System.out.println("Variable not found: " + arg); - } + String arg = args[0]; + if (arg.contains("=")) { + String[] parts = arg.split("=", 2); + String key = parts[0].trim(); + String value = parts[1].trim(); + context.setEnvVar(key, value); + System.out.println("Variable set: " + key + "=" + value); + } else { + String value = context.getEnvVar(arg); + if (value != null) { + System.out.println(arg + "=" + value); + } else { + System.out.println("Variable not found: " + arg); + } + } } - } - @Override - public String description() { - return "Displays, sets, or retrieves shell environment variables."; - } + @Override + public String description() { + return "Displays, sets, or retrieves shell environment variables."; + } - @Override - public String usage() { - return "Usage: set [variable[=value]]"; - } + @Override + public String usage() { + return "Usage: set [variable[=value]]"; + } } diff --git a/src/main/java/com/mycmd/commands/SfcCommand.java b/src/main/java/com/mycmd/commands/SfcCommand.java index 96ebf56..f441fe3 100644 --- a/src/main/java/com/mycmd/commands/SfcCommand.java +++ b/src/main/java/com/mycmd/commands/SfcCommand.java @@ -14,62 +14,61 @@ */ public class SfcCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - String os = System.getProperty("os.name").toLowerCase(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + String os = System.getProperty("os.name").toLowerCase(); - if (!os.contains("win")) { - System.out.println("SFC (System File Checker) is only available on Windows systems."); - return; - } + if (!os.contains("win")) { + System.out.println("SFC (System File Checker) is only available on Windows systems."); + return; + } - if (args.length == 0) { - System.out.println("Microsoft Windows System File Checker"); - System.out.println("\nUsage:"); - System.out.println(" sfc [/scannow] [/verifyonly] [/scanfile=]"); - System.out.println("\nOptions:"); - System.out.println(" /scannow - Scans integrity of all protected system files"); - System.out.println(" /verifyonly - Scans integrity but does not repair"); - System.out.println(" /scanfile - Scans integrity of specific file"); - System.out.println("\nNote: Administrator privileges required."); - return; - } + if (args.length == 0) { + System.out.println("Microsoft Windows System File Checker"); + System.out.println("\nUsage:"); + System.out.println(" sfc [/scannow] [/verifyonly] [/scanfile=]"); + System.out.println("\nOptions:"); + System.out.println(" /scannow - Scans integrity of all protected system files"); + System.out.println(" /verifyonly - Scans integrity but does not repair"); + System.out.println(" /scanfile - Scans integrity of specific file"); + System.out.println("\nNote: Administrator privileges required."); + return; + } - try { - StringBuilder cmdBuilder = new StringBuilder("sfc"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + try { + StringBuilder cmdBuilder = new StringBuilder("sfc"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing sfc: " + e.getMessage()); - System.out.println("Administrator privileges may be required."); + } catch (Exception e) { + System.out.println("Error executing sfc: " + e.getMessage()); + System.out.println("Administrator privileges may be required."); + } } - } - @Override - public String description() { - return "System File Checker - Scans and verifies system files."; - } + @Override + public String description() { + return "System File Checker - Scans and verifies system files."; + } - @Override - public String usage() { - return "sfc [/scannow] [/verifyonly] [/scanfile=]"; - } + @Override + public String usage() { + return "sfc [/scannow] [/verifyonly] [/scanfile=]"; + } } diff --git a/src/main/java/com/mycmd/commands/ShutdownCommand.java b/src/main/java/com/mycmd/commands/ShutdownCommand.java index fa8eb19..593c17e 100644 --- a/src/main/java/com/mycmd/commands/ShutdownCommand.java +++ b/src/main/java/com/mycmd/commands/ShutdownCommand.java @@ -14,110 +14,103 @@ */ public class ShutdownCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("Usage: shutdown [/i | /l | /s | /r | /a | /p | /h | /e]"); - System.out.println( - " [/f] [/m \\\\computer][/t xxx][/d [p:]xx:yy [/c \"comment\"]]"); - System.out.println("\n No args Display help."); - System.out.println(" /i Display the GUI interface (must be the first option)."); - System.out.println(" /l Log off (cannot be used with /m or /d options)."); - System.out.println(" /s Shutdown the computer."); - System.out.println(" /r Shutdown and restart the computer."); - System.out.println(" /a Abort a system shutdown."); - System.out.println(" /p Turn off the local computer with no time-out or warning."); - System.out.println(" /h Hibernate the local computer."); - System.out.println(" /f Force running applications to close without warning."); - System.out.println(" /t xxx Set time-out period before shutdown to xxx seconds."); - System.out.println("\nNote: Administrator privileges required."); - System.out.println("Warning: This command will actually shutdown/restart your system!"); - return; - } - - System.out.println("WARNING: This will execute a real shutdown command!"); - System.out.print("Are you sure you want to continue? (yes/no): "); - - java.util.Scanner scanner = new java.util.Scanner(System.in); - String confirmation = scanner.nextLine().trim().toLowerCase(); - if (!confirmation.equals("yes")) { - System.out.println("Shutdown cancelled."); - return; - } - - try { - StringBuilder cmdBuilder = new StringBuilder("shutdown"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } - - ProcessBuilder pb = new ProcessBuilder(); - String os = System.getProperty("os.name").toLowerCase(); - - if (os.contains("win")) { - pb.command("cmd.exe", "/c", cmdBuilder.toString()); - } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) { - pb.command("sh", "-c", cmdBuilder.toString()); - } else { - System.out.println("Unsupported operating system: " + os); - return; - } - - Process process = pb.start(); - Thread outputThread = - new Thread( - () -> { - try (BufferedReader reader = - new BufferedReader(new InputStreamReader(process.getInputStream()))) { - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("Usage: shutdown [/i | /l | /s | /r | /a | /p | /h | /e]"); + System.out.println(" [/f] [/m \\\\computer][/t xxx][/d [p:]xx:yy [/c \"comment\"]]"); + System.out.println("\n No args Display help."); + System.out.println(" /i Display the GUI interface (must be the first option)."); + System.out.println(" /l Log off (cannot be used with /m or /d options)."); + System.out.println(" /s Shutdown the computer."); + System.out.println(" /r Shutdown and restart the computer."); + System.out.println(" /a Abort a system shutdown."); + System.out.println(" /p Turn off the local computer with no time-out or warning."); + System.out.println(" /h Hibernate the local computer."); + System.out.println(" /f Force running applications to close without warning."); + System.out.println(" /t xxx Set time-out period before shutdown to xxx seconds."); + System.out.println("\nNote: Administrator privileges required."); + System.out.println("Warning: This command will actually shutdown/restart your system!"); + return; + } + + System.out.println("WARNING: This will execute a real shutdown command!"); + System.out.print("Are you sure you want to continue? (yes/no): "); + + java.util.Scanner scanner = new java.util.Scanner(System.in); + String confirmation = scanner.nextLine().trim().toLowerCase(); + if (!confirmation.equals("yes")) { + System.out.println("Shutdown cancelled."); + return; + } + + try { + StringBuilder cmdBuilder = new StringBuilder("shutdown"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } + + ProcessBuilder pb = new ProcessBuilder(); + String os = System.getProperty("os.name").toLowerCase(); + + if (os.contains("win")) { + pb.command("cmd.exe", "/c", cmdBuilder.toString()); + } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) { + pb.command("sh", "-c", cmdBuilder.toString()); + } else { + System.out.println("Unsupported operating system: " + os); + return; + } + + Process process = pb.start(); + Thread outputThread = new Thread(() -> { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } } catch (IOException e) { - System.err.println("Error reading output: " + e.getMessage()); + System.err.println("Error reading output: " + e.getMessage()); } - }); - - Thread errorThread = - new Thread( - () -> { - try (BufferedReader reader = - new BufferedReader(new InputStreamReader(process.getErrorStream()))) { - String line; - while ((line = reader.readLine()) != null) { - System.err.println(line); - } + }); + + Thread errorThread = new Thread(() -> { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + String line; + while ((line = reader.readLine()) != null) { + System.err.println(line); + } } catch (IOException e) { - System.err.println("Error reading error stream: " + e.getMessage()); + System.err.println("Error reading error stream: " + e.getMessage()); } - }); + }); - outputThread.start(); - errorThread.start(); + outputThread.start(); + errorThread.start(); - boolean finished = process.waitFor(30, TimeUnit.SECONDS); - if (!finished) { - process.destroyForcibly(); - System.out.println("Command timed out."); - process.waitFor(); - } + boolean finished = process.waitFor(30, TimeUnit.SECONDS); + if (!finished) { + process.destroyForcibly(); + System.out.println("Command timed out."); + process.waitFor(); + } - outputThread.join(); - errorThread.join(); + outputThread.join(); + errorThread.join(); - } catch (Exception e) { - System.out.println("Error executing shutdown: " + e.getMessage()); - System.out.println("Administrator privileges may be required."); + } catch (Exception e) { + System.out.println("Error executing shutdown: " + e.getMessage()); + System.out.println("Administrator privileges may be required."); + } } - } - @Override - public String description() { - return "Shuts down or restarts the computer."; - } + @Override + public String description() { + return "Shuts down or restarts the computer."; + } - @Override - public String usage() { - return "shutdown [/s | /r | /l] [/f] [/t seconds]"; - } + @Override + public String usage() { + return "shutdown [/s | /r | /l] [/f] [/t seconds]"; + } } diff --git a/src/main/java/com/mycmd/commands/SortCommand.java b/src/main/java/com/mycmd/commands/SortCommand.java index b18a1aa..d5f8237 100644 --- a/src/main/java/com/mycmd/commands/SortCommand.java +++ b/src/main/java/com/mycmd/commands/SortCommand.java @@ -16,73 +16,73 @@ */ public class SortCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("Sorts input and writes results to output."); - System.out.println("\nSORT [/R] [/+n] [/M kilobytes] [/L locale] [/REC recordbytes]"); - System.out.println(" [[drive1:][path1]filename1] [/T [drive2:][path2]]"); - System.out.println(" [/O [drive3:][path3]filename3]"); - System.out.println("\n /R Reverses the sort order"); - System.out.println(" /+n Specifies the character number to begin each comparison"); - System.out.println(" filename1 Specifies the file to be sorted"); - return; + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("Sorts input and writes results to output."); + System.out.println("\nSORT [/R] [/+n] [/M kilobytes] [/L locale] [/REC recordbytes]"); + System.out.println(" [[drive1:][path1]filename1] [/T [drive2:][path2]]"); + System.out.println(" [/O [drive3:][path3]filename3]"); + System.out.println("\n /R Reverses the sort order"); + System.out.println(" /+n Specifies the character number to begin each comparison"); + System.out.println(" filename1 Specifies the file to be sorted"); + return; + } + + boolean reverse = false; + int argIndex = 0; + + // Parse flags + while (argIndex < args.length && args[argIndex].startsWith("/")) { + String flag = args[argIndex].toUpperCase(); + if (flag.equals("/R")) reverse = true; + argIndex++; + } + + if (argIndex >= args.length) { + System.out.println("Missing filename."); + return; + } + + String filename = args[argIndex]; + java.io.File file = new java.io.File(filename); + + if (!file.isAbsolute()) { + file = new java.io.File(context.getCurrentDir(), filename); + } + + if (!file.exists()) { + System.out.println("File not found - " + filename); + return; + } + + List lines = new ArrayList<>(); + + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + while ((line = reader.readLine()) != null) { + lines.add(line); + } + } + + Collections.sort(lines); + + if (reverse) { + Collections.reverse(lines); + } + + for (String line : lines) { + System.out.println(line); + } } - boolean reverse = false; - int argIndex = 0; - - // Parse flags - while (argIndex < args.length && args[argIndex].startsWith("/")) { - String flag = args[argIndex].toUpperCase(); - if (flag.equals("/R")) reverse = true; - argIndex++; - } - - if (argIndex >= args.length) { - System.out.println("Missing filename."); - return; - } - - String filename = args[argIndex]; - java.io.File file = new java.io.File(filename); - - if (!file.isAbsolute()) { - file = new java.io.File(context.getCurrentDir(), filename); - } - - if (!file.exists()) { - System.out.println("File not found - " + filename); - return; + @Override + public String description() { + return "Sorts the contents of a text file."; } - List lines = new ArrayList<>(); - - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { - String line; - while ((line = reader.readLine()) != null) { - lines.add(line); - } - } - - Collections.sort(lines); - - if (reverse) { - Collections.reverse(lines); + @Override + public String usage() { + return "sort [/R] filename"; } - - for (String line : lines) { - System.out.println(line); - } - } - - @Override - public String description() { - return "Sorts the contents of a text file."; - } - - @Override - public String usage() { - return "sort [/R] filename"; - } } diff --git a/src/main/java/com/mycmd/commands/StartCommand.java b/src/main/java/com/mycmd/commands/StartCommand.java index e5bc33a..38167ee 100644 --- a/src/main/java/com/mycmd/commands/StartCommand.java +++ b/src/main/java/com/mycmd/commands/StartCommand.java @@ -11,62 +11,62 @@ */ public class StartCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("Starts a separate window to run a specified program or command."); - System.out.println("\nSTART [\"title\"] [/D path] [/I] [/MIN] [/MAX] [/WAIT]"); - System.out.println(" [/B] [command/program] [parameters]"); - System.out.println("\n \"title\" Title to display in window title bar."); - System.out.println(" /D path Specifies startup directory."); - System.out.println(" /MIN Start window minimized."); - System.out.println(" /MAX Start window maximized."); - System.out.println(" /WAIT Start application and wait for it to terminate."); - System.out.println(" /B Start application without creating a new window."); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("Starts a separate window to run a specified program or command."); + System.out.println("\nSTART [\"title\"] [/D path] [/I] [/MIN] [/MAX] [/WAIT]"); + System.out.println(" [/B] [command/program] [parameters]"); + System.out.println("\n \"title\" Title to display in window title bar."); + System.out.println(" /D path Specifies startup directory."); + System.out.println(" /MIN Start window minimized."); + System.out.println(" /MAX Start window maximized."); + System.out.println(" /WAIT Start application and wait for it to terminate."); + System.out.println(" /B Start application without creating a new window."); + return; + } - String os = System.getProperty("os.name").toLowerCase(); + String os = System.getProperty("os.name").toLowerCase(); - try { - if (os.contains("win")) { - // Windows - use start command - StringBuilder cmdBuilder = new StringBuilder("start"); - for (String arg : args) { - if (arg.contains(" ")) { - cmdBuilder.append(" \"").append(arg).append("\""); - } else { - cmdBuilder.append(" ").append(arg); - } - } + try { + if (os.contains("win")) { + // Windows - use start command + StringBuilder cmdBuilder = new StringBuilder("start"); + for (String arg : args) { + if (arg.contains(" ")) { + cmdBuilder.append(" \"").append(arg).append("\""); + } else { + cmdBuilder.append(" ").append(arg); + } + } - ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); - pb.directory(context.getCurrentDir()); - pb.start(); // Don't wait for completion + ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); + pb.directory(context.getCurrentDir()); + pb.start(); // Don't wait for completion - System.out.println("Started: " + String.join(" ", args)); + System.out.println("Started: " + String.join(" ", args)); - } else { - // Unix-like systems - use nohup or direct execution - ProcessBuilder pb = new ProcessBuilder(args); - pb.directory(context.getCurrentDir()); - pb.start(); + } else { + // Unix-like systems - use nohup or direct execution + ProcessBuilder pb = new ProcessBuilder(args); + pb.directory(context.getCurrentDir()); + pb.start(); - System.out.println("Started: " + String.join(" ", args)); - } + System.out.println("Started: " + String.join(" ", args)); + } - } catch (Exception e) { - System.out.println("Error starting process: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error starting process: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Starts a separate window to run a specified program or command."; - } + @Override + public String description() { + return "Starts a separate window to run a specified program or command."; + } - @Override - public String usage() { - return "start [\"title\"] [/D path] [/MIN] [/MAX] [/WAIT] [command]"; - } + @Override + public String usage() { + return "start [\"title\"] [/D path] [/MIN] [/MAX] [/WAIT] [command]"; + } } diff --git a/src/main/java/com/mycmd/commands/SysteminfoCommand.java b/src/main/java/com/mycmd/commands/SysteminfoCommand.java index e268456..082719c 100644 --- a/src/main/java/com/mycmd/commands/SysteminfoCommand.java +++ b/src/main/java/com/mycmd/commands/SysteminfoCommand.java @@ -12,61 +12,60 @@ import java.util.TimeZone; public class SysteminfoCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean(); - NumberFormat nf = NumberFormat.getInstance(); - Runtime rt = Runtime.getRuntime(); - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - sdf.setTimeZone(TimeZone.getDefault()); + @Override + public void execute(String[] args, ShellContext context) { + OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean(); + NumberFormat nf = NumberFormat.getInstance(); + Runtime rt = Runtime.getRuntime(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + sdf.setTimeZone(TimeZone.getDefault()); - String hostname; - try { - hostname = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException e) { - hostname = System.getenv("COMPUTERNAME"); - if (hostname == null) hostname = System.getenv("HOSTNAME"); - if (hostname == null) hostname = "Unknown"; - } + String hostname; + try { + hostname = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + hostname = System.getenv("COMPUTERNAME"); + if (hostname == null) hostname = System.getenv("HOSTNAME"); + if (hostname == null) hostname = "Unknown"; + } - long uptime = ManagementFactory.getRuntimeMXBean().getUptime(); - long bootTimeMillis = System.currentTimeMillis() - uptime; - long maxMem = rt.maxMemory(); - long totalMem = rt.totalMemory(); - long freeMem = rt.freeMemory(); - long usedMem = totalMem - freeMem; + long uptime = ManagementFactory.getRuntimeMXBean().getUptime(); + long bootTimeMillis = System.currentTimeMillis() - uptime; + long maxMem = rt.maxMemory(); + long totalMem = rt.totalMemory(); + long freeMem = rt.freeMemory(); + long usedMem = totalMem - freeMem; - System.out.println(); - System.out.println("Host Name: " + hostname); - System.out.println("OS Name: " + System.getProperty("os.name")); - System.out.println("OS Version: " + System.getProperty("os.version")); - System.out.println("Architecture: " + System.getProperty("os.arch")); - System.out.println("User Name: " + System.getProperty("user.name")); - System.out.println("Java Vendor: " + System.getProperty("java.vendor")); - System.out.println("Java VM: " + System.getProperty("java.vm.name")); - System.out.println("Available Processors: " + osBean.getAvailableProcessors()); - System.out.println("JVM Boot Time: " + sdf.format(new Date(bootTimeMillis))); - System.out.println("User Language: " + System.getProperty("user.language")); - System.out.println("User Country: " + System.getProperty("user.country")); - System.out.println("Home Directory: " + System.getProperty("user.home")); - System.out.println(); - System.out.println("JVM Memory (Heap):"); - System.out.println(" Total: " + nf.format(totalMem / (1024 * 1024)) + " MB"); - System.out.println(" Used: " + nf.format(usedMem / (1024 * 1024)) + " MB"); - System.out.println(" Free: " + nf.format(freeMem / (1024 * 1024)) + " MB"); - System.out.println( - " Max: " - + (maxMem == Long.MAX_VALUE ? "No Limit" : nf.format(maxMem / (1024 * 1024)) + " MB")); - System.out.println(); - } + System.out.println(); + System.out.println("Host Name: " + hostname); + System.out.println("OS Name: " + System.getProperty("os.name")); + System.out.println("OS Version: " + System.getProperty("os.version")); + System.out.println("Architecture: " + System.getProperty("os.arch")); + System.out.println("User Name: " + System.getProperty("user.name")); + System.out.println("Java Vendor: " + System.getProperty("java.vendor")); + System.out.println("Java VM: " + System.getProperty("java.vm.name")); + System.out.println("Available Processors: " + osBean.getAvailableProcessors()); + System.out.println("JVM Boot Time: " + sdf.format(new Date(bootTimeMillis))); + System.out.println("User Language: " + System.getProperty("user.language")); + System.out.println("User Country: " + System.getProperty("user.country")); + System.out.println("Home Directory: " + System.getProperty("user.home")); + System.out.println(); + System.out.println("JVM Memory (Heap):"); + System.out.println(" Total: " + nf.format(totalMem / (1024 * 1024)) + " MB"); + System.out.println(" Used: " + nf.format(usedMem / (1024 * 1024)) + " MB"); + System.out.println(" Free: " + nf.format(freeMem / (1024 * 1024)) + " MB"); + System.out.println( + " Max: " + (maxMem == Long.MAX_VALUE ? "No Limit" : nf.format(maxMem / (1024 * 1024)) + " MB")); + System.out.println(); + } - @Override - public String description() { - return "Displays system and JVM information."; - } + @Override + public String description() { + return "Displays system and JVM information."; + } - @Override - public String usage() { - return "systeminfo"; - } + @Override + public String usage() { + return "systeminfo"; + } } diff --git a/src/main/java/com/mycmd/commands/TaskkillCommand.java b/src/main/java/com/mycmd/commands/TaskkillCommand.java index 2145891..89ccb9f 100644 --- a/src/main/java/com/mycmd/commands/TaskkillCommand.java +++ b/src/main/java/com/mycmd/commands/TaskkillCommand.java @@ -14,63 +14,61 @@ */ public class TaskkillCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("TASKKILL [/S system [/U username [/P [password]]]]"); - System.out.println(" { [/FI filter] [/PID processid | /IM imagename] } [/T] [/F]"); - System.out.println("\nDescription:"); - System.out.println( - " This tool is used to terminate tasks by process id (PID) or image name."); - System.out.println("\nExamples:"); - System.out.println(" taskkill /IM notepad.exe"); - System.out.println(" taskkill /PID 1234"); - System.out.println(" taskkill /F /IM chrome.exe"); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("TASKKILL [/S system [/U username [/P [password]]]]"); + System.out.println(" { [/FI filter] [/PID processid | /IM imagename] } [/T] [/F]"); + System.out.println("\nDescription:"); + System.out.println(" This tool is used to terminate tasks by process id (PID) or image name."); + System.out.println("\nExamples:"); + System.out.println(" taskkill /IM notepad.exe"); + System.out.println(" taskkill /PID 1234"); + System.out.println(" taskkill /F /IM chrome.exe"); + return; + } - String os = System.getProperty("os.name").toLowerCase(); + String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - try { - StringBuilder cmdBuilder = new StringBuilder("taskkill"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + if (os.contains("win")) { + try { + StringBuilder cmdBuilder = new StringBuilder("taskkill"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing taskkill: " + e.getMessage()); - } - } else { - // Unix-like systems - use kill command - System.out.println("On Unix-like systems, use 'kill' command instead."); - System.out.println("Example: kill -9 "); + } catch (Exception e) { + System.out.println("Error executing taskkill: " + e.getMessage()); + } + } else { + // Unix-like systems - use kill command + System.out.println("On Unix-like systems, use 'kill' command instead."); + System.out.println("Example: kill -9 "); + } } - } - @Override - public String description() { - return "Terminates one or more processes."; - } + @Override + public String description() { + return "Terminates one or more processes."; + } - @Override - public String usage() { - return "taskkill [/F] [/PID processid | /IM imagename]"; - } + @Override + public String usage() { + return "taskkill [/F] [/PID processid | /IM imagename]"; + } } diff --git a/src/main/java/com/mycmd/commands/TasklistCommand.java b/src/main/java/com/mycmd/commands/TasklistCommand.java index 52a6109..a7b45b4 100644 --- a/src/main/java/com/mycmd/commands/TasklistCommand.java +++ b/src/main/java/com/mycmd/commands/TasklistCommand.java @@ -14,63 +14,62 @@ */ public class TasklistCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - System.out.println(); - System.out.printf("%-40s %10s %15s%n", "Image Name", "PID", "Memory Usage"); - System.out.println("=".repeat(70)); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + System.out.println(); + System.out.printf("%-40s %10s %15s%n", "Image Name", "PID", "Memory Usage"); + System.out.println("=".repeat(70)); - // Get current Java process information - RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); - String jvmName = runtimeMXBean.getName(); - String[] parts = jvmName.split("@"); - String pid = parts.length > 0 ? parts[0] : "Unknown"; + // Get current Java process information + RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); + String jvmName = runtimeMXBean.getName(); + String[] parts = jvmName.split("@"); + String pid = parts.length > 0 ? parts[0] : "Unknown"; - // Get memory info - Runtime runtime = Runtime.getRuntime(); - long usedMemory = (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024); // MB + // Get memory info + Runtime runtime = Runtime.getRuntime(); + long usedMemory = (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024); // MB - System.out.printf("%-40s %10s %12s MB%n", "java.exe", pid, usedMemory); + System.out.printf("%-40s %10s %12s MB%n", "java.exe", pid, usedMemory); - // Try to get system processes using ProcessHandle (Java 9+) - try { - ProcessHandle.allProcesses() - .limit(20) // Limit to first 20 processes - .forEach( - process -> { - ProcessHandle.Info info = process.info(); - long processPid = process.pid(); - String command = info.command().orElse("Unknown"); + // Try to get system processes using ProcessHandle (Java 9+) + try { + ProcessHandle.allProcesses() + .limit(20) // Limit to first 20 processes + .forEach(process -> { + ProcessHandle.Info info = process.info(); + long processPid = process.pid(); + String command = info.command().orElse("Unknown"); - // Extract just the executable name from full path - String execName = command; - if (command.contains("/") || command.contains("\\")) { - int lastSlash = Math.max(command.lastIndexOf('/'), command.lastIndexOf('\\')); - execName = command.substring(lastSlash + 1); - } + // Extract just the executable name from full path + String execName = command; + if (command.contains("/") || command.contains("\\")) { + int lastSlash = Math.max(command.lastIndexOf('/'), command.lastIndexOf('\\')); + execName = command.substring(lastSlash + 1); + } - // Truncate long names - if (execName.length() > 40) { - execName = execName.substring(0, 37) + "..."; - } + // Truncate long names + if (execName.length() > 40) { + execName = execName.substring(0, 37) + "..."; + } - System.out.printf("%-40s %10d %15s%n", execName, processPid, "N/A"); - }); - } catch (Exception e) { - // ProcessHandle not available or error accessing processes - System.out.println("\n[Additional process information not available]"); - } + System.out.printf("%-40s %10d %15s%n", execName, processPid, "N/A"); + }); + } catch (Exception e) { + // ProcessHandle not available or error accessing processes + System.out.println("\n[Additional process information not available]"); + } - System.out.println(); - } + System.out.println(); + } - @Override - public String description() { - return "Display a list of currently running processes."; - } + @Override + public String description() { + return "Display a list of currently running processes."; + } - @Override - public String usage() { - return "tasklist"; - } + @Override + public String usage() { + return "tasklist"; + } } diff --git a/src/main/java/com/mycmd/commands/TelnetCommand.java b/src/main/java/com/mycmd/commands/TelnetCommand.java index 73240c4..f8aaff1 100644 --- a/src/main/java/com/mycmd/commands/TelnetCommand.java +++ b/src/main/java/com/mycmd/commands/TelnetCommand.java @@ -13,86 +13,85 @@ */ public class TelnetCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length < 1) { - System.out.println("Usage: " + usage()); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length < 1) { + System.out.println("Usage: " + usage()); + return; + } - String host = args[0]; - int port = 23; - if (args.length >= 2) { - try { - port = Integer.parseInt(args[1]); - } catch (NumberFormatException e) { - System.out.println("Invalid port: " + args[1]); - return; - } - } + String host = args[0]; + int port = 23; + if (args.length >= 2) { + try { + port = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + System.out.println("Invalid port: " + args[1]); + return; + } + } - Thread reader = null; - try (Socket socket = new Socket(host, port)) { - socket.setSoTimeout(0); // blocking reads - System.out.println("Connected to " + host + ":" + port + " (type 'exit' to quit)"); + Thread reader = null; + try (Socket socket = new Socket(host, port)) { + socket.setSoTimeout(0); // blocking reads + System.out.println("Connected to " + host + ":" + port + " (type 'exit' to quit)"); - // Reader thread: prints remote data to stdout - reader = - new Thread( - () -> { - try (InputStream in = socket.getInputStream(); - InputStreamReader isr = new InputStreamReader(in); - BufferedReader br = new BufferedReader(isr)) { + // Reader thread: prints remote data to stdout + reader = new Thread( + () -> { + try (InputStream in = socket.getInputStream(); + InputStreamReader isr = new InputStreamReader(in); + BufferedReader br = new BufferedReader(isr)) { - char[] buffer = new char[2048]; - int read; - while ((read = br.read(buffer)) != -1) { - System.out.print(new String(buffer, 0, read)); - System.out.flush(); - } - } catch (IOException ignored) { - // socket closed or stream ended + char[] buffer = new char[2048]; + int read; + while ((read = br.read(buffer)) != -1) { + System.out.print(new String(buffer, 0, read)); + System.out.flush(); + } + } catch (IOException ignored) { + // socket closed or stream ended + } + }, + "telnet-reader"); + reader.setDaemon(true); + reader.start(); + + // Writer loop: read stdin and send to remote + BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); + try (OutputStream out = socket.getOutputStream(); + OutputStreamWriter osw = new OutputStreamWriter(out); + BufferedWriter bw = new BufferedWriter(osw)) { + String line; + while ((line = stdin.readLine()) != null) { + if ("exit".equalsIgnoreCase(line.trim())) break; + bw.write(line); + bw.write("\r\n"); // typical telnet line ending + bw.flush(); } - }, - "telnet-reader"); - reader.setDaemon(true); - reader.start(); + } catch (IOException ignored) { + // stdin/socket error, will disconnect + } + } catch (IOException e) { + System.out.println("Connection failed: " + e.getMessage()); + } - // Writer loop: read stdin and send to remote - BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); - try (OutputStream out = socket.getOutputStream(); - OutputStreamWriter osw = new OutputStreamWriter(out); - BufferedWriter bw = new BufferedWriter(osw)) { - String line; - while ((line = stdin.readLine()) != null) { - if ("exit".equalsIgnoreCase(line.trim())) break; - bw.write(line); - bw.write("\r\n"); // typical telnet line ending - bw.flush(); + if (reader != null) { + try { + reader.join(1000); // wait up to 1 second for reader to finish + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } } - } catch (IOException ignored) { - // stdin/socket error, will disconnect - } - } catch (IOException e) { - System.out.println("Connection failed: " + e.getMessage()); } - if (reader != null) { - try { - reader.join(1000); // wait up to 1 second for reader to finish - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + @Override + public String description() { + return "Simple TCP client for interactive sessions."; } - } - @Override - public String description() { - return "Simple TCP client for interactive sessions."; - } - - @Override - public String usage() { - return "telnet [port]"; - } + @Override + public String usage() { + return "telnet [port]"; + } } diff --git a/src/main/java/com/mycmd/commands/TimeCommand.java b/src/main/java/com/mycmd/commands/TimeCommand.java index e2bc2cd..957fd78 100644 --- a/src/main/java/com/mycmd/commands/TimeCommand.java +++ b/src/main/java/com/mycmd/commands/TimeCommand.java @@ -20,27 +20,27 @@ * Example output: "The current time is: 13.5.07.12" */ public class TimeCommand implements Command { - /** - * Print the current time. - * - * @param args ignored for this command; may be empty or contain unused tokens. - * @param context the current shell context; not used by this command. - */ - @Override - public void execute(String[] args, ShellContext context) { - LocalTime now = LocalTime.now(); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("H.mm.ss.SS"); - String formattedTime = now.format(formatter); - System.out.println("The current time is: " + formattedTime); - } + /** + * Print the current time. + * + * @param args ignored for this command; may be empty or contain unused tokens. + * @param context the current shell context; not used by this command. + */ + @Override + public void execute(String[] args, ShellContext context) { + LocalTime now = LocalTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("H.mm.ss.SS"); + String formattedTime = now.format(formatter); + System.out.println("The current time is: " + formattedTime); + } - @Override - public String description() { - return "Display the current local time."; - } + @Override + public String description() { + return "Display the current local time."; + } - @Override - public String usage() { - return "time"; - } + @Override + public String usage() { + return "time"; + } } diff --git a/src/main/java/com/mycmd/commands/TimeoutCommand.java b/src/main/java/com/mycmd/commands/TimeoutCommand.java index 4d736aa..54d9d7d 100644 --- a/src/main/java/com/mycmd/commands/TimeoutCommand.java +++ b/src/main/java/com/mycmd/commands/TimeoutCommand.java @@ -6,183 +6,172 @@ import java.util.concurrent.atomic.AtomicBoolean; public class TimeoutCommand implements Command { - /** - * Execute the timeout command. - * - *

This command will wait for the specified number of seconds before continuing. If the user - * presses Enter before the timeout expires, the command will terminate immediately. - * - * @param args The arguments to the command. - * @param context The context of the shell. - * @throws IOException If an I/O error occurs. - */ - @Override - public void execute(String[] args, ShellContext context) { - int seconds = -1; - boolean hasSecondsArg = false; - boolean hasSlashT = false; - boolean noBreak = false; + /** + * Execute the timeout command. + * + *

This command will wait for the specified number of seconds before continuing. If the user + * presses Enter before the timeout expires, the command will terminate immediately. + * + * @param args The arguments to the command. + * @param context The context of the shell. + * @throws IOException If an I/O error occurs. + */ + @Override + public void execute(String[] args, ShellContext context) { + int seconds = -1; + boolean hasSecondsArg = false; + boolean hasSlashT = false; + boolean noBreak = false; - for (int i = 0; i < args.length; i++) { - if (args[i].equalsIgnoreCase("/t") - && i + 1 < args.length - && args[i + 1].matches("[+-]?\\d+")) { - if (hasSlashT) { - System.out.println( - "Error: Invalid syntax. '/t' option is not allowed more than '1' time(s)."); - return; - } - seconds = Integer.parseInt(args[i + 1]); - i++; - hasSecondsArg = true; - hasSlashT = true; - } else if (args[i].equalsIgnoreCase("/nobreak")) { - if (noBreak) { - System.out.println( - "Error: Invalid syntax. '/nobreak' option is not allowed more than '1' time(s)."); - return; - } - noBreak = true; - } else if (args[i].matches("[+-]?\\d+")) { - if (hasSecondsArg) { - System.out.println( - "Error: Invalid syntax. Default option is not allowed more than '1' time(s)."); - return; + for (int i = 0; i < args.length; i++) { + if (args[i].equalsIgnoreCase("/t") && i + 1 < args.length && args[i + 1].matches("[+-]?\\d+")) { + if (hasSlashT) { + System.out.println("Error: Invalid syntax. '/t' option is not allowed more than '1' time(s)."); + return; + } + seconds = Integer.parseInt(args[i + 1]); + i++; + hasSecondsArg = true; + hasSlashT = true; + } else if (args[i].equalsIgnoreCase("/nobreak")) { + if (noBreak) { + System.out.println( + "Error: Invalid syntax. '/nobreak' option is not allowed more than '1' time(s)."); + return; + } + noBreak = true; + } else if (args[i].matches("[+-]?\\d+")) { + if (hasSecondsArg) { + System.out.println("Error: Invalid syntax. Default option is not allowed more than '1' time(s)."); + return; + } + seconds = Integer.parseInt(args[i]); + hasSecondsArg = true; + } else if (args[i].equalsIgnoreCase("/t")) { + System.out.println("Error: Invalid syntax. Value expected for '/t'."); + return; + } else { + System.out.println("Error: Invalid syntax. Unrecognized argument: " + args[i]); + return; + } } - seconds = Integer.parseInt(args[i]); - hasSecondsArg = true; - } else if (args[i].equalsIgnoreCase("/t")) { - System.out.println("Error: Invalid syntax. Value expected for '/t'."); - return; - } else { - System.out.println("Error: Invalid syntax. Unrecognized argument: " + args[i]); - return; - } - } - if (!hasSecondsArg) { - System.out.println("Error: Invalid syntax. Seconds value is required."); - return; - } + if (!hasSecondsArg) { + System.out.println("Error: Invalid syntax. Seconds value is required."); + return; + } - if (seconds < -1 || seconds > 99999) { - System.out.println( - "Error: Invalid value for timeout specified. Valid range is 0-99999 seconds."); - return; - } + if (seconds < -1 || seconds > 99999) { + System.out.println("Error: Invalid value for timeout specified. Valid range is 0-99999 seconds."); + return; + } - if (seconds == -1) { - System.out.println(); - PauseCommand pauseCmd = new PauseCommand(); - pauseCmd.execute(new String[0], context); - return; - } + if (seconds == -1) { + System.out.println(); + PauseCommand pauseCmd = new PauseCommand(); + pauseCmd.execute(new String[0], context); + return; + } - AtomicBoolean interrupted = new AtomicBoolean(false); - AtomicBoolean stopInput = new AtomicBoolean(false); - Thread inputThread = null; + AtomicBoolean interrupted = new AtomicBoolean(false); + AtomicBoolean stopInput = new AtomicBoolean(false); + Thread inputThread = null; - if (!noBreak) { - inputThread = - new Thread( - () -> { + if (!noBreak) { + inputThread = new Thread(() -> { try { - // Poll non-blocking so we can stop the thread - // deterministically. - while (!stopInput.get()) { - if (System.in.available() > 0) { - int r = System.in.read(); - // Treat CR or LF as Enter across platforms - if (r == '\n' || r == '\r') { - interrupted.set(true); - break; - } - } else { - try { - Thread.sleep(25); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - break; - } + // Poll non-blocking so we can stop the thread + // deterministically. + while (!stopInput.get()) { + if (System.in.available() > 0) { + int r = System.in.read(); + // Treat CR or LF as Enter across platforms + if (r == '\n' || r == '\r') { + interrupted.set(true); + break; + } + } else { + try { + Thread.sleep(25); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + break; + } + } } - } } catch (IOException e) { - // Best-effort only; fall through. + // Best-effort only; fall through. } - }); - inputThread.setDaemon(true); - inputThread.start(); - } - System.out.println(); - - for (; seconds > 0; seconds--) { - if (!noBreak && interrupted.get()) { - System.out.println("\r"); + }); + inputThread.setDaemon(true); + inputThread.start(); + } System.out.println(); - if (inputThread != null) { - stopInput.set(true); - try { - inputThread.join(200); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } + + for (; seconds > 0; seconds--) { + if (!noBreak && interrupted.get()) { + System.out.println("\r"); + System.out.println(); + if (inputThread != null) { + stopInput.set(true); + try { + inputThread.join(200); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + } + return; + } + + System.out.print("\rWaiting for " + + seconds + + " seconds, press " + + (noBreak ? "CTRL+C to quit ..." : "enter key to continue ...")); + System.out.flush(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + if (noBreak) { + continue; + } + System.out.println(); + Thread.currentThread().interrupt(); + break; + } } - return; - } - System.out.print( - "\rWaiting for " - + seconds - + " seconds, press " - + (noBreak ? "CTRL+C to quit ..." : "enter key to continue ...")); - System.out.flush(); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - if (noBreak) { - continue; + // Normal completion: stop the input thread before draining. + if (!noBreak && inputThread != null) { + stopInput.set(true); + try { + inputThread.join(200); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } } + try { + // Drain any remaining bytes so subsequent commands don't immediately see + // leftover input. This is a best-effort drain; System.in.available() may + // not be supported on all streams, but for typical console streams it helps. + while (System.in.available() > 0) { + System.in.read(); + } + } catch (IOException e) { + // Ignore: if we can't drain the stream it's non-fatal; any leftover input + // will be handled by the next read and is acceptable. + } + + System.out.println("\r"); System.out.println(); - Thread.currentThread().interrupt(); - break; - } } - // Normal completion: stop the input thread before draining. - if (!noBreak && inputThread != null) { - stopInput.set(true); - try { - inputThread.join(200); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } - } - try { - // Drain any remaining bytes so subsequent commands don't immediately see - // leftover input. This is a best-effort drain; System.in.available() may - // not be supported on all streams, but for typical console streams it helps. - while (System.in.available() > 0) { - System.in.read(); - } - } catch (IOException e) { - // Ignore: if we can't drain the stream it's non-fatal; any leftover input - // will be handled by the next read and is acceptable. + @Override + public String description() { + return "Sets a timeout for command execution."; } - System.out.println("\r"); - System.out.println(); - } - - @Override - public String description() { - return "Sets a timeout for command execution."; - } - - @Override - public String usage() { - return "timeout \n" - + "timeout /t \n" - + "timeout /t /nobreak\n" - + "timeout /t -1"; - } + @Override + public String usage() { + return "timeout \n" + "timeout /t \n" + "timeout /t /nobreak\n" + "timeout /t -1"; + } } diff --git a/src/main/java/com/mycmd/commands/TitleCommand.java b/src/main/java/com/mycmd/commands/TitleCommand.java index 7eeadc3..9453707 100644 --- a/src/main/java/com/mycmd/commands/TitleCommand.java +++ b/src/main/java/com/mycmd/commands/TitleCommand.java @@ -17,23 +17,23 @@ * information is displayed. */ public class TitleCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - if (args.length > 0) { - String title = String.join(" ", args); - System.out.println("\033]0;" + title + "\007"); - } else { - System.out.println("Usage: " + usage()); + @Override + public void execute(String[] args, ShellContext context) { + if (args.length > 0) { + String title = String.join(" ", args); + System.out.println("\033]0;" + title + "\007"); + } else { + System.out.println("Usage: " + usage()); + } } - } - @Override - public String description() { - return "Set the terminal window title."; - } + @Override + public String description() { + return "Set the terminal window title."; + } - @Override - public String usage() { - return "title "; - } + @Override + public String usage() { + return "title "; + } } diff --git a/src/main/java/com/mycmd/commands/TouchCommand.java b/src/main/java/com/mycmd/commands/TouchCommand.java index 6047f96..33ea349 100644 --- a/src/main/java/com/mycmd/commands/TouchCommand.java +++ b/src/main/java/com/mycmd/commands/TouchCommand.java @@ -18,30 +18,30 @@ * indicating whether a new file was created or an existing file's timestamp was updated. */ public class TouchCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length < 1) { // ✅ Check for at least 1 argument - System.out.println("Usage: " + usage()); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length < 1) { // ✅ Check for at least 1 argument + System.out.println("Usage: " + usage()); + return; + } - File file = new File(context.getCurrentDir(), args[0]); // ✅ Use args[0] - if (file.createNewFile()) { - System.out.println("File created: " + args[0]); // ✅ Use args[0] - } else { - // Update timestamp - file.setLastModified(System.currentTimeMillis()); - System.out.println("File timestamp updated: " + args[0]); // ✅ Use args[0] + File file = new File(context.getCurrentDir(), args[0]); // ✅ Use args[0] + if (file.createNewFile()) { + System.out.println("File created: " + args[0]); // ✅ Use args[0] + } else { + // Update timestamp + file.setLastModified(System.currentTimeMillis()); + System.out.println("File timestamp updated: " + args[0]); // ✅ Use args[0] + } } - } - @Override - public String description() { - return "Create a new empty file or update the timestamp of an existing file."; - } + @Override + public String description() { + return "Create a new empty file or update the timestamp of an existing file."; + } - @Override - public String usage() { - return "touch "; - } + @Override + public String usage() { + return "touch "; + } } diff --git a/src/main/java/com/mycmd/commands/TracertCommand.java b/src/main/java/com/mycmd/commands/TracertCommand.java index afbf8d6..9bccd8f 100644 --- a/src/main/java/com/mycmd/commands/TracertCommand.java +++ b/src/main/java/com/mycmd/commands/TracertCommand.java @@ -13,62 +13,62 @@ */ public class TracertCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("Usage: tracert [-d] [-h maximum_hops] [-w timeout] target_name"); - System.out.println("\nTraces the route packets take to a network host."); - System.out.println("\nOptions:"); - System.out.println(" -d Do not resolve addresses to hostnames."); - System.out.println(" -h maximum_hops Maximum number of hops to search for target."); - System.out.println(" -w timeout Wait timeout milliseconds for each reply."); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("Usage: tracert [-d] [-h maximum_hops] [-w timeout] target_name"); + System.out.println("\nTraces the route packets take to a network host."); + System.out.println("\nOptions:"); + System.out.println(" -d Do not resolve addresses to hostnames."); + System.out.println(" -h maximum_hops Maximum number of hops to search for target."); + System.out.println(" -w timeout Wait timeout milliseconds for each reply."); + return; + } - try { - StringBuilder cmdBuilder = new StringBuilder(); - String os = System.getProperty("os.name").toLowerCase(); + try { + StringBuilder cmdBuilder = new StringBuilder(); + String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - cmdBuilder.append("tracert"); - } else { - cmdBuilder.append("traceroute"); - } + if (os.contains("win")) { + cmdBuilder.append("tracert"); + } else { + cmdBuilder.append("traceroute"); + } - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - ProcessBuilder pb = new ProcessBuilder(); + ProcessBuilder pb = new ProcessBuilder(); - if (os.contains("win")) { - pb.command("cmd.exe", "/c", cmdBuilder.toString()); - } else { - pb.command("sh", "-c", cmdBuilder.toString()); - } + if (os.contains("win")) { + pb.command("cmd.exe", "/c", cmdBuilder.toString()); + } else { + pb.command("sh", "-c", cmdBuilder.toString()); + } - Process process = pb.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + Process process = pb.start(); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing tracert: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error executing tracert: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Traces the route packets take to a network host."; - } + @Override + public String description() { + return "Traces the route packets take to a network host."; + } - @Override - public String usage() { - return "tracert [-d] [-h maximum_hops] target_name"; - } + @Override + public String usage() { + return "tracert [-d] [-h maximum_hops] target_name"; + } } diff --git a/src/main/java/com/mycmd/commands/TreeCommand.java b/src/main/java/com/mycmd/commands/TreeCommand.java index f68df8b..863ba0b 100644 --- a/src/main/java/com/mycmd/commands/TreeCommand.java +++ b/src/main/java/com/mycmd/commands/TreeCommand.java @@ -20,43 +20,43 @@ * beneath the current location. */ public class TreeCommand implements Command { - public void execute(String[] args, ShellContext context) { - File[] files = context.getCurrentDir().listFiles(); + public void execute(String[] args, ShellContext context) { + File[] files = context.getCurrentDir().listFiles(); - if (files == null || files.length == 0) { - System.out.println("No files found."); - return; - } + if (files == null || files.length == 0) { + System.out.println("No files found."); + return; + } - System.out.println(context.getCurrentDir().getAbsolutePath()); - printDirectory(files, "", true); - System.out.println(); - } + System.out.println(context.getCurrentDir().getAbsolutePath()); + printDirectory(files, "", true); + System.out.println(); + } - private void printDirectory(File[] files, String prefix, boolean isLast) { - if (files == null || files.length == 0) return; + private void printDirectory(File[] files, String prefix, boolean isLast) { + if (files == null || files.length == 0) return; - for (int i = 0; i < files.length; i++) { - File f = files[i]; - if (f.isHidden()) continue; + for (int i = 0; i < files.length; i++) { + File f = files[i]; + if (f.isHidden()) continue; - boolean last = (i == files.length - 1); - System.out.println(prefix + (last ? "└───" : "├───") + f.getName()); + boolean last = (i == files.length - 1); + System.out.println(prefix + (last ? "└───" : "├───") + f.getName()); - if (f.isDirectory()) { - String newPrefix = prefix + (last ? " " : "│ "); - printDirectory(f.listFiles(), newPrefix, last); - } + if (f.isDirectory()) { + String newPrefix = prefix + (last ? " " : "│ "); + printDirectory(f.listFiles(), newPrefix, last); + } + } } - } - @Override - public String description() { - return "Display the directory tree structure."; - } + @Override + public String description() { + return "Display the directory tree structure."; + } - @Override - public String usage() { - return "tree"; - } + @Override + public String usage() { + return "tree"; + } } diff --git a/src/main/java/com/mycmd/commands/TypeCommand.java b/src/main/java/com/mycmd/commands/TypeCommand.java index bbf3864..fdf8742 100644 --- a/src/main/java/com/mycmd/commands/TypeCommand.java +++ b/src/main/java/com/mycmd/commands/TypeCommand.java @@ -20,34 +20,34 @@ *

Note: Best suited for text files. Binary files may produce garbled output. */ public class TypeCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - if (args.length == 0) { - System.out.println("Usage: " + usage()); - return; + @Override + public void execute(String[] args, ShellContext context) { + if (args.length == 0) { + System.out.println("Usage: " + usage()); + return; + } + File file = new File(context.getCurrentDir(), args[0]); + if (!file.exists() || !file.isFile()) { + System.out.println("File not found."); + return; + } + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + String line; + while ((line = br.readLine()) != null) { + System.out.println(line); + } + } catch (IOException e) { + System.out.println("Error reading file: " + e.getMessage()); + } } - File file = new File(context.getCurrentDir(), args[0]); - if (!file.exists() || !file.isFile()) { - System.out.println("File not found."); - return; - } - try (BufferedReader br = new BufferedReader(new FileReader(file))) { - String line; - while ((line = br.readLine()) != null) { - System.out.println(line); - } - } catch (IOException e) { - System.out.println("Error reading file: " + e.getMessage()); - } - } - @Override - public String description() { - return "Display the contents of a text file."; - } + @Override + public String description() { + return "Display the contents of a text file."; + } - @Override - public String usage() { - return "type "; - } + @Override + public String usage() { + return "type "; + } } diff --git a/src/main/java/com/mycmd/commands/UnaliasCommand.java b/src/main/java/com/mycmd/commands/UnaliasCommand.java index 996db2f..1a4dabe 100644 --- a/src/main/java/com/mycmd/commands/UnaliasCommand.java +++ b/src/main/java/com/mycmd/commands/UnaliasCommand.java @@ -5,31 +5,31 @@ import java.io.IOException; public class UnaliasCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args == null || args.length == 0) { - System.out.println("Usage: " + usage()); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args == null || args.length == 0) { + System.out.println("Usage: " + usage()); + return; + } - for (String name : args) { - if (name == null || name.trim().isEmpty()) continue; - if (context.hasAlias(name)) { - context.removeAlias(name); - System.out.println("Removed alias: " + name); - } else { - System.out.println("Alias not found: " + name); - } + for (String name : args) { + if (name == null || name.trim().isEmpty()) continue; + if (context.hasAlias(name)) { + context.removeAlias(name); + System.out.println("Removed alias: " + name); + } else { + System.out.println("Alias not found: " + name); + } + } } - } - @Override - public String description() { - return "Remove one or more aliases."; - } + @Override + public String description() { + return "Remove one or more aliases."; + } - @Override - public String usage() { - return "unalias name [name2 ...]"; - } + @Override + public String usage() { + return "unalias name [name2 ...]"; + } } diff --git a/src/main/java/com/mycmd/commands/UptimeCommand.java b/src/main/java/com/mycmd/commands/UptimeCommand.java index 6e05557..f96e389 100644 --- a/src/main/java/com/mycmd/commands/UptimeCommand.java +++ b/src/main/java/com/mycmd/commands/UptimeCommand.java @@ -20,34 +20,34 @@ *

This is useful for monitoring how long a shell session has been active. */ public class UptimeCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - Instant startTime = context.getStartTime(); - Instant now = Instant.now(); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + Instant startTime = context.getStartTime(); + Instant now = Instant.now(); - // Calculate duration between start time and now - Duration uptime = Duration.between(startTime, now); + // Calculate duration between start time and now + Duration uptime = Duration.between(startTime, now); - long seconds = uptime.getSeconds(); - long days = seconds / 86400; - long hours = (seconds % 86400) / 3600; - long minutes = (seconds % 3600) / 60; - long secs = seconds % 60; + long seconds = uptime.getSeconds(); + long days = seconds / 86400; + long hours = (seconds % 86400) / 3600; + long minutes = (seconds % 3600) / 60; + long secs = seconds % 60; - System.out.print("Uptime: "); - if (days > 0) { - System.out.print(days + " day" + (days != 1 ? "s" : "") + ", "); + System.out.print("Uptime: "); + if (days > 0) { + System.out.print(days + " day" + (days != 1 ? "s" : "") + ", "); + } + System.out.printf("%02d:%02d:%02d%n", hours, minutes, secs); } - System.out.printf("%02d:%02d:%02d%n", hours, minutes, secs); - } - @Override - public String description() { - return "Display how long the shell has been running since startup."; - } + @Override + public String description() { + return "Display how long the shell has been running since startup."; + } - @Override - public String usage() { - return "uptime"; - } + @Override + public String usage() { + return "uptime"; + } } diff --git a/src/main/java/com/mycmd/commands/VerifyCommand.java b/src/main/java/com/mycmd/commands/VerifyCommand.java index 633a771..e4501d2 100644 --- a/src/main/java/com/mycmd/commands/VerifyCommand.java +++ b/src/main/java/com/mycmd/commands/VerifyCommand.java @@ -12,35 +12,35 @@ */ public class VerifyCommand implements Command { - private static boolean verifyEnabled = false; - - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("VERIFY is " + (verifyEnabled ? "on" : "off") + "."); - return; + private static boolean verifyEnabled = false; + + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("VERIFY is " + (verifyEnabled ? "on" : "off") + "."); + return; + } + + String option = args[0].toUpperCase(); + + if (option.equals("ON")) { + verifyEnabled = true; + System.out.println("VERIFY is on."); + } else if (option.equals("OFF")) { + verifyEnabled = false; + System.out.println("VERIFY is off."); + } else { + System.out.println("Must specify ON or OFF."); + } } - String option = args[0].toUpperCase(); - - if (option.equals("ON")) { - verifyEnabled = true; - System.out.println("VERIFY is on."); - } else if (option.equals("OFF")) { - verifyEnabled = false; - System.out.println("VERIFY is off."); - } else { - System.out.println("Must specify ON or OFF."); + @Override + public String description() { + return "Enables or disables file verification."; } - } - @Override - public String description() { - return "Enables or disables file verification."; - } - - @Override - public String usage() { - return "verify [ON | OFF]"; - } + @Override + public String usage() { + return "verify [ON | OFF]"; + } } diff --git a/src/main/java/com/mycmd/commands/VersionCommand.java b/src/main/java/com/mycmd/commands/VersionCommand.java index 975bc40..13e6287 100644 --- a/src/main/java/com/mycmd/commands/VersionCommand.java +++ b/src/main/java/com/mycmd/commands/VersionCommand.java @@ -14,18 +14,18 @@ *

Note: This command does not accept any arguments and always displays the same version string. */ public class VersionCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - System.out.println("MyCMD Java Shell v1.0"); - } + @Override + public void execute(String[] args, ShellContext context) { + System.out.println("MyCMD Java Shell v1.0"); + } - @Override - public String description() { - return "Display the version information of the MyCMD shell."; - } + @Override + public String description() { + return "Display the version information of the MyCMD shell."; + } - @Override - public String usage() { - return "ver"; - } + @Override + public String usage() { + return "ver"; + } } diff --git a/src/main/java/com/mycmd/commands/VolCommand.java b/src/main/java/com/mycmd/commands/VolCommand.java index f0bc5aa..2b61f2e 100644 --- a/src/main/java/com/mycmd/commands/VolCommand.java +++ b/src/main/java/com/mycmd/commands/VolCommand.java @@ -12,49 +12,48 @@ */ public class VolCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - File drive; - - if (args.length == 0) { - drive = context.getCurrentDir(); - } else { - String drivePath = args[0]; - if (!drivePath.endsWith("\\") && !drivePath.endsWith("/")) { - drivePath += "\\"; - } - drive = new File(drivePath); + @Override + public void execute(String[] args, ShellContext context) throws IOException { + File drive; + + if (args.length == 0) { + drive = context.getCurrentDir(); + } else { + String drivePath = args[0]; + if (!drivePath.endsWith("\\") && !drivePath.endsWith("/")) { + drivePath += "\\"; + } + drive = new File(drivePath); + } + + if (!drive.exists()) { + System.out.println("The system cannot find the drive specified."); + return; + } + + // Get drive letter + String path = drive.getAbsolutePath(); + String driveLetter = path.substring(0, Math.min(2, path.length())); + + System.out.println(" Volume in drive " + driveLetter + " has no label."); + System.out.println(" Volume Serial Number is " + getSerialNumber(drive)); } - if (!drive.exists()) { - System.out.println("The system cannot find the drive specified."); - return; + private String getSerialNumber(File drive) { + // Generate a pseudo-serial based on drive properties + long totalSpace = drive.getTotalSpace(); + long freeSpace = drive.getFreeSpace(); + long combined = totalSpace ^ freeSpace; + return String.format("%04X-%04X", (int) ((combined >>> 16) & 0xFFFF), (int) (combined & 0xFFFF)); } - // Get drive letter - String path = drive.getAbsolutePath(); - String driveLetter = path.substring(0, Math.min(2, path.length())); - - System.out.println(" Volume in drive " + driveLetter + " has no label."); - System.out.println(" Volume Serial Number is " + getSerialNumber(drive)); - } - - private String getSerialNumber(File drive) { - // Generate a pseudo-serial based on drive properties - long totalSpace = drive.getTotalSpace(); - long freeSpace = drive.getFreeSpace(); - long combined = totalSpace ^ freeSpace; - return String.format( - "%04X-%04X", (int) ((combined >>> 16) & 0xFFFF), (int) (combined & 0xFFFF)); - } - - @Override - public String description() { - return "Display the disk volume label and serial number."; - } - - @Override - public String usage() { - return "vol [drive:]"; - } + @Override + public String description() { + return "Display the disk volume label and serial number."; + } + + @Override + public String usage() { + return "vol [drive:]"; + } } diff --git a/src/main/java/com/mycmd/commands/WhoamiCommand.java b/src/main/java/com/mycmd/commands/WhoamiCommand.java index bc972e7..1a139de 100644 --- a/src/main/java/com/mycmd/commands/WhoamiCommand.java +++ b/src/main/java/com/mycmd/commands/WhoamiCommand.java @@ -15,18 +15,18 @@ * as reported by the Java runtime. */ public class WhoamiCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) { - System.out.println(System.getProperty("user.name")); - } + @Override + public void execute(String[] args, ShellContext context) { + System.out.println(System.getProperty("user.name")); + } - @Override - public String description() { - return "Display the username of logged in user"; - } + @Override + public String description() { + return "Display the username of logged in user"; + } - @Override - public String usage() { - return "whoami"; - } + @Override + public String usage() { + return "whoami"; + } } diff --git a/src/main/java/com/mycmd/commands/WmicCommand.java b/src/main/java/com/mycmd/commands/WmicCommand.java index 56a0247..df1078d 100644 --- a/src/main/java/com/mycmd/commands/WmicCommand.java +++ b/src/main/java/com/mycmd/commands/WmicCommand.java @@ -14,60 +14,59 @@ */ public class WmicCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("WMIC - Windows Management Instrumentation Command-line"); - System.out.println("Usage: wmic [global switches] "); - System.out.println("\nCommon commands:"); - System.out.println(" wmic cpu get name"); - System.out.println(" wmic bios get serialnumber"); - System.out.println(" wmic os get caption"); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("WMIC - Windows Management Instrumentation Command-line"); + System.out.println("Usage: wmic [global switches] "); + System.out.println("\nCommon commands:"); + System.out.println(" wmic cpu get name"); + System.out.println(" wmic bios get serialnumber"); + System.out.println(" wmic os get caption"); + return; + } - // Check if wmic is available on the system - String os = System.getProperty("os.name").toLowerCase(); - if (!os.contains("win")) { - System.out.println("WMIC is only available on Windows systems."); - return; - } + // Check if wmic is available on the system + String os = System.getProperty("os.name").toLowerCase(); + if (!os.contains("win")) { + System.out.println("WMIC is only available on Windows systems."); + return; + } - try { - // Build the wmic command - StringBuilder cmdBuilder = new StringBuilder("wmic"); - for (String arg : args) { - cmdBuilder.append(" ").append(arg); - } + try { + // Build the wmic command + StringBuilder cmdBuilder = new StringBuilder("wmic"); + for (String arg : args) { + cmdBuilder.append(" ").append(arg); + } - Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + Process process = Runtime.getRuntime().exec(cmdBuilder.toString()); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing WMIC command: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Error executing WMIC command: " + e.getMessage()); + } } - } - @Override - public String description() { - return "Windows Management Instrumentation Command-line interface."; - } + @Override + public String description() { + return "Windows Management Instrumentation Command-line interface."; + } - @Override - public String usage() { - return "wmic [query]"; - } + @Override + public String usage() { + return "wmic [query]"; + } } diff --git a/src/main/java/com/mycmd/commands/XcopyCommand.java b/src/main/java/com/mycmd/commands/XcopyCommand.java index 4dc9149..b2138fb 100644 --- a/src/main/java/com/mycmd/commands/XcopyCommand.java +++ b/src/main/java/com/mycmd/commands/XcopyCommand.java @@ -13,68 +13,64 @@ */ public class XcopyCommand implements Command { - @Override - public void execute(String[] args, ShellContext context) throws IOException { - if (args.length == 0) { - System.out.println("Copies files and directory trees."); - System.out.println("\nXCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]]"); - System.out.println(" [/V] [/W] [/C] [/I] [/Q] [/F] [/L]"); - System.out.println(" [/H] [/R] [/T] [/U] [/K] [/N] [/O]"); - System.out.println(" [/X] [/Y] [/-Y] [/Z] [/B]"); - System.out.println( - "\n /S Copies directories and subdirectories except empty ones."); - System.out.println( - " /E Copies directories and subdirectories, including empty ones."); - System.out.println(" /Y Suppresses prompting to confirm overwriting."); - System.out.println( - " /I If destination does not exist and copying more than one file,"); - System.out.println(" assumes that destination must be a directory."); - return; - } + @Override + public void execute(String[] args, ShellContext context) throws IOException { + if (args.length == 0) { + System.out.println("Copies files and directory trees."); + System.out.println("\nXCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]]"); + System.out.println(" [/V] [/W] [/C] [/I] [/Q] [/F] [/L]"); + System.out.println(" [/H] [/R] [/T] [/U] [/K] [/N] [/O]"); + System.out.println(" [/X] [/Y] [/-Y] [/Z] [/B]"); + System.out.println("\n /S Copies directories and subdirectories except empty ones."); + System.out.println(" /E Copies directories and subdirectories, including empty ones."); + System.out.println(" /Y Suppresses prompting to confirm overwriting."); + System.out.println(" /I If destination does not exist and copying more than one file,"); + System.out.println(" assumes that destination must be a directory."); + return; + } - String os = System.getProperty("os.name").toLowerCase(); + String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - try { - StringBuilder cmdBuilder = new StringBuilder("xcopy"); - for (String arg : args) { - cmdBuilder.append(" \"").append(arg).append("\""); - } + if (os.contains("win")) { + try { + StringBuilder cmdBuilder = new StringBuilder("xcopy"); + for (String arg : args) { + cmdBuilder.append(" \"").append(arg).append("\""); + } - ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); - pb.directory(context.getCurrentDir()); - Process process = pb.start(); + ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString()); + pb.directory(context.getCurrentDir()); + Process process = pb.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - BufferedReader errorReader = - new BufferedReader(new InputStreamReader(process.getErrorStream())); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } - while ((line = errorReader.readLine()) != null) { - System.err.println(line); - } + while ((line = errorReader.readLine()) != null) { + System.err.println(line); + } - process.waitFor(); + process.waitFor(); - } catch (Exception e) { - System.out.println("Error executing xcopy: " + e.getMessage()); - } - } else { - System.out.println("XCOPY is not available on this system. Use 'cp -r' instead."); + } catch (Exception e) { + System.out.println("Error executing xcopy: " + e.getMessage()); + } + } else { + System.out.println("XCOPY is not available on this system. Use 'cp -r' instead."); + } } - } - @Override - public String description() { - return "Copies files and directory trees."; - } + @Override + public String description() { + return "Copies files and directory trees."; + } - @Override - public String usage() { - return "xcopy source [destination] [/S] [/E] [/Y]"; - } + @Override + public String usage() { + return "xcopy source [destination] [/S] [/E] [/Y]"; + } } diff --git a/src/main/java/com/mycmd/gui/MainApp.java b/src/main/java/com/mycmd/gui/MainApp.java index faaee80..9dd7945 100644 --- a/src/main/java/com/mycmd/gui/MainApp.java +++ b/src/main/java/com/mycmd/gui/MainApp.java @@ -10,42 +10,43 @@ /** JavaFX entry point — futuristic terminal window for MyCMD. */ public class MainApp extends Application { - private static ShellEngine engine; - private static ShellContext context; - private static CommandRegistry registry; - - @Override - public void start(Stage stage) throws Exception { - // initialize core shell - context = new ShellContext(); - registry = new CommandRegistry(); - engine = new ShellEngine(registry, context); - - // register built-in commands (auto load) - registerBuiltIns(); - - FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/mycmd/gui/terminal.fxml")); - Scene scene = new Scene(loader.load()); - scene.getStylesheets().add(getClass().getResource("/com/mycmd/gui/style.css").toExternalForm()); - - TerminalController controller = loader.getController(); - controller.init(engine, context); - - stage.setTitle("MyCMD ░▓ Java Terminal ▓░"); - stage.getIcons().add(new Image(getClass().getResourceAsStream("/com/mycmd/gui/icon.png"))); - stage.setScene(scene); - stage.setResizable(false); - stage.show(); - } - - private void registerBuiltIns() { - registry.register("alias", new com.mycmd.commands.AliasCommand()); - registry.register("dir", new com.mycmd.commands.DirCommand()); - registry.register("echo", new com.mycmd.commands.EchoCommand()); - // add others automatically here as you expand - } - - public static void main(String[] args) { - launch(); - } + private static ShellEngine engine; + private static ShellContext context; + private static CommandRegistry registry; + + @Override + public void start(Stage stage) throws Exception { + // initialize core shell + context = new ShellContext(); + registry = new CommandRegistry(); + engine = new ShellEngine(registry, context); + + // register built-in commands (auto load) + registerBuiltIns(); + + FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/mycmd/gui/terminal.fxml")); + Scene scene = new Scene(loader.load()); + scene.getStylesheets() + .add(getClass().getResource("/com/mycmd/gui/style.css").toExternalForm()); + + TerminalController controller = loader.getController(); + controller.init(engine, context); + + stage.setTitle("MyCMD ░▓ Java Terminal ▓░"); + stage.getIcons().add(new Image(getClass().getResourceAsStream("/com/mycmd/gui/icon.png"))); + stage.setScene(scene); + stage.setResizable(false); + stage.show(); + } + + private void registerBuiltIns() { + registry.register("alias", new com.mycmd.commands.AliasCommand()); + registry.register("dir", new com.mycmd.commands.DirCommand()); + registry.register("echo", new com.mycmd.commands.EchoCommand()); + // add others automatically here as you expand + } + + public static void main(String[] args) { + launch(); + } } diff --git a/src/main/java/com/mycmd/gui/TerminalController.java b/src/main/java/com/mycmd/gui/TerminalController.java index a1e93d3..d555575 100644 --- a/src/main/java/com/mycmd/gui/TerminalController.java +++ b/src/main/java/com/mycmd/gui/TerminalController.java @@ -11,33 +11,37 @@ /** Controller for the FXML terminal. */ public class TerminalController { - @FXML private TextArea outputArea; - @FXML private TextField inputField; - @FXML private ScrollPane scrollPane; - - private ShellEngine engine; - private ShellContext context; - - public void init(ShellEngine engine, ShellContext context) { - this.engine = engine; - this.context = context; - - output("💻 Welcome to MyCMD - Java made Terminal"); - output("Type 'help' for available commands.\n"); - - inputField.setOnKeyPressed( - event -> { - if (event.getCode() == KeyCode.ENTER) { - String input = inputField.getText(); - inputField.clear(); - output("> " + input); - engine.execute(input); - scrollPane.setVvalue(1.0); - } + @FXML + private TextArea outputArea; + + @FXML + private TextField inputField; + + @FXML + private ScrollPane scrollPane; + + private ShellEngine engine; + private ShellContext context; + + public void init(ShellEngine engine, ShellContext context) { + this.engine = engine; + this.context = context; + + output("💻 Welcome to MyCMD - Java made Terminal"); + output("Type 'help' for available commands.\n"); + + inputField.setOnKeyPressed(event -> { + if (event.getCode() == KeyCode.ENTER) { + String input = inputField.getText(); + inputField.clear(); + output("> " + input); + engine.execute(input); + scrollPane.setVvalue(1.0); + } }); - } + } - private void output(String text) { - outputArea.appendText(text + "\n"); - } + private void output(String text) { + outputArea.appendText(text + "\n"); + } } From 6e1b4f9617a9e50e046c53b0eed2040e3124819d Mon Sep 17 00:00:00 2001 From: Saurav Bhowmick <51038890+SauravBhowmick@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:40:06 +0100 Subject: [PATCH 3/7] Refactor : Update pom.xml --- pom.xml | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 2363e7a..cf23153 100644 --- a/pom.xml +++ b/pom.xml @@ -55,19 +55,27 @@ - + org.apache.maven.plugins - maven-jar-plugin - 3.3.0 - - - - true - com.mycmd.gui.MainApp - - - + maven-shade-plugin + 3.5.3 + + + package + + shade + + + false + + + com.mycmd.gui.MainApp + + + + + From b43b8fea9bfc178669d055c9dd46bb5f704e3e52 Mon Sep 17 00:00:00 2001 From: Anshuman Jadiya Date: Wed, 12 Nov 2025 16:28:01 +0530 Subject: [PATCH 4/7] Set minimum JRE version to 17 in build script --- scripts/build-windows.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-windows.bat b/scripts/build-windows.bat index ae13569..c4a11be 100644 --- a/scripts/build-windows.bat +++ b/scripts/build-windows.bat @@ -100,7 +100,7 @@ REM --- Regenerate Launch4j config XML dynamically --- echo ^%%JAVA_HOME%%;%%PATH%%^ echo ^false^ echo ^false^ - echo ^^ + echo ^17 echo ^^ echo ^ echo ^ From 5500162e7c8726fb89e968375d80e46b5c341d18 Mon Sep 17 00:00:00 2001 From: Anshuman Jadiya Date: Wed, 12 Nov 2025 16:48:59 +0530 Subject: [PATCH 5/7] Change timeout handling to throw IOException Throw IOException on command timeout instead of printing message. --- src/main/java/com/mycmd/commands/AssocCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/mycmd/commands/AssocCommand.java b/src/main/java/com/mycmd/commands/AssocCommand.java index 7a5d288..1338f6d 100644 --- a/src/main/java/com/mycmd/commands/AssocCommand.java +++ b/src/main/java/com/mycmd/commands/AssocCommand.java @@ -75,7 +75,7 @@ public void execute(String[] args, ShellContext context) throws IOException { if (!finished) { process.destroyForcibly(); - System.out.println("Command timed out."); + throw new IOException("Command timed out after 30 seconds"); } try { From 734fba1d6dc228225e500bde2498a02722b5e18c Mon Sep 17 00:00:00 2001 From: Anshuman Jadiya Date: Wed, 12 Nov 2025 16:51:52 +0530 Subject: [PATCH 6/7] Improve error handling in AssocCommand Refactor error handling in AssocCommand to throw IOExceptions. --- src/main/java/com/mycmd/commands/AssocCommand.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/mycmd/commands/AssocCommand.java b/src/main/java/com/mycmd/commands/AssocCommand.java index 1338f6d..22bf9b3 100644 --- a/src/main/java/com/mycmd/commands/AssocCommand.java +++ b/src/main/java/com/mycmd/commands/AssocCommand.java @@ -84,10 +84,11 @@ public void execute(String[] args, ShellContext context) throws IOException { Thread.currentThread().interrupt(); } - } catch (Exception e) { - System.out.println("Error executing assoc: " + e.getMessage()); - } - } + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new IOException("Error executing assoc", e); + } @Override public String description() { From 963f76aad3e6a4a546b20490fed50d44813858a8 Mon Sep 17 00:00:00 2001 From: Anshuman Jadiya Date: Wed, 12 Nov 2025 18:59:40 +0530 Subject: [PATCH 7/7] Enhance argument handling in XcopyCommand Escape quotes and special characters in arguments for xcopy command. --- src/main/java/com/mycmd/commands/XcopyCommand.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/mycmd/commands/XcopyCommand.java b/src/main/java/com/mycmd/commands/XcopyCommand.java index b2138fb..a7ca466 100644 --- a/src/main/java/com/mycmd/commands/XcopyCommand.java +++ b/src/main/java/com/mycmd/commands/XcopyCommand.java @@ -33,9 +33,12 @@ public void execute(String[] args, ShellContext context) throws IOException { if (os.contains("win")) { try { - StringBuilder cmdBuilder = new StringBuilder("xcopy"); - for (String arg : args) { - cmdBuilder.append(" \"").append(arg).append("\""); + StringBuilder cmdBuilder = new StringBuilder("xcopy"); + for (String arg : args) { + // Escape quotes and other special characters + String escaped = arg.replace("\"", "\\\""); + cmdBuilder.append(" \"").append(escaped).append("\""); + } } ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmdBuilder.toString());