Commit 78d43b05 78d43b05bf6dfd37b5f251715211f48f3f22fb58 by Sergey Poznyakoff

Begin imap client implementation.

* include/mailutils/imap.h: New file.
* include/mailutils/Makefile.am (pkginclude_HEADERS): Add imap.h

* libproto/imap/capability.c: New file.
* libproto/imap/capatst.c: New file.
* libproto/imap/carrier.c: New file.
* libproto/imap/connect.c: New file.
* libproto/imap/create.c: New file.
* libproto/imap/destroy.c: New file.
* libproto/imap/disconnect.c: New file.
* libproto/imap/err.c: New file.
* libproto/imap/fake-folder.c: New file.
* libproto/imap/logout.c: New file.
* libproto/imap/response.c: New file.
* libproto/imap/state.c: New file.
* libproto/imap/tag.c: New file.
* libproto/imap/trace.c: New file.
* libproto/imap/Makefile.am (libmu_imap_la_SOURCES): Temporarly
remove folder.c, mbox.c and url.c. Add new files.

* mu/getarg.c: New file.
* mu/imap.c: New file.
* mu/verbose.c: New file.
* mu/Makefile.am (IDLE_MODULES): New variable.
(IMAP_C): New variable.
(MODULES): Add $(IMAP_C).
(mu_SOURCES): Add getarg.c and verbose.c
(mu-setup.h, mu-setup.c): Add IDLE_MODULES both to the dependencies
and to the mu-setup.awk command line.
* mu/mu-setup.awk: New keyword mu-cond.
* mu/pop.c: Add mu-cond keyword.

* include/mailutils/sys/imap.h: Rewrite.
* include/mailutils/sys/pop3.h (MU_POP3_CHECK_EAGAIN): Take into
account MU_ERR_REPLY and MU_ERR_BADREPLY, which are recoverable errors.

* libmailutils/base/list.c (mu_list_clear): Return immediately if
list is NULL.
* libmu_auth/sql.c (sql_escape_string): Remove unused variable.

* libproto/pop/pop3_carrier.c (mu_pop3_get_carrier): Increase refcount
on the returned stream.
* libproto/pop/pop3_response.c (mu_pop3_response): Check POP3 reply code.
1 parent 966a860c
...@@ -52,6 +52,7 @@ pkginclude_HEADERS = \ ...@@ -52,6 +52,7 @@ pkginclude_HEADERS = \
52 gsasl.h\ 52 gsasl.h\
53 guile.h\ 53 guile.h\
54 header.h\ 54 header.h\
55 imap.h\
55 io.h\ 56 io.h\
56 iterator.h\ 57 iterator.h\
57 kwd.h\ 58 kwd.h\
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 #ifndef _MAILUTILS_IMAP_H
19 #define _MAILUTILS_IMAP_H
20
21 #include <mailutils/iterator.h>
22 #include <mailutils/debug.h>
23 #include <mailutils/stream.h>
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29 #define MU_IMAP_DEFAULT_PORT 143
30 #define MU_IMAP_DEFAULT_SSL_PORT 993
31
32 typedef struct _mu_imap *mu_imap_t;
33
34 enum mu_imap_state
35 {
36 MU_IMAP_STATE_INIT, /* Initial state */
37 MU_IMAP_STATE_NONAUTH, /* Non-Authenticated State */
38 MU_IMAP_STATE_AUTH, /* Authenticated State */
39 MU_IMAP_STATE_SELECTED, /* Selected State */
40 MU_IMAP_STATE_LOGOUT /* Logout State */
41 };
42
43 int mu_imap_create (mu_imap_t *pimap);
44 void mu_imap_destroy (mu_imap_t *pimap);
45
46 int mu_imap_connect (mu_imap_t imap);
47 int mu_imap_disconnect (mu_imap_t imap);
48
49 int mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter);
50 int mu_imap_capability_test (mu_imap_t imap, const char *name,
51 const char **pret);
52
53 int mu_imap_logout (mu_imap_t imap);
54
55 int mu_imap_set_carrier (mu_imap_t imap, mu_stream_t carrier);
56 int mu_imap_get_carrier (mu_imap_t imap, mu_stream_t *pcarrier);
57
58 #define MU_IMAP_TRACE_CLR 0
59 #define MU_IMAP_TRACE_SET 1
60 #define MU_IMAP_TRACE_QRY 2
61 int mu_imap_trace (mu_imap_t imap, int op);
62 int mu_imap_trace_mask (mu_imap_t imap, int op, int lev);
63
64 int mu_imap_strerror (mu_imap_t imap, const char **pstr);
65
66 int mu_imap_state (mu_imap_t imap, int *pstate);
67 int mu_imap_state_str (int state, const char **pstr);
68
69 int mu_imap_tag (mu_imap_t imap, const char **pseq);
70
71 #ifdef __cplusplus
72 }
73 #endif
74
75 #endif /* _MAILUTILS_IMAP_H */
76
77
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2005, 2007, 2009, 2010 Free Software 2 Copyright (C) 2010 Free Software Foundation, Inc.
3 Foundation, Inc.
4 3
5 This library is free software; you can redistribute it and/or 4 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 5 modify it under the terms of the GNU Lesser General Public
...@@ -23,210 +22,119 @@ ...@@ -23,210 +22,119 @@
23 # include <mailutils/sys/mailbox.h> 22 # include <mailutils/sys/mailbox.h>
24 # include <mailutils/sys/registrar.h> 23 # include <mailutils/sys/registrar.h>
25 # include <mailutils/sys/auth.h> 24 # include <mailutils/sys/auth.h>
25 # include <mailutils/imap.h>
26 26
27 # ifdef __cplusplus 27 # ifdef __cplusplus
28 extern "C" { 28 extern "C" {
29 # endif 29 # endif
30 30
31 # define CLEAR_STATE(f_imap) \ 31 #define MU_IMAP_RESP 0x01
32 f_imap->selected = NULL, f_imap->state = IMAP_NO_STATE 32 #define MU_IMAP_TRACE 0x02
33 #define MU_IMAP_XSCRIPT_MASK(n) (1<<((n)+1))
33 34
34 /* Clear the state and close the stream. */ 35 enum mu_imap_client_state
35 # define CHECK_ERROR_CLOSE(folder, f_imap, status) \ 36 {
37 MU_IMAP_NO_STATE,
38 MU_IMAP_ERROR,
39 MU_IMAP_CONNECT,
40 MU_IMAP_GREETINGS,
41 MU_IMAP_CONNECTED,
42 MU_IMAP_CAPABILITY_RX,
43 MU_IMAP_LOGOUT_RX,
44 };
45
46 enum mu_imap_response
47 {
48 MU_IMAP_OK,
49 MU_IMAP_NO,
50 MU_IMAP_BAD
51 };
52
53 struct _mu_imap
54 {
55 int flags;
56
57 /* Holds the tagged response to the last command */
58 char *tagbuf;
59 size_t tagsize;
60 enum mu_imap_response resp_code;
61
62 /* Untagged responses */
63 mu_list_t untagged_resp;
64
65 /* Error string (if any) */
66 char *errstr;
67 size_t errsize;
68
69 /* Input line buffer */
70 char *rdbuf;
71 size_t rdsize;
72
73 enum mu_imap_state state;
74 enum mu_imap_state imap_state;
75
76 /* Tag */
77 size_t tag_len; /* Length of the command tag */
78 int *tag_buf; /* Tag number (BCD) */
79 char *tag_str; /* String representation (tag_len + 1 bytes, asciiz) */
80
81 mu_list_t capa;
82 mu_stream_t carrier;
83 };
84
85 #define MU_IMAP_FSET(p,f) ((p)->flags |= (f))
86 #define MU_IMAP_FISSET(p,f) ((p)->flags & (f))
87 #define MU_IMAP_FCLR(p,f) ((p)->flags &= ~(f))
88
89 int _mu_imap_init (mu_imap_t imap);
90 int _mu_imap_trace_enable (mu_imap_t imap);
91 int _mu_imap_trace_disable (mu_imap_t imap);
92 int _mu_imap_xscript_level (mu_imap_t imap, int xlev);
93
94 /* If status indicates an error, return.
95 */
96 #define MU_IMAP_CHECK_ERROR(imap, status) \
36 do \ 97 do \
37 { \ 98 { \
38 if (status != 0) \ 99 if (status != 0) \
39 { \ 100 { \
40 mu_stream_close (folder->stream); \ 101 imap->state = MU_IMAP_ERROR; \
41 CLEAR_STATE (f_imap); \
42 return status; \ 102 return status; \
43 } \ 103 } \
44 } \ 104 } \
45 while (0) 105 while (0)
46 106
47 /* Clear the state. */ 107 /* Check if status indicates an error.
48 # define CHECK_ERROR(f_imap, status) \ 108 If the error is recoverable just return the status.
109 Otherwise, set the error state and return the status
110 */
111 #define MU_IMAP_CHECK_EAGAIN(imap, status) \
49 do \ 112 do \
50 { \ 113 { \
51 if (status != 0) \ 114 switch (status) \
52 { \ 115 { \
53 CLEAR_STATE (f_imap); \ 116 case 0: \
117 break; \
118 case EAGAIN: \
119 case EINPROGRESS: \
120 case EINTR: \
121 case MU_ERR_REPLY: \
122 case MU_ERR_BADREPLY: \
54 return status; \ 123 return status; \
55 } \ 124 default: \
56 } \ 125 imap->state = MU_IMAP_ERROR; \
57 while (0)
58
59 /* Clear the state for non recoverable error. */
60 # define CHECK_EAGAIN(f_imap, status) \
61 do \
62 { \
63 if (status != 0) \
64 { \
65 if (status != EAGAIN && status != EINPROGRESS && status != EINTR) \
66 { \
67 CLEAR_STATE (f_imap); \
68 } \
69 return status; \ 126 return status; \
70 } \ 127 } \
71 } \ 128 } \
72 while (0) 129 while (0)
73 130
74 struct _f_imap; 131 int _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t len);
75 struct _m_imap; 132 void _mu_imap_clrerrstr (mu_imap_t imap);
76 struct _msg_imap;
77 typedef struct _f_imap *f_imap_t;
78 typedef struct _m_imap *m_imap_t;
79 typedef struct _msg_imap *msg_imap_t;
80
81 enum imap_state
82 {
83 IMAP_NO_STATE=0,
84 IMAP_AUTH, IMAP_AUTH_DONE,
85 IMAP_APPEND, IMAP_APPEND_CONT, IMAP_APPEND_SEND, IMAP_APPEND_ACK,
86 IMAP_BODY,
87 IMAP_CLOSE, IMAP_CLOSE_ACK,
88 IMAP_COPY, IMAP_COPY_ACK,
89 IMAP_CREATE, IMAP_CREATE_ACK,
90 IMAP_DELETE, IMAP_DELETE_ACK,
91 IMAP_EXPUNGE, IMAP_EXPUNGE_ACK,
92 IMAP_FETCH, IMAP_FETCH_ACK,
93 IMAP_GREETINGS,
94 IMAP_HEADER,
95 IMAP_HEADER_FIELD,
96 IMAP_LIST, IMAP_LIST_PARSE, IMAP_LIST_ACK,
97 IMAP_LOGIN, IMAP_LOGIN_ACK,
98 IMAP_LOGOUT, IMAP_LOGOUT_ACK,
99 IMAP_LSUB, IMAP_LSUB_ACK,
100 IMAP_MESSAGE,
101 IMAP_NOOP, IMAP_NOOP_ACK,
102 IMAP_OPEN_CONNECTION,
103 IMAP_RENAME, IMAP_RENAME_ACK,
104 IMAP_SCAN, IMAP_SCAN_ACK,
105 IMAP_SELECT, IMAP_SELECT_ACK,
106 IMAP_STORE, IMAP_STORE_ACK,
107 IMAP_SUBSCRIBE, IMAP_SUBSCRIBE_ACK,
108 IMAP_UNSUBSCRIBE, IMAP_UNSUBSCRIBE_ACK
109 };
110
111 enum imap_auth_state
112 {
113 /* ANONYMOUS */
114 IMAP_AUTH_ANON_REQ_WRITE,
115 IMAP_AUTH_ANON_REQ_SEND,
116 IMAP_AUTH_ANON_WAIT_CONT,
117 IMAP_AUTH_ANON_MSG,
118 IMAP_AUTH_ANON_MSG_SEND,
119 IMAP_AUTH_ANON_WAIT_RESP
120 };
121
122 struct literal_string
123 {
124 char *buffer;
125 size_t buflen;
126 size_t total;
127 msg_imap_t msg_imap;
128 enum imap_state type;
129 size_t nleft; /* nleft to read in the literal. */
130 };
131
132 struct _f_imap
133 {
134 /* Back pointer. */
135 mu_folder_t folder;
136 m_imap_t selected;
137
138 enum imap_state state;
139 int imaps; /* IMAPS or IMAP? */
140 133
141 size_t seq; /* Sequence number to build a tag. */ 134 int _mu_imap_tag_next (mu_imap_t imap);
142 char **capav; /* Cabilities of the server. */ 135 int _mu_imap_tag_clr (mu_imap_t imap);
143 int capac; /* Number of capabilities in the above array */
144 int flags;
145
146 /* IO use to hold the literal and quoted strings send by
147 the IMAP server. */
148 struct
149 {
150 mu_stream_t stream;
151 mu_off_t offset;
152 size_t nleft; /* nleft to read in the literal. */
153 msg_imap_t msg_imap;
154 enum imap_state type;
155 } string;
156
157 /* Use for LIST and LSUB. */
158 mu_list_t flist;
159 mu_folder_enumerate_fp enum_fun;
160 void *enum_data;
161 int enum_stop;
162
163 int isopen;
164
165 /* Server channel buffer I/O */
166 size_t buflen;
167 char *buffer;
168 char *ptr;
169 char *nl;
170 mu_off_t offset; /* Dummy, this is used because of the stream buffering.
171 The mu_stream_t maintains and offset and the offset we
172 use must be in sync. */
173
174 /* Login */
175 char *user;
176 mu_secret_t secret;
177
178 /* AUTHENTICATE states */
179 enum imap_auth_state auth_state;
180 };
181
182 struct _m_imap
183 {
184 /* Back pointers. */
185 mu_mailbox_t mailbox;
186 f_imap_t f_imap;
187 size_t messages_count;
188 size_t imessages_count;
189 msg_imap_t *imessages;
190 size_t recent;
191 size_t unseen;
192 unsigned long uidvalidity;
193 size_t uidnext;
194 char *name;
195 enum imap_state state;
196 /* mailbox operations can be sequences of folder operations, and
197 thus need to keep meta-state, mailbox_imap_open(), for example. */
198 };
199
200 struct _msg_imap
201 {
202 /* Back pointers. */
203 mu_message_t message;
204 m_imap_t m_imap;
205 size_t num;
206 size_t part;
207 size_t num_parts;
208 msg_imap_t *parts;
209 msg_imap_t parent;
210 int flags;
211 size_t uid;
212
213 mu_header_t fheader;
214 char *internal_date;
215
216 size_t mu_message_size;
217 size_t mu_message_lines;
218 size_t body_size;
219 size_t body_lines;
220 size_t header_size;
221 size_t header_lines;
222 };
223 136
224 int imap_writeline (f_imap_t, const char *format, ...) MU_PRINTFLIKE(2,3); 137 int _mu_imap_response (mu_imap_t imap);
225 int imap_write (f_imap_t);
226 int imap_send (f_imap_t);
227 int imap_parse (f_imap_t);
228 int imap_readline (f_imap_t);
229 char *section_name (msg_imap_t);
230 138
231 # ifdef __cplusplus 139 # ifdef __cplusplus
232 } 140 }
......
...@@ -93,28 +93,31 @@ int _mu_pop3_trace_disable (mu_pop3_t pop3); ...@@ -93,28 +93,31 @@ int _mu_pop3_trace_disable (mu_pop3_t pop3);
93 93
94 int _mu_pop3_init (mu_pop3_t pop3); 94 int _mu_pop3_init (mu_pop3_t pop3);
95 95
96 /* Check for non recoverable error. 96 /* Check if status indicates an error.
97 The error is consider not recoverable if not part of the signal set: 97 If the error is recoverable just return the status.
98 EAGAIN, EINPROGRESS, EINTR. 98 Otherwise, set the error state and return the status
99 For unrecoverable error we reset, by moving the working ptr
100 to the begining of the buffer and setting the state to error.
101 */ 99 */
102 #define MU_POP3_CHECK_EAGAIN(pop3, status) \ 100 #define MU_POP3_CHECK_EAGAIN(pop3, status) \
103 do \ 101 do \
104 { \ 102 { \
105 if (status != 0) \ 103 switch (status) \
106 { \
107 if (status != EAGAIN && status != EINPROGRESS && status != EINTR) \
108 { \ 104 { \
105 case 0: \
106 break; \
107 case EAGAIN: \
108 case EINPROGRESS: \
109 case EINTR: \
110 case MU_ERR_REPLY: \
111 case MU_ERR_BADREPLY: \
112 return status; \
113 default: \
109 pop3->state = MU_POP3_ERROR; \ 114 pop3->state = MU_POP3_ERROR; \
110 } \
111 return status; \ 115 return status; \
112 } \ 116 } \
113 } \ 117 } \
114 while (0) 118 while (0)
115 119
116 /* If error return. 120 /* If status indicates an error, return.
117 Check status an reset(see MU_POP2_CHECK_EAGAIN) the buffer.
118 */ 121 */
119 #define MU_POP3_CHECK_ERROR(pop3, status) \ 122 #define MU_POP3_CHECK_ERROR(pop3, status) \
120 do \ 123 do \
......
...@@ -65,6 +65,8 @@ mu_list_clear (mu_list_t list) ...@@ -65,6 +65,8 @@ mu_list_clear (mu_list_t list)
65 struct list_data *current; 65 struct list_data *current;
66 struct list_data *previous; 66 struct list_data *previous;
67 67
68 if (!list)
69 return;
68 mu_monitor_wrlock (list->monitor); 70 mu_monitor_wrlock (list->monitor);
69 for (current = list->head.next; current != &list->head;) 71 for (current = list->head.next; current != &list->head;)
70 { 72 {
......
...@@ -88,7 +88,6 @@ sql_escape_string (const char *ustr) ...@@ -88,7 +88,6 @@ sql_escape_string (const char *ustr)
88 char * 88 char *
89 mu_sql_expand_query (const char *query, const char *ustr) 89 mu_sql_expand_query (const char *query, const char *ustr)
90 { 90 {
91 int rc;
92 char *res; 91 char *res;
93 char *esc_ustr; 92 char *esc_ustr;
94 struct mu_wordsplit ws; 93 struct mu_wordsplit ws;
......
...@@ -21,8 +21,24 @@ lib_LTLIBRARIES = libmu_imap.la ...@@ -21,8 +21,24 @@ lib_LTLIBRARIES = libmu_imap.la
21 libmu_imap_la_LDFLAGS=-version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@ 21 libmu_imap_la_LDFLAGS=-version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@
22 libmu_imap_la_LIBADD = ${MU_LIB_AUTH} ${MU_LIB_MAILUTILS} @INTLLIBS@ 22 libmu_imap_la_LIBADD = ${MU_LIB_AUTH} ${MU_LIB_MAILUTILS} @INTLLIBS@
23 23
24 # FIXME: Put these back when ready
25
26 # folder.c\
27 # mbox.c\
28 # url.c
24 libmu_imap_la_SOURCES = \ 29 libmu_imap_la_SOURCES = \
25 folder.c\ 30 fake-folder.c\
26 mbox.c\ 31 capability.c\
27 url.c 32 capatst.c\
33 carrier.c\
34 connect.c\
35 create.c\
36 destroy.c\
37 disconnect.c\
38 err.c\
39 logout.c\
40 response.c\
41 state.c\
42 tag.c\
43 trace.c
28 44
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 <mailutils/types.h>
23 #include <mailutils/cctype.h>
24 #include <mailutils/cstr.h>
25 #include <mailutils/errno.h>
26 #include <mailutils/stream.h>
27 #include <mailutils/list.h>
28 #include <mailutils/wordsplit.h>
29 #include <mailutils/sys/imap.h>
30
31 static int
32 capa_comp (const void *item, const void *value)
33 {
34 const char *capa = item;
35 const char *needle = value;
36 for (; *needle; capa++, needle++)
37 {
38 if (!*capa)
39 return 1;
40 if (mu_tolower (*capa) != mu_tolower (*needle))
41 return 1;
42 }
43 return !(*capa == 0 || *capa == '=');
44 }
45
46 int
47 mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter)
48 {
49 int status;
50
51 if (imap == NULL)
52 return EINVAL;
53 if (!imap->carrier)
54 return MU_ERR_NO_TRANSPORT;
55 if (imap->state != MU_IMAP_CONNECTED)
56 return MU_ERR_SEQ;
57
58 if (imap->capa)
59 {
60 if (!reread)
61 {
62 if (!piter)
63 return 0;
64 return mu_list_get_iterator (imap->capa, piter);
65 }
66 mu_list_clear (imap->capa);
67 }
68 else
69 {
70 status = mu_list_create (&imap->capa);
71 MU_IMAP_CHECK_ERROR (imap, status);
72 mu_list_set_comparator (imap->capa, capa_comp);
73 mu_list_set_destroy_item (imap->capa, mu_list_free_item);
74 }
75
76 switch (imap->state)
77 {
78 case MU_IMAP_CONNECTED:
79 status = _mu_imap_tag_next (imap);
80 MU_IMAP_CHECK_EAGAIN (imap, status);
81 status = mu_stream_printf (imap->carrier, "%s CAPABILITY\r\n",
82 imap->tag_str);
83 MU_IMAP_CHECK_EAGAIN (imap, status);
84 imap->state = MU_IMAP_CAPABILITY_RX;
85
86 case MU_IMAP_CAPABILITY_RX:
87 status = _mu_imap_response (imap);
88 MU_IMAP_CHECK_EAGAIN (imap, status);
89 if (imap->resp_code != MU_IMAP_OK)
90 return MU_ERR_REPLY;
91 else
92 {
93 size_t count;
94 char *str;
95
96 imap->state = MU_IMAP_CONNECTED;
97 mu_list_count (imap->untagged_resp, &count);
98 if (mu_list_get (imap->untagged_resp, 0, (void*)&str) == 0)
99 {
100 size_t i;
101
102 struct mu_wordsplit ws;
103
104 if (mu_wordsplit (str, &ws,
105 MU_WRDSF_NOVAR | MU_WRDSF_NOCMD |
106 MU_WRDSF_SQUEEZE_DELIMS))
107 {
108 int ec = errno;
109 mu_error ("mu_imap_capability: cannot split line: %s",
110 mu_wordsplit_strerror (&ws));
111 return ec;
112 }
113 if (ws.ws_wordc > 1 &&
114 mu_c_strcasecmp (ws.ws_wordv[0], "CAPABILITY") == 0)
115 {
116 for (i = 1; i < ws.ws_wordc; i++)
117 {
118 mu_list_append (imap->capa, ws.ws_wordv[i]);
119 ws.ws_wordv[i] = NULL;
120 }
121 }
122 mu_wordsplit_free (&ws);
123 }
124 if (piter)
125 status = mu_list_get_iterator (imap->capa, piter);
126 else
127 status = 0;
128 }
129 break;
130
131 case MU_IMAP_ERROR:
132 status = ECANCELED;
133 break;
134
135 default:
136 status = EINPROGRESS;
137 }
138 return status;
139 }
140
141
142
143
144
145
146
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 <mailutils/types.h>
23 #include <mailutils/list.h>
24 #include <mailutils/sys/imap.h>
25
26 int
27 mu_imap_capability_test (mu_imap_t imap, const char *name, const char **pret)
28 {
29 int rc;
30
31 rc = mu_imap_capability (imap, 0, NULL);
32 if (rc)
33 return rc;
34 return mu_list_locate (imap->capa, (void*) name, (void**)pret);
35 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <mailutils/errno.h>
26 #include <mailutils/sys/imap.h>
27
28 int
29 mu_imap_set_carrier (mu_imap_t imap, mu_stream_t carrier)
30 {
31 /* Sanity checks. */
32 if (imap == NULL)
33 return EINVAL;
34
35 if (imap->carrier)
36 {
37 /* Close any old carrier. */
38 mu_imap_disconnect (imap);
39 mu_stream_destroy (&imap->carrier);
40 }
41 mu_stream_ref (carrier);
42 imap->carrier = carrier;
43 if (MU_IMAP_FISSET (imap, MU_IMAP_TRACE))
44 _mu_imap_trace_enable (imap);
45 imap->state = MU_IMAP_CONNECT;
46 return 0;
47 }
48
49 int
50 mu_imap_get_carrier (mu_imap_t imap, mu_stream_t *pcarrier)
51 {
52 /* Sanity checks. */
53 if (imap == NULL)
54 return EINVAL;
55 if (pcarrier == NULL)
56 return MU_ERR_OUT_PTR_NULL;
57
58 mu_stream_ref (imap->carrier);
59 *pcarrier = imap->carrier;
60 return 0;
61 }
62
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <mailutils/errno.h>
25 #include <mailutils/wordsplit.h>
26 #include <mailutils/sys/imap.h>
27
28
29 int
30 mu_imap_connect (mu_imap_t imap)
31 {
32 int status;
33
34 if (imap == NULL)
35 return EINVAL;
36 if (imap->carrier == NULL)
37 return EINVAL;
38 switch (imap->state)
39 {
40 default:
41 case MU_IMAP_NO_STATE:
42 status = mu_imap_disconnect (imap);
43 if (status != 0)
44 {
45 /* Sleep for 2 seconds (FIXME: Must be configurable) */
46 struct timeval tval;
47 tval.tv_sec = 2;
48 tval.tv_usec = 0;
49 select (0, NULL, NULL, NULL, &tval);
50 }
51 imap->state = MU_IMAP_CONNECT;
52
53 case MU_IMAP_CONNECT:
54 /* Establish the connection. */
55 if (!mu_stream_is_open (imap->carrier))
56 {
57 status = mu_stream_open (imap->carrier);
58 MU_IMAP_CHECK_EAGAIN (imap, status);
59 MU_IMAP_FCLR (imap, MU_IMAP_RESP);
60 }
61 imap->state = MU_IMAP_GREETINGS;
62
63 case MU_IMAP_GREETINGS:
64 status = mu_stream_getline (imap->carrier, &imap->rdbuf,
65 &imap->rdsize, NULL);
66 MU_IMAP_CHECK_EAGAIN (imap, status);
67 if (imap->rdsize < 2 ||
68 !(imap->rdbuf[0] == '*' && imap->rdbuf[1] == ' '))
69 {
70 mu_error ("mu_imap_connect: invalid server response: %s",
71 imap->rdbuf);
72 imap->state = MU_IMAP_ERROR;
73 return MU_ERR_BADREPLY;
74 }
75 else
76 {
77 struct mu_wordsplit ws;
78
79 if (mu_wordsplit (imap->rdbuf, &ws,
80 MU_WRDSF_NOVAR | MU_WRDSF_NOCMD |
81 MU_WRDSF_SQUEEZE_DELIMS))
82 {
83 int ec = errno;
84 mu_error ("mu_imap_connect: cannot split line: %s",
85 mu_wordsplit_strerror (&ws));
86 imap->state = MU_IMAP_ERROR;
87 return ec;
88 }
89 if (ws.ws_wordc < 2)
90 status = MU_ERR_BADREPLY;
91 else if (strcmp (ws.ws_wordv[1], "BYE") == 0)
92 {
93 status = EACCES;
94 _mu_imap_seterrstr (imap, imap->rdbuf + 2,
95 strlen (imap->rdbuf + 2));
96 }
97 else if (strcmp (ws.ws_wordv[1], "PREAUTH") == 0)
98 {
99 status = 0;
100 imap->state = MU_IMAP_CONNECTED;
101 imap->imap_state = MU_IMAP_STATE_AUTH;
102 }
103 else if (strcmp (ws.ws_wordv[1], "OK") == 0)
104 {
105 status = 0;
106 imap->state = MU_IMAP_CONNECTED;
107 imap->imap_state = MU_IMAP_STATE_NONAUTH;
108 }
109 else
110 {
111 status = MU_ERR_BADREPLY;
112 imap->state = MU_IMAP_ERROR;
113 }
114 mu_wordsplit_free (&ws);
115 }
116 }
117
118 return status;
119 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 <errno.h>
24 #include <mailutils/errno.h>
25 #include <mailutils/sys/imap.h>
26 #include <mailutils/list.h>
27
28 int
29 mu_imap_create (mu_imap_t *pimap)
30 {
31 mu_imap_t imap;
32
33 /* Sanity check. */
34 if (pimap == NULL)
35 return EINVAL;
36
37 imap = calloc (1, sizeof *imap);
38 if (imap == NULL)
39 return ENOMEM;
40
41 _mu_imap_init (imap);
42
43 *pimap = imap;
44 return 0;
45 }
46
47 int
48 _mu_imap_init (mu_imap_t imap)
49 {
50 if (imap == NULL)
51 return EINVAL;
52 if (imap->carrier == 0)
53 {
54 int rc;
55
56 if (imap->untagged_resp)
57 mu_list_clear (imap->untagged_resp);
58 mu_list_destroy (&imap->capa);
59 _mu_imap_clrerrstr (imap);
60 rc = _mu_imap_tag_clr (imap);
61 imap->flags = 0;
62 if (rc)
63 return rc;
64 }
65 imap->state = MU_IMAP_NO_STATE; /* Init with no state. */
66 return 0;
67 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 <mailutils/errno.h>
24 #include <mailutils/sys/imap.h>
25 #include <mailutils/list.h>
26
27 void
28 mu_imap_destroy (mu_imap_t *pimap)
29 {
30 if (pimap && *pimap)
31 {
32 mu_imap_t imap = *pimap;
33
34 /* Free the response buffer. */
35 if (imap->tagbuf)
36 free (imap->tagbuf);
37 /* Free the read buffer. */
38 if (imap->rdbuf)
39 free (imap->rdbuf);
40
41 if (imap->errstr)
42 free (imap->errstr);
43
44 if (imap->tag_str)
45 free (imap->tag_str);
46 if (imap->tag_buf)
47 free (imap->tag_buf);
48
49 mu_list_destroy (&imap->untagged_resp);
50 mu_list_destroy (&imap->capa);
51
52 mu_stream_destroy (&imap->carrier);
53
54 free (imap);
55
56 *pimap = NULL;
57 }
58 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 <errno.h>
25 #include <mailutils/sys/imap.h>
26
27 int
28 mu_imap_disconnect (mu_imap_t imap)
29 {
30 /* Sanity checks. */
31 if (imap == NULL)
32 return EINVAL;
33
34 imap->state = MU_IMAP_NO_STATE;
35 MU_IMAP_FCLR (imap, MU_IMAP_RESP);
36
37 if (imap->rdbuf)
38 imap->rdbuf[0] = 0;
39
40 mu_list_clear (imap->untagged_resp);
41 mu_list_clear (imap->capa);
42
43 /* Close the stream. */
44 if (mu_stream_is_open (imap->carrier))
45 return mu_stream_close (imap->carrier);
46 return 0;
47 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 #include <stdlib.h>
22 #include <string.h>
23 #include <mailutils/errno.h>
24 #include <mailutils/sys/imap.h>
25
26 int
27 _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t len)
28 {
29 if (len + 1 > imap->errsize)
30 {
31 char *p = realloc (imap->errstr, len + 1);
32 if (!p)
33 return ENOMEM;
34 imap->errsize = len + 1;
35 }
36 memcpy (imap->errstr, str, len);
37 imap->errstr[len] = 0;
38 return 0;
39 }
40
41 void
42 _mu_imap_clrerrstr (mu_imap_t imap)
43 {
44 if (imap->errstr)
45 imap->errstr[0] = 0;
46 }
47
48 int
49 mu_imap_strerror (mu_imap_t imap, const char **pstr)
50 {
51 if (imap->errstr)
52 {
53 *pstr = imap->errstr;
54 return 0;
55 }
56 *pstr = "(no error)";
57 return MU_ERR_NOENT;
58 }
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 #include <mailutils/mailutils.h>
5
6 mu_record_t mu_imap_record = NULL;
7 mu_record_t mu_imaps_record = NULL;
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 <mailutils/errno.h>
23 #include <mailutils/stream.h>
24 #include <mailutils/sys/imap.h>
25
26 int
27 mu_imap_logout (mu_imap_t imap)
28 {
29 int status;
30
31 if (imap == NULL)
32 return EINVAL;
33 if (!imap->carrier)
34 return MU_ERR_NO_TRANSPORT;
35 if (imap->state != MU_IMAP_CONNECTED)
36 return MU_ERR_SEQ;
37
38 switch (imap->state)
39 {
40 case MU_IMAP_CONNECTED:
41 status = _mu_imap_tag_next (imap);
42 MU_IMAP_CHECK_EAGAIN (imap, status);
43 status = mu_stream_printf (imap->carrier, "%s LOGOUT\r\n",
44 imap->tag_str);
45 MU_IMAP_CHECK_EAGAIN (imap, status);
46 imap->state = MU_IMAP_LOGOUT_RX;
47
48 case MU_IMAP_LOGOUT_RX:
49 status = _mu_imap_response (imap);
50 MU_IMAP_CHECK_EAGAIN (imap, status);
51 imap->state = MU_IMAP_NO_STATE;
52 imap->imap_state = MU_IMAP_STATE_LOGOUT;
53 break;
54
55 default:
56 status = EINPROGRESS;
57 }
58 return status;
59 }
60
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <mailutils/cctype.h>
25 #include <mailutils/cstr.h>
26 #include <mailutils/stream.h>
27 #include <mailutils/errno.h>
28 #include <mailutils/sys/imap.h>
29
30 #define IS_PREFIX(s, len, pfx) \
31 ((len) >= sizeof (pfx) - 1 && \
32 memcmp ((s), (pfx), sizeof (pfx) - 1) == 0 && \
33 s[sizeof (pfx) - 1] == ' ')
34
35 int
36 _mu_imap_response (mu_imap_t imap)
37 {
38 size_t n = 0;
39 int status = 0;
40
41 if (imap == NULL)
42 return EINVAL;
43
44 if (MU_IMAP_FISSET (imap, MU_IMAP_RESP))
45 return 0;
46
47 _mu_imap_clrerrstr (imap);
48 if (imap->untagged_resp)
49 mu_list_clear (imap->untagged_resp);
50 else
51 {
52 status = mu_list_create (&imap->untagged_resp);
53 MU_IMAP_CHECK_ERROR (imap, status);
54 mu_list_set_destroy_item (imap->untagged_resp, mu_list_free_item);
55 }
56
57 while (1)
58 {
59 status = mu_stream_getline (imap->carrier, &imap->rdbuf,
60 &imap->rdsize, NULL);
61 if (status == 0)
62 {
63 n = mu_rtrim_class (imap->rdbuf, MU_CTYPE_SPACE);
64 if (imap->rdbuf[0] == '*' && imap->rdbuf[1] == ' ')
65 {
66 char *p = mu_str_skip_cset (imap->rdbuf + 2, " ");
67 mu_list_append (imap->untagged_resp, strdup (p));
68 }
69 else if (n > imap->tag_len + 3 &&
70 memcmp (imap->rdbuf, imap->tag_str, imap->tag_len) == 0
71 && imap->rdbuf[imap->tag_len] == ' ')
72 {
73 char *p = mu_str_skip_cset (imap->rdbuf + imap->tag_len, " ");
74 size_t len = strlen (p);
75
76 if (len >= imap->tagsize)
77 {
78 char *np = realloc (imap->tagbuf, len + 1);
79 if (!np)
80 {
81 imap->state = MU_IMAP_ERROR;
82 return ENOMEM;
83 }
84 imap->tagsize = len + 1;
85 imap->tagbuf = np;
86 }
87 strcpy (imap->tagbuf, p);
88 if (IS_PREFIX(p, len, "OK"))
89 imap->resp_code = MU_IMAP_OK;
90 else if (IS_PREFIX(p, len, "NO"))
91 imap->resp_code = MU_IMAP_NO;
92 else if (IS_PREFIX(p, len, "BAD"))
93 imap->resp_code = MU_IMAP_BAD;
94 else
95 status = MU_ERR_BADREPLY;
96 MU_IMAP_FSET (imap, MU_IMAP_RESP);
97 break;
98 }
99 else
100 {
101 imap->state = MU_IMAP_ERROR;
102 return MU_ERR_BADREPLY;
103 }
104 }
105 else
106 {
107 imap->state = MU_IMAP_ERROR;
108 return status;
109 }
110 }
111 return status;
112 }
113
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 #include <errno.h>
22 #include <mailutils/nls.h>
23 #include <mailutils/sys/imap.h>
24
25 const char *_mu_imap_state_name[] = {
26 N_("initial"),
27 N_("non-authenticated"),
28 N_("authenticated"),
29 N_("selected"),
30 N_("logout")
31 };
32 int _mu_imap_state_count = MU_ARRAY_SIZE (_mu_imap_state_name);
33
34 int
35 mu_imap_state (mu_imap_t imap, int *pstate)
36 {
37 if (imap == NULL || pstate == NULL)
38 return EINVAL;
39 *pstate = imap->imap_state;
40 return 0;
41 }
42
43 int
44 mu_imap_state_str (int state, const char **pstr)
45 {
46 if (state < 0 || state >= _mu_imap_state_count)
47 return EINVAL;
48 *pstr = gettext (_mu_imap_state_name[state]);
49 return 0;
50 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 #include <stdlib.h>
22 #include <errno.h>
23 #include <mailutils/sys/imap.h>
24
25 static int
26 _mu_imap_tag_incr (mu_imap_t imap)
27 {
28 int i = 0;
29
30 while (1)
31 {
32 if (++imap->tag_buf[i] <= 9)
33 break;
34 imap->tag_buf[i] = 0;
35 if (++i == imap->tag_len)
36 {
37 char *sp;
38 int *np = realloc (imap->tag_buf, imap->tag_len + 1);
39 if (!np)
40 return ENOMEM;
41 imap->tag_buf = np;
42 sp = realloc (imap->tag_str, imap->tag_len + 2);
43 if (!sp)
44 return ENOMEM;
45 imap->tag_str = sp;
46 imap->tag_len++;
47 }
48 }
49 return 0;
50 }
51
52 static void
53 _mu_imap_tag_print (mu_imap_t imap)
54 {
55 int i;
56
57 for (i = 0; i < imap->tag_len; i++)
58 imap->tag_str[imap->tag_len-i-1] = imap->tag_buf[i] + '0';
59 imap->tag_str[i] = 0;
60 }
61
62 int
63 _mu_imap_tag_clr (mu_imap_t imap)
64 {
65 int i;
66
67 if (imap->tag_len == 0)
68 {
69 imap->tag_len = 2;
70 imap->tag_buf = calloc (imap->tag_len, sizeof (imap->tag_buf[0]));
71 if (!imap->tag_buf)
72 return ENOMEM;
73 imap->tag_str = calloc (imap->tag_len + 1, sizeof (imap->tag_str[0]));
74 if (!imap->tag_str)
75 {
76 free (imap->tag_buf);
77 return ENOMEM;
78 }
79 }
80 for (i = 0; i < imap->tag_len; i++)
81 imap->tag_buf[i] = 0;
82 _mu_imap_tag_print (imap);
83 return 0;
84 }
85
86 int
87 _mu_imap_tag_next (mu_imap_t imap)
88 {
89 int status;
90 status = _mu_imap_tag_incr (imap);
91 if (status == 0)
92 _mu_imap_tag_print (imap);
93 return status;
94 }
95
96 int
97 mu_imap_tag (mu_imap_t imap, const char **ptag)
98 {
99 if (!imap)
100 return EINVAL;
101 *ptag = imap->tag_str;
102 return 0;
103 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 <string.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <mailutils/error.h>
26 #include <mailutils/errno.h>
27 #include <mailutils/nls.h>
28 #include <mailutils/stream.h>
29 #include <mailutils/sys/imap.h>
30
31 static const char *imap_prefix[] = {
32 "S: ", "C: "
33 };
34
35 int
36 _mu_imap_trace_enable (mu_imap_t imap)
37 {
38 int rc = 0;
39 mu_debug_t debug;
40 mu_stream_t dstr, xstr;
41
42 if (!imap->carrier)
43 {
44 MU_IMAP_FSET (imap, MU_IMAP_TRACE);
45 return 0;
46 }
47
48 mu_diag_get_debug (&debug);
49
50 rc = mu_dbgstream_create (&dstr, debug, MU_DIAG_DEBUG, 0);
51 if (rc)
52 mu_error (_("cannot create debug stream; transcript disabled: %s"),
53 mu_strerror (rc));
54 else
55 {
56 rc = mu_xscript_stream_create (&xstr, imap->carrier, dstr,
57 imap_prefix);
58 if (rc)
59 mu_error (_("cannot create transcript stream: %s"),
60 mu_strerror (rc));
61 else
62 {
63 mu_stream_unref (imap->carrier);
64 imap->carrier = xstr;
65 MU_IMAP_FSET (imap, MU_IMAP_TRACE);
66 }
67 }
68
69 return rc;
70 }
71
72 int
73 _mu_imap_trace_disable (mu_imap_t imap)
74 {
75 mu_stream_t xstr = imap->carrier;
76 mu_stream_t stream[2];
77 int rc;
78
79 if (!xstr)
80 return 0;
81
82 rc = mu_stream_ioctl (xstr, MU_IOCTL_GET_TRANSPORT, stream);
83 if (rc)
84 return rc;
85
86 imap->carrier = stream[0];
87 mu_stream_destroy (&xstr);
88 MU_IMAP_FCLR (imap, MU_IMAP_TRACE);
89 return 0;
90 }
91
92 int
93 mu_imap_trace (mu_imap_t imap, int op)
94 {
95 int trace_on = MU_IMAP_FISSET (imap, MU_IMAP_TRACE);
96
97 switch (op)
98 {
99 case MU_IMAP_TRACE_SET:
100 if (trace_on)
101 return MU_ERR_EXISTS;
102 return _mu_imap_trace_enable (imap);
103
104 case MU_IMAP_TRACE_CLR:
105 if (!trace_on)
106 return MU_ERR_NOENT;
107 return _mu_imap_trace_disable (imap);
108
109 case MU_IMAP_TRACE_QRY:
110 if (!trace_on)
111 return MU_ERR_NOENT;
112 return 0;
113 }
114 return EINVAL;
115 }
116
117 int
118 mu_imap_trace_mask (mu_imap_t imap, int op, int lev)
119 {
120 switch (op)
121 {
122 case MU_IMAP_TRACE_SET:
123 imap->flags |= MU_IMAP_XSCRIPT_MASK(lev);
124 break;
125
126 case MU_IMAP_TRACE_CLR:
127 imap->flags &= ~MU_IMAP_XSCRIPT_MASK(lev);
128 break;
129
130 case MU_IMAP_TRACE_QRY:
131 if (imap->flags & MU_IMAP_XSCRIPT_MASK(lev))
132 break;
133 return MU_ERR_NOENT;
134
135 default:
136 return EINVAL;
137 }
138 return 0;
139 }
140
141 int
142 _mu_imap_xscript_level (mu_imap_t imap, int xlev)
143 {
144 if (mu_stream_ioctl (imap->carrier, MU_IOCTL_LEVEL, &xlev) == 0)
145 return xlev;
146 return MU_XSCRIPT_NORMAL;
147 }
...@@ -55,6 +55,7 @@ mu_pop3_get_carrier (mu_pop3_t pop3, mu_stream_t *pcarrier) ...@@ -55,6 +55,7 @@ mu_pop3_get_carrier (mu_pop3_t pop3, mu_stream_t *pcarrier)
55 if (pcarrier == NULL) 55 if (pcarrier == NULL)
56 return MU_ERR_OUT_PTR_NULL; 56 return MU_ERR_OUT_PTR_NULL;
57 57
58 mu_stream_ref (pop3->carrier);
58 *pcarrier = pop3->carrier; 59 *pcarrier = pop3->carrier;
59 return 0; 60 return 0;
60 } 61 }
......
...@@ -67,6 +67,13 @@ mu_pop3_response (mu_pop3_t pop3, size_t *pnread) ...@@ -67,6 +67,13 @@ mu_pop3_response (mu_pop3_t pop3, size_t *pnread)
67 else if (pop3->ackbuf) 67 else if (pop3->ackbuf)
68 n = strlen (pop3->ackbuf); 68 n = strlen (pop3->ackbuf);
69 69
70 if (n < 3)
71 status = MU_ERR_BADREPLY;
72 else if (strncmp (pop3->ackbuf, "-ERR", 4) == 0)
73 status = MU_ERR_REPLY;
74 else if (strncmp (pop3->ackbuf, "+OK", 3))
75 status = MU_ERR_BADREPLY;
76
70 if (pnread) 77 if (pnread)
71 *pnread = n; 78 *pnread = n;
72 return status; 79 return status;
......
...@@ -18,16 +18,24 @@ ...@@ -18,16 +18,24 @@
18 bin_PROGRAMS = mu 18 bin_PROGRAMS = mu
19 dist_bin_SCRIPTS = mailutils-config 19 dist_bin_SCRIPTS = mailutils-config
20 20
21 IDLE_MODULES=
22
21 if MU_COND_SUPPORT_POP 23 if MU_COND_SUPPORT_POP
22 POP_C=pop.c 24 POP_C=pop.c
25 else
26 IDLE_MODULES+=pop.c
23 endif 27 endif
24 28
25 EXTRA_DIST=pop.c mu-setup.h mu-setup.c mu-setup.awk 29 if MU_COND_SUPPORT_IMAP
26 BUILT_SOURCES=mu-setup.h mu-setup.c 30 IMAP_C=imap.c
31 else
32 IDLE_MODULES+=imap.c
33 endif
27 34
28 MODULES = \ 35 MODULES = \
29 acl.c\ 36 acl.c\
30 cflags.c\ 37 cflags.c\
38 $(IMAP_C)\
31 filter.c\ 39 filter.c\
32 flt2047.c\ 40 flt2047.c\
33 help.c\ 41 help.c\
...@@ -39,9 +47,11 @@ MODULES = \ ...@@ -39,9 +47,11 @@ MODULES = \
39 47
40 mu_SOURCES = \ 48 mu_SOURCES = \
41 dispatch.c\ 49 dispatch.c\
50 getarg.c\
42 mu.h\ 51 mu.h\
43 mu.c\ 52 mu.c\
44 shell.c\ 53 shell.c\
54 verbose.c\
45 $(MODULES) 55 $(MODULES)
46 56
47 mu_LDADD = \ 57 mu_LDADD = \
...@@ -68,8 +78,10 @@ AM_CPPFLAGS = \ ...@@ -68,8 +78,10 @@ AM_CPPFLAGS = \
68 -DPYTHON_LIBS="\"$(PYTHON_LIBS)\"" \ 78 -DPYTHON_LIBS="\"$(PYTHON_LIBS)\"" \
69 -DI18NLIBS="\"$(LIBINTL)\"" 79 -DI18NLIBS="\"$(LIBINTL)\""
70 80
71 mu-setup.h: Makefile.am $(MODULES) 81 mu-setup.h: Makefile.am $(MODULES) $(IDLE_MODULES)
72 $(AM_V_GEN)$(AWK) -f $(top_srcdir)/mu/mu-setup.awk -v mode=h $(MODULES) > mu-setup.h 82 $(AM_V_GEN)$(AWK) -f $(top_srcdir)/mu/mu-setup.awk -v mode=h \
83 $(MODULES) $(IDLE_MODULES) > mu-setup.h
73 84
74 mu-setup.c: Makefile.am $(MODULES) 85 mu-setup.c: Makefile.am $(MODULES)
75 $(AM_V_GEN)$(AWK) -f $(top_srcdir)/mu/mu-setup.awk -v mode=c $(MODULES) > mu-setup.c 86 $(AM_V_GEN)$(AWK) -f $(top_srcdir)/mu/mu-setup.awk -v mode=c \
87 $(MODULES) $(IDLE_MODULES) > mu-setup.c
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 #if defined(HAVE_CONFIG_H)
18 # include <config.h>
19 #endif
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <netdb.h>
24 #include <mailutils/mailutils.h>
25 #include "mu.h"
26
27 int
28 get_bool (const char *str, int *pb)
29 {
30 if (mu_c_strcasecmp (str, "yes") == 0
31 || mu_c_strcasecmp (str, "on") == 0
32 || mu_c_strcasecmp (str, "true") == 0)
33 *pb = 1;
34 else if (mu_c_strcasecmp (str, "no") == 0
35 || mu_c_strcasecmp (str, "off") == 0
36 || mu_c_strcasecmp (str, "false") == 0)
37 *pb = 0;
38 else
39 return 1;
40
41 return 0;
42 }
43
44 int
45 get_port (const char *port_str, int *pn)
46 {
47 short port_num;
48 long num;
49 char *p;
50
51 num = port_num = strtol (port_str, &p, 0);
52 if (*p == 0)
53 {
54 if (num != port_num)
55 {
56 mu_error ("bad port number: %s", port_str);
57 return 1;
58 }
59 }
60 else
61 {
62 struct servent *sp = getservbyname (port_str, "tcp");
63 if (!sp)
64 {
65 mu_error ("unknown port name");
66 return 1;
67 }
68 port_num = ntohs (sp->s_port);
69 }
70 *pn = port_num;
71 return 0;
72 }
73
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 #if defined(HAVE_CONFIG_H)
18 # include <config.h>
19 #endif
20 #include <stdlib.h>
21 #include <string.h>
22 #include <termios.h>
23 #include <unistd.h>
24 #include <netdb.h>
25 #include <mailutils/mailutils.h>
26 #include <mailutils/imap.h>
27 #include "mu.h"
28 #include "argp.h"
29 #include "xalloc.h"
30
31 static char imap_doc[] = N_("mu imap - IMAP4 client shell.");
32 char imap_docstring[] = N_("IMAP4 client shell");
33 static char imap_args_doc[] = "";
34
35 static struct argp_option imap_options[] = {
36 { NULL }
37 };
38
39 static error_t
40 imap_parse_opt (int key, char *arg, struct argp_state *state)
41 {
42 switch (key)
43 {
44 default:
45 return ARGP_ERR_UNKNOWN;
46 }
47 return 0;
48 }
49
50 static struct argp imap_argp = {
51 imap_options,
52 imap_parse_opt,
53 imap_args_doc,
54 imap_doc,
55 NULL,
56 NULL,
57 NULL
58 };
59
60
61 static mu_imap_t imap;
62
63 static enum mu_imap_state
64 current_imap_state ()
65 {
66 int state;
67 if (imap == NULL)
68 state = MU_IMAP_STATE_INIT;
69 else
70 {
71 mu_imap_state (imap, &state);
72 if (state == MU_IMAP_STATE_LOGOUT)
73 state = MU_IMAP_STATE_INIT;
74 }
75 return state;
76 }
77
78
79 static void
80 imap_set_verbose ()
81 {
82 if (imap)
83 {
84 if (QRY_VERBOSE ())
85 mu_imap_trace (imap, MU_IMAP_TRACE_SET);
86 else
87 mu_imap_trace (imap, MU_IMAP_TRACE_CLR);
88 }
89 }
90
91 void
92 imap_set_verbose_mask ()
93 {
94 if (imap)
95 {
96 mu_imap_trace_mask (imap, QRY_VERBOSE_MASK (MU_XSCRIPT_SECURE)
97 ? MU_IMAP_TRACE_SET : MU_IMAP_TRACE_CLR,
98 MU_XSCRIPT_SECURE);
99 mu_imap_trace_mask (imap, QRY_VERBOSE_MASK (MU_XSCRIPT_PAYLOAD)
100 ? MU_IMAP_TRACE_SET : MU_IMAP_TRACE_CLR,
101 MU_XSCRIPT_PAYLOAD);
102 }
103 }
104
105 static int
106 com_verbose (int argc, char **argv)
107 {
108 return shell_verbose (argc, argv,
109 imap_set_verbose, imap_set_verbose_mask);
110
111 }
112
113 static int connect_argc;
114 static char **connect_argv;
115 #define host connect_argv[0]
116 static int port = MU_IMAP_DEFAULT_PORT;
117
118 static char *username;
119
120 static void
121 imap_prompt_env ()
122 {
123 enum mu_imap_state state = current_imap_state ();
124 if (!mutool_prompt_env)
125 mutool_prompt_env = xcalloc (2*7 + 1, sizeof(mutool_prompt_env[0]));
126
127 mutool_prompt_env[0] = "user";
128 mutool_prompt_env[1] = (state >= MU_IMAP_STATE_AUTH && username) ?
129 username : "[nouser]";
130
131 mutool_prompt_env[2] = "host";
132 mutool_prompt_env[3] = connect_argv ? host : "[nohost]";
133
134 mutool_prompt_env[4] = "program-name";
135 mutool_prompt_env[5] = (char*) mu_program_name;
136
137 mutool_prompt_env[6] = "canonical-program-name";
138 mutool_prompt_env[7] = "mu";
139
140 mutool_prompt_env[8] = "package";
141 mutool_prompt_env[9] = PACKAGE;
142
143 mutool_prompt_env[10] = "version";
144 mutool_prompt_env[11] = PACKAGE_VERSION;
145
146 mutool_prompt_env[12] = "status";
147 if (mu_imap_state_str (state, (const char **) &mutool_prompt_env[13]))
148 mutool_prompt_env[12] = NULL;
149
150 mutool_prompt_env[14] = NULL;
151 }
152
153
154 static int
155 com_disconnect (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
156 {
157 if (imap)
158 {
159 mu_imap_disconnect (imap);
160 mu_imap_destroy (&imap);
161
162 mu_argcv_free (connect_argc, connect_argv);
163 connect_argc = 0;
164 connect_argv = NULL;
165 imap_prompt_env ();
166 }
167 return 0;
168 }
169
170 static int
171 com_connect (int argc, char **argv)
172 {
173 int status;
174 int n = 0;
175 int tls = 0;
176 int i = 1;
177 enum mu_imap_state state;
178
179 for (i = 1; i < argc; i++)
180 {
181 if (strcmp (argv[i], "-tls") == 0)
182 {
183 if (WITH_TLS)
184 tls = 1;
185 else
186 {
187 mu_error ("TLS not supported");
188 return 0;
189 }
190 }
191 else
192 break;
193 }
194
195 argc -= i;
196 argv += i;
197
198 if (argc >= 2)
199 {
200 if (get_port (argv[1], &n))
201 return 0;
202 }
203 else if (tls)
204 n = MU_IMAP_DEFAULT_SSL_PORT;
205 else
206 n = MU_IMAP_DEFAULT_PORT;
207
208 state = current_imap_state ();
209
210 if (state != MU_IMAP_STATE_INIT)
211 com_disconnect (0, NULL);
212
213 status = mu_imap_create (&imap);
214 if (status == 0)
215 {
216 mu_stream_t tcp;
217
218 if (QRY_VERBOSE ())
219 {
220 imap_set_verbose ();
221 imap_set_verbose_mask ();
222 }
223 status = mu_tcp_stream_create (&tcp, argv[0], n, MU_STREAM_READ);
224 if (status == 0)
225 {
226 #ifdef WITH_TLS
227 if (tls)
228 {
229 mu_stream_t tlsstream;
230
231 status = mu_tls_client_stream_create (&tlsstream, tcp, tcp, 0);
232 mu_stream_unref (tcp);
233 if (status)
234 {
235 mu_error ("cannot create TLS stream: %s",
236 mu_strerror (status));
237 return 0;
238 }
239 tcp = tlsstream;
240 }
241 #endif
242 mu_imap_set_carrier (imap, tcp);
243 status = mu_imap_connect (imap);
244 if (status)
245 {
246 const char *err;
247
248 mu_error ("Failed to connect: %s", mu_strerror (status));
249 if (mu_imap_strerror (imap, &err))
250 mu_error ("server response: %s", err);
251 mu_imap_destroy (&imap);
252 }
253 }
254 else
255 mu_imap_destroy (&imap);
256 }
257 else
258 mu_error ("Failed to create imap: %s", mu_strerror (status));
259
260 if (!status)
261 {
262 connect_argc = argc;
263 connect_argv = xcalloc (argc, sizeof (*connect_argv));
264 for (i = 0; i < argc; i++)
265 connect_argv[i] = xstrdup (argv[i]);
266 connect_argv[i] = NULL;
267 port = n;
268
269 imap_prompt_env ();
270 }
271
272 return status;
273 }
274
275 static int
276 com_logout (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
277 {
278 int status = 0;
279 if (imap)
280 {
281 if (mu_imap_logout (imap) == 0)
282 {
283 status = com_disconnect (0, NULL);
284 }
285 else
286 {
287 mu_stream_printf (mustrout, "Try 'exit' to leave %s\n",
288 mu_program_name);
289 }
290 }
291 else
292 mu_stream_printf (mustrout, "Try 'exit' to leave %s\n", mu_program_name);
293 return status;
294 }
295
296 static int
297 com_capability (int argc, char **argv)
298 {
299 mu_iterator_t iterator = NULL;
300 int status = 0;
301 int reread = 0;
302 int i = 1;
303
304 for (i = 1; i < argc; i++)
305 {
306 if (strcmp (argv[i], "-reread") == 0)
307 reread = 1;
308 else
309 break;
310 }
311
312 if (i < argc)
313 {
314 if (reread)
315 {
316 status = mu_imap_capability (imap, 1, NULL);
317 if (status)
318 return status;
319 }
320 for (; i < argc; i++)
321 {
322 const char *elt;
323 int rc = mu_imap_capability_test (imap, argv[i], &elt);
324 switch (rc)
325 {
326 case 0:
327 if (*elt)
328 mu_stream_printf (mustrout, "%s: %s\n", argv[i], elt);
329 else
330 mu_stream_printf (mustrout, "%s is set\n", argv[i]);
331 break;
332
333 case MU_ERR_NOENT:
334 mu_stream_printf (mustrout, "%s is not set\n", argv[i]);
335 break;
336
337 default:
338 return rc;
339 }
340 }
341 }
342 else
343 {
344 status = mu_imap_capability (imap, reread, &iterator);
345
346 if (status == 0)
347 {
348 for (mu_iterator_first (iterator);
349 !mu_iterator_is_done (iterator); mu_iterator_next (iterator))
350 {
351 char *capa = NULL;
352 mu_iterator_current (iterator, (void **) &capa);
353 mu_stream_printf (mustrout, "CAPA: %s\n", capa ? capa : "");
354 }
355 mu_iterator_destroy (&iterator);
356 }
357 }
358 return status;
359 }
360
361
362 struct mutool_command imap_comtab[] = {
363 { "capability", 1, -1, com_capability,
364 /* TRANSLATORS: -reread is a keyword; do not translate. */
365 N_("[-reread] [NAME...]"),
366 N_("list server capabilities") },
367 { "verbose", 1, 4, com_verbose,
368 "[on|off|mask|unmask] [secure [payload]]",
369 N_("control the protocol tracing") },
370 { "connect", 1, 4, com_connect,
371 /* TRANSLATORS: --tls is a keyword. */
372 N_("[-tls] HOSTNAME [PORT]"),
373 N_("open connection") },
374 { "disconnect", 1, 1,
375 com_disconnect,
376 NULL,
377 N_("close connection") },
378 { "logout", 1, 1, com_logout,
379 NULL,
380 N_("quit imap session") },
381 { "quit", 1, 1, com_logout,
382 NULL,
383 N_("same as `logout'") },
384 { NULL }
385 };
386
387 int
388 mutool_imap (int argc, char **argv)
389 {
390 int index;
391
392 if (argp_parse (&imap_argp, argc, argv, ARGP_IN_ORDER, &index, NULL))
393 return 1;
394
395 argc -= index;
396 argv += index;
397
398 if (argc)
399 {
400 mu_error (_("too many arguments"));
401 return 1;
402 }
403
404 /* Command line prompt */
405 mutool_shell_prompt = xstrdup ("imap> ");
406 imap_prompt_env ();
407 mutool_shell ("imap", imap_comtab);
408 return 0;
409 }
410
411 /*
412 MU Setup: imap
413 mu-handler: mutool_imap
414 mu-docstring: imap_docstring
415 mu-cond: ENABLE_IMAP
416 End MU Setup:
417 */
...@@ -55,7 +55,11 @@ END { ...@@ -55,7 +55,11 @@ END {
55 print "extern int", setup[name,"handler"], "(int argc, char **argv);" 55 print "extern int", setup[name,"handler"], "(int argc, char **argv);"
56 print "extern char " setup[name,"docstring"] "[];" 56 print "extern char " setup[name,"docstring"] "[];"
57 } else { 57 } else {
58 if (setup[name,"cond"])
59 print "#ifdef", setup[name,"cond"]
58 print "{", "\"" name "\",", setup[name,"handler"] ",", setup[name,"docstring"], "}," 60 print "{", "\"" name "\",", setup[name,"handler"] ",", setup[name,"docstring"], "},"
61 if (setup[name,"cond"])
62 print "#endif"
59 } 63 }
60 } 64 }
61 } 65 }
......
...@@ -40,3 +40,21 @@ mu_stream_t mutool_open_pager (void); ...@@ -40,3 +40,21 @@ mu_stream_t mutool_open_pager (void);
40 int mu_help (void); 40 int mu_help (void);
41 mutool_action_t dispatch_find_action (const char *name); 41 mutool_action_t dispatch_find_action (const char *name);
42 char *dispatch_docstring (const char *text); 42 char *dispatch_docstring (const char *text);
43
44
45 #define VERBOSE_MASK(n) (1<<((n)+1))
46 #define SET_VERBOSE_MASK(n) (shell_verbose_flags |= VERBOSE_MASK (n))
47 #define CLR_VERBOSE_MASK(n) (shell_verbose_flags &= ~VERBOSE_MASK (n))
48 #define QRY_VERBOSE_MASK(n) (shell_verbose_flags & VERBOSE_MASK (n))
49 #define HAS_VERBOSE_MASK(n) (shell_verbose_flags & ~1)
50 #define SET_VERBOSE() (shell_verbose_flags |= 1)
51 #define CLR_VERBOSE() (shell_verbose_flags &= ~1)
52 #define QRY_VERBOSE() (shell_verbose_flags & 1)
53
54 extern int shell_verbose_flags;
55 int shell_verbose (int argc, char **argv,
56 void (*set_verbose) (void), void (*set_mask) (void));
57
58
59 int get_bool (const char *str, int *pb);
60 int get_port (const char *port_str, int *pn);
......
...@@ -19,9 +19,7 @@ ...@@ -19,9 +19,7 @@
19 #endif 19 #endif
20 #include <stdlib.h> 20 #include <stdlib.h>
21 #include <string.h> 21 #include <string.h>
22 #include <termios.h>
23 #include <unistd.h> 22 #include <unistd.h>
24 #include <netdb.h>
25 #include <mailutils/mailutils.h> 23 #include <mailutils/mailutils.h>
26 #include "mu.h" 24 #include "mu.h"
27 #include "argp.h" 25 #include "argp.h"
...@@ -56,67 +54,8 @@ static struct argp pop_argp = { ...@@ -56,67 +54,8 @@ static struct argp pop_argp = {
56 NULL 54 NULL
57 }; 55 };
58 56
59 int
60 get_bool (const char *str, int *pb)
61 {
62 if (mu_c_strcasecmp (str, "yes") == 0
63 || mu_c_strcasecmp (str, "on") == 0
64 || mu_c_strcasecmp (str, "true") == 0)
65 *pb = 1;
66 else if (mu_c_strcasecmp (str, "no") == 0
67 || mu_c_strcasecmp (str, "off") == 0
68 || mu_c_strcasecmp (str, "false") == 0)
69 *pb = 0;
70 else
71 return 1;
72
73 return 0;
74 }
75
76 int
77 get_port (const char *port_str, int *pn)
78 {
79 short port_num;
80 long num;
81 char *p;
82
83 num = port_num = strtol (port_str, &p, 0);
84 if (*p == 0)
85 {
86 if (num != port_num)
87 {
88 mu_error ("bad port number: %s", port_str);
89 return 1;
90 }
91 }
92 else
93 {
94 struct servent *sp = getservbyname (port_str, "tcp");
95 if (!sp)
96 {
97 mu_error ("unknown port name");
98 return 1;
99 }
100 port_num = ntohs (sp->s_port);
101 }
102 *pn = port_num;
103 return 0;
104 }
105
106
107 /* Global handle for pop3. */ 57 /* Global handle for pop3. */
108 mu_pop3_t pop3; 58 static mu_pop3_t pop3;
109
110 /* Flag if verbosity is needed. */
111 int verbose;
112 #define VERBOSE_MASK(n) (1<<((n)+1))
113 #define SET_VERBOSE_MASK(n) (verbose |= VERBOSE_MASK (n))
114 #define CLR_VERBOSE_MASK(n) (verbose &= VERBOSE_MASK (n))
115 #define QRY_VERBOSE_MASK(n) (verbose & VERBOSE_MASK (n))
116 #define HAS_VERBOSE_MASK(n) (verbose & ~1)
117 #define SET_VERBOSE() (verbose |= 1)
118 #define CLR_VERBOSE() (verbose &= ~1)
119 #define QRY_VERBOSE() (verbose & 1)
120 59
121 enum pop_session_status 60 enum pop_session_status
122 { 61 {
...@@ -125,15 +64,15 @@ enum pop_session_status ...@@ -125,15 +64,15 @@ enum pop_session_status
125 pop_session_logged_in 64 pop_session_logged_in
126 }; 65 };
127 66
128 enum pop_session_status pop_session_status; 67 static enum pop_session_status pop_session_status;
129 68
130 int connect_argc; 69 static int connect_argc;
131 char **connect_argv; 70 static char **connect_argv;
132 71
133 /* Host we are connected to. */ 72 /* Host we are connected to. */
134 #define host connect_argv[0] 73 #define host connect_argv[0]
135 int port = 110; 74 static int port = 110;
136 char *username; 75 static char *username;
137 76
138 const char * 77 const char *
139 pop_session_str (enum pop_session_status stat) 78 pop_session_str (enum pop_session_status stat)
...@@ -185,63 +124,27 @@ pop_prompt_env () ...@@ -185,63 +124,27 @@ pop_prompt_env ()
185 } 124 }
186 125
187 126
188 static int 127 static void
189 string_to_xlev (const char *name, int *pv) 128 pop_set_verbose (void)
190 {
191 if (strcmp (name, "secure") == 0)
192 *pv = MU_XSCRIPT_SECURE;
193 else if (strcmp (name, "payload") == 0)
194 *pv = MU_XSCRIPT_PAYLOAD;
195 else
196 return 1;
197 return 0;
198 }
199
200 static int
201 change_verbose_mask (int set, int argc, char **argv)
202 {
203 int i;
204
205 for (i = 0; i < argc; i++)
206 {
207 int lev;
208
209 if (string_to_xlev (argv[i], &lev))
210 {
211 mu_error ("unknown level: %s", argv[i]);
212 return 1;
213 }
214 if (set)
215 SET_VERBOSE_MASK (lev);
216 else
217 CLR_VERBOSE_MASK (lev);
218 }
219 return 0;
220 }
221
222 void
223 set_verbose (mu_pop3_t p)
224 { 129 {
225 if (p) 130 if (pop3)
226 { 131 {
227 if (QRY_VERBOSE ()) 132 if (QRY_VERBOSE ())
228 { 133 mu_pop3_trace (pop3, MU_POP3_TRACE_SET);
229 mu_pop3_trace (p, MU_POP3_TRACE_SET);
230 }
231 else 134 else
232 mu_pop3_trace (p, MU_POP3_TRACE_CLR); 135 mu_pop3_trace (pop3, MU_POP3_TRACE_CLR);
233 } 136 }
234 } 137 }
235 138
236 void 139 static void
237 set_verbose_mask (mu_pop3_t p) 140 pop_set_verbose_mask (void)
238 { 141 {
239 if (p) 142 if (pop3)
240 { 143 {
241 mu_pop3_trace_mask (p, QRY_VERBOSE_MASK (MU_XSCRIPT_SECURE) 144 mu_pop3_trace_mask (pop3, QRY_VERBOSE_MASK (MU_XSCRIPT_SECURE)
242 ? MU_POP3_TRACE_SET : MU_POP3_TRACE_CLR, 145 ? MU_POP3_TRACE_SET : MU_POP3_TRACE_CLR,
243 MU_XSCRIPT_SECURE); 146 MU_XSCRIPT_SECURE);
244 mu_pop3_trace_mask (p, QRY_VERBOSE_MASK (MU_XSCRIPT_PAYLOAD) 147 mu_pop3_trace_mask (pop3, QRY_VERBOSE_MASK (MU_XSCRIPT_PAYLOAD)
245 ? MU_POP3_TRACE_SET : MU_POP3_TRACE_CLR, 148 ? MU_POP3_TRACE_SET : MU_POP3_TRACE_CLR,
246 MU_XSCRIPT_PAYLOAD); 149 MU_XSCRIPT_PAYLOAD);
247 } 150 }
...@@ -250,50 +153,8 @@ set_verbose_mask (mu_pop3_t p) ...@@ -250,50 +153,8 @@ set_verbose_mask (mu_pop3_t p)
250 static int 153 static int
251 com_verbose (int argc, char **argv) 154 com_verbose (int argc, char **argv)
252 { 155 {
253 if (argc == 1) 156 return shell_verbose (argc, argv,
254 { 157 pop_set_verbose, pop_set_verbose_mask);
255 if (QRY_VERBOSE ())
256 {
257 mu_stream_printf (mustrout, "verbose is on");
258 if (HAS_VERBOSE_MASK ())
259 {
260 char *delim = " (";
261
262 if (QRY_VERBOSE_MASK (MU_XSCRIPT_SECURE))
263 {
264 mu_stream_printf (mustrout, "%ssecure", delim);
265 delim = ", ";
266 }
267 if (QRY_VERBOSE_MASK (MU_XSCRIPT_PAYLOAD))
268 mu_stream_printf (mustrout, "%spayload", delim);
269 mu_stream_printf (mustrout, ")");
270 }
271 mu_stream_printf (mustrout, "\n");
272 }
273 else
274 mu_stream_printf (mustrout, "verbose is off\n");
275 }
276 else
277 {
278 int bv;
279
280 if (get_bool (argv[1], &bv) == 0)
281 {
282 verbose |= bv;
283 if (argc > 2)
284 change_verbose_mask (verbose, argc - 2, argv + 2);
285 set_verbose (pop3);
286 }
287 else if (strcmp (argv[1], "mask") == 0)
288 change_verbose_mask (1, argc - 2, argv + 2);
289 else if (strcmp (argv[1], "unmask") == 0)
290 change_verbose_mask (0, argc - 2, argv + 2);
291 else
292 mu_error ("unknown subcommand");
293 set_verbose_mask (pop3);
294 }
295
296 return 0;
297 } 158 }
298 159
299 static int 160 static int
...@@ -655,8 +516,8 @@ com_connect (int argc, char **argv) ...@@ -655,8 +516,8 @@ com_connect (int argc, char **argv)
655 516
656 if (QRY_VERBOSE ()) 517 if (QRY_VERBOSE ())
657 { 518 {
658 set_verbose (pop3); 519 pop_set_verbose ();
659 set_verbose_mask (pop3); 520 pop_set_verbose_mask ();
660 } 521 }
661 status = mu_tcp_stream_create (&tcp, argv[0], n, MU_STREAM_READ); 522 status = mu_tcp_stream_create (&tcp, argv[0], n, MU_STREAM_READ);
662 if (status == 0) 523 if (status == 0)
...@@ -779,7 +640,7 @@ struct mutool_command pop_comtab[] = { ...@@ -779,7 +640,7 @@ struct mutool_command pop_comtab[] = {
779 N_("NAME"), 640 N_("NAME"),
780 N_("send login") }, 641 N_("send login") },
781 { "verbose", 1, 4, com_verbose, 642 { "verbose", 1, 4, com_verbose,
782 "[on|off|mask|unmask] [secret [payload]]", 643 "[on|off|mask|unmask] [secure [payload]]",
783 N_("control the protocol tracing") }, 644 N_("control the protocol tracing") },
784 { NULL } 645 { NULL }
785 }; 646 };
...@@ -813,5 +674,6 @@ mutool_pop (int argc, char **argv) ...@@ -813,5 +674,6 @@ mutool_pop (int argc, char **argv)
813 MU Setup: pop 674 MU Setup: pop
814 mu-handler: mutool_pop 675 mu-handler: mutool_pop
815 mu-docstring: pop_docstring 676 mu-docstring: pop_docstring
677 mu-cond: ENABLE_POP
816 End MU Setup: 678 End MU Setup:
817 */ 679 */
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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 #if defined(HAVE_CONFIG_H)
18 # include <config.h>
19 #endif
20 #include <stdlib.h>
21 #include <string.h>
22 #include <mailutils/mailutils.h>
23 #include "mu.h"
24
25 /* Manipulations with verbosity flags, which are common for pop and imap. */
26 int shell_verbose_flags;
27
28 static int
29 string_to_xlev (const char *name, int *pv)
30 {
31 if (strcmp (name, "secure") == 0)
32 *pv = MU_XSCRIPT_SECURE;
33 else if (strcmp (name, "payload") == 0)
34 *pv = MU_XSCRIPT_PAYLOAD;
35 else
36 return 1;
37 return 0;
38 }
39
40 static int
41 change_verbose_mask (int set, int argc, char **argv)
42 {
43 int i;
44
45 for (i = 0; i < argc; i++)
46 {
47 int lev;
48
49 if (string_to_xlev (argv[i], &lev))
50 {
51 mu_error ("unknown level: %s", argv[i]);
52 return 1;
53 }
54 if (set)
55 SET_VERBOSE_MASK (lev);
56 else
57 CLR_VERBOSE_MASK (lev);
58 }
59 return 0;
60 }
61
62 int
63 shell_verbose (int argc, char **argv,
64 void (*set_verbose) (void), void (*set_mask) (void))
65 {
66 if (argc == 1)
67 {
68 if (QRY_VERBOSE ())
69 {
70 mu_stream_printf (mustrout, "verbose is on");
71 if (HAS_VERBOSE_MASK ())
72 {
73 char *delim = " (";
74
75 if (QRY_VERBOSE_MASK (MU_XSCRIPT_SECURE))
76 {
77 mu_stream_printf (mustrout, "%ssecure", delim);
78 delim = ", ";
79 }
80 if (QRY_VERBOSE_MASK (MU_XSCRIPT_PAYLOAD))
81 mu_stream_printf (mustrout, "%spayload", delim);
82 mu_stream_printf (mustrout, ")");
83 }
84 mu_stream_printf (mustrout, "\n");
85 }
86 else
87 mu_stream_printf (mustrout, "verbose is off\n");
88 }
89 else
90 {
91 int bv;
92
93 if (get_bool (argv[1], &bv) == 0)
94 {
95 if (bv)
96 SET_VERBOSE ();
97 else
98 CLR_VERBOSE ();
99 if (argc > 2)
100 change_verbose_mask (shell_verbose_flags, argc - 2, argv + 2);
101 set_verbose ();
102 }
103 else if (strcmp (argv[1], "mask") == 0)
104 change_verbose_mask (1, argc - 2, argv + 2);
105 else if (strcmp (argv[1], "unmask") == 0)
106 change_verbose_mask (0, argc - 2, argv + 2);
107 else
108 mu_error ("unknown subcommand");
109 set_mask ();
110 }
111
112 return 0;
113 }
114