|
|
|
@ -1,213 +1,442 @@
|
|
|
|
|
package hosts
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
"bufio"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"net"
|
|
|
|
|
"os"
|
|
|
|
|
"runtime"
|
|
|
|
|
"strings"
|
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
|
|
"b612.me/staros/sysconf"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var hostsPath string
|
|
|
|
|
var hostsCfg *sysconf.SysConf
|
|
|
|
|
var haveError error
|
|
|
|
|
var lock sync.Mutex
|
|
|
|
|
var reverse bool = false
|
|
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
func SystemHostpath() string {
|
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
|
hostsPath = `C:\Windows\System32\drivers\etc\hosts`
|
|
|
|
|
} else {
|
|
|
|
|
hostsPath = `/etc/hosts`
|
|
|
|
|
return `C:\Windows\System32\drivers\etc\hosts`
|
|
|
|
|
}
|
|
|
|
|
return `/etc/hosts`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func SetHostsPath(path string) {
|
|
|
|
|
hostsPath = path
|
|
|
|
|
type HostNode struct {
|
|
|
|
|
uid uint64
|
|
|
|
|
nextuid uint64
|
|
|
|
|
lastuid uint64
|
|
|
|
|
IP string
|
|
|
|
|
Host []string
|
|
|
|
|
Comment string
|
|
|
|
|
Original string
|
|
|
|
|
OnlyComment bool
|
|
|
|
|
Valid bool
|
|
|
|
|
}
|
|
|
|
|
type Host struct {
|
|
|
|
|
idx uint64
|
|
|
|
|
hostPath string
|
|
|
|
|
nextUid uint64
|
|
|
|
|
lastUid uint64
|
|
|
|
|
fulldata map[uint64]*HostNode
|
|
|
|
|
hostData map[string][]*HostNode
|
|
|
|
|
ipData map[string][]*HostNode
|
|
|
|
|
sync.RWMutex
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetHostsPath() string {
|
|
|
|
|
return hostsPath
|
|
|
|
|
func NewHosts() *Host {
|
|
|
|
|
return &Host{
|
|
|
|
|
hostData: make(map[string][]*HostNode),
|
|
|
|
|
ipData: make(map[string][]*HostNode),
|
|
|
|
|
fulldata: make(map[uint64]*HostNode),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Parse() error {
|
|
|
|
|
hostsCfg = new(sysconf.SysConf)
|
|
|
|
|
hostsCfg.EqualFlag = ` `
|
|
|
|
|
hostsCfg.HaveSegMent = false
|
|
|
|
|
hostsCfg.CommentCR = true
|
|
|
|
|
hostsCfg.CommentFlag = []string{"#"}
|
|
|
|
|
data, haveError := ioutil.ReadFile(hostsPath)
|
|
|
|
|
if haveError != nil {
|
|
|
|
|
return haveError
|
|
|
|
|
}
|
|
|
|
|
data = bytes.ReplaceAll(data, []byte(` `), []byte(" "))
|
|
|
|
|
haveError = hostsCfg.Parse(data)
|
|
|
|
|
return haveError
|
|
|
|
|
|
|
|
|
|
func (h *Host) Parse(hostPath string) error {
|
|
|
|
|
h.Lock()
|
|
|
|
|
defer h.Unlock()
|
|
|
|
|
h.hostPath = hostPath
|
|
|
|
|
h.fulldata = make(map[uint64]*HostNode)
|
|
|
|
|
h.hostData = make(map[string][]*HostNode)
|
|
|
|
|
h.ipData = make(map[string][]*HostNode)
|
|
|
|
|
return h.parse()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetIpByDomain(domainName string) []string {
|
|
|
|
|
if haveError != nil {
|
|
|
|
|
return []string{}
|
|
|
|
|
func (h *Host) parse() error {
|
|
|
|
|
f, err := os.OpenFile(h.hostPath, os.O_RDONLY, 0666)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("open hosts file %s error: %s", h.hostPath, err)
|
|
|
|
|
}
|
|
|
|
|
defer f.Close()
|
|
|
|
|
buf := bufio.NewReader(f)
|
|
|
|
|
for {
|
|
|
|
|
line, err := buf.ReadString('\n')
|
|
|
|
|
if err == io.EOF {
|
|
|
|
|
if h.idx-1 >= 0 {
|
|
|
|
|
h.fulldata[h.idx].nextuid = 0
|
|
|
|
|
h.lastUid = h.idx
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("read hosts file error: %s", err)
|
|
|
|
|
}
|
|
|
|
|
h.idx++
|
|
|
|
|
line = strings.TrimSpace(line)
|
|
|
|
|
data, _ := h.parseLine(line)
|
|
|
|
|
data.uid = h.idx
|
|
|
|
|
data.lastuid = h.idx - 1
|
|
|
|
|
data.nextuid = h.idx + 1
|
|
|
|
|
h.fulldata[data.uid] = &data
|
|
|
|
|
if h.nextUid == 0 {
|
|
|
|
|
h.nextUid = h.idx
|
|
|
|
|
}
|
|
|
|
|
if data.Valid {
|
|
|
|
|
for _, v := range data.Host {
|
|
|
|
|
h.hostData[v] = append(h.hostData[v], &data)
|
|
|
|
|
}
|
|
|
|
|
h.ipData[data.IP] = append(h.ipData[data.IP], &data)
|
|
|
|
|
}
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if !reverse {
|
|
|
|
|
hostsCfg.Reverse()
|
|
|
|
|
reverse = !reverse
|
|
|
|
|
}
|
|
|
|
|
return hostsCfg.Data[0].GetAll(domainName)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetDomainByIp(IpAddr string) []string {
|
|
|
|
|
if haveError != nil {
|
|
|
|
|
return []string{}
|
|
|
|
|
func (h *Host) parseLine(data string) (HostNode, error) {
|
|
|
|
|
var res = HostNode{
|
|
|
|
|
Original: data,
|
|
|
|
|
}
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if reverse {
|
|
|
|
|
hostsCfg.Reverse()
|
|
|
|
|
reverse = !reverse
|
|
|
|
|
if len(data) == 0 {
|
|
|
|
|
return res, fmt.Errorf("empty line")
|
|
|
|
|
}
|
|
|
|
|
return hostsCfg.Data[0].GetAll(IpAddr)
|
|
|
|
|
if data[0] == '#' {
|
|
|
|
|
res.Comment = data
|
|
|
|
|
res.OnlyComment = true
|
|
|
|
|
return res, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func AddHosts(ip, host string) {
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if reverse {
|
|
|
|
|
hostsCfg.Data[0].AddValue(host, ip, "")
|
|
|
|
|
} else {
|
|
|
|
|
hostsCfg.Data[0].AddValue(ip, host, "")
|
|
|
|
|
var dataArr []string
|
|
|
|
|
cache := ""
|
|
|
|
|
for k, v := range data {
|
|
|
|
|
if v == '#' {
|
|
|
|
|
if len(cache) > 0 {
|
|
|
|
|
dataArr = append(dataArr, cache)
|
|
|
|
|
cache = ""
|
|
|
|
|
}
|
|
|
|
|
dataArr = append(dataArr, data[k:])
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func RemoveHost(ip, host string) {
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if reverse {
|
|
|
|
|
hostsCfg.Data[0].DeleteValue(host, ip)
|
|
|
|
|
if v == ' ' || v == '\t' {
|
|
|
|
|
if len(cache) > 0 {
|
|
|
|
|
dataArr = append(dataArr, cache)
|
|
|
|
|
cache = ""
|
|
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
cache += string(v)
|
|
|
|
|
}
|
|
|
|
|
if len(cache) > 0 {
|
|
|
|
|
dataArr = append(dataArr, cache)
|
|
|
|
|
}
|
|
|
|
|
if len(dataArr) < 2 {
|
|
|
|
|
return res, fmt.Errorf("invalid line")
|
|
|
|
|
}
|
|
|
|
|
if strings.HasPrefix(dataArr[1], "#") {
|
|
|
|
|
return res, fmt.Errorf("invalid line")
|
|
|
|
|
}
|
|
|
|
|
if net.ParseIP(dataArr[0]) == nil {
|
|
|
|
|
return res, fmt.Errorf("invalid ip address")
|
|
|
|
|
}
|
|
|
|
|
for k, v := range dataArr {
|
|
|
|
|
switch k {
|
|
|
|
|
case 0:
|
|
|
|
|
res.IP = v
|
|
|
|
|
default:
|
|
|
|
|
if strings.HasPrefix(v, "#") {
|
|
|
|
|
res.Comment = v
|
|
|
|
|
} else {
|
|
|
|
|
hostsCfg.Data[0].DeleteValue(ip, host)
|
|
|
|
|
res.Host = append(res.Host, v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
res.Valid = true
|
|
|
|
|
return res, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func RemoveHostbyIp(ip string) {
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if reverse {
|
|
|
|
|
hostsCfg.Reverse()
|
|
|
|
|
reverse = !reverse
|
|
|
|
|
func (h *Host) List() []*HostNode {
|
|
|
|
|
h.RLock()
|
|
|
|
|
defer h.RUnlock()
|
|
|
|
|
var res []*HostNode
|
|
|
|
|
nextUid := h.nextUid
|
|
|
|
|
for {
|
|
|
|
|
if nextUid == 0 {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
res = append(res, h.fulldata[nextUid])
|
|
|
|
|
nextUid = h.fulldata[nextUid].nextuid
|
|
|
|
|
}
|
|
|
|
|
hostsCfg.Data[0].Delete(ip)
|
|
|
|
|
return res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func RemoveHostbyHost(host string) {
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if !reverse {
|
|
|
|
|
hostsCfg.Reverse()
|
|
|
|
|
reverse = !reverse
|
|
|
|
|
func (h *Host) ListByHost(host string) []*HostNode {
|
|
|
|
|
h.RLock()
|
|
|
|
|
defer h.RUnlock()
|
|
|
|
|
if h.hostData == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
hostsCfg.Data[0].Delete(host)
|
|
|
|
|
return h.hostData[host]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SetHost 设定唯一的Host对应值,一个host对应一个ip,其余的删除
|
|
|
|
|
func SetHost(ip, host string) {
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if !reverse {
|
|
|
|
|
hostsCfg.Reverse()
|
|
|
|
|
reverse = !reverse
|
|
|
|
|
func (h *Host) ListIPsByHost(host string) []string {
|
|
|
|
|
h.RLock()
|
|
|
|
|
defer h.RUnlock()
|
|
|
|
|
if h.hostData == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
hostsCfg.Data[0].Set(host, ip, "")
|
|
|
|
|
var res []string
|
|
|
|
|
for _, v := range h.hostData[host] {
|
|
|
|
|
res = append(res, v.IP)
|
|
|
|
|
}
|
|
|
|
|
return res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func SetHostbyIp(ip, host string) {
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if reverse {
|
|
|
|
|
hostsCfg.Reverse()
|
|
|
|
|
reverse = !reverse
|
|
|
|
|
func (h *Host) ListFirstIPByHost(host string) string {
|
|
|
|
|
h.RLock()
|
|
|
|
|
defer h.RUnlock()
|
|
|
|
|
if h.hostData == nil {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
hostsCfg.Data[0].Set(ip, host, "")
|
|
|
|
|
for _, v := range h.hostData[host] {
|
|
|
|
|
return v.IP
|
|
|
|
|
}
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Build() string {
|
|
|
|
|
if reverse {
|
|
|
|
|
hostsCfg.Reverse()
|
|
|
|
|
reverse = !reverse
|
|
|
|
|
func (h *Host) ListByIP(ip string) []*HostNode {
|
|
|
|
|
h.RLock()
|
|
|
|
|
defer h.RUnlock()
|
|
|
|
|
if h.ipData == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return string(hostsCfg.Build())
|
|
|
|
|
return h.ipData[ip]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Write() error {
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
data := []byte(Build())
|
|
|
|
|
return ioutil.WriteFile(hostsPath, data, 0644)
|
|
|
|
|
func (h *Host) ListHostsByIP(ip string) []string {
|
|
|
|
|
h.RLock()
|
|
|
|
|
return h.listHostsByIP(ip)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetHostList() []string {
|
|
|
|
|
func (h *Host) listHostsByIP(ip string) []string {
|
|
|
|
|
if h.ipData == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
var res []string
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if !reverse {
|
|
|
|
|
hostsCfg.Reverse()
|
|
|
|
|
reverse = !reverse
|
|
|
|
|
for _, v := range h.ipData[ip] {
|
|
|
|
|
res = append(res, v.Host...)
|
|
|
|
|
}
|
|
|
|
|
for _, v := range hostsCfg.Data[0].NodeData {
|
|
|
|
|
if v != nil {
|
|
|
|
|
res = append(res, v.Key)
|
|
|
|
|
return res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Host) ListFirstHostByIP(ip string) string {
|
|
|
|
|
h.RLock()
|
|
|
|
|
defer h.RUnlock()
|
|
|
|
|
if h.ipData == nil {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
for _, v := range h.ipData[ip] {
|
|
|
|
|
if len(v.Host) > 0 {
|
|
|
|
|
return v.Host[0]
|
|
|
|
|
}
|
|
|
|
|
return res
|
|
|
|
|
}
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetIpList() []string {
|
|
|
|
|
var res []string
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if reverse {
|
|
|
|
|
hostsCfg.Reverse()
|
|
|
|
|
reverse = !reverse
|
|
|
|
|
func (h *Host) AddHosts(ip string, hosts ...string) error {
|
|
|
|
|
return h.addHosts("", ip, hosts...)
|
|
|
|
|
}
|
|
|
|
|
for _, v := range hostsCfg.Data[0].NodeData {
|
|
|
|
|
if v != nil {
|
|
|
|
|
res = append(res, v.Key)
|
|
|
|
|
|
|
|
|
|
func (h *Host) AddHostsComment(comment string, ip string, hosts ...string) error {
|
|
|
|
|
return h.addHosts(comment, ip, hosts...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Host) RemoveIPHosts(ip string, hosts ...string) error {
|
|
|
|
|
h.Lock()
|
|
|
|
|
defer h.Unlock()
|
|
|
|
|
if h.ipData == nil {
|
|
|
|
|
return fmt.Errorf("hosts data not initialized")
|
|
|
|
|
}
|
|
|
|
|
ipInfo := h.ipData[ip]
|
|
|
|
|
if len(ipInfo) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
cntfor:
|
|
|
|
|
for _, v := range ipInfo {
|
|
|
|
|
for _, host := range hosts {
|
|
|
|
|
if len(v.Host) == 1 && v.Host[0] == host {
|
|
|
|
|
delete(h.ipData, ip)
|
|
|
|
|
if v.lastuid != 0 {
|
|
|
|
|
h.fulldata[v.lastuid].nextuid = v.nextuid
|
|
|
|
|
} else {
|
|
|
|
|
h.nextUid = v.nextuid
|
|
|
|
|
}
|
|
|
|
|
return res
|
|
|
|
|
if v.nextuid != 0 {
|
|
|
|
|
h.fulldata[v.nextuid].lastuid = v.lastuid
|
|
|
|
|
} else {
|
|
|
|
|
h.lastUid = v.lastuid
|
|
|
|
|
}
|
|
|
|
|
var newHostData []*HostNode
|
|
|
|
|
for _, vv := range h.hostData[v.Host[0]] {
|
|
|
|
|
if vv.uid != v.uid {
|
|
|
|
|
newHostData = append(newHostData, vv)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
h.hostData[host] = newHostData
|
|
|
|
|
delete(h.fulldata, v.uid)
|
|
|
|
|
v = nil
|
|
|
|
|
continue cntfor
|
|
|
|
|
}
|
|
|
|
|
if len(v.Host) > 1 {
|
|
|
|
|
var newHosts []string
|
|
|
|
|
for _, vv := range v.Host {
|
|
|
|
|
if vv != host {
|
|
|
|
|
newHosts = append(newHosts, vv)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
v.Host = newHosts
|
|
|
|
|
var newHostData []*HostNode
|
|
|
|
|
for _, vv := range h.hostData[host] {
|
|
|
|
|
if vv.uid != v.uid {
|
|
|
|
|
newHostData = append(newHostData, vv)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
h.hostData[host] = newHostData
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetAllListbyHost() map[string][]string {
|
|
|
|
|
res := make(map[string][]string)
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if !reverse {
|
|
|
|
|
hostsCfg.Reverse()
|
|
|
|
|
reverse = !reverse
|
|
|
|
|
func (h *Host) RemoveIPs(ips ...string) error {
|
|
|
|
|
h.Lock()
|
|
|
|
|
defer h.Unlock()
|
|
|
|
|
if h.ipData == nil {
|
|
|
|
|
return fmt.Errorf("hosts data not initialized")
|
|
|
|
|
}
|
|
|
|
|
for _, ip := range ips {
|
|
|
|
|
ipInfo := h.ipData[ip]
|
|
|
|
|
if len(ipInfo) == 0 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
for _, v := range ipInfo {
|
|
|
|
|
delete(h.ipData, ip)
|
|
|
|
|
delete(h.fulldata, v.uid)
|
|
|
|
|
if v.lastuid != 0 {
|
|
|
|
|
h.fulldata[v.lastuid].nextuid = v.nextuid
|
|
|
|
|
} else {
|
|
|
|
|
h.nextUid = v.nextuid
|
|
|
|
|
}
|
|
|
|
|
for _, v := range hostsCfg.Data[0].NodeData {
|
|
|
|
|
if v != nil {
|
|
|
|
|
res[v.Key] = v.Value
|
|
|
|
|
if v.nextuid != 0 {
|
|
|
|
|
h.fulldata[v.nextuid].lastuid = v.lastuid
|
|
|
|
|
} else {
|
|
|
|
|
h.lastUid = v.lastuid
|
|
|
|
|
}
|
|
|
|
|
for _, host := range v.Host {
|
|
|
|
|
var newHostData []*HostNode
|
|
|
|
|
for _, vv := range h.hostData[host] {
|
|
|
|
|
if vv.uid != v.uid {
|
|
|
|
|
newHostData = append(newHostData, vv)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
h.hostData[host] = newHostData
|
|
|
|
|
}
|
|
|
|
|
return res
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetAllListbyIp() map[string][]string {
|
|
|
|
|
res := make(map[string][]string)
|
|
|
|
|
lock.Lock()
|
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
if reverse {
|
|
|
|
|
hostsCfg.Reverse()
|
|
|
|
|
reverse = !reverse
|
|
|
|
|
func (h *Host) RemoveHosts(hosts ...string) error {
|
|
|
|
|
h.Lock()
|
|
|
|
|
defer h.Unlock()
|
|
|
|
|
if h.hostData == nil {
|
|
|
|
|
return fmt.Errorf("hosts data not initialized")
|
|
|
|
|
}
|
|
|
|
|
for _, host := range hosts {
|
|
|
|
|
hostInfo := h.hostData[host]
|
|
|
|
|
if len(hostInfo) == 0 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
delete(h.hostData, host)
|
|
|
|
|
for _, v := range hostInfo {
|
|
|
|
|
var newHosts []string
|
|
|
|
|
for _, vv := range v.Host {
|
|
|
|
|
if vv != host {
|
|
|
|
|
newHosts = append(newHosts, vv)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
v.Host = newHosts
|
|
|
|
|
if len(v.Host) == 0 {
|
|
|
|
|
delete(h.ipData, v.IP)
|
|
|
|
|
if v.lastuid != 0 {
|
|
|
|
|
h.fulldata[v.lastuid].nextuid = v.nextuid
|
|
|
|
|
} else {
|
|
|
|
|
h.nextUid = v.nextuid
|
|
|
|
|
}
|
|
|
|
|
if v.nextuid != 0 {
|
|
|
|
|
h.fulldata[v.nextuid].lastuid = v.lastuid
|
|
|
|
|
} else {
|
|
|
|
|
h.lastUid = v.lastuid
|
|
|
|
|
}
|
|
|
|
|
for _, v := range hostsCfg.Data[0].NodeData {
|
|
|
|
|
if v != nil {
|
|
|
|
|
res[v.Key] = v.Value
|
|
|
|
|
delete(h.fulldata, v.uid)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return res
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Host) SetIPHosts(ip string, hosts ...string) error {
|
|
|
|
|
err := h.RemoveIPs(ip)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return h.AddHosts(ip, hosts...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Host) addHosts(comment string, ip string, hosts ...string) error {
|
|
|
|
|
h.Lock()
|
|
|
|
|
defer h.Unlock()
|
|
|
|
|
if h.hostData == nil {
|
|
|
|
|
return fmt.Errorf("hosts data not initialized")
|
|
|
|
|
}
|
|
|
|
|
ipInfo := h.listHostsByIP(ip)
|
|
|
|
|
var needAddHosts []string
|
|
|
|
|
for _, v := range hosts {
|
|
|
|
|
if !inArray(ipInfo, v) {
|
|
|
|
|
needAddHosts = append(needAddHosts, v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if len(needAddHosts) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
hostNode := HostNode{
|
|
|
|
|
uid: h.idx + 1,
|
|
|
|
|
nextuid: 0,
|
|
|
|
|
lastuid: h.lastUid,
|
|
|
|
|
IP: ip,
|
|
|
|
|
Host: needAddHosts,
|
|
|
|
|
Valid: true,
|
|
|
|
|
Comment: comment,
|
|
|
|
|
}
|
|
|
|
|
h.idx++
|
|
|
|
|
h.fulldata[h.lastUid].nextuid = h.idx
|
|
|
|
|
h.lastUid = h.idx
|
|
|
|
|
h.fulldata[h.idx] = &hostNode
|
|
|
|
|
h.ipData[ip] = append(h.ipData[ip], &hostNode)
|
|
|
|
|
for _, v := range needAddHosts {
|
|
|
|
|
h.hostData[v] = append(h.hostData[v], &hostNode)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func inArray(arr []string, v string) bool {
|
|
|
|
|
for _, vv := range arr {
|
|
|
|
|
if v == vv {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|