diff options
author | Runxi Yu <me@runxiyu.org> | 2025-01-15 01:48:18 +0800 |
---|---|---|
committer | Runxi Yu <me@runxiyu.org> | 2025-01-15 01:48:18 +0800 |
commit | 807e74c8cb04b834e82d73da036ca9585b559201 (patch) | |
tree | ab18ed9130d6f87385a7c9fd9b05485b30bccb2f /serve_imap.go | |
parent | server_state_ -> mx_server_state_ (diff) | |
download | maild-807e74c8cb04b834e82d73da036ca9585b559201.tar.gz maild-807e74c8cb04b834e82d73da036ca9585b559201.tar.zst maild-807e74c8cb04b834e82d73da036ca9585b559201.zip |
Add an IMAP stub
Diffstat (limited to 'serve_imap.go')
-rw-r--r-- | serve_imap.go | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/serve_imap.go b/serve_imap.go new file mode 100644 index 0000000..742bb0f --- /dev/null +++ b/serve_imap.go @@ -0,0 +1,79 @@ +package main + +import ( + "bufio" + "context" + "crypto/tls" + "net" + + "github.com/jackc/pgx/v5/pgxpool" + "go.lindenii.runxiyu.org/lindenii-common/clog" +) + +type imap_server_state_t uint + +const ( + imap_server_state_begin imap_server_state_t = iota + imap_server_state_helo + imap_server_state_mail + imap_server_state_rcpt +) + +type imap_recv_session struct { + buf_conn *bufio.ReadWriter + net_conn net.Conn + tls_conn *tls.Conn + my_server_name string + db *pgxpool.Pool +} + +func (session *imap_recv_session) handle(ctx context.Context) error { + session.buf_conn = bufio.NewReadWriter(bufio.NewReader(session.net_conn), bufio.NewWriter(session.net_conn)) + session.buf_conn.WriteString("Not implemented\r\n") + session.buf_conn.Flush() + return nil +} + +func imap_new_session(ctx context.Context, net_conn net.Conn) error { + session := imap_recv_session{ + net_conn: net_conn, + } + return session.handle(ctx) +} + +func serve_imap() { + var imap_net, imap_addr string + config_consistent_run(func() { + imap_net = config.IMAP.Net + imap_addr = config.IMAP.Addr + }) + listener, err := net.Listen(imap_net, imap_addr) + if err != nil { + clog.Fatal(1, "IMAP: Cannot listen: "+err.Error()) + } + defer listener.Close() + clog.Info("IMAP: Listening via " + imap_net + " on " + imap_addr) + + for { + conn, err := listener.Accept() + if err != nil { + clog.Error("IMAP: Cannot accept connection: " + err.Error()) + } + clog.Info("IMAP: Accepted connection from " + conn.RemoteAddr().String()) + + go func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err := imap_new_session(ctx, conn) + if err != nil { + if err == err_connection_handler_eof { + clog.Info("IMAP: Connection for " + conn.RemoteAddr().String() + " closed with EOF") + } else { + clog.Error("IMAP: Connection handler for " + conn.RemoteAddr().String() + " returned error: " + err.Error()) + } + } else { + clog.Info("IMAP: Connection for " + conn.RemoteAddr().String() + " closed gracefully") + } + }() + } +} |