Skip to content

Commit d4b7d20

Browse files
Merge pull request #61 from thidaskaveesha/feat.pingCMD
[FEATURE] Ping Command #58
2 parents e9e98c5 + f5ef4c6 commit d4b7d20

File tree

2 files changed

+153
-20
lines changed

2 files changed

+153
-20
lines changed

src/main/java/com/mycmd/App.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ private static void registerCommands(Map<String, Command> commands) {
7777
commands.put("tree", new TreeCommand());
7878
commands.put("date", new DateCommand());
7979
commands.put("history", new HistoryCommand());
80+
commands.put("ping", new PingCommand());
8081
commands.put("pwd", new PwdCommand());
8182
commands.put("uptime", new UptimeCommand());
8283
commands.put("clearhistory", new ClearHistoryCommand());
Lines changed: 152 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,181 @@
1+
package com.mycmd.commands;
2+
3+
import com.mycmd.Command;
4+
import com.mycmd.ShellContext;
5+
16
import java.io.BufferedReader;
7+
import java.io.IOException;
28
import java.io.InputStreamReader;
39

410
/**
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.
616
*
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)
1021
*
11-
* Usage: java PingCommand hostname
22+
* Examples:
23+
* - ping google.com
24+
* - ping 8.8.8.8
25+
* - ping google.com -n 10
1226
*
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.
1629
*/
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");
2144
return;
2245
}
2346

2447
String host = args[0];
48+
49+
// Build ping command based on operating system
50+
String[] command = buildPingCommand(host, args);
2551

2652
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();
2956

30-
// Read the output of the ping command
57+
// Read and display output in real-time
3158
BufferedReader reader = new BufferedReader(
3259
new InputStreamReader(process.getInputStream())
3360
);
61+
BufferedReader errorReader = new BufferedReader(
62+
new InputStreamReader(process.getErrorStream())
63+
);
3464

3565
String line;
66+
// Display standard output
3667
while ((line = reader.readLine()) != null) {
3768
System.out.println(line);
3869
}
70+
71+
// Display error output if any
72+
while ((line = errorReader.readLine()) != null) {
73+
System.err.println(line);
74+
}
3975

40-
// Wait for the process to finish
76+
// Wait for the process to complete
4177
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+
}
4382

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);
4788
}
4889
}
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+
}
49181
}

0 commit comments

Comments
 (0)