Initial euclide.org release
This commit is contained in:
199
utils.go
Normal file
199
utils.go
Normal file
@@ -0,0 +1,199 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pyke369/golang-support/rcache"
|
||||
)
|
||||
|
||||
func stringInSlice(a string, list []string) bool {
|
||||
for _, b := range list {
|
||||
if b == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// inArray checks if there is a member of "search" in "list". sort list to be more
|
||||
// efficiant. adapt with sorting "search" too
|
||||
func inArray(search, list []string) bool {
|
||||
sort.Strings(list)
|
||||
for _, g := range search {
|
||||
i := sort.Search(len(list), func(i int) bool { return list[i] >= g })
|
||||
if i < len(list) && list[i] == g {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// printJSON pretty print d
|
||||
func printJSON(d interface{}) []byte {
|
||||
ret, _ := json.MarshalIndent(d, " ", " ")
|
||||
return ret
|
||||
}
|
||||
|
||||
// reverse the part order on every member of the array
|
||||
func reverse(s string) string {
|
||||
part := strings.Split(s, ".")
|
||||
for i, j := 0, len(part)-1; i < j; i, j = i+1, j-1 {
|
||||
part[i], part[j] = part[j], part[i]
|
||||
}
|
||||
return strings.Join(part, ".")
|
||||
}
|
||||
|
||||
// domainSort sort string by first reversing them
|
||||
func domainSort(s []string) {
|
||||
for i := range s {
|
||||
s[i] = reverse(s[i])
|
||||
}
|
||||
sort.Strings(s)
|
||||
for i := range s {
|
||||
s[i] = reverse(s[i])
|
||||
}
|
||||
}
|
||||
|
||||
func ptrToIP(s string) string {
|
||||
s = reverse(s)
|
||||
count := 0
|
||||
ip := ""
|
||||
version := 4
|
||||
for _, elt := range strings.Split(s, ".") {
|
||||
switch elt {
|
||||
case "":
|
||||
case "ip6":
|
||||
version = 6
|
||||
case "in-addr":
|
||||
case "arpa":
|
||||
default:
|
||||
count++
|
||||
ip += elt
|
||||
if version == 4 && count != 4 {
|
||||
ip += "."
|
||||
}
|
||||
if version == 6 && count%4 == 0 && count != 32 {
|
||||
ip += ":"
|
||||
}
|
||||
}
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
||||
func ipToInt(ip string) *big.Int {
|
||||
return big.NewInt(0).SetBytes([]byte(net.ParseIP(ip)))
|
||||
}
|
||||
|
||||
// iPtoReverse calculate the reverse name associated with an IPv4 or v6
|
||||
func iPtoReverse(ip net.IP) (arpa string) {
|
||||
const hexDigit = "0123456789abcdef"
|
||||
// code copied and adapted from the net library
|
||||
// ip can be 4 or 16 bytes long
|
||||
if ip.To4() != nil {
|
||||
if len(ip) == 16 {
|
||||
return uitoa(uint(ip[15])) + "." + uitoa(uint(ip[14])) + "." + uitoa(uint(ip[13])) + "." + uitoa(uint(ip[12])) + ".in-addr.arpa."
|
||||
}
|
||||
return uitoa(uint(ip[3])) + "." + uitoa(uint(ip[2])) + "." + uitoa(uint(ip[1])) + "." + uitoa(uint(ip[0])) + ".in-addr.arpa."
|
||||
}
|
||||
// Must be IPv6
|
||||
buf := make([]byte, 0, len(ip)*4+len("ip6.arpa."))
|
||||
|
||||
// Add it, in reverse, to the buffer
|
||||
for i := len(ip) - 1; i >= 0; i-- {
|
||||
v := ip[i]
|
||||
buf = append(buf, hexDigit[v&0xF])
|
||||
buf = append(buf, '.')
|
||||
buf = append(buf, hexDigit[v>>4])
|
||||
buf = append(buf, '.')
|
||||
}
|
||||
// Append "ip6.arpa." and return (buf already has the final .)
|
||||
buf = append(buf, "ip6.arpa."...)
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
// Convert unsigned integer to decimal string.
|
||||
// code copied from the net library
|
||||
func uitoa(val uint) string {
|
||||
if val == 0 { // avoid string allocation
|
||||
return "0"
|
||||
}
|
||||
var buf [20]byte // big enough for 64bit value base 10
|
||||
i := len(buf) - 1
|
||||
for val >= 10 {
|
||||
q := val / 10
|
||||
buf[i] = byte('0' + val - q*10)
|
||||
i--
|
||||
val = q
|
||||
}
|
||||
// val < 10
|
||||
buf[i] = byte('0' + val)
|
||||
return string(buf[i:])
|
||||
}
|
||||
|
||||
func trimPoint(s string) string {
|
||||
return strings.TrimRight(s, ".")
|
||||
}
|
||||
|
||||
func addPoint(s string) string {
|
||||
s = trimPoint(s)
|
||||
if !strings.HasSuffix(s, ".") && !strings.HasSuffix(s, "*") {
|
||||
s = s + "."
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// add double quotes at the begining and the end of the string.
|
||||
func addQuotes(s string) string {
|
||||
const q = "\""
|
||||
s = strings.Trim(s, q)
|
||||
s = strings.Replace(s, q, "\\\"", -1)
|
||||
return q + s + q
|
||||
}
|
||||
|
||||
func validSRVName(s string) bool {
|
||||
return rcache.Get("^_[a-z0-9]+\\._(tcp|udp|tls)[^ ]+$").MatchString(s)
|
||||
}
|
||||
|
||||
func validSRV(s string) string {
|
||||
// _service._proto.name. TTL class SRV priority weight port target.
|
||||
match := rcache.Get("^([0-9]+) +([0-9]+) +([0-9]+) +(.+)$").FindStringSubmatch(s)
|
||||
if len(match) > 0 && validName(match[4], false) {
|
||||
return match[4]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func validName(s string, wildcard bool) bool {
|
||||
if !wildcard {
|
||||
return rcache.Get(
|
||||
"^(([a-z0-9]|[a-z0-9_][a-z0-9_\\-]*[a-z0-9])\\.)*([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9])\\.$").MatchString(s)
|
||||
}
|
||||
return rcache.Get(
|
||||
"^(\\*\\.)?(([a-z0-9]|[a-z0-9_][a-z0-9_\\-]*[a-z0-9])\\.)*([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9])\\.$").MatchString(s)
|
||||
}
|
||||
|
||||
func validMX(s string) string {
|
||||
match := rcache.Get("^([0-9]+) +(.+)$").FindStringSubmatch(s)
|
||||
if len(match) > 0 && validName(match[2], false) {
|
||||
return match[2]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func validCAA(s string) string {
|
||||
match := rcache.Get("^([0-9]+) +(issue|issuewild|iodef) +(.+)$").FindStringSubmatch(s)
|
||||
if len(match) == 0 {
|
||||
return ""
|
||||
}
|
||||
i, _ := strconv.Atoi(match[1])
|
||||
if i < 0 || i > 255 {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s %s %s", match[1], match[2], addQuotes(match[3]))
|
||||
}
|
||||
Reference in New Issue
Block a user