mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-09-04 13:36:35 +02:00
98 lines
2.6 KiB
Go
98 lines
2.6 KiB
Go
package ctrld
|
|
|
|
import (
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
// AbsHomeDir returns the absolute path to given filename using home directory as root dir.
|
|
func AbsHomeDir(filename string) string {
|
|
dir, err := UserHomeDir()
|
|
if err != nil {
|
|
return filename
|
|
}
|
|
return filepath.Join(dir, filename)
|
|
}
|
|
|
|
func dirWritable(dir string) (bool, error) {
|
|
f, err := os.CreateTemp(dir, "")
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
defer os.Remove(f.Name())
|
|
return true, f.Close()
|
|
}
|
|
|
|
// ServiceHomeDir returns the directory where a ctrld service with root or
|
|
// administrator rights keeps its files. It has no fallback to the home
|
|
// directory of the current user. A caller without root that only reads can
|
|
// thus look where the service wrote.
|
|
func ServiceHomeDir() (string, error) {
|
|
if runtime.GOOS == "windows" {
|
|
// If we're on windows, use the install path for this.
|
|
exePath, err := os.Executable()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return filepath.Dir(exePath), nil
|
|
}
|
|
return "/etc/controld", nil
|
|
}
|
|
|
|
// UserHomeDir returns the home directory for user who is running ctrld.
|
|
func UserHomeDir() (string, error) {
|
|
// viper will expand for us.
|
|
dir, err := ServiceHomeDir()
|
|
if err != nil || runtime.GOOS == "windows" {
|
|
return dir, err
|
|
}
|
|
if err := os.MkdirAll(dir, 0750); err != nil {
|
|
return os.UserHomeDir() // fallback to user home directory
|
|
}
|
|
if ok, _ := dirWritable(dir); !ok {
|
|
return os.UserHomeDir()
|
|
}
|
|
return dir, nil
|
|
}
|
|
|
|
// SavedStaticDnsSettingsFilePath returns the file path where the static DNS settings
|
|
// for the provided interface are saved.
|
|
//
|
|
// The caller must ensure iface is non-nil.
|
|
func SavedStaticDnsSettingsFilePath(iface *net.Interface) string {
|
|
// The file is stored in the user home directory under a hidden file.
|
|
return AbsHomeDir(".dns_" + iface.Name)
|
|
}
|
|
|
|
// SavedStaticNameserversAndPath returns the stored static nameservers for the given interface,
|
|
// and the absolute path to file that stored the settings.
|
|
//
|
|
// The caller must ensure iface is non-nil.
|
|
func SavedStaticNameserversAndPath(iface *net.Interface) ([]string, string) {
|
|
file := SavedStaticDnsSettingsFilePath(iface)
|
|
data, err := os.ReadFile(file)
|
|
if err != nil || len(data) == 0 {
|
|
return nil, file
|
|
}
|
|
saveValues := strings.Split(string(data), ",")
|
|
var ns []string
|
|
for _, v := range saveValues {
|
|
// Skip any IP that is loopback
|
|
if ip := net.ParseIP(v); ip != nil && ip.IsLoopback() {
|
|
continue
|
|
}
|
|
ns = append(ns, v)
|
|
}
|
|
return ns, file
|
|
}
|
|
|
|
// SavedStaticNameservers is like SavedStaticNameserversAndPath, but only returns the static nameservers.
|
|
func SavedStaticNameservers(iface *net.Interface) []string {
|
|
nss, _ := SavedStaticNameserversAndPath(iface)
|
|
return nss
|
|
}
|