1package util 2 3import ( 4 "fmt" 5 "net" 6 "net/url" 7 "strings" 8 9 "github.com/future-architect/vuls/config" 10) 11 12// GenWorkers generates goroutine 13// http://qiita.com/na-o-ys/items/65373132b1c5bc973cca 14func GenWorkers(num int) chan<- func() { 15 tasks := make(chan func()) 16 for i := 0; i < num; i++ { 17 go func() { 18 defer func() { 19 if p := recover(); p != nil { 20 log := NewCustomLogger(config.ServerInfo{}) 21 log.Errorf("run time panic: %v", p) 22 } 23 }() 24 for f := range tasks { 25 f() 26 } 27 }() 28 } 29 return tasks 30} 31 32// AppendIfMissing append to the slice if missing 33func AppendIfMissing(slice []string, s string) []string { 34 for _, ele := range slice { 35 if ele == s { 36 return slice 37 } 38 } 39 return append(slice, s) 40} 41 42// URLPathJoin make URL 43func URLPathJoin(baseURL string, paths ...string) (string, error) { 44 baseURL = strings.TrimSuffix(baseURL, "/") 45 trimmedPaths := []string{} 46 for _, path := range paths { 47 trimmed := strings.Trim(path, " /") 48 if len(trimmed) != 0 { 49 trimmedPaths = append(trimmedPaths, trimmed) 50 } 51 } 52 var url *url.URL 53 url, err := url.Parse(baseURL) 54 if err != nil { 55 return "", err 56 } 57 url.Path += "/" + strings.Join(trimmedPaths, "/") 58 return url.String(), nil 59} 60 61// URLPathParamJoin make URL 62func URLPathParamJoin(baseURL string, paths []string, params map[string]string) (string, error) { 63 urlPath, err := URLPathJoin(baseURL, paths...) 64 if err != nil { 65 return "", err 66 } 67 u, err := url.Parse(urlPath) 68 if err != nil { 69 return "", err 70 } 71 72 parameters := url.Values{} 73 for key := range params { 74 parameters.Add(key, params[key]) 75 } 76 u.RawQuery = parameters.Encode() 77 return u.String(), nil 78} 79 80// IP returns scanner network ip addresses 81func IP() (ipv4Addrs []string, ipv6Addrs []string, err error) { 82 ifaces, err := net.Interfaces() 83 if err != nil { 84 return nil, nil, err 85 } 86 for _, i := range ifaces { 87 addrs, _ := i.Addrs() 88 for _, addr := range addrs { 89 var ip net.IP 90 switch v := addr.(type) { 91 case *net.IPNet: 92 ip = v.IP 93 case *net.IPAddr: 94 ip = v.IP 95 } 96 97 // only global unicast address 98 if !ip.IsGlobalUnicast() { 99 continue 100 } 101 102 if ok := ip.To4(); ok != nil { 103 ipv4Addrs = append(ipv4Addrs, ip.String()) 104 } else { 105 ipv6Addrs = append(ipv6Addrs, ip.String()) 106 } 107 } 108 } 109 return ipv4Addrs, ipv6Addrs, nil 110} 111 112// ProxyEnv returns shell environment variables to set proxy 113func ProxyEnv() string { 114 httpProxyEnv := "" 115 keys := []string{ 116 "http_proxy", 117 "https_proxy", 118 "HTTP_PROXY", 119 "HTTPS_PROXY", 120 } 121 for _, key := range keys { 122 httpProxyEnv += fmt.Sprintf( 123 ` %s="%s"`, key, config.Conf.HTTPProxy) 124 } 125 return httpProxyEnv 126} 127 128// PrependProxyEnv prepends proxy environment variable 129func PrependProxyEnv(cmd string) string { 130 if len(config.Conf.HTTPProxy) == 0 { 131 return cmd 132 } 133 return fmt.Sprintf("%s %s", ProxyEnv(), cmd) 134} 135 136// func unixtime(s string) (time.Time, error) { 137// i, err := strconv.ParseInt(s, 10, 64) 138// if err != nil { 139// return time.Time{}, err 140// } 141// return time.Unix(i, 0), nil 142// } 143 144// Truncate truncates string to the length 145func Truncate(str string, length int) string { 146 if length < 0 { 147 return str 148 } 149 if length <= len(str) { 150 return str[:length] 151 } 152 return str 153} 154 155// Distinct a slice 156func Distinct(ss []string) (distincted []string) { 157 m := map[string]bool{} 158 for _, s := range ss { 159 if _, found := m[s]; !found { 160 m[s] = true 161 distincted = append(distincted, s) 162 } 163 } 164 return 165} 166