1 /* GNU Mailutils -- a suite of utilities for electronic mail 2 Copyright (C) 2010-2021 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_SYS_IMAP_H 19 # define _MAILUTILS_SYS_IMAP_H 20 21 # include <mailutils/sys/folder.h> 22 # include <mailutils/sys/mailbox.h> 23 # include <mailutils/sys/registrar.h> 24 # include <mailutils/sys/auth.h> 25 # include <mailutils/imapio.h> 26 # include <mailutils/imap.h> 27 28 # ifdef __cplusplus 29 extern "C" { 30 # endif 31 32 #define MU_IMAP_RESP 0x01 33 #define MU_IMAP_TRACE 0x02 34 #define MU_IMAP_XSCRIPT_MASK(n) (1<<((n)+1)) 35 #define MU_IMAP_SET_XSCRIPT_MASK(imap,n) \ 36 do \ 37 (imap)->flags |= MU_IMAP_XSCRIPT_MASK (n); \ 38 while (0) 39 #define MU_IMAP_CLR_XSCRIPT_MASK(imap,n) \ 40 do \ 41 (imap)->flags &= ~MU_IMAP_XSCRIPT_MASK (n); \ 42 while (0) 43 #define MU_IMAP_IS_XSCRIPT_MASK(imap,n) \ 44 ((imap)->flags & MU_IMAP_XSCRIPT_MASK (n)) 45 46 enum mu_imap_client_state 47 { 48 MU_IMAP_CLIENT_READY, 49 MU_IMAP_CLIENT_ERROR, 50 MU_IMAP_CLIENT_CONNECT_RX, 51 MU_IMAP_CLIENT_GREETINGS, 52 MU_IMAP_CLIENT_CAPABILITY_RX, 53 MU_IMAP_CLIENT_LOGIN_RX, 54 MU_IMAP_CLIENT_LOGOUT_RX, 55 MU_IMAP_CLIENT_ID_RX, 56 MU_IMAP_CLIENT_SELECT_RX, 57 MU_IMAP_CLIENT_STATUS_RX, 58 MU_IMAP_CLIENT_NOOP_RX, 59 MU_IMAP_CLIENT_FETCH_RX, 60 MU_IMAP_CLIENT_STORE_RX, 61 MU_IMAP_CLIENT_DELETE_RX, 62 MU_IMAP_CLIENT_RENAME_RX, 63 MU_IMAP_CLIENT_CLOSE_RX, 64 MU_IMAP_CLIENT_UNSELECT_RX, 65 MU_IMAP_CLIENT_CHECK_RX, 66 MU_IMAP_CLIENT_COPY_RX, 67 MU_IMAP_CLIENT_EXPUNGE_RX, 68 MU_IMAP_CLIENT_APPEND_RX, 69 MU_IMAP_CLIENT_LIST_RX, 70 MU_IMAP_CLIENT_SUBSCRIBE_RX, 71 MU_IMAP_CLIENT_UNSUBSCRIBE_RX, 72 MU_IMAP_CLIENT_LSUB_RX, 73 MU_IMAP_CLIENT_STARTTLS_RX, 74 MU_IMAP_CLIENT_SEARCH_RX, 75 MU_IMAP_CLIENT_CLOSING 76 }; 77 78 enum mu_imap_response 79 { 80 MU_IMAP_OK, 81 MU_IMAP_NO, 82 MU_IMAP_BAD 83 }; 84 85 struct _mu_imap 86 { 87 int flags; 88 89 /* Holds the recent response */ 90 enum mu_imap_response response; 91 /* The recent response code */ 92 int response_code; 93 94 /* Error string (if any) */ 95 char *errstr; 96 size_t errsize; 97 98 enum mu_imap_client_state client_state; 99 enum mu_imap_session_state session_state; 100 101 /* Tag */ 102 size_t tag_len; /* Length of the command tag */ 103 int *tag_buf; /* Tag number (BCD) */ 104 char *tag_str; /* String representation (tag_len + 1 bytes, asciiz) */ 105 106 mu_list_t capa; 107 mu_imapio_t io; 108 109 char *mbox_name; /* Name of the currently opened mailbox */ 110 int mbox_writable:1; /* Is it open read/write? */ 111 struct mu_imap_stat mbox_stat; /* Stats obtained from it */ 112 113 /* Folder data */ 114 int separator; /* Separator character */ 115 size_t prefix_len; /* Path prefix length */ 116 117 /* Callbacks */ 118 struct 119 { 120 mu_imap_callback_t action; 121 void *data; 122 } callback[_MU_IMAP_CB_MAX]; 123 }; 124 125 enum imap_eltype 126 { 127 imap_eltype_string, 128 imap_eltype_list 129 }; 130 131 struct imap_list_element 132 { 133 enum imap_eltype type; 134 union 135 { 136 mu_list_t list; 137 char *string; 138 } v; 139 }; 140 141 #define MU_IMAP_FSET(p,f) ((p)->flags |= (f)) 142 #define MU_IMAP_FISSET(p,f) ((p)->flags & (f)) 143 #define MU_IMAP_FCLR(p,f) ((p)->flags &= ~(f)) 144 145 int _mu_imap_init (mu_imap_t imap); 146 int _mu_imap_trace_enable (mu_imap_t imap); 147 int _mu_imap_trace_disable (mu_imap_t imap); 148 int _mu_imap_xscript_level (mu_imap_t imap, int xlev); 149 150 typedef void (*mu_imap_response_action_t) (mu_imap_t imap, mu_list_t resp, 151 void *data); 152 153 struct imap_command 154 { 155 int session_state; 156 char *capa; 157 int rx_state; 158 int argc; 159 char const **argv; 160 char const *extra; 161 mu_msgset_t msgset; 162 void (*tagged_handler) (mu_imap_t); 163 mu_imap_response_action_t untagged_handler; 164 void *untagged_handler_data; 165 }; 166 167 int mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd); 168 169 /* If status indicates an error, return. 170 */ 171 #define MU_IMAP_CHECK_ERROR(imap, status) \ 172 do \ 173 { \ 174 if (status != 0) \ 175 { \ 176 imap->client_state = MU_IMAP_CLIENT_ERROR; \ 177 return status; \ 178 } \ 179 } \ 180 while (0) 181 182 /* Check if status indicates an error. 183 If the error is recoverable just return the status. 184 Otherwise, set the error state and return the status 185 */ 186 #define MU_IMAP_CHECK_EAGAIN(imap, status) \ 187 do \ 188 { \ 189 switch (status) \ 190 { \ 191 case 0: \ 192 break; \ 193 case EAGAIN: \ 194 case EINPROGRESS: \ 195 case EINTR: \ 196 return status; \ 197 case MU_ERR_REPLY: \ 198 case MU_ERR_BADREPLY: \ 199 imap->client_state = MU_IMAP_CLIENT_READY; \ 200 return status; \ 201 default: \ 202 imap->client_state = MU_IMAP_CLIENT_ERROR; \ 203 return status; \ 204 } \ 205 } \ 206 while (0) 207 208 int _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t len); 209 int _mu_imap_seterrstrz (mu_imap_t imap, const char *str); 210 void _mu_imap_clrerrstr (mu_imap_t imap); 211 212 int _mu_imap_tag_next (mu_imap_t imap); 213 int _mu_imap_tag_clr (mu_imap_t imap); 214 215 216 int _mu_imap_untagged_response_to_list (mu_imap_t imap, mu_list_t *plist); 217 int _mu_imap_process_untagged_response (mu_imap_t imap, mu_list_t list, 218 mu_imap_response_action_t fun, 219 void *data); 220 int _mu_imap_process_tagged_response (mu_imap_t imap, mu_list_t resp); 221 222 int _mu_imap_response (mu_imap_t imap, mu_imap_response_action_t fun, 223 void *data); 224 225 int _mu_imap_list_element_is_string (struct imap_list_element *elt, 226 const char *str); 227 int _mu_imap_list_element_is_nil (struct imap_list_element *elt); 228 229 int _mu_imap_list_nth_element_is_string (mu_list_t list, size_t n, 230 const char *str); 231 232 int _mu_imap_collect_flags (struct imap_list_element *arg, int *res); 233 234 struct imap_list_element *_mu_imap_list_at (mu_list_t list, int idx); 235 236 int _mu_imap_parse_fetch_response (mu_list_t resp, mu_list_t *result_list); 237 238 void _mu_close_handler (mu_imap_t imap); 239 240 /* ----------------------------- */ 241 /* URL Auxiliaries */ 242 /* ----------------------------- */ 243 int _mu_imap_url_init (mu_url_t url); 244 int _mu_imaps_url_init (mu_url_t url); 245 246 /* ----------------------------- */ 247 /* Mailbox interface */ 248 /* ----------------------------- */ 249 250 int _mu_imap_mailbox_init (mu_mailbox_t mailbox); 251 252 #define _MU_IMAP_MSG_SCANNED 0x01 /* Message has already been scanned */ 253 #define _MU_IMAP_MSG_CACHED 0x02 /* Message is cached */ 254 #define _MU_IMAP_MSG_LINES 0x04 /* Number of lines is computed */ 255 #define _MU_IMAP_MSG_ATTRCHG 0x08 /* Message attributes has changed */ 256 257 struct _mu_imap_message 258 { 259 int flags; 260 size_t msgno; /* Message sequence number */ 261 size_t uid; /* Message UID */ 262 int attr_flags; /* Attributes */ 263 mu_off_t offset; /* Offset in the message cache stream */ 264 mu_off_t body_start; /* Start of message, relative to offset */ 265 mu_off_t body_end; /* End of message, relative to offset */ 266 size_t header_lines; /* Number of lines in the header */ 267 size_t body_lines; /* Number of lines in the body */ 268 size_t message_size; /* Message size */ 269 size_t message_lines; /* Number of lines in the message */ 270 struct mu_imapenvelope *env; /* IMAP envelope */ 271 mu_stream_t header_stream; /* Memory stream with message headers */ 272 mu_message_t message; /* Pointer to the message structure */ 273 struct _mu_imap_mailbox *imbx; /* Back pointer. */ 274 }; 275 276 #define _MU_IMAP_MBX_UPTODATE 0x01 277 278 struct _mu_imap_mailbox 279 { 280 int flags; 281 struct mu_imap_stat stats; /* Mailbox statistics */ 282 struct _mu_imap_message **msgs; /* Array of messages */ 283 size_t msgs_cnt; /* Number of used slots in msgs */ 284 size_t msgs_max; /* Number of slots in msgs */ 285 mu_stream_t cache; /* Message cache stream */ 286 int last_error; /* Last error code */ 287 mu_mailbox_t mbox; 288 }; 289 290 # ifdef __cplusplus 291 } 292 # endif 293 294 #endif /* _MAILUTILS_SYS_IMAP_H */ 295