]>
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"
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")
62 switch strings
.ToUpper(cmd
) {
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 conn
.user
= conn
.line
[len("USER "):]
125 func (conn
*connection
) doPASS() {
126 if conn
.state
!= stateAuth
{
127 conn
.err(errStateAuth
)
131 if len(conn
.user
) == 0 {
136 pass
:= conn
.line
[len("PASS "):]
137 if mbox
, err
:= conn
.po
.OpenMailbox(conn
.user
, pass
); err
== nil {
138 conn
.state
= stateTxn
142 conn
.err(err
.Error())
146 func (conn
*connection
) doSTAT() {
147 if conn
.state
!= stateTxn
{
148 conn
.err(errStateTxn
)
152 msgs
, err
:= conn
.mb
.ListMessages()
154 conn
.err(err
.Error())
160 for _
, msg
:= range msgs
{
168 conn
.ok(fmt
.Sprintf("%d %d", num
, size
))
171 func (conn
*connection
) doLIST() {
172 if conn
.state
!= stateTxn
{
173 conn
.err(errStateTxn
)
177 msgs
, err
:= conn
.mb
.ListMessages()
179 conn
.err(err
.Error())
183 conn
.ok("scan listing")
184 for _
, msg
:= range msgs
{
185 conn
.tp
.PrintfLine("%d %d", msg
.ID(), msg
.Size())
187 conn
.tp
.PrintfLine(".")
190 func (conn
*connection
) doRETR() {
191 if conn
.state
!= stateTxn
{
192 conn
.err(errStateTxn
)
196 msg
:= conn
.getRequestedMessage()
202 conn
.err(errDeletedMsg
)
206 rc
, err
:= conn
.mb
.Retrieve(msg
)
208 conn
.err(err
.Error())
212 conn
.ok(fmt
.Sprintf("%d", msg
.Size()))
214 w
:= conn
.tp
.DotWriter()
219 func (conn
*connection
) doDELE() {
220 if conn
.state
!= stateTxn
{
221 conn
.err(errStateTxn
)
225 msg
:= conn
.getRequestedMessage()
231 conn
.err(errDeletedMsg
)
235 if err
:= conn
.mb
.Delete(msg
); err
!= nil {
236 conn
.err(err
.Error())
242 func (conn
*connection
) doRSET() {
243 if conn
.state
!= stateTxn
{
244 conn
.err(errStateTxn
)
251 func (conn
*connection
) getRequestedMessage() Message
{
254 if _
, err
:= fmt
.Sscanf(conn
.line
, "%s %d", &cmd
, &idx
); err
!= nil {
260 conn
.err("invalid message-number")
264 msg
:= conn
.mb
.GetMessage(idx
)
266 conn
.err("no such message")