package utils import ( "fmt" "github.com/urfave/cli/v2" "net" "strings" "sync" ) func getData(domain string, logIp bool) string { ips, _ := net.LookupIP(domain) var filteredIps []string for _, ip := range ips { if !ip.IsLoopback() { filteredIps = append(filteredIps, ip.String()) } } if len(filteredIps) > 0 { if logIp { return fmt.Sprintf( "%s\t%s", domain, strings.Join(filteredIps, " "), ) } } return "" } func runWorker( domain string, tlds chan string, logIp bool, ) <-chan string { results := make(chan string) go func() { defer close(results) for tld := range tlds { if result := getData(domain+tld, logIp); result != "" { results <- result } } }() return results } func merge(cs ...<-chan string) <-chan string { var wg sync.WaitGroup out := make(chan string) output := func(c <-chan string) { defer wg.Done() for n := range c { out <- n } } wg.Add(len(cs)) for _, c := range cs { go output(c) } go func() { wg.Wait() close(out) }() return out } func ProcessCli(cCtx *cli.Context) error { tlds := cCtx.String("tlds") threads := cCtx.Int("threads") var tldsList []string if tlds != "" { if err := ReadFileLines(tlds, &tldsList); err != nil { return err } } for argsIndex := 0; argsIndex < cCtx.Args().Len(); argsIndex++ { domain := cCtx.Args().Get(argsIndex) if tlds != "" { domain = domain + "." } tldsLine := make(chan string, 1) workers := make([]<-chan string, threads) for i := 0; i < threads; i++ { workers[i] = runWorker(domain, tldsLine, true) } for _, tld := range tldsList { tldsLine <- tld } close(tldsLine) for result := range merge(workers...) { fmt.Println(result) } } return nil }