aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/emersion/go-imap/client/cmd_any.go
blob: cb0d38a1e1adb189d52efeeab34df9bd5645e1c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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
}