89 lines
2.1 KiB
Go
89 lines
2.1 KiB
Go
package client
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"github.com/emersion/go-imap"
|
|
"github.com/emersion/go-imap/commands"
|
|
)
|
|
|
|
// ErrAlreadyLoggedOut is returned if Logout is called when the client is
|
|
// already logged out.
|
|
var ErrAlreadyLoggedOut = errors.New("Already logged out")
|
|
|
|
// Capability requests a listing of capabilities that the server supports.
|
|
// Capabilities are often returned by the server with the greeting or with the
|
|
// STARTTLS and LOGIN responses, so usually explicitly requesting capabilities
|
|
// isn't needed.
|
|
//
|
|
// Most of the time, Support should be used instead.
|
|
func (c *Client) Capability() (map[string]bool, error) {
|
|
cmd := &commands.Capability{}
|
|
|
|
if status, err := c.execute(cmd, nil); err != nil {
|
|
return nil, err
|
|
} else if err := status.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
c.locker.Lock()
|
|
caps := c.caps
|
|
c.locker.Unlock()
|
|
return caps, nil
|
|
}
|
|
|
|
// Support checks if cap is a capability supported by the server. If the server
|
|
// hasn't sent its capabilities yet, Support requests them.
|
|
func (c *Client) Support(cap string) (bool, error) {
|
|
c.locker.Lock()
|
|
ok := c.caps != nil
|
|
c.locker.Unlock()
|
|
|
|
// If capabilities are not cached, request them
|
|
if !ok {
|
|
if _, err := c.Capability(); err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
|
|
c.locker.Lock()
|
|
supported := c.caps[cap]
|
|
c.locker.Unlock()
|
|
|
|
return supported, nil
|
|
}
|
|
|
|
// Noop always succeeds and does nothing.
|
|
//
|
|
// It can be used as a periodic poll for new messages or message status updates
|
|
// during a period of inactivity. It can also be used to reset any inactivity
|
|
// autologout timer on the server.
|
|
func (c *Client) Noop() error {
|
|
cmd := new(commands.Noop)
|
|
|
|
status, err := c.execute(cmd, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return status.Err()
|
|
}
|
|
|
|
// Logout gracefully closes the connection.
|
|
func (c *Client) Logout() error {
|
|
if c.State() == imap.LogoutState {
|
|
return ErrAlreadyLoggedOut
|
|
}
|
|
|
|
cmd := new(commands.Logout)
|
|
|
|
if status, err := c.execute(cmd, nil); err == errClosed {
|
|
// Server closed connection, that's what we want anyway
|
|
return nil
|
|
} else if err != nil {
|
|
return err
|
|
} else if status != nil {
|
|
return status.Err()
|
|
}
|
|
return nil
|
|
}
|