// RootStatus serves the Inbucket status page func RootStatus(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { smtpListener := fmt.Sprintf("%s:%d", config.GetSMTPConfig().IP4address.String(), config.GetSMTPConfig().IP4port) pop3Listener := fmt.Sprintf("%s:%d", config.GetPOP3Config().IP4address.String(), config.GetPOP3Config().IP4port) webListener := fmt.Sprintf("%s:%d", config.GetWebConfig().IP4address.String(), config.GetWebConfig().IP4port) return httpd.RenderTemplate("root/status.html", w, map[string]interface{}{ "ctx": ctx, "version": config.Version, "buildDate": config.BuildDate, "smtpListener": smtpListener, "pop3Listener": pop3Listener, "webListener": webListener, "smtpConfig": config.GetSMTPConfig(), "dataStoreConfig": config.GetDataStoreConfig(), }) }
// New creates a new Server struct func New(shutdownChan chan bool) *Server { // Get a new instance of the the FileDataStore - the locking and counting // mechanisms are both global variables in the smtpd package. If that // changes in the future, this should be modified to use the same DataStore // instance. ds := smtpd.DefaultFileDataStore() cfg := config.GetPOP3Config() return &Server{ domain: cfg.Domain, dataStore: ds, maxIdleSeconds: cfg.MaxIdleSeconds, globalShutdown: shutdownChan, localShutdown: make(chan bool), waitgroup: new(sync.WaitGroup), } }
// Start the server and listen for connections func (s *Server) Start() { cfg := config.GetPOP3Config() addr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%v:%v", cfg.IP4address, cfg.IP4port)) if err != nil { log.Errorf("POP3 Failed to build tcp4 address: %v", err) // serve() never called, so we do local shutdown here close(s.localShutdown) s.emergencyShutdown() return } log.Infof("POP3 listening on TCP4 %v", addr) s.listener, err = net.ListenTCP("tcp4", addr) if err != nil { log.Errorf("POP3 failed to start tcp4 listener: %v", err) // serve() never called, so we do local shutdown here close(s.localShutdown) s.emergencyShutdown() return } // Listener go routine go s.serve() // Wait for shutdown select { case _ = <-s.globalShutdown: } log.Tracef("POP3 shutdown requested, connections will be drained") // Closing the listener will cause the serve() go routine to exit if err := s.listener.Close(); err != nil { log.Errorf("Error closing POP3 listener: %v", err) } }