/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2010-2021 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
. */
#ifndef _MAILUTILS_SYS_IMAP_H
# define _MAILUTILS_SYS_IMAP_H
# include
# include
# include
# include
# include
# include
# ifdef __cplusplus
extern "C" {
# endif
#define MU_IMAP_RESP 0x01
#define MU_IMAP_TRACE 0x02
#define MU_IMAP_XSCRIPT_MASK(n) (1<<((n)+1))
#define MU_IMAP_SET_XSCRIPT_MASK(imap,n) \
do \
(imap)->flags |= MU_IMAP_XSCRIPT_MASK (n); \
while (0)
#define MU_IMAP_CLR_XSCRIPT_MASK(imap,n) \
do \
(imap)->flags &= ~MU_IMAP_XSCRIPT_MASK (n); \
while (0)
#define MU_IMAP_IS_XSCRIPT_MASK(imap,n) \
((imap)->flags & MU_IMAP_XSCRIPT_MASK (n))
enum mu_imap_client_state
{
MU_IMAP_CLIENT_READY,
MU_IMAP_CLIENT_ERROR,
MU_IMAP_CLIENT_CONNECT_RX,
MU_IMAP_CLIENT_GREETINGS,
MU_IMAP_CLIENT_CAPABILITY_RX,
MU_IMAP_CLIENT_LOGIN_RX,
MU_IMAP_CLIENT_LOGOUT_RX,
MU_IMAP_CLIENT_ID_RX,
MU_IMAP_CLIENT_SELECT_RX,
MU_IMAP_CLIENT_STATUS_RX,
MU_IMAP_CLIENT_NOOP_RX,
MU_IMAP_CLIENT_FETCH_RX,
MU_IMAP_CLIENT_STORE_RX,
MU_IMAP_CLIENT_DELETE_RX,
MU_IMAP_CLIENT_RENAME_RX,
MU_IMAP_CLIENT_CLOSE_RX,
MU_IMAP_CLIENT_UNSELECT_RX,
MU_IMAP_CLIENT_CHECK_RX,
MU_IMAP_CLIENT_COPY_RX,
MU_IMAP_CLIENT_EXPUNGE_RX,
MU_IMAP_CLIENT_APPEND_RX,
MU_IMAP_CLIENT_LIST_RX,
MU_IMAP_CLIENT_SUBSCRIBE_RX,
MU_IMAP_CLIENT_UNSUBSCRIBE_RX,
MU_IMAP_CLIENT_LSUB_RX,
MU_IMAP_CLIENT_STARTTLS_RX,
MU_IMAP_CLIENT_SEARCH_RX,
MU_IMAP_CLIENT_CLOSING
};
enum mu_imap_response
{
MU_IMAP_OK,
MU_IMAP_NO,
MU_IMAP_BAD
};
struct _mu_imap
{
int flags;
/* Holds the recent response */
enum mu_imap_response response;
/* The recent response code */
int response_code;
/* Error string (if any) */
char *errstr;
size_t errsize;
enum mu_imap_client_state client_state;
enum mu_imap_session_state session_state;
/* Tag */
size_t tag_len; /* Length of the command tag */
int *tag_buf; /* Tag number (BCD) */
char *tag_str; /* String representation (tag_len + 1 bytes, asciiz) */
mu_list_t capa;
mu_imapio_t io;
char *mbox_name; /* Name of the currently opened mailbox */
int mbox_writable:1; /* Is it open read/write? */
struct mu_imap_stat mbox_stat; /* Stats obtained from it */
/* Folder data */
int separator; /* Separator character */
size_t prefix_len; /* Path prefix length */
/* Callbacks */
struct
{
mu_imap_callback_t action;
void *data;
} callback[_MU_IMAP_CB_MAX];
};
enum imap_eltype
{
imap_eltype_string,
imap_eltype_list
};
struct imap_list_element
{
enum imap_eltype type;
union
{
mu_list_t list;
char *string;
} v;
};
#define MU_IMAP_FSET(p,f) ((p)->flags |= (f))
#define MU_IMAP_FISSET(p,f) ((p)->flags & (f))
#define MU_IMAP_FCLR(p,f) ((p)->flags &= ~(f))
int _mu_imap_init (mu_imap_t imap);
int _mu_imap_trace_enable (mu_imap_t imap);
int _mu_imap_trace_disable (mu_imap_t imap);
int _mu_imap_xscript_level (mu_imap_t imap, int xlev);
typedef void (*mu_imap_response_action_t) (mu_imap_t imap, mu_list_t resp,
void *data);
struct imap_command
{
int session_state;
char *capa;
int rx_state;
int argc;
char const **argv;
char const *extra;
mu_msgset_t msgset;
void (*tagged_handler) (mu_imap_t);
mu_imap_response_action_t untagged_handler;
void *untagged_handler_data;
};
int mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd);
/* If status indicates an error, return.
*/
#define MU_IMAP_CHECK_ERROR(imap, status) \
do \
{ \
if (status != 0) \
{ \
imap->client_state = MU_IMAP_CLIENT_ERROR; \
return status; \
} \
} \
while (0)
/* Check if status indicates an error.
If the error is recoverable just return the status.
Otherwise, set the error state and return the status
*/
#define MU_IMAP_CHECK_EAGAIN(imap, status) \
do \
{ \
switch (status) \
{ \
case 0: \
break; \
case EAGAIN: \
case EINPROGRESS: \
case EINTR: \
return status; \
case MU_ERR_REPLY: \
case MU_ERR_BADREPLY: \
imap->client_state = MU_IMAP_CLIENT_READY; \
return status; \
default: \
imap->client_state = MU_IMAP_CLIENT_ERROR; \
return status; \
} \
} \
while (0)
int _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t len);
int _mu_imap_seterrstrz (mu_imap_t imap, const char *str);
void _mu_imap_clrerrstr (mu_imap_t imap);
int _mu_imap_tag_next (mu_imap_t imap);
int _mu_imap_tag_clr (mu_imap_t imap);
int _mu_imap_untagged_response_to_list (mu_imap_t imap, mu_list_t *plist);
int _mu_imap_process_untagged_response (mu_imap_t imap, mu_list_t list,
mu_imap_response_action_t fun,
void *data);
int _mu_imap_process_tagged_response (mu_imap_t imap, mu_list_t resp);
int _mu_imap_response (mu_imap_t imap, mu_imap_response_action_t fun,
void *data);
int _mu_imap_list_element_is_string (struct imap_list_element *elt,
const char *str);
int _mu_imap_list_element_is_nil (struct imap_list_element *elt);
int _mu_imap_list_nth_element_is_string (mu_list_t list, size_t n,
const char *str);
int _mu_imap_collect_flags (struct imap_list_element *arg, int *res);
struct imap_list_element *_mu_imap_list_at (mu_list_t list, int idx);
int _mu_imap_parse_fetch_response (mu_list_t resp, mu_list_t *result_list);
void _mu_close_handler (mu_imap_t imap);
/* ----------------------------- */
/* URL Auxiliaries */
/* ----------------------------- */
int _mu_imap_url_init (mu_url_t url);
int _mu_imaps_url_init (mu_url_t url);
/* ----------------------------- */
/* Mailbox interface */
/* ----------------------------- */
int _mu_imap_mailbox_init (mu_mailbox_t mailbox);
#define _MU_IMAP_MSG_SCANNED 0x01 /* Message has already been scanned */
#define _MU_IMAP_MSG_CACHED 0x02 /* Message is cached */
#define _MU_IMAP_MSG_LINES 0x04 /* Number of lines is computed */
#define _MU_IMAP_MSG_ATTRCHG 0x08 /* Message attributes has changed */
struct _mu_imap_message
{
int flags;
size_t msgno; /* Message sequence number */
size_t uid; /* Message UID */
int attr_flags; /* Attributes */
mu_off_t offset; /* Offset in the message cache stream */
mu_off_t body_start; /* Start of message, relative to offset */
mu_off_t body_end; /* End of message, relative to offset */
size_t header_lines; /* Number of lines in the header */
size_t body_lines; /* Number of lines in the body */
size_t message_size; /* Message size */
size_t message_lines; /* Number of lines in the message */
struct mu_imapenvelope *env; /* IMAP envelope */
mu_stream_t header_stream; /* Memory stream with message headers */
mu_message_t message; /* Pointer to the message structure */
struct _mu_imap_mailbox *imbx; /* Back pointer. */
};
#define _MU_IMAP_MBX_UPTODATE 0x01
struct _mu_imap_mailbox
{
int flags;
struct mu_imap_stat stats; /* Mailbox statistics */
struct _mu_imap_message **msgs; /* Array of messages */
size_t msgs_cnt; /* Number of used slots in msgs */
size_t msgs_max; /* Number of slots in msgs */
mu_stream_t cache; /* Message cache stream */
int last_error; /* Last error code */
mu_mailbox_t mbox;
};
# ifdef __cplusplus
}
# endif
#endif /* _MAILUTILS_SYS_IMAP_H */