1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
| package main
import (
"bufio"
"flag"
"fmt"
"io"
"os"
"strings"
"sync"
)
//https://manytools.org/hacker-tools/ascii-banner/
// Rounded font
const banner = ``
const common_usage = `ishttp: check if a port is http/https in minimal effort
echo qq.com | ishttp`
type Options struct {
threadNum int
InputFile string
OutputFile string
help bool
timeout int
}
var options = &Options{}
const symbol_for_os_stdin = "os.Stdin"
func main() {
initprog()
doSth()
}
func initprog() {
flag.IntVar(&options.threadNum,"t",30,"线程数")
flag.IntVar(&options.timeout,"w",5,"每次请求默认超时时间")
flag.BoolVar(&options.help,"h",false,"打印帮助")
flag.StringVar(&options.InputFile,"iL",symbol_for_os_stdin,"输入文件")
flag.StringVar(&options.OutputFile,"o","os.Stdout","输出文件(当前不支持自定义此选项)")
flag.Usage = func() {
fmt.Fprintln(os.Stderr, banner)
flag.PrintDefaults()
fmt.Fprintln(os.Stderr, common_usage)
}
flag.Parse()
if (options.InputFile==symbol_for_os_stdin && !hasStdin()) || options.help{
flag.Usage()
os.Exit(0)
}
}
func hasStdin() bool {
//https://stackoverflow.com/questions/22563616/determine-if-stdin-has-data-with-go
fi, err := os.Stdin.Stat()
if err != nil {
panic(err)
}
return fi.Mode()&os.ModeNamedPipe != 0
}
func throwErr(errdesc string, err error) {
fmt.Fprintln(os.Stderr, strings.Repeat("-", 50))
fmt.Fprintln(os.Stderr, errdesc)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
}
fmt.Fprintln(os.Stderr, strings.Repeat("-", 50))
}
func doSth() {
//读取输入
var inputScanner *bufio.Scanner
var finput io.Reader
if options.InputFile==symbol_for_os_stdin {
finput = os.Stdin
} else {
var err error
finput,err = os.Open(options.InputFile)
if err!=nil{
throwErr("打开输入文件失败",err)
}
}
inputScanner = bufio.NewScanner(finput)
var wg sync.WaitGroup
var ch = make(chan struct{}, options.threadNum)
for inputScanner.Scan() {
entry := inputScanner.Text()
wg.Add(1)
ch <- struct{}{} // acquire a token
go func(single_entry string) {
defer wg.Done()
doSthUnit(single_entry)
<-ch // release the token
}(entry)
}
wg.Wait()
}
func doSthUnit(entry string) {
fmt.Fprintln(os.Stdout, entry)
}
|