imap client: implement select/examine.
* include/mailutils/imap.h (mu_imap_stat): New structs. (MU_IMAP_STAT_DEFINED_FLAGS,MU_IMAP_STAT_PERMANENT_FLAGS) (MU_IMAP_STAT_MESSAGE_COUNT,MU_IMAP_STAT_RECENT_COUNT) (MU_IMAP_STAT_FIRST_UNSEEN,MU_IMAP_STAT_UIDNEXT) (MU_IMAP_STAT_UIDVALIDITY): New flags. (mu_imap_select): New proto. * include/mailutils/imapio.h (mu_imap_flag_to_attribute) (mu_imap_format_flags): New protos. * include/mailutils/sys/imap.h (mu_imap_client_state) <MU_IMAP_SELECT_RX>: New state. (_mu_imap) <mbox_name,mbox_writable,mbox_stat>: New members. * libmailutils/imapio/flags.c: New file. * libmailutils/imapio/Makefile.am: Add flags.c * libproto/imap/select.c: New file. * libproto/imap/Makefile.am: Add select.c * libproto/imap/err.c (_mu_imap_seterrstr) (_mu_imap_clrerrstr, mu_imap_strerror): Allow for imap==NULL. * libproto/imap/id.c (mu_imap_id): Set errstr on MU_ERR_BADREPLY * libproto/imap/login.c (mu_imap_login): Likewise. * libproto/imap/resplist.c (_mu_imap_list_element_is_string): New function. * mu/imap.c: Implement examine and select.
Showing
12 changed files
with
458 additions
and
5 deletions
... | @@ -37,7 +37,7 @@ enum mu_imap_state | ... | @@ -37,7 +37,7 @@ enum mu_imap_state |
37 | MU_IMAP_STATE_NONAUTH, /* Non-Authenticated State */ | 37 | MU_IMAP_STATE_NONAUTH, /* Non-Authenticated State */ |
38 | MU_IMAP_STATE_AUTH, /* Authenticated State */ | 38 | MU_IMAP_STATE_AUTH, /* Authenticated State */ |
39 | MU_IMAP_STATE_SELECTED, /* Selected State */ | 39 | MU_IMAP_STATE_SELECTED, /* Selected State */ |
40 | MU_IMAP_STATE_LOGOUT /* Logout State */ | 40 | MU_IMAP_STATE_LOGOUT, /* Logout State */ |
41 | }; | 41 | }; |
42 | 42 | ||
43 | int mu_imap_create (mu_imap_t *pimap); | 43 | int mu_imap_create (mu_imap_t *pimap); |
... | @@ -70,7 +70,31 @@ int mu_imap_state (mu_imap_t imap, int *pstate); | ... | @@ -70,7 +70,31 @@ int mu_imap_state (mu_imap_t imap, int *pstate); |
70 | int mu_imap_state_str (int state, const char **pstr); | 70 | int mu_imap_state_str (int state, const char **pstr); |
71 | 71 | ||
72 | int mu_imap_tag (mu_imap_t imap, const char **pseq); | 72 | int mu_imap_tag (mu_imap_t imap, const char **pseq); |
73 | 73 | ||
74 | |||
75 | #define MU_IMAP_STAT_DEFINED_FLAGS 0x01 | ||
76 | #define MU_IMAP_STAT_PERMANENT_FLAGS 0x02 | ||
77 | #define MU_IMAP_STAT_MESSAGE_COUNT 0x04 | ||
78 | #define MU_IMAP_STAT_RECENT_COUNT 0x08 | ||
79 | #define MU_IMAP_STAT_FIRST_UNSEEN 0x10 | ||
80 | #define MU_IMAP_STAT_UIDNEXT 0x20 | ||
81 | #define MU_IMAP_STAT_UIDVALIDITY 0x40 | ||
82 | |||
83 | struct mu_imap_stat | ||
84 | { | ||
85 | int flags; /* Bitmap of what fields are filled */ | ||
86 | int defined_flags; /* Flags defined for this mailbox */ | ||
87 | int permanent_flags; /* Flags that can be changed permanently */ | ||
88 | size_t message_count; /* Number of messages */ | ||
89 | size_t recent_count; /* Number of recent messages */ | ||
90 | size_t first_unseen; /* Sequence number of the first unseen message */ | ||
91 | size_t uidnext; /* The next unique identifier value. */ | ||
92 | unsigned long uidvalidity; /* The unique identifier validity value. */ | ||
93 | }; | ||
94 | |||
95 | int mu_imap_select (mu_imap_t imap, const char *mbox, int writable, | ||
96 | struct mu_imap_stat *ps); | ||
97 | |||
74 | #ifdef __cplusplus | 98 | #ifdef __cplusplus |
75 | } | 99 | } |
76 | #endif | 100 | #endif | ... | ... |
... | @@ -45,6 +45,9 @@ int mu_imapio_get_trace (mu_imapio_t io); | ... | @@ -45,6 +45,9 @@ int mu_imapio_get_trace (mu_imapio_t io); |
45 | int mu_imapio_getbuf (mu_imapio_t io, char **pptr, size_t *psize); | 45 | int mu_imapio_getbuf (mu_imapio_t io, char **pptr, size_t *psize); |
46 | 46 | ||
47 | int mu_imapio_reply_string (struct _mu_imapio *io, size_t start, char **pbuf); | 47 | int mu_imapio_reply_string (struct _mu_imapio *io, size_t start, char **pbuf); |
48 | |||
49 | int mu_imap_flag_to_attribute (const char *item, int *attr); | ||
50 | int mu_imap_format_flags (mu_stream_t str, int flags); | ||
48 | 51 | ||
49 | #ifdef __cplusplus | 52 | #ifdef __cplusplus |
50 | } | 53 | } | ... | ... |
... | @@ -44,6 +44,7 @@ enum mu_imap_client_state | ... | @@ -44,6 +44,7 @@ enum mu_imap_client_state |
44 | MU_IMAP_LOGIN_RX, | 44 | MU_IMAP_LOGIN_RX, |
45 | MU_IMAP_LOGOUT_RX, | 45 | MU_IMAP_LOGOUT_RX, |
46 | MU_IMAP_ID_RX, | 46 | MU_IMAP_ID_RX, |
47 | MU_IMAP_SELECT_RX | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | enum mu_imap_response | 50 | enum mu_imap_response |
... | @@ -77,6 +78,10 @@ struct _mu_imap | ... | @@ -77,6 +78,10 @@ struct _mu_imap |
77 | 78 | ||
78 | mu_list_t capa; | 79 | mu_list_t capa; |
79 | mu_imapio_t io; | 80 | mu_imapio_t io; |
81 | |||
82 | char *mbox_name; /* Name of the currently opened mailbox */ | ||
83 | int mbox_writable:1; /* Is it open read/write? */ | ||
84 | struct mu_imap_stat mbox_stat; /* Stats obtained from it */ | ||
80 | }; | 85 | }; |
81 | 86 | ||
82 | enum imap_eltype | 87 | enum imap_eltype |
... | @@ -151,6 +156,9 @@ int _mu_imap_response (mu_imap_t imap); | ... | @@ -151,6 +156,9 @@ int _mu_imap_response (mu_imap_t imap); |
151 | 156 | ||
152 | int _mu_imap_untagged_response_clear (mu_imap_t imap); | 157 | int _mu_imap_untagged_response_clear (mu_imap_t imap); |
153 | int _mu_imap_untagged_response_add (mu_imap_t imap); | 158 | int _mu_imap_untagged_response_add (mu_imap_t imap); |
159 | |||
160 | int _mu_imap_list_element_is_string (struct imap_list_element *elt, | ||
161 | const char *str); | ||
154 | 162 | ||
155 | # ifdef __cplusplus | 163 | # ifdef __cplusplus |
156 | } | 164 | } | ... | ... |
libmailutils/imapio/flags.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2011 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 3, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Mailutils is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | #include <config.h> | ||
18 | #include <mailutils/types.h> | ||
19 | #include <mailutils/imapio.h> | ||
20 | #include <mailutils/attribute.h> | ||
21 | #include <mailutils/stream.h> | ||
22 | #include <mailutils/errno.h> | ||
23 | #include <mailutils/cstr.h> | ||
24 | #include <mailutils/sys/imapio.h> | ||
25 | |||
26 | static struct | ||
27 | { | ||
28 | char *name; | ||
29 | int flag; | ||
30 | } | ||
31 | _imap4_attrlist[] = | ||
32 | { | ||
33 | { "\\Answered", MU_ATTRIBUTE_ANSWERED }, | ||
34 | { "\\Flagged", MU_ATTRIBUTE_FLAGGED }, | ||
35 | { "\\Deleted", MU_ATTRIBUTE_DELETED }, | ||
36 | { "\\Draft", MU_ATTRIBUTE_DRAFT }, | ||
37 | { "\\Seen", MU_ATTRIBUTE_SEEN|MU_ATTRIBUTE_READ }, | ||
38 | }; | ||
39 | |||
40 | static int _imap4_nattr = MU_ARRAY_SIZE (_imap4_attrlist); | ||
41 | |||
42 | int | ||
43 | mu_imap_flag_to_attribute (const char *item, int *attr) | ||
44 | { | ||
45 | int i; | ||
46 | |||
47 | if (mu_c_strcasecmp (item, "\\Recent") == 0) | ||
48 | { | ||
49 | *attr |= MU_ATTRIBUTE_RECENT; | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | for (i = 0; i < _imap4_nattr; i++) | ||
54 | if (mu_c_strcasecmp (item, _imap4_attrlist[i].name) == 0) | ||
55 | { | ||
56 | *attr |= _imap4_attrlist[i].flag; | ||
57 | return 0; | ||
58 | } | ||
59 | return MU_ERR_NOENT; | ||
60 | } | ||
61 | |||
62 | int | ||
63 | mu_imap_format_flags (mu_stream_t str, int flags) | ||
64 | { | ||
65 | int i; | ||
66 | int delim = 0; | ||
67 | |||
68 | for (i = 0; i < _imap4_nattr; i++) | ||
69 | if ((flags & _imap4_attrlist[i].flag) == _imap4_attrlist[i].flag) | ||
70 | { | ||
71 | if (delim) | ||
72 | mu_stream_printf (str, " "); | ||
73 | mu_stream_printf (str, "%s", _imap4_attrlist[i].name); | ||
74 | delim = 1; | ||
75 | } | ||
76 | |||
77 | if (MU_ATTRIBUTE_IS_UNSEEN (flags)) | ||
78 | { | ||
79 | if (delim) | ||
80 | mu_stream_printf (str, " "); | ||
81 | mu_stream_printf (str, "\\Recent"); | ||
82 | } | ||
83 | |||
84 | return 0; | ||
85 | } |
... | @@ -26,6 +26,8 @@ | ... | @@ -26,6 +26,8 @@ |
26 | int | 26 | int |
27 | _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t len) | 27 | _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t len) |
28 | { | 28 | { |
29 | if (!imap) | ||
30 | return EINVAL; | ||
29 | if (len + 1 > imap->errsize) | 31 | if (len + 1 > imap->errsize) |
30 | { | 32 | { |
31 | char *p = realloc (imap->errstr, len + 1); | 33 | char *p = realloc (imap->errstr, len + 1); |
... | @@ -42,13 +44,18 @@ _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t len) | ... | @@ -42,13 +44,18 @@ _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t len) |
42 | void | 44 | void |
43 | _mu_imap_clrerrstr (mu_imap_t imap) | 45 | _mu_imap_clrerrstr (mu_imap_t imap) |
44 | { | 46 | { |
45 | if (imap->errstr) | 47 | if (imap && imap->errstr) |
46 | imap->errstr[0] = 0; | 48 | imap->errstr[0] = 0; |
47 | } | 49 | } |
48 | 50 | ||
49 | int | 51 | int |
50 | mu_imap_strerror (mu_imap_t imap, const char **pstr) | 52 | mu_imap_strerror (mu_imap_t imap, const char **pstr) |
51 | { | 53 | { |
54 | if (!imap) | ||
55 | { | ||
56 | *pstr = "(imap not initialized)"; | ||
57 | return EINVAL; | ||
58 | } | ||
52 | if (imap->errstr) | 59 | if (imap->errstr) |
53 | { | 60 | { |
54 | *pstr = imap->errstr; | 61 | *pstr = imap->errstr; | ... | ... |
... | @@ -105,11 +105,11 @@ parse_id_reply (mu_imap_t imap, mu_assoc_t *passoc) | ... | @@ -105,11 +105,11 @@ parse_id_reply (mu_imap_t imap, mu_assoc_t *passoc) |
105 | return st.ret; | 105 | return st.ret; |
106 | } | 106 | } |
107 | 107 | ||
108 | |||
109 | int | 108 | int |
110 | mu_imap_id (mu_imap_t imap, char **idenv, mu_assoc_t *passoc) | 109 | mu_imap_id (mu_imap_t imap, char **idenv, mu_assoc_t *passoc) |
111 | { | 110 | { |
112 | int status; | 111 | int status; |
112 | char *p; | ||
113 | 113 | ||
114 | if (imap == NULL) | 114 | if (imap == NULL) |
115 | return EINVAL; | 115 | return EINVAL; |
... | @@ -171,6 +171,11 @@ mu_imap_id (mu_imap_t imap, char **idenv, mu_assoc_t *passoc) | ... | @@ -171,6 +171,11 @@ mu_imap_id (mu_imap_t imap, char **idenv, mu_assoc_t *passoc) |
171 | 171 | ||
172 | case MU_IMAP_BAD: | 172 | case MU_IMAP_BAD: |
173 | status = MU_ERR_BADREPLY; | 173 | status = MU_ERR_BADREPLY; |
174 | if (mu_imapio_reply_string (imap->io, 2, &p) == 0) | ||
175 | { | ||
176 | _mu_imap_seterrstr (imap, p, strlen (p)); | ||
177 | free (p); | ||
178 | } | ||
174 | break; | 179 | break; |
175 | } | 180 | } |
176 | imap->state = MU_IMAP_CONNECTED; | 181 | imap->state = MU_IMAP_CONNECTED; | ... | ... |
... | @@ -18,7 +18,8 @@ | ... | @@ -18,7 +18,8 @@ |
18 | #ifdef HAVE_CONFIG_H | 18 | #ifdef HAVE_CONFIG_H |
19 | # include <config.h> | 19 | # include <config.h> |
20 | #endif | 20 | #endif |
21 | 21 | #include <stdlib.h> | |
22 | #include <string.h> | ||
22 | #include <mailutils/errno.h> | 23 | #include <mailutils/errno.h> |
23 | #include <mailutils/stream.h> | 24 | #include <mailutils/stream.h> |
24 | #include <mailutils/sys/imap.h> | 25 | #include <mailutils/sys/imap.h> |
... | @@ -27,6 +28,7 @@ int | ... | @@ -27,6 +28,7 @@ int |
27 | mu_imap_login (mu_imap_t imap, const char *user, const char *pass) | 28 | mu_imap_login (mu_imap_t imap, const char *user, const char *pass) |
28 | { | 29 | { |
29 | int status; | 30 | int status; |
31 | char *p; | ||
30 | 32 | ||
31 | if (imap == NULL) | 33 | if (imap == NULL) |
32 | return EINVAL; | 34 | return EINVAL; |
... | @@ -67,6 +69,11 @@ mu_imap_login (mu_imap_t imap, const char *user, const char *pass) | ... | @@ -67,6 +69,11 @@ mu_imap_login (mu_imap_t imap, const char *user, const char *pass) |
67 | 69 | ||
68 | case MU_IMAP_BAD: | 70 | case MU_IMAP_BAD: |
69 | status = MU_ERR_BADREPLY; | 71 | status = MU_ERR_BADREPLY; |
72 | if (mu_imapio_reply_string (imap->io, 2, &p) == 0) | ||
73 | { | ||
74 | _mu_imap_seterrstr (imap, p, strlen (p)); | ||
75 | free (p); | ||
76 | } | ||
70 | break; | 77 | break; |
71 | } | 78 | } |
72 | imap->state = MU_IMAP_CONNECTED; | 79 | imap->state = MU_IMAP_CONNECTED; | ... | ... |
... | @@ -254,3 +254,13 @@ _mu_imap_untagged_response_add (mu_imap_t imap) | ... | @@ -254,3 +254,13 @@ _mu_imap_untagged_response_add (mu_imap_t imap) |
254 | mu_list_append (imap->untagged_resp, elt); | 254 | mu_list_append (imap->untagged_resp, elt); |
255 | return 0; | 255 | return 0; |
256 | } | 256 | } |
257 | |||
258 | int | ||
259 | _mu_imap_list_element_is_string (struct imap_list_element *elt, | ||
260 | const char *str) | ||
261 | { | ||
262 | if (elt->type != imap_eltype_string) | ||
263 | return 0; | ||
264 | return strcmp (elt->v.string, str) == 0; | ||
265 | } | ||
266 | ... | ... |
libproto/imap/select.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2010, 2011 Free Software Foundation, Inc. | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 3 of the License, or (at your option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General | ||
15 | Public License along with this library. If not, see | ||
16 | <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | |||
22 | #include <stdlib.h> | ||
23 | #include <string.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include <mailutils/assoc.h> | ||
26 | #include <mailutils/stream.h> | ||
27 | #include <mailutils/imap.h> | ||
28 | #include <mailutils/sys/imap.h> | ||
29 | |||
30 | static int | ||
31 | _collect_flags (void *item, void *data) | ||
32 | { | ||
33 | struct imap_list_element *elt = item; | ||
34 | int *args = data; | ||
35 | |||
36 | if (elt->type == imap_eltype_string) | ||
37 | mu_imap_flag_to_attribute (elt->v.string, args); | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static int | ||
42 | _parse_stat (void *item, void *data) | ||
43 | { | ||
44 | struct imap_list_element *response = item; | ||
45 | mu_imap_t imap = data; | ||
46 | struct imap_list_element *elt; | ||
47 | size_t count; | ||
48 | int rc; | ||
49 | char *p; | ||
50 | |||
51 | if (response->type != imap_eltype_list) | ||
52 | return 0; | ||
53 | |||
54 | mu_list_count (response->v.list, &count); | ||
55 | |||
56 | rc = mu_list_get (response->v.list, 0, (void*) &elt); | ||
57 | if (rc) | ||
58 | return rc; | ||
59 | |||
60 | if (_mu_imap_list_element_is_string (elt, "OK")) | ||
61 | { | ||
62 | struct imap_list_element *arg; | ||
63 | |||
64 | if (count < 3) | ||
65 | return 0; /* ignore the line */ | ||
66 | rc = mu_list_get (response->v.list, 1, (void*) &elt); | ||
67 | if (rc) | ||
68 | return rc; | ||
69 | rc = mu_list_get (response->v.list, 2, (void*) &arg); | ||
70 | if (rc) | ||
71 | return rc; | ||
72 | |||
73 | if (_mu_imap_list_element_is_string (elt, "[UIDVALIDITY")) | ||
74 | { | ||
75 | if (arg->type != imap_eltype_string) | ||
76 | return 0; | ||
77 | imap->mbox_stat.uidvalidity = strtoul (arg->v.string, &p, 10); | ||
78 | if (*p == ']') | ||
79 | imap->mbox_stat.flags |= MU_IMAP_STAT_UIDVALIDITY; | ||
80 | } | ||
81 | else if (_mu_imap_list_element_is_string (elt, "[UIDNEXT")) | ||
82 | { | ||
83 | if (arg->type != imap_eltype_string) | ||
84 | return 0; | ||
85 | imap->mbox_stat.uidnext = strtoul (arg->v.string, &p, 10); | ||
86 | if (*p == ']') | ||
87 | imap->mbox_stat.flags |= MU_IMAP_STAT_UIDNEXT; | ||
88 | } | ||
89 | else if (_mu_imap_list_element_is_string (elt, "[UNSEEN")) | ||
90 | { | ||
91 | if (arg->type != imap_eltype_string) | ||
92 | return 0; | ||
93 | imap->mbox_stat.first_unseen = strtoul (arg->v.string, &p, 10); | ||
94 | if (*p == ']') | ||
95 | imap->mbox_stat.flags |= MU_IMAP_STAT_FIRST_UNSEEN; | ||
96 | } | ||
97 | else if (_mu_imap_list_element_is_string (elt, "[PERMANENTFLAGS")) | ||
98 | { | ||
99 | if (arg->type != imap_eltype_list) | ||
100 | return 0; | ||
101 | mu_list_do (arg->v.list, _collect_flags, | ||
102 | &imap->mbox_stat.permanent_flags); | ||
103 | imap->mbox_stat.flags |= MU_IMAP_STAT_PERMANENT_FLAGS; | ||
104 | } | ||
105 | } | ||
106 | else if (_mu_imap_list_element_is_string (elt, "FLAGS")) | ||
107 | { | ||
108 | struct imap_list_element *arg; | ||
109 | rc = mu_list_get (response->v.list, 1, (void*) &arg); | ||
110 | if (rc) | ||
111 | return 0; | ||
112 | if (arg->type != imap_eltype_list) | ||
113 | return 0; | ||
114 | mu_list_do (arg->v.list, _collect_flags, &imap->mbox_stat.defined_flags); | ||
115 | imap->mbox_stat.flags |= MU_IMAP_STAT_DEFINED_FLAGS; | ||
116 | } | ||
117 | else if (count == 2) | ||
118 | { | ||
119 | struct imap_list_element *arg; | ||
120 | rc = mu_list_get (response->v.list, 1, (void*) &arg); | ||
121 | if (rc) | ||
122 | return rc; | ||
123 | if (_mu_imap_list_element_is_string (arg, "EXISTS")) | ||
124 | { | ||
125 | imap->mbox_stat.message_count = strtoul (elt->v.string, &p, 10); | ||
126 | if (*p == 0) | ||
127 | imap->mbox_stat.flags |= MU_IMAP_STAT_MESSAGE_COUNT; | ||
128 | } | ||
129 | else if (_mu_imap_list_element_is_string (arg, "RECENT")) | ||
130 | { | ||
131 | imap->mbox_stat.recent_count = strtoul (elt->v.string, &p, 10); | ||
132 | if (*p == 0) | ||
133 | imap->mbox_stat.flags |= MU_IMAP_STAT_RECENT_COUNT; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | int | ||
141 | mu_imap_select (mu_imap_t imap, const char *mbox, int writable, | ||
142 | struct mu_imap_stat *ps) | ||
143 | { | ||
144 | int status; | ||
145 | char *p; | ||
146 | |||
147 | if (imap == NULL) | ||
148 | return EINVAL; | ||
149 | if (!imap->io) | ||
150 | return MU_ERR_NO_TRANSPORT; | ||
151 | if (imap->state != MU_IMAP_CONNECTED) | ||
152 | return MU_ERR_SEQ; | ||
153 | if (imap->imap_state != MU_IMAP_STATE_AUTH && | ||
154 | imap->imap_state != MU_IMAP_STATE_SELECTED) | ||
155 | return MU_ERR_SEQ; | ||
156 | |||
157 | if (!mbox) | ||
158 | { | ||
159 | if (imap->imap_state == MU_IMAP_STATE_SELECTED) | ||
160 | { | ||
161 | if (ps) | ||
162 | *ps = imap->mbox_stat; | ||
163 | return 0; | ||
164 | } | ||
165 | return MU_ERR_INFO_UNAVAILABLE; | ||
166 | } | ||
167 | |||
168 | if (imap->mbox_name && strcmp (imap->mbox_name, mbox) == 0 | ||
169 | && writable == imap->mbox_writable) | ||
170 | { | ||
171 | if (ps) | ||
172 | *ps = imap->mbox_stat; | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | switch (imap->state) | ||
177 | { | ||
178 | case MU_IMAP_CONNECTED: | ||
179 | status = _mu_imap_tag_next (imap); | ||
180 | MU_IMAP_CHECK_EAGAIN (imap, status); | ||
181 | status = mu_imapio_printf (imap->io, "%s %s %s\r\n", | ||
182 | imap->tag_str, | ||
183 | writable ? "SELECT" : "EXAMINE", | ||
184 | mbox); | ||
185 | MU_IMAP_CHECK_ERROR (imap, status); | ||
186 | MU_IMAP_FCLR (imap, MU_IMAP_RESP); | ||
187 | imap->state = MU_IMAP_SELECT_RX; | ||
188 | |||
189 | case MU_IMAP_SELECT_RX: | ||
190 | status = _mu_imap_response (imap); | ||
191 | MU_IMAP_CHECK_EAGAIN (imap, status); | ||
192 | switch (imap->resp_code) | ||
193 | { | ||
194 | case MU_IMAP_OK: | ||
195 | imap->imap_state = MU_IMAP_STATE_SELECTED; | ||
196 | free (imap->mbox_name); | ||
197 | imap->mbox_name = strdup (mbox); | ||
198 | if (!imap->mbox_name) | ||
199 | { | ||
200 | imap->state = MU_IMAP_ERROR; | ||
201 | return errno; | ||
202 | } | ||
203 | imap->mbox_writable = writable; | ||
204 | memset (&imap->mbox_stat, 0, sizeof (imap->mbox_stat)); | ||
205 | mu_list_do (imap->untagged_resp, _parse_stat, imap); | ||
206 | if (ps) | ||
207 | *ps = imap->mbox_stat; | ||
208 | break; | ||
209 | |||
210 | case MU_IMAP_NO: | ||
211 | status = EACCES; | ||
212 | break; | ||
213 | |||
214 | case MU_IMAP_BAD: | ||
215 | status = MU_ERR_BADREPLY; | ||
216 | if (mu_imapio_reply_string (imap->io, 2, &p) == 0) | ||
217 | { | ||
218 | _mu_imap_seterrstr (imap, p, strlen (p)); | ||
219 | free (p); | ||
220 | } | ||
221 | break; | ||
222 | } | ||
223 | imap->state = MU_IMAP_CONNECTED; | ||
224 | break; | ||
225 | |||
226 | default: | ||
227 | status = EINPROGRESS; | ||
228 | } | ||
229 | return status; | ||
230 | } |
... | @@ -25,6 +25,7 @@ | ... | @@ -25,6 +25,7 @@ |
25 | #include <netinet/in.h> | 25 | #include <netinet/in.h> |
26 | #include <mailutils/mailutils.h> | 26 | #include <mailutils/mailutils.h> |
27 | #include <mailutils/imap.h> | 27 | #include <mailutils/imap.h> |
28 | #include <mailutils/imapio.h> | ||
28 | #include "mu.h" | 29 | #include "mu.h" |
29 | #include "argp.h" | 30 | #include "argp.h" |
30 | #include "xalloc.h" | 31 | #include "xalloc.h" |
... | @@ -454,6 +455,71 @@ com_id (int argc, char **argv) | ... | @@ -454,6 +455,71 @@ com_id (int argc, char **argv) |
454 | } | 455 | } |
455 | return status; | 456 | return status; |
456 | } | 457 | } |
458 | |||
459 | static void | ||
460 | print_imap_stats (struct mu_imap_stat *st) | ||
461 | { | ||
462 | if (st->flags & MU_IMAP_STAT_DEFINED_FLAGS) | ||
463 | { | ||
464 | mu_printf (_("Flags defined: ")); | ||
465 | mu_imap_format_flags (mu_strout, st->defined_flags); | ||
466 | mu_printf ("\n"); | ||
467 | } | ||
468 | if (st->flags & MU_IMAP_STAT_PERMANENT_FLAGS) | ||
469 | { | ||
470 | mu_printf (_("Flags permanent: ")); | ||
471 | mu_imap_format_flags (mu_strout, st->permanent_flags); | ||
472 | mu_printf ("\n"); | ||
473 | } | ||
474 | |||
475 | if (st->flags & MU_IMAP_STAT_MESSAGE_COUNT) | ||
476 | mu_printf (_("Total messages: %lu\n"), (unsigned long) st->message_count); | ||
477 | if (st->flags & MU_IMAP_STAT_RECENT_COUNT) | ||
478 | mu_printf (_("Recent messages: %lu\n"), (unsigned long) st->recent_count); | ||
479 | if (st->flags & MU_IMAP_STAT_FIRST_UNSEEN) | ||
480 | mu_printf (_("First unseen message: %lu\n"), | ||
481 | (unsigned long) st->first_unseen); | ||
482 | if (st->flags & MU_IMAP_STAT_UIDNEXT) | ||
483 | mu_printf (_("Next UID: %lu\n"), (unsigned long) st->uidnext); | ||
484 | if (st->flags & MU_IMAP_STAT_UIDVALIDITY) | ||
485 | mu_printf (_("UID validity: %lu\n"), st->uidvalidity); | ||
486 | } | ||
487 | |||
488 | |||
489 | static int | ||
490 | select_mbox (int argc, char **argv, int writable) | ||
491 | { | ||
492 | int status; | ||
493 | struct mu_imap_stat st; | ||
494 | |||
495 | status = mu_imap_select (imap, argv[1], writable, &st); | ||
496 | if (status == 0) | ||
497 | { | ||
498 | print_imap_stats (&st); | ||
499 | imap_prompt_env (); | ||
500 | } | ||
501 | else | ||
502 | { | ||
503 | const char *str; | ||
504 | |||
505 | mu_error ("select failed: %s", mu_strerror (status)); | ||
506 | if (mu_imap_strerror (imap, &str) == 0) | ||
507 | mu_error ("server reply: %s", str); | ||
508 | } | ||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | static int | ||
513 | com_select (int argc, char **argv) | ||
514 | { | ||
515 | return select_mbox (argc, argv, 1); | ||
516 | } | ||
517 | |||
518 | static int | ||
519 | com_examine (int argc, char **argv) | ||
520 | { | ||
521 | return select_mbox (argc, argv, 0); | ||
522 | } | ||
457 | 523 | ||
458 | 524 | ||
459 | struct mutool_command imap_comtab[] = { | 525 | struct mutool_command imap_comtab[] = { |
... | @@ -481,6 +547,12 @@ struct mutool_command imap_comtab[] = { | ... | @@ -481,6 +547,12 @@ struct mutool_command imap_comtab[] = { |
481 | { "id", 1, -1, com_id, | 547 | { "id", 1, -1, com_id, |
482 | N_("[-test KW] [ARG [ARG...]]"), | 548 | N_("[-test KW] [ARG [ARG...]]"), |
483 | N_("send ID command") }, | 549 | N_("send ID command") }, |
550 | { "select", 1, 2, com_select, | ||
551 | N_("MBOX"), | ||
552 | N_("select a mailbox") }, | ||
553 | { "examine", 1, 2, com_examine, | ||
554 | N_("MBOX"), | ||
555 | N_("examine a mailbox") }, | ||
484 | { "quit", 1, 1, com_logout, | 556 | { "quit", 1, 1, com_logout, |
485 | NULL, | 557 | NULL, |
486 | N_("same as `logout'") }, | 558 | N_("same as `logout'") }, | ... | ... |
-
Please register or sign in to post a comment