package main import ( "context" "crypto/tls" "log" "sync" sr "tildegit.org/tjp/sliderule" "tildegit.org/tjp/sliderule/finger" "tildegit.org/tjp/sliderule/gemini" "tildegit.org/tjp/sliderule/gopher" "tildegit.org/tjp/sliderule/logging" ) func main() { conf := configure() gemTLS, err := gemini.FileTLS(conf.tlsCertFile, conf.tlsKeyFile) if err != nil { log.Fatal(err) } ctx, _, info, warn, errlog := serverContext() gopherSrv, err := buildGopher(ctx, conf, info, errlog) if err != nil { log.Fatal(err) } fingerSrv, err := buildFinger(ctx, conf, info, errlog) if err != nil { log.Fatal(err) } dropped, err := dropPrivileges() if err != nil { log.Fatal(err) } if !dropped { _ = warn.Log("msg", "dropping privileges to 'nobody' failed") } gemSrv, err := buildGemini(ctx, conf, gemTLS, info, errlog) if err != nil { log.Fatal(err) } wg := &sync.WaitGroup{} wg.Add(3) go runServer(gemSrv, wg) go runServer(gopherSrv, wg) go runServer(fingerSrv, wg) wg.Wait() } func buildGemini( ctx context.Context, conf config, gemTLS *tls.Config, infolog logging.Logger, errlog logging.Logger, ) (sr.Server, error) { handler := logging.LogRequests(infolog)(geminiRouter(conf)) infolog.Log("msg", "starting gemini server", "gemini_root", conf.geminiRoot) return gemini.NewServer(ctx, conf.hostname, "tcp", "", handler, errlog, gemTLS) } func buildGopher( ctx context.Context, conf config, infolog logging.Logger, errlog logging.Logger, ) (sr.Server, error) { handler := logging.LogRequests(infolog)(gopherRouter(conf)) infolog.Log("msg", "starting gopher server", "gopher_root", conf.gopherRoot) return gopher.NewServer(ctx, conf.hostname, "tcp", "", handler, errlog) } func buildFinger( ctx context.Context, conf config, infolog logging.Logger, errlog logging.Logger, ) (sr.Server, error) { handler := logging.LogRequests(infolog)(fingerHandler(conf)) infolog.Log("msg", "starting finger server", "finger_users", len(conf.fingerResponses)) return finger.NewServer(ctx, conf.hostname, "tcp", "", handler, errlog) } func runServer(server sr.Server, wg *sync.WaitGroup) error { defer wg.Done() return server.Serve() }