NeoMutt  2023-03-22-27-g3cb248
Teaching an old dog new tricks
DOXYGEN
mbox_open_append()

Open a Mailbox for appending. More...

+ Collaboration diagram for mbox_open_append():

Functions

static bool comp_mbox_open_append (struct Mailbox *m, OpenMailboxFlags flags)
 Open a Mailbox for appending - Implements MxOps::mbox_open_append() -. More...
 
static bool imap_mbox_open_append (struct Mailbox *m, OpenMailboxFlags flags)
 Open a Mailbox for appending - Implements MxOps::mbox_open_append() -. More...
 
static bool maildir_mbox_open_append (struct Mailbox *m, OpenMailboxFlags flags)
 Open a Mailbox for appending - Implements MxOps::mbox_open_append() -. More...
 
static bool mh_mbox_open_append (struct Mailbox *m, OpenMailboxFlags flags)
 Open a Mailbox for appending - Implements MxOps::mbox_open_append() -. More...
 
static bool mbox_mbox_open_append (struct Mailbox *m, OpenMailboxFlags flags)
 Open a Mailbox for appending - Implements MxOps::mbox_open_append() -. More...
 

Detailed Description

Open a Mailbox for appending.

Parameters
mMailbox to open
flagsFlags, see OpenMailboxFlags
Return values
trueSuccess
falseFailure
Precondition
m is not NULL

Function Documentation

◆ comp_mbox_open_append()

static bool comp_mbox_open_append ( struct Mailbox m,
OpenMailboxFlags  flags 
)
static

Open a Mailbox for appending - Implements MxOps::mbox_open_append() -.

flags may also contain MUTT_NEWFOLDER

To append to a compressed mailbox we need an append-hook (or both open- and close-hooks).

Definition at line 505 of file compress.c.

506{
507 /* If this succeeds, we know there's an open-hook */
508 struct CompressInfo *ci = set_compress_info(m);
509 if (!ci)
510 return false;
511
512 /* To append we need an append-hook or a close-hook */
513 if (!ci->cmd_append && !ci->cmd_close)
514 {
515 mutt_error(_("Can't append without an append-hook or close-hook : %s"),
516 mailbox_path(m));
517 goto cmoa_fail1;
518 }
519
520 if (setup_paths(m) != 0)
521 goto cmoa_fail2;
522
523 /* Lock the realpath for the duration of the append.
524 * It will be unlocked in the close */
525 if (!lock_realpath(m, true))
526 {
527 mutt_error(_("Unable to lock mailbox"));
528 goto cmoa_fail2;
529 }
530
531 /* Open the existing mailbox, unless we are appending */
532 if (!ci->cmd_append && (mutt_file_get_size(m->realpath) > 0))
533 {
534 int rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
535 if (rc == 0)
536 {
537 mutt_error(_("Compress command failed: %s"), ci->cmd_open);
538 goto cmoa_fail2;
539 }
541 }
542 else
543 {
544 m->type = cs_subset_enum(NeoMutt->sub, "mbox_type");
545 }
546
547 /* We can only deal with mbox and mmdf mailboxes */
548 if ((m->type != MUTT_MBOX) && (m->type != MUTT_MMDF))
549 {
550 mutt_error(_("Unsupported mailbox type for appending"));
551 goto cmoa_fail2;
552 }
553
554 ci->child_ops = mx_get_ops(m->type);
555 if (!ci->child_ops)
556 {
557 mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->type);
558 goto cmoa_fail2;
559 }
560
561 if (!ci->child_ops->mbox_open_append(m, flags))
562 goto cmoa_fail2;
563
564 return true;
565
566cmoa_fail2:
567 /* remove the partial uncompressed file */
568 (void) remove(mailbox_path(m));
569cmoa_fail1:
570 /* Free the compress_info to prevent close from trying to recompress */
572
573 return false;
574}
static struct CompressInfo * set_compress_info(struct Mailbox *m)
Find the compress hooks for a mailbox.
Definition: compress.c:201
static void compress_info_free(struct Mailbox *m)
Frees the compress info members and structure.
Definition: compress.c:231
static int setup_paths(struct Mailbox *m)
Set the mailbox paths.
Definition: compress.c:155
static int execute_command(struct Mailbox *m, const char *command, const char *progress)
Run a system command.
Definition: compress.c:326
static bool lock_realpath(struct Mailbox *m, bool excl)
Try to lock the Mailbox.realpath.
Definition: compress.c:88
unsigned char cs_subset_enum(const struct ConfigSubset *sub, const char *name)
Get a enumeration config item by name.
Definition: helpers.c:97
long mutt_file_get_size(const char *path)
Get the size of a file.
Definition: file.c:1538
#define mutt_error(...)
Definition: logging.h:87
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:209
@ MUTT_MMDF
'mmdf' Mailbox type
Definition: mailbox.h:46
@ MUTT_MBOX
'mbox' Mailbox type
Definition: mailbox.h:45
#define _(a)
Definition: message.h:28
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:140
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1334
Private data for compress.
Definition: lib.h:47
const char * cmd_append
append-hook command
Definition: lib.h:48
const char * cmd_open
open-hook command
Definition: lib.h:50
const struct MxOps * child_ops
callbacks of de-compressed file
Definition: lib.h:52
const char * cmd_close
close-hook command
Definition: lib.h:49
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
bool(* mbox_open_append)(struct Mailbox *m, OpenMailboxFlags flags)
Definition: mxapi.h:171
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:

◆ imap_mbox_open_append()

static bool imap_mbox_open_append ( struct Mailbox m,
OpenMailboxFlags  flags 
)
static

Open a Mailbox for appending - Implements MxOps::mbox_open_append() -.

Definition at line 2158 of file imap.c.

2159{
2160 if (!m->account)
2161 return false;
2162
2163 /* in APPEND mode, we appear to hijack an existing IMAP connection -
2164 * mailbox is brand new and mostly empty */
2166 struct ImapMboxData *mdata = imap_mdata_get(m);
2167
2168 int rc = imap_mailbox_status(m, false);
2169 if (rc >= 0)
2170 return true;
2171 if (rc == -1)
2172 return false;
2173
2174 char buf[PATH_MAX + 64];
2175 snprintf(buf, sizeof(buf), _("Create %s?"), mdata->name);
2176 const bool c_confirm_create = cs_subset_bool(NeoMutt->sub, "confirm_create");
2177 if (c_confirm_create && (mutt_yesorno(buf, MUTT_YES) != MUTT_YES))
2178 return false;
2179
2180 if (imap_create_mailbox(adata, mdata->name) < 0)
2181 return false;
2182
2183 return true;
2184}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:89
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: mdata.c:60
int imap_mailbox_status(struct Mailbox *m, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1284
int imap_create_mailbox(struct ImapAccountData *adata, const char *mailbox)
Create a new mailbox.
Definition: imap.c:453
#define PATH_MAX
Definition: mutt.h:41
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:39
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:194
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: adata.h:40
IMAP-specific Mailbox data -.
Definition: mdata.h:39
void * mdata
Driver specific data.
Definition: mailbox.h:132
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:127
+ Here is the call graph for this function:

◆ maildir_mbox_open_append()

static bool maildir_mbox_open_append ( struct Mailbox m,
OpenMailboxFlags  flags 
)
static

Open a Mailbox for appending - Implements MxOps::mbox_open_append() -.

Definition at line 1110 of file maildir.c.

1111{
1112 if (!(flags & (MUTT_APPEND | MUTT_APPENDNEW | MUTT_NEWFOLDER)))
1113 {
1114 return true;
1115 }
1116
1117 errno = 0;
1118 if ((mutt_file_mkdir(mailbox_path(m), S_IRWXU) != 0) && (errno != EEXIST))
1119 {
1121 return false;
1122 }
1123
1124 char tmp[PATH_MAX] = { 0 };
1125 snprintf(tmp, sizeof(tmp), "%s/cur", mailbox_path(m));
1126 errno = 0;
1127 if ((mkdir(tmp, S_IRWXU) != 0) && (errno != EEXIST))
1128 {
1129 mutt_perror(tmp);
1130 rmdir(mailbox_path(m));
1131 return false;
1132 }
1133
1134 snprintf(tmp, sizeof(tmp), "%s/new", mailbox_path(m));
1135 errno = 0;
1136 if ((mkdir(tmp, S_IRWXU) != 0) && (errno != EEXIST))
1137 {
1138 mutt_perror(tmp);
1139 snprintf(tmp, sizeof(tmp), "%s/cur", mailbox_path(m));
1140 rmdir(tmp);
1141 rmdir(mailbox_path(m));
1142 return false;
1143 }
1144
1145 snprintf(tmp, sizeof(tmp), "%s/tmp", mailbox_path(m));
1146 errno = 0;
1147 if ((mkdir(tmp, S_IRWXU) != 0) && (errno != EEXIST))
1148 {
1149 mutt_perror(tmp);
1150 snprintf(tmp, sizeof(tmp), "%s/cur", mailbox_path(m));
1151 rmdir(tmp);
1152 snprintf(tmp, sizeof(tmp), "%s/new", mailbox_path(m));
1153 rmdir(tmp);
1154 rmdir(mailbox_path(m));
1155 return false;
1156 }
1157
1158 return true;
1159}
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:952
#define mutt_perror(...)
Definition: logging.h:88
#define MUTT_NEWFOLDER
Create a new folder - same as MUTT_APPEND, but uses mutt_file_fopen() with mode "w" for mbox-style fo...
Definition: mxapi.h:66
#define MUTT_APPEND
Open mailbox for appending messages.
Definition: mxapi.h:63
#define MUTT_APPENDNEW
Set in mx_open_mailbox_append if the mailbox doesn't exist.
Definition: mxapi.h:70
+ Here is the call graph for this function:

◆ mh_mbox_open_append()

static bool mh_mbox_open_append ( struct Mailbox m,
OpenMailboxFlags  flags 
)
static

Open a Mailbox for appending - Implements MxOps::mbox_open_append() -.

Definition at line 860 of file mh.c.

861{
862 if (!(flags & (MUTT_APPENDNEW | MUTT_NEWFOLDER)))
863 return true;
864
865 if (mutt_file_mkdir(mailbox_path(m), S_IRWXU))
866 {
868 return false;
869 }
870
871 char tmp[PATH_MAX] = { 0 };
872 snprintf(tmp, sizeof(tmp), "%s/.mh_sequences", mailbox_path(m));
873 const int i = creat(tmp, S_IRWXU);
874 if (i == -1)
875 {
876 mutt_perror(tmp);
877 rmdir(mailbox_path(m));
878 return false;
879 }
880 close(i);
881
882 return true;
883}
+ Here is the call graph for this function:

◆ mbox_mbox_open_append()

static bool mbox_mbox_open_append ( struct Mailbox m,
OpenMailboxFlags  flags 
)
static

Open a Mailbox for appending - Implements MxOps::mbox_open_append() -.

Definition at line 982 of file mbox.c.

983{
984 if (init_mailbox(m) != 0)
985 return false;
986
988 if (!adata)
989 return false;
990
991 if (!adata->fp)
992 {
993 // create dir recursively
994 char *tmp_path = mutt_path_dirname(mailbox_path(m));
995 if (mutt_file_mkdir(tmp_path, S_IRWXU) == -1)
996 {
998 FREE(&tmp_path);
999 return false;
1000 }
1001 FREE(&tmp_path);
1002
1003 adata->fp = mutt_file_fopen(mailbox_path(m), (flags & MUTT_NEWFOLDER) ? "w+" : "a+");
1004 if (!adata->fp)
1005 {
1007 return false;
1008 }
1009
1010 if (mbox_lock_mailbox(m, true, true) != false)
1011 {
1012 mutt_error(_("Couldn't lock %s"), mailbox_path(m));
1013 mutt_file_fclose(&adata->fp);
1014 return false;
1015 }
1016 }
1017
1018 if (!mutt_file_seek(adata->fp, 0, SEEK_END))
1019 {
1020 mutt_file_fclose(&adata->fp);
1021 return false;
1022 }
1023
1024 return true;
1025}
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:634
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition: file.c:708
static int mbox_lock_mailbox(struct Mailbox *m, bool excl, bool retry)
Lock a mailbox.
Definition: mbox.c:134
static struct MboxAccountData * mbox_adata_get(struct Mailbox *m)
Get the private data associated with a Mailbox.
Definition: mbox.c:119
static int init_mailbox(struct Mailbox *m)
Add Mbox data to the Mailbox.
Definition: mbox.c:100
#define FREE(x)
Definition: memory.h:43
char * mutt_path_dirname(const char *path)
Return a path up to, but not including, the final '/'.
Definition: path.c:376
Mbox-specific Account data -.
Definition: lib.h:49
+ Here is the call graph for this function: