127
package CFG
import (
"errors"
"fmt"
"os"
"strings"
)
var ConfFile = "/etc/manhttpd/manhttpd.conf"
var NoConfError = errors.New("no configuration file found")
func setV(a any) func(j string) error {
switch v := a.(type) {
case *string:
return func(j string) error {
*v = j
return nil
}
case *bool:
return func(j string) error {
j = strings.ToLower(j)
*v = "yes" == j
if (*v) || "no" == j {
return nil
}
return errors.New("invalid boolean value: " + j)
}
}
return nil
}
func rmComment(s *string) bool {
i := strings.Index(*s, "#")
if i >= 0 {
*s = (*s)[:i]
}
*s = strings.TrimSpace(*s)
return len(*s) == 0
}
func getKV(line, k, v *string) bool {
i := strings.Index(*line, "=")
if i < 0 {
return false
}
*k = strings.TrimSpace((*line)[:i])
*v = strings.TrimSpace((*line)[i+1:])
return len(*k) == 0 || len(*v) == 0
}
var mp = map[string]any{
"hostname": &Hostname,
"port": &Port,
"addr": &Addr,
"require_auth": &RequireAuth,
"passwd_file": &PasswdFile,
"tldr_pages": &TldrPages,
"tldr_dir": &TldrDir,
"enable_stats": &EnableStats,
"statistic_db": &StatisticDB,
"use_tls": &UseTLS,
"tls_cert_file": &TLSCertFile,
"tls_key_file": &TLSKeyFile,
}
func parse() error {
b, err := os.ReadFile(ConfFile)
if err != nil {
return NoConfError
}
var line, k, v string
var i int
var a any
var fn func(j string) error
var ok bool
errFmt := "invalid %s in " + ConfFile + " at line %d: %s"
ErrPrint := func(e, s string) {
fmt.Fprintf(os.Stderr, errFmt, e, i+1, s)
}
for i, line = range strings.Split(string(b), "\n") {
if len(line) == 0 {
continue
}
if rmComment(&line) {
continue
}
if getKV(&line, &k, &v) {
ErrPrint("format", line)
continue
}
if a, ok = mp[k]; !ok {
ErrPrint("key", k)
continue
}
fn = setV(a)
if fn == nil {
continue
}
err = fn(v)
if err != nil {
ErrPrint(fmt.Sprintf("value for %s", k), v)
continue
}
}
return nil
}
func MakeConfig() string {
var s, i string
for k, a := range mp {
switch v := a.(type) {
case *string:
i = *v
case *bool:
i = map[bool]string{true: "yes", false: "no"}[*v]
default:
continue
}
if len(i) == 0 {
continue
}
s += fmt.Sprintf("%s = %s\n", k, i)
}
return s
}