]>
src.bluestatic.org Git - mailpopbox.git/blob - pop3/conn.go
94173be7bfe02570f55b2f821906228a175e54a0
14 stateAuth state
= iota
20 errStateAuth
= "not in AUTHORIZATION"
21 errStateTxn
= "not in TRANSACTION"
22 errSyntax
= "syntax error"
23 errDeletedMsg
= "no such message - deleted"
26 type connection
struct {
39 func AcceptConnection(netConn net
.Conn
, po PostOffice
) {
42 tp
: textproto
.NewConn(netConn
),
47 conn
.ok(fmt
.Sprintf("POP3 (mailpopbox) server %s", po
.Name()))
50 conn
.line
, err
= conn
.tp
.ReadLine()
52 conn
.err("did't catch that")
57 if _
, err
:= fmt
.Sscanf(conn
.line
, "%s", &cmd
); err
!= nil {
58 conn
.err("invalid command")
83 conn
.err("unknown command")
88 func (conn
*connection
) ok(msg
string) {
92 conn
.tp
.PrintfLine("+OK%s", msg
)
95 func (conn
*connection
) err(msg
string) {
98 conn
.tp
.PrintfLine("-ERR%s", msg
)
102 func (conn
*connection
) doQUIT() {
103 defer conn
.tp
.Close()
106 err
:= conn
.mb
.Close()
108 conn
.err("failed to remove some messages")
115 func (conn
*connection
) doUSER() {
116 if conn
.state
!= stateAuth
{
117 conn
.err(errStateAuth
)
121 if _
, err
:= fmt
.Sscanf(conn
.line
, "USER %s", &conn
.user
); err
!= nil {
129 func (conn
*connection
) doPASS() {
130 if conn
.state
!= stateAuth
{
131 conn
.err(errStateAuth
)
135 if len(conn
.user
) == 0 {
140 pass
:= strings
.TrimPrefix(conn
.line
, "PASS ")
141 if mbox
, err
:= conn
.po
.OpenMailbox(conn
.user
, pass
); err
== nil {
142 conn
.state
= stateTxn
146 conn
.err(err
.Error())
150 func (conn
*connection
) doSTAT() {
151 if conn
.state
!= stateTxn
{
152 conn
.err(errStateTxn
)
156 msgs
, err
:= conn
.mb
.ListMessages()
158 conn
.err(err
.Error())
164 for _
, msg
:= range msgs
{
172 conn
.ok(fmt
.Sprintf("%d %d", num
, size
))
175 func (conn
*connection
) doLIST() {
176 if conn
.state
!= stateTxn
{
177 conn
.err(errStateTxn
)
181 msgs
, err
:= conn
.mb
.ListMessages()
183 conn
.err(err
.Error())
187 conn
.ok("scan listing")
188 for _
, msg
:= range msgs
{
189 conn
.tp
.PrintfLine("%d %d", msg
.ID(), msg
.Size())
191 conn
.tp
.PrintfLine(".")
194 func (conn
*connection
) doRETR() {
195 if conn
.state
!= stateTxn
{
196 conn
.err(errStateTxn
)
200 msg
:= conn
.getRequestedMessage()
206 conn
.err(errDeletedMsg
)
210 rc
, err
:= conn
.mb
.Retrieve(msg
)
212 conn
.err(err
.Error())
216 w
:= conn
.tp
.DotWriter()
221 func (conn
*connection
) doDELE() {
222 if conn
.state
!= stateTxn
{
223 conn
.err(errStateTxn
)
227 msg
:= conn
.getRequestedMessage()
233 conn
.err(errDeletedMsg
)
237 if err
:= conn
.mb
.Delete(msg
); err
!= nil {
238 conn
.err(err
.Error())
244 func (conn
*connection
) doRSET() {
245 if conn
.state
!= stateTxn
{
246 conn
.err(errStateTxn
)
253 func (conn
*connection
) getRequestedMessage() Message
{
256 if _
, err
:= fmt
.Sscanf(conn
.line
, "%s %d", &cmd
, &idx
); err
!= nil {
262 conn
.err("invalid message-number")
266 msg
:= conn
.mb
.GetMessage(idx
)
268 conn
.err("no such message")