summaryrefslogtreecommitdiff
path: root/config.go
blob: 78bdc3161818fc58e88f0fa186051ffdcead65ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package main

import (
	"flag"
	"fmt"
	"github.com/BurntSushi/toml"
	"github.com/imdario/mergo"
	"os"
	"path/filepath"
	"sync"
)

type config struct {
	Address     *string
	Port        *int
	Debug       *bool
	Quiet       *bool
	CfgFile     *string
	Servers     *[]string
	NoTcp       *bool   `toml:"no-tcp"`
	NoHttp      *bool   `toml:"no-http"`
	HttpAddress *string `toml:"http-address"`
	HttpPort    *int    `toml:"http-port"`
	UdpTimeout  *int    `toml:"udp-timeout"`
	TcpTimeout  *int    `toml:"tcp-timeout"`
	sync.RWMutex
}

// Global
var cfg config

// Defaults, overwritten by config and then flags
// TODO pick better nameservers
var defaultCfg = config{
	Address:     ptrStr("127.0.0.1"),
	Port:        ptrInt(6881),
	Debug:       ptrBool(false),
	CfgFile:     ptrStr("/etc/nomoreads/config"),
	Servers:     &[]string{"8.8.8.8", "8.8.4.4"},
	Quiet:       ptrBool(false),
	NoTcp:       ptrBool(false),
	NoHttp:      ptrBool(false),
	HttpAddress: ptrStr("localhost"),
	HttpPort:    ptrInt(8080),
	UdpTimeout:  ptrInt(10),
	TcpTimeout:  ptrInt(10),
}

func loadConfigFlags() config {
	newCfg := config{}
	flag.StringVar(&newCfg.Address, "address", defaultCfg.Address, "listen address")
	flag.IntVar(&newCfg.Port, "port", defaultCfg.BasePort, "listen port")
	flag.BoolVar(&newCfg.Debug, "debug", defaultCfg.Debug, "provide debug output")
	flag.BoolVar(&newCfg.Quiet, "quiet", defaultCfg.Quiet, "log only errors")
	flag.BoolVar(&newCfg.NoTcp, "no-tcp", defaultCfg.NoTcp, "no TCP listener")
	flag.BoolVar(&newCfg.NoHttp, "no-http", defaultCfg.NoHttp, "no HTTP service")
	flag.StringVar(&newCfg.HttpAddress, "http-address", defaultCfg.HttpAddress, "HTTP listen address")
	flag.IntVar(&newCfg.HttpPort, "http-port", defaultCfg.HttpPort, "HTTP listen port")
	flag.IntVar(&newCfg.UdpTimeout, "udp-timeout", defaultCfg.UdpTimeout, "UDP timeout in seconds")
	flag.IntVar(&newCfg.TcpTimeout, "tcp-timeout", defaultCfg.TcpTimeout, "TCP timeout in seconds")

	flag.Parse()

	if cfg.Debug {
		fmt.Printf("Configuration flags read: %v\n", newCfg)
	}
	mergo.MergeWitOverwrite(&cfg, newCfg)
}

func loadConfigFile() config {
	newCfg := config{}
	// Read current value of configuration file
	cfgPath, _ := filepath.Abs(cfg.CfgFile)
	if _, err := os.Stat(cfgPath); !os.IsNotExist(err) {
		// fmt.Printf("Using configuration from %s\n", cfgPath)
		md, err := toml.DecodeFile(cfgPath, &newCfg)
		if err != nil {
			fmt.Printf("Failed to read configuration: %q\n", err)
			os.Exit(1)
		}
		if len(md.Undecoded()) > 0 {
			fmt.Printf("Extraneous configuration keys: %q\n", md.Undecoded())
		}
	}

	if cfg.Debug {
		fmt.Printf("Configuration file read: %v\n", newCfg)
	}
	mergo.MergeWitOverwrite(&cfg, newCfg)
}