1 /** 2 * @file 3 * API for mx backends 4 * 5 * @authors 6 * Copyright (C) 1996-2000,2010,2013 Michael R. Elkins <me@mutt.org> 7 * Copyright (C) 2018-2019 Richard Russon <rich@flatcap.org> 8 * 9 * @copyright 10 * This program is free software: you can redistribute it and/or modify it under 11 * the terms of the GNU General Public License as published by the Free Software 12 * Foundation, either version 2 of the License, or (at your option) any later 13 * version. 14 * 15 * This program is distributed in the hope that it will be useful, but WITHOUT 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 18 * details. 19 * 20 * You should have received a copy of the GNU General Public License along with 21 * this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #ifndef MUTT_CORE_MXAPI_H 25 #define MUTT_CORE_MXAPI_H 26 27 #include "config.h" 28 #include <stdbool.h> 29 #include <stdint.h> 30 #include <stdio.h> 31 #include <sys/types.h> 32 #include "mailbox.h" 33 34 struct Account; 35 struct Email; 36 struct stat; 37 38 /** 39 * struct Message - A local copy of an email 40 */ 41 struct Message 42 { 43 FILE *fp; ///< pointer to the message data 44 char *path; ///< path to temp file 45 char *committed_path; ///< the final path generated by mx_msg_commit() 46 bool write; ///< nonzero if message is open for writing 47 struct 48 { 49 bool read : 1; ///< Message has been read 50 bool flagged : 1; ///< Message is flagged 51 bool replied : 1; ///< Message has been replied to 52 bool draft : 1; ///< Message has been read 53 } flags; ///< Flags for the Message 54 time_t received; ///< Time at which this message was received 55 }; 56 57 58 /* flags for mutt_open_mailbox() */ 59 typedef uint8_t OpenMailboxFlags; ///< Flags for mutt_open_mailbox(), e.g. #MUTT_NOSORT 60 #define MUTT_OPEN_NO_FLAGS 0 ///< No flags are set 61 #define MUTT_NOSORT (1 << 0) ///< Do not sort the mailbox after opening it 62 #define MUTT_APPEND (1 << 1) ///< Open mailbox for appending messages 63 #define MUTT_READONLY (1 << 2) ///< Open in read-only mode 64 #define MUTT_QUIET (1 << 3) ///< Do not print any messages 65 #define MUTT_NEWFOLDER (1 << 4) ///< Create a new folder - same as #MUTT_APPEND, 66 ///< but uses mutt_file_fopen() with mode "w" for mbox-style folders. 67 ///< This will truncate an existing file. 68 #define MUTT_PEEK (1 << 5) ///< Revert atime back after taking a look (if applicable) 69 #define MUTT_APPENDNEW (1 << 6) ///< Set in mx_open_mailbox_append if the mailbox doesn't exist. 70 ///< Used by maildir/mh to create the mailbox. 71 /** 72 * enum MxStatus - Return values from mbox_check(), mbox_check_stats(), 73 * mbox_snc(), and mbox_close() 74 */ 75 enum MxStatus 76 { 77 MX_STATUS_ERROR = -1, ///< An error occurred 78 MX_STATUS_OK, ///< No changes 79 MX_STATUS_NEW_MAIL, ///< New mail received in Mailbox 80 MX_STATUS_LOCKED, ///< Couldn't lock the Mailbox 81 MX_STATUS_REOPENED, ///< Mailbox was reopened 82 MX_STATUS_FLAGS, ///< Nondestructive flags change (IMAP) 83 }; 84 85 /** 86 * enum MxOpenReturns - Return values for mbox_open() 87 */ 88 enum MxOpenReturns 89 { 90 MX_OPEN_OK, ///< Open succeeded 91 MX_OPEN_ERROR, ///< Open failed with an error 92 MX_OPEN_ABORT, ///< Open was aborted 93 }; 94 95 /** 96 * @defgroup mx_api Mailbox API 97 * 98 * The Mailbox API 99 * 100 * Each backend provides a set of functions through which the Mailbox, messages, 101 * tags and paths are manipulated. 102 */ 103 struct MxOps 104 { 105 enum MailboxType type; ///< Mailbox type, e.g. #MUTT_IMAP 106 const char *name; ///< Mailbox name, e.g. "imap" 107 bool is_local; ///< True, if Mailbox type has local files/dirs 108 109 /** 110 * @defgroup mx_ac_owns_path ac_owns_path() 111 * @ingroup mx_api 112 * 113 * ac_owns_path - Check whether an Account owns a Mailbox path 114 * @param a Account 115 * @param path Mailbox Path 116 * @retval true Account handles path 117 * @retval false Account does not handle path 118 * 119 * **Contract** 120 * - @a a is not NULL 121 * - @a path is not NULL 122 */ 123 bool (*ac_owns_path)(struct Account *a, const char *path); 124 125 /** 126 * @defgroup mx_ac_add ac_add() 127 * @ingroup mx_api 128 * 129 * ac_add - Add a Mailbox to an Account 130 * @param a Account to add to 131 * @param m Mailbox to add 132 * @retval true Success 133 * @retval false Error 134 * 135 * **Contract** 136 * - @a a is not NULL 137 * - @a m is not NULL 138 */ 139 bool (*ac_add)(struct Account *a, struct Mailbox *m); 140 141 /** 142 * @defgroup mx_mbox_open mbox_open() 143 * @ingroup mx_api 144 * 145 * mbox_open - Open a Mailbox 146 * @param m Mailbox to open 147 * @retval enum #MxOpenReturns 148 * 149 * **Contract** 150 * - @a m is not NULL 151 */ 152 enum MxOpenReturns (*mbox_open)(struct Mailbox *m); 153 154 /** 155 * @defgroup mx_mbox_open_append mbox_open_append() 156 * @ingroup mx_api 157 * 158 * mbox_open_append - Open a Mailbox for appending 159 * @param m Mailbox to open 160 * @param flags Flags, see #OpenMailboxFlags 161 * @retval true Success 162 * @retval false Failure 163 * 164 * **Contract** 165 * - @a m is not NULL 166 */ 167 bool (*mbox_open_append)(struct Mailbox *m, OpenMailboxFlags flags); 168 169 /** 170 * @defgroup mx_mbox_check mbox_check() 171 * @ingroup mx_api 172 * 173 * mbox_check - Check for new mail 174 * @param m Mailbox 175 * @retval enum #MxStatus 176 * 177 * **Contract** 178 * - @a m is not NULL 179 */ 180 enum MxStatus (*mbox_check)(struct Mailbox *m); 181 182 /** 183 * @defgroup mx_mbox_check_stats mbox_check_stats() 184 * @ingroup mx_api 185 * 186 * mbox_check_stats - Check the Mailbox statistics 187 * @param m Mailbox to check 188 * @param flags Function flags 189 * @retval enum #MxStatus 190 * 191 * **Contract** 192 * - @a m is not NULL 193 */ 194 enum MxStatus (*mbox_check_stats)(struct Mailbox *m, uint8_t flags); 195 196 /** 197 * @defgroup mx_mbox_sync mbox_sync() 198 * @ingroup mx_api 199 * 200 * mbox_sync - Save changes to the Mailbox 201 * @param m Mailbox to sync 202 * @retval enum #MxStatus 203 * 204 * **Contract** 205 * - @a m is not NULL 206 */ 207 enum MxStatus (*mbox_sync)(struct Mailbox *m); 208 209 /** 210 * @defgroup mx_mbox_close mbox_close() 211 * @ingroup mx_api 212 * 213 * mbox_close - Close a Mailbox 214 * @param m Mailbox to close 215 * @retval enum #MxStatus 216 * 217 * **Contract** 218 * - @a m is not NULL 219 */ 220 enum MxStatus (*mbox_close)(struct Mailbox *m); 221 222 /** 223 * @defgroup mx_msg_open msg_open() 224 * @ingroup mx_api 225 * 226 * msg_open - Open an email message in a Mailbox 227 * @param m Mailbox 228 * @param msg Message to open 229 * @param msgno Index of message to open 230 * @retval true Success 231 * @retval false Error 232 * 233 * **Contract** 234 * - @a m is not NULL 235 * - @a msg is not NULL 236 * - 0 <= @a msgno < msg->msg_count 237 */ 238 bool (*msg_open)(struct Mailbox *m, struct Message *msg, int msgno); 239 240 /** 241 * @defgroup mx_msg_open_new msg_open_new() 242 * @ingroup mx_api 243 * 244 * msg_open_new - Open a new message in a Mailbox 245 * @param m Mailbox 246 * @param msg Message to open 247 * @param e Email 248 * @retval true Success 249 * @retval false Failure 250 * 251 * **Contract** 252 * - @a m is not NULL 253 * - @a msg is not NULL 254 */ 255 bool (*msg_open_new)(struct Mailbox *m, struct Message *msg, const struct Email *e); 256 257 /** 258 * @defgroup mx_msg_commit msg_commit() 259 * @ingroup mx_api 260 * 261 * msg_commit - Save changes to an email 262 * @param m Mailbox 263 * @param msg Message to commit 264 * @retval 0 Success 265 * @retval -1 Failure 266 * 267 * **Contract** 268 * - @a m is not NULL 269 * - @a msg is not NULL 270 */ 271 int (*msg_commit) (struct Mailbox *m, struct Message *msg); 272 273 /** 274 * @defgroup mx_msg_close msg_close() 275 * @ingroup mx_api 276 * 277 * msg_close - Close an email 278 * @param m Mailbox 279 * @param msg Message to close 280 * @retval 0 Success 281 * @retval -1 Failure 282 * 283 * **Contract** 284 * - @a m is not NULL 285 * - @a msg is not NULL 286 */ 287 int (*msg_close) (struct Mailbox *m, struct Message *msg); 288 289 /** 290 * @defgroup mx_msg_padding_size msg_padding_size() 291 * @ingroup mx_api 292 * 293 * msg_padding_size - Bytes of padding between messages 294 * @param m Mailbox 295 * @retval num Bytes of padding 296 * 297 * **Contract** 298 * - @a m is not NULL 299 */ 300 int (*msg_padding_size)(struct Mailbox *m); 301 302 /** 303 * @defgroup mx_msg_save_hcache msg_save_hcache() 304 * @ingroup mx_api 305 * 306 * msg_save_hcache - Save message to the header cache 307 * @param m Mailbox 308 * @param e Email 309 * @retval 0 Success 310 * @retval -1 Failure 311 * 312 * **Contract** 313 * - @a m is not NULL 314 * - @a e is not NULL 315 */ 316 int (*msg_save_hcache) (struct Mailbox *m, struct Email *e); 317 318 /** 319 * @defgroup mx_tags_edit tags_edit() 320 * @ingroup mx_api 321 * 322 * tags_edit - Prompt and validate new messages tags 323 * @param m Mailbox 324 * @param tags Existing tags 325 * @param buf Buffer to store the tags 326 * @param buflen Length of buffer 327 * @retval -1 Error 328 * @retval 0 No valid user input 329 * @retval 1 Buf set 330 * 331 * **Contract** 332 * - @a m is not NULL 333 * - @a buf is not NULL 334 */ 335 int (*tags_edit) (struct Mailbox *m, const char *tags, char *buf, size_t buflen); 336 337 /** 338 * @defgroup mx_tags_commit tags_commit() 339 * @ingroup mx_api 340 * 341 * tags_commit - Save the tags to a message 342 * @param m Mailbox 343 * @param e Email 344 * @param buf Buffer containing tags 345 * @retval 0 Success 346 * @retval -1 Failure 347 * 348 * **Contract** 349 * - @a m is not NULL 350 * - @a e is not NULL 351 * - @a buf is not NULL 352 */ 353 int (*tags_commit) (struct Mailbox *m, struct Email *e, char *buf); 354 355 /** 356 * @defgroup mx_path_probe path_probe() 357 * @ingroup mx_api 358 * 359 * path_probe - Does this Mailbox type recognise this path? 360 * @param path Path to examine 361 * @param st stat buffer (for local filesystems) 362 * @retval num Type, e.g. #MUTT_IMAP 363 * 364 * **Contract** 365 * - @a path is not NULL 366 */ 367 enum MailboxType (*path_probe)(const char *path, const struct stat *st); 368 369 /** 370 * @defgroup mx_path_canon path_canon() 371 * @ingroup mx_api 372 * 373 * path_canon - Canonicalise a Mailbox path 374 * @param buf Path to modify 375 * @param buflen Length of buffer 376 * @retval 0 Success 377 * @retval -1 Failure 378 * 379 * **Contract** 380 * - @a buf is not NULL 381 */ 382 int (*path_canon) (char *buf, size_t buflen); 383 384 /** 385 * @defgroup mx_path_pretty path_pretty() 386 * @ingroup mx_api 387 * 388 * path_pretty - Abbreviate a Mailbox path 389 * @param buf Path to modify 390 * @param buflen Length of buffer 391 * @param folder Base path for '=' substitution 392 * @retval 0 Success 393 * @retval -1 Failure 394 * 395 * **Contract** 396 * - @a buf is not NULL 397 */ 398 int (*path_pretty) (char *buf, size_t buflen, const char *folder); 399 400 /** 401 * @defgroup mx_path_parent path_parent() 402 * @ingroup mx_api 403 * 404 * path_parent - Find the parent of a Mailbox path 405 * @param buf Path to modify 406 * @param buflen Length of buffer 407 * @retval 0 Success 408 * @retval -1 Failure 409 * 410 * **Contract** 411 * - @a buf is not NULL 412 */ 413 int (*path_parent) (char *buf, size_t buflen); 414 415 /** 416 * @defgroup mx_path_is_empty path_is_empty() 417 * @ingroup mx_api 418 * 419 * path_is_empty - Is the Mailbox empty? 420 * @param path Mailbox to check 421 * @retval 1 Mailbox is empty 422 * @retval 0 Mailbox contains mail 423 * @retval -1 Error 424 * 425 * **Contract** 426 * - @a path is not NULL and not empty 427 */ 428 int (*path_is_empty) (const char *path); 429 }; 430 431 #endif /* MUTT_CORE_MXAPI_H */ 432 433