]>
src.bluestatic.org Git - mailpopbox.git/blob - pop3/conn.go
14 stateAuth state
= iota
20 errStateAuth
= "not in AUTHORIZATION"
21 errStateTxn
= "not in TRANSACTION"
22 errSyntax
= "syntax error"
25 type connection
struct {
38 func AcceptConnection(netConn net
.Conn
, po PostOffice
) {
41 tp
: textproto
.NewConn(netConn
),
46 conn
.ok(fmt
.Sprintf("POP3 (mailpopbox) server %s", po
.Name()))
49 conn
.line
, err
= conn
.tp
.ReadLine()
51 conn
.err("did't catch that")
56 if _
, err
:= fmt
.Sscanf(conn
.line
, "%s", &cmd
); err
!= nil {
57 conn
.err("invalid command")
82 conn
.err("unknown command")
87 func (conn
*connection
) ok(msg
string) {
91 conn
.tp
.PrintfLine("+OK%s", msg
)
94 func (conn
*connection
) err(msg
string) {
97 conn
.tp
.PrintfLine("-ERR%s", msg
)
101 func (conn
*connection
) doQUIT() {
102 defer conn
.tp
.Close()
105 err
:= conn
.mb
.Close()
107 conn
.err("failed to remove some messages")
114 func (conn
*connection
) doUSER() {
115 if conn
.state
!= stateAuth
{
116 conn
.err(errStateAuth
)
120 if _
, err
:= fmt
.Sscanf(conn
.line
, "USER %s", &conn
.user
); err
!= nil {
128 func (conn
*connection
) doPASS() {
129 if conn
.state
!= stateAuth
{
130 conn
.err(errStateAuth
)
134 if len(conn
.user
) == 0 {
139 pass
:= strings
.TrimPrefix(conn
.line
, "PASS ")
140 if mbox
, err
:= conn
.po
.OpenMailbox(conn
.user
, pass
); err
== nil {
141 conn
.state
= stateTxn
145 conn
.err(err
.Error())
149 func (conn
*connection
) doSTAT() {
150 if conn
.state
!= stateTxn
{
151 conn
.err(errStateTxn
)
155 msgs
, err
:= conn
.mb
.ListMessages()
157 conn
.err(err
.Error())
163 for _
, msg
:= range msgs
{
171 conn
.ok(fmt
.Sprintf("%d %d", num
, size
))
174 func (conn
*connection
) doLIST() {
175 if conn
.state
!= stateTxn
{
176 conn
.err(errStateTxn
)
180 msgs
, err
:= conn
.mb
.ListMessages()
182 conn
.err(err
.Error())
186 conn
.ok("scan listing")
187 for _
, msg
:= range msgs
{
188 conn
.tp
.PrintfLine("%d %d", msg
.ID(), msg
.Size())
190 conn
.tp
.PrintfLine(".")
193 func (conn
*connection
) doRETR() {
194 if conn
.state
!= stateTxn
{
195 conn
.err(errStateTxn
)
199 msg
:= conn
.getRequestedMessage()
204 rc
, err
:= conn
.mb
.Retrieve(msg
)
206 conn
.err(err
.Error())
210 w
:= conn
.tp
.DotWriter()
215 func (conn
*connection
) doDELE() {
216 if conn
.state
!= stateTxn
{
217 conn
.err(errStateTxn
)
221 msg
:= conn
.getRequestedMessage()
226 if err
:= conn
.mb
.Delete(msg
); err
!= nil {
227 conn
.err(err
.Error())
233 func (conn
*connection
) doRSET() {
234 if conn
.state
!= stateTxn
{
235 conn
.err(errStateTxn
)
242 func (conn
*connection
) getRequestedMessage() Message
{
245 if _
, err
:= fmt
.Sscanf(conn
.line
, "%s %d", &cmd
, &idx
); err
!= nil {
251 conn
.err("invalid message-number")
255 msg
:= conn
.mb
.GetMessage(idx
)
257 conn
.err("no such message")