From 40afef8ffd6424e295aa7d4ef968d633a906fa5d Mon Sep 17 00:00:00 2001 From: Jens-Hilmar Bradt <17177271+jenshb@users.noreply.github.com> Date: Fri, 13 Jun 2025 13:13:51 +0200 Subject: [PATCH] Fix: Add optional message_num argument in POP3 LIST command (#518) https://datatracker.ietf.org/doc/html/rfc1939#page-6 > If an argument was given and the POP3 server issues a positive response with a line containing information for that message. This line is called a "scan listing" for that message. --- internal/pop3/server.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/internal/pop3/server.go b/internal/pop3/server.go index 0ad614a..19dc82a 100644 --- a/internal/pop3/server.go +++ b/internal/pop3/server.go @@ -221,12 +221,23 @@ func handleTransactionCommand(conn net.Conn, cmd string, args []string, messages for _, m := range messages { totalSize += m.Size } - sendResponse(conn, fmt.Sprintf("+OK %d messages (%d octets)", len(messages), int64(totalSize))) - for row, m := range messages { - sendResponse(conn, fmt.Sprintf("%d %d", row+1, int64(m.Size))) // Convert Size to int64 when printing + if len(args) > 0 { + arg, _ := getSafeArg(args, 0) + nr, err := strconv.Atoi(arg) + if err != nil || nr < 1 || nr > len(messages) { + sendResponse(conn, "-ERR no such message") + return + } + sendResponse(conn, fmt.Sprintf("+OK %d %d", nr, int64(messages[nr-1].Size))) + } else { + sendResponse(conn, fmt.Sprintf("+OK %d messages (%d octets)", len(messages), int64(totalSize))) + + for row, m := range messages { + sendResponse(conn, fmt.Sprintf("%d %d", row+1, int64(m.Size))) // Convert Size to int64 when printing + } + sendResponse(conn, ".") } - sendResponse(conn, ".") case "UIDL": sendResponse(conn, "+OK unique-id listing follows") for row, m := range messages {