package CFG import ( "context" "errors" "git.sophuwu.com/gophuwu/flags" "git.sophuwu.com/manweb/logs" "golang.org/x/sys/unix" "net/http" "os" "os/exec" "os/signal" "strings" ) var ( Mandoc string = "mandoc" DbCmd string = "apropos" // or "whatis" ManCmd string = "man" Hostname string = "" Port string = "8082" Addr string = "0.0.0.0" RequireAuth bool = false PasswdFile string = "/var/lib/manweb/authuwu.db" TldrPages bool = false TldrDir string = "/var/lib/manweb/tldr" TldrGitSrc string = "https://github.com/tldr-pages/tldr.git" EnableStats bool = false StatisticDB string = "/var/lib/manweb/manweb.db" UseTLS bool = false TLSCertFile string = "" TLSKeyFile string = "" ) func which(s string) (string, error) { c := exec.Command("which", s) b, e := c.CombinedOutput() return strings.TrimSpace(string(b)), e } func checkCmds() { var err error errfmt := "dependency `%s` not found" Mandoc, err = which("mandoc") if err != nil || len(Mandoc) == 0 { logs.Fatalf(errfmt, "mandoc") } ManCmd, err = which("man") if err != nil || len(ManCmd) == 0 { logs.Fatalf(errfmt, "man") } DbCmd, err = which("apropos") if err != nil || len(DbCmd) == 0 { DbCmd, err = which("whatis") if err != nil || len(DbCmd) == 0 { logs.Fatalf(errfmt, "apropos") } } } func getHostname() { var e error var b []byte var s string if s = os.Getenv("HOSTNAME"); s != "" { Hostname = s } else if s, e = os.Hostname(); e == nil { Hostname = s } else if b, e = os.ReadFile("/etc/hostname"); e == nil { Hostname = strings.TrimSpace(string(b)) } } func getEnvs() { var s string s = os.Getenv("ListenPort") if s != "" { Port = s } s = os.Getenv("ListenAddr") if s != "" { Addr = s } } func ParseConfig() { checkCmds() s, err := flags.GetStringFlag("conf") logs.CheckFatal("getting conf flag", err) if s != "" { ConfFile = s } err = parse() if err != nil { if !errors.Is(err, NoConfError) { logs.Fatal("parsing conf file", err) } getEnvs() } if Hostname == "" { getHostname() } } func HttpHostname(r *http.Request) string { if Hostname != "" { return Hostname } if r.Host != "" { return r.Host } if r.URL != nil && r.URL.Host != "" { return r.URL.Host } if r.TLS != nil && r.TLS.ServerName != "" { return r.TLS.ServerName } return "" } func ListenAndServe(h http.Handler) { var err error server := http.Server{ Addr: Addr + ":" + Port, Handler: h, } sigchan := make(chan os.Signal) go func() { signal.Notify(sigchan, unix.SIGINT, unix.SIGTERM, unix.SIGQUIT, unix.SIGKILL, unix.SIGSTOP) <-sigchan logs.Log("Stopping server...") err = server.Shutdown(context.Background()) if err != nil { logs.Log("Error stopping server: %v", err) } }() logs.Log("Starting server on", server.Addr) if UseTLS && TLSCertFile != "" && TLSKeyFile != "" { err = server.ListenAndServeTLS(TLSCertFile, TLSKeyFile) } else { err = server.ListenAndServe() } if err != nil && !errors.Is(err, http.ErrServerClosed) { logs.Log("Error starting server:", err) } logs.Log("Server stopped.") }