You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.4 KiB

package main
import (
"bytes"
"fmt"
"net"
"os"
"os/exec"
"sort"
"strings"
"sync"
"time"
)
// PingResult holds the result of a ping operation
type PingResult struct {
IP net.IP
Message string
}
// parseIP parses the string IP to net.IP
func parseIP(ipStr string) net.IP {
return net.ParseIP(ipStr)
}
// pingIP pings an IP address and sends a PingResult to the results channel.
func pingIP(ipStr string, wg *sync.WaitGroup, results chan<- PingResult) {
defer wg.Done()
ip := parseIP(ipStr)
cmd := exec.Command("ping", "-c", "3", "-W", "5", ipStr)
if err := cmd.Run(); err != nil {
results <- PingResult{IP: ip, Message: fmt.Sprintf("\x1b[0m%s\x1b[0m is \x1b[1m\x1b[31mdown\x1b[0m", ipStr)}
} else {
results <- PingResult{IP: ip, Message: fmt.Sprintf("\x1b[1m%s\x1b[0m is \x1b[1m\x1b[32mup\x1b[0m", ipStr)}
}
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: chkip <IP1> <IP2> <IP3> ...")
return
}
var wg sync.WaitGroup
results := make(chan PingResult, len(os.Args)-1)
// Start the spinner in a goroutine
stopSpinner := make(chan struct{})
go func() {
spinner := []rune{'-', '\\', '|', '/'}
i := 0
for {
select {
case <-stopSpinner:
return
default:
fmt.Printf("\rPlease wait... %c", spinner[i%len(spinner)])
i++
time.Sleep(100 * time.Millisecond) // Adjust speed as needed
}
}
}()
// Start a goroutine for each IP address.
for _, ipStr := range os.Args[1:] {
wg.Add(1)
go pingIP(ipStr, &wg, results)
}
// Close the results channel once all goroutines have finished.
go func() {
wg.Wait()
close(results)
fmt.Printf("\r%s\r", strings.Repeat(" ", 16)) // Use enough spaces to cover the expected line length
}()
// Collect results
pingResults := make([]PingResult, 0, len(os.Args)-1)
for result := range results {
pingResults = append(pingResults, result)
}
// Sort results based on IP address
sort.Slice(pingResults, func(i, j int) bool {
return bytes.Compare(pingResults[i].IP, pingResults[j].IP) < 0
})
// Print sorted results
for _, result := range pingResults {
fmt.Println(result.Message)
}
}