1
0
Fork 0
HostPersister/hosts/file.go

98 lines
1.8 KiB
Go

package hosts
import (
"bufio"
"os"
)
func NewHostsFile(filePath string) (*File, error) {
theHostFile := &File{filePath: filePath}
err := theHostFile.ReadHostsFile()
if err == nil {
return theHostFile, nil
}
return nil, err
}
type File struct {
filePath string
Entries []Entry
LF string
}
func (f *File) ReadHostsFile() error {
f.Entries = nil
theFile, err := os.Open(f.filePath)
if err != nil {
return err
}
defer theFile.Close()
sc := bufio.NewScanner(theFile)
sc.Split(bufio.ScanLines)
for sc.Scan() {
t := sc.Text()
entry, err := ParseEntryString(t)
if err != nil {
return err
}
f.Entries = append(f.Entries, entry)
}
return sc.Err()
}
func (f *File) WriteHostsFile() error {
// default LF to \n
if f.LF == "" {
f.LF = "\n"
}
theFile, err := os.OpenFile(f.filePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer theFile.Close()
for _, entry := range f.Entries {
_, err = theFile.WriteString(entry.ToLine() + f.LF)
if err != nil {
return err
}
}
return nil
}
func (f *File) HasDomain(domain string) bool {
for _, entry := range f.Entries {
if entry.HasDomain(domain) {
return true
}
}
return false
}
func (f *File) indexDomainSingleton(domain string) int {
for i, entry := range f.Entries {
if len(entry.Domains) == 1 && entry.HasDomain(domain) {
return i
}
}
return -1
}
func (f *File) HasDomainSingleton(domain string) bool {
return f.indexDomainSingleton(domain) > -1
}
func (f *File) OverwriteDomainSingleton(domain string, ipAddress string) {
idx := f.indexDomainSingleton(domain)
if idx == -1 {
f.Entries = append(f.Entries, Entry{
IPAddress: ipAddress,
Domains: []string{domain},
})
} else {
theEntry := f.Entries[idx]
theEntry.IPAddress = ipAddress
f.Entries = append(append(f.Entries[:idx], theEntry), f.Entries[idx+1:]...)
}
}