|
| 1 | +package com.mycmd.commands; |
| 2 | + |
| 3 | +import com.mycmd.Command; |
| 4 | +import com.mycmd.ShellContext; |
| 5 | + |
1 | 6 | import java.io.BufferedReader; |
| 7 | +import java.io.IOException; |
2 | 8 | import java.io.InputStreamReader; |
3 | 9 |
|
4 | 10 | /** |
5 | | - * Executes the system ping command to test network connectivity. |
| 11 | + * Tests network connectivity to a given hostname or IP address. |
| 12 | + * |
| 13 | + * This command wraps the system ping utility to send ICMP echo requests |
| 14 | + * and displays response times or timeout status for each attempt. It uses |
| 15 | + * the native ping command available on the operating system. |
6 | 16 | * |
7 | | - * This is a standalone utility that wraps the Windows cmd.exe ping command. |
8 | | - * It executes the ping command as a subprocess and displays the output to |
9 | | - * the user, including network round-trip times and packet statistics. |
| 17 | + * Usage: |
| 18 | + * - ping <hostname> : Ping the specified host with default count (4 packets) |
| 19 | + * - ping <hostname> -t : Ping continuously until stopped (Windows-style) |
| 20 | + * - ping <hostname> -n <count> : Ping with specified packet count (Windows-style) |
10 | 21 | * |
11 | | - * Usage: java PingCommand hostname |
| 22 | + * Examples: |
| 23 | + * - ping google.com |
| 24 | + * - ping 8.8.8.8 |
| 25 | + * - ping google.com -n 10 |
12 | 26 | * |
13 | | - * Note: This implementation is Windows-specific as it uses "cmd.exe /c ping". |
14 | | - * The command requires at least one argument (the hostname or IP address to ping). |
15 | | - * It waits for the ping process to complete and displays the exit code. |
| 27 | + * Note: This implementation uses the system's native ping command for |
| 28 | + * accurate network connectivity testing and proper ICMP handling. |
16 | 29 | */ |
17 | | -public class PingCommand { |
18 | | - public static void main(String[] args) { |
19 | | - if (args.length < 1) { |
20 | | - System.out.println("Usage: java PingCommand <hostname>"); |
| 30 | +public class PingCommand implements Command { |
| 31 | + |
| 32 | + @Override |
| 33 | + public void execute(String[] args, ShellContext context) throws IOException { |
| 34 | + if (args.length == 0) { |
| 35 | + System.out.println("Usage: ping <hostname> [options]"); |
| 36 | + System.out.println("Options:"); |
| 37 | + System.out.println(" -t Ping continuously until stopped"); |
| 38 | + System.out.println(" -n <count> Number of echo requests to send"); |
| 39 | + System.out.println(); |
| 40 | + System.out.println("Examples:"); |
| 41 | + System.out.println(" ping google.com"); |
| 42 | + System.out.println(" ping 8.8.8.8"); |
| 43 | + System.out.println(" ping google.com -n 10"); |
21 | 44 | return; |
22 | 45 | } |
23 | 46 |
|
24 | 47 | String host = args[0]; |
| 48 | + |
| 49 | + // Build ping command based on operating system |
| 50 | + String[] command = buildPingCommand(host, args); |
25 | 51 |
|
26 | 52 | try { |
27 | | - // Run the ping command |
28 | | - Process process = Runtime.getRuntime().exec("cmd.exe /c ping " + host); |
| 53 | + // Execute the ping command |
| 54 | + ProcessBuilder pb = new ProcessBuilder(command); |
| 55 | + Process process = pb.start(); |
29 | 56 |
|
30 | | - // Read the output of the ping command |
| 57 | + // Read and display output in real-time |
31 | 58 | BufferedReader reader = new BufferedReader( |
32 | 59 | new InputStreamReader(process.getInputStream()) |
33 | 60 | ); |
| 61 | + BufferedReader errorReader = new BufferedReader( |
| 62 | + new InputStreamReader(process.getErrorStream()) |
| 63 | + ); |
34 | 64 |
|
35 | 65 | String line; |
| 66 | + // Display standard output |
36 | 67 | while ((line = reader.readLine()) != null) { |
37 | 68 | System.out.println(line); |
38 | 69 | } |
| 70 | + |
| 71 | + // Display error output if any |
| 72 | + while ((line = errorReader.readLine()) != null) { |
| 73 | + System.err.println(line); |
| 74 | + } |
39 | 75 |
|
40 | | - // Wait for the process to finish |
| 76 | + // Wait for the process to complete |
41 | 77 | int exitCode = process.waitFor(); |
42 | | - System.out.println("Ping command exited with code: " + exitCode); |
| 78 | + |
| 79 | + if (exitCode != 0) { |
| 80 | + System.out.println("Ping command failed with exit code: " + exitCode); |
| 81 | + } |
43 | 82 |
|
44 | | - } catch (Exception e) { |
45 | | - System.out.println("Error executing ping command."); |
46 | | - e.printStackTrace(); |
| 83 | + } catch (InterruptedException e) { |
| 84 | + System.out.println("Ping command was interrupted."); |
| 85 | + Thread.currentThread().interrupt(); |
| 86 | + } catch (IOException e) { |
| 87 | + throw new IOException("Failed to execute ping command: " + e.getMessage(), e); |
47 | 88 | } |
48 | 89 | } |
| 90 | + |
| 91 | + /** |
| 92 | + * Builds the appropriate ping command based on the operating system and arguments. |
| 93 | + */ |
| 94 | + private String[] buildPingCommand(String host, String[] args) { |
| 95 | + String os = System.getProperty("os.name").toLowerCase(); |
| 96 | + |
| 97 | + if (os.contains("win")) { |
| 98 | + return buildWindowsPingCommand(host, args); |
| 99 | + } else { |
| 100 | + return buildUnixPingCommand(host, args); |
| 101 | + } |
| 102 | + } |
| 103 | + |
| 104 | + /** |
| 105 | + * Builds ping command for Windows systems. |
| 106 | + */ |
| 107 | + private String[] buildWindowsPingCommand(String host, String[] args) { |
| 108 | + java.util.List<String> command = new java.util.ArrayList<>(); |
| 109 | + command.add("ping"); |
| 110 | + |
| 111 | + // Parse arguments for Windows ping options |
| 112 | + boolean continuous = false; |
| 113 | + int count = 4; // Default count |
| 114 | + |
| 115 | + for (int i = 1; i < args.length; i++) { |
| 116 | + if ("-t".equals(args[i])) { |
| 117 | + continuous = true; |
| 118 | + } else if ("-n".equals(args[i]) && i + 1 < args.length) { |
| 119 | + try { |
| 120 | + count = Integer.parseInt(args[i + 1]); |
| 121 | + i++; // Skip the next argument as it's the count value |
| 122 | + } catch (NumberFormatException e) { |
| 123 | + System.out.println("Warning: Invalid count value, using default (4)"); |
| 124 | + } |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + if (continuous) { |
| 129 | + command.add("-t"); |
| 130 | + } else { |
| 131 | + command.add("-n"); |
| 132 | + command.add(String.valueOf(count)); |
| 133 | + } |
| 134 | + |
| 135 | + command.add(host); |
| 136 | + return command.toArray(new String[0]); |
| 137 | + } |
| 138 | + |
| 139 | + /** |
| 140 | + * Builds ping command for Unix-like systems (Linux, macOS). |
| 141 | + */ |
| 142 | + private String[] buildUnixPingCommand(String host, String[] args) { |
| 143 | + java.util.List<String> command = new java.util.ArrayList<>(); |
| 144 | + command.add("ping"); |
| 145 | + |
| 146 | + // Parse arguments for Unix ping options |
| 147 | + int count = 4; // Default count |
| 148 | + |
| 149 | + for (int i = 1; i < args.length; i++) { |
| 150 | + if ("-t".equals(args[i])) { |
| 151 | + // Unix ping doesn't use -t, just omit count for continuous |
| 152 | + count = -1; |
| 153 | + } else if ("-n".equals(args[i]) && i + 1 < args.length) { |
| 154 | + try { |
| 155 | + count = Integer.parseInt(args[i + 1]); |
| 156 | + i++; // Skip the next argument as it's the count value |
| 157 | + } catch (NumberFormatException e) { |
| 158 | + System.out.println("Warning: Invalid count value, using default (4)"); |
| 159 | + } |
| 160 | + } |
| 161 | + } |
| 162 | + |
| 163 | + if (count > 0) { |
| 164 | + command.add("-c"); |
| 165 | + command.add(String.valueOf(count)); |
| 166 | + } |
| 167 | + |
| 168 | + command.add(host); |
| 169 | + return command.toArray(new String[0]); |
| 170 | + } |
| 171 | + |
| 172 | + @Override |
| 173 | + public String description() { |
| 174 | + return "Tests network connectivity to a hostname or IP address"; |
| 175 | + } |
| 176 | + |
| 177 | + @Override |
| 178 | + public String usage() { |
| 179 | + return "ping <hostname> [options]"; |
| 180 | + } |
49 | 181 | } |
0 commit comments