NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
mbox_sync()

Save changes to the Mailbox. More...

+ Collaboration diagram for mbox_sync():

Functions

static enum MxStatus comp_mbox_sync (struct Mailbox *m)
 Save changes to the Mailbox - Implements MxOps::mbox_sync() -Changes in NeoMutt only affect the tmp file. More...
 
enum MxStatus maildir_mbox_sync (struct Mailbox *m)
 Save changes to the Mailbox - Implements MxOps::mbox_sync() -. More...
 
enum MxStatus mh_mbox_sync (struct Mailbox *m)
 Save changes to the Mailbox - Implements MxOps::mbox_sync() -. More...
 
static enum MxStatus mbox_mbox_sync (struct Mailbox *m)
 Save changes to the Mailbox - Implements MxOps::mbox_sync() -. More...
 
static enum MxStatus nntp_mbox_sync (struct Mailbox *m)
 Save changes to the Mailbox - Implements MxOps::mbox_sync() -. More...
 
static enum MxStatus nm_mbox_sync (struct Mailbox *m)
 Save changes to the Mailbox - Implements MxOps::mbox_sync() -. More...
 
static enum MxStatus pop_mbox_sync (struct Mailbox *m)
 Save changes to the Mailbox - Implements MxOps::mbox_sync() -Update POP mailbox, delete messages from server. More...
 

Detailed Description

Save changes to the Mailbox.

Parameters
mMailbox to sync
Return values
enumMxStatus

Contract

Function Documentation

◆ comp_mbox_sync()

static enum MxStatus comp_mbox_sync ( struct Mailbox m)
static

Save changes to the Mailbox - Implements MxOps::mbox_sync() -Changes in NeoMutt only affect the tmp file.

Calling comp_mbox_sync() will commit them to the compressed file.

Definition at line 615 of file compress.c.

616 {
617  if (!m->compress_info)
618  return MX_STATUS_ERROR;
619 
620  struct CompressInfo *ci = m->compress_info;
621 
622  if (!ci->cmd_close)
623  {
624  mutt_error(_("Can't sync a compressed file without a close-hook"));
625  return MX_STATUS_ERROR;
626  }
627 
628  const struct MxOps *ops = ci->child_ops;
629  if (!ops)
630  return MX_STATUS_ERROR;
631 
632  if (!lock_realpath(m, true))
633  {
634  mutt_error(_("Unable to lock mailbox"));
635  return MX_STATUS_ERROR;
636  }
637 
638  enum MxStatus check = comp_mbox_check(m);
639  if (check != MX_STATUS_OK)
640  goto sync_cleanup;
641 
642  check = ops->mbox_sync(m);
643  if (check != MX_STATUS_OK)
644  goto sync_cleanup;
645 
646  int rc = execute_command(m, ci->cmd_close, _("Compressing %s"));
647  if (rc == 0)
648  {
649  check = MX_STATUS_ERROR;
650  goto sync_cleanup;
651  }
652 
653  check = MX_STATUS_OK;
654 
655 sync_cleanup:
656  store_size(m);
657  unlock_realpath(m);
658  return check;
659 }
#define mutt_error(...)
Definition: logging.h:88
#define _(a)
Definition: message.h:28
const char * cmd_close
close-hook command
Definition: lib.h:49
static void store_size(const struct Mailbox *m)
Save the size of the compressed file.
Definition: compress.c:178
static enum MxStatus comp_mbox_check(struct Mailbox *m)
Check for new mail - Implements MxOps::mbox_check() -.
Definition: compress.c:579
enum MxStatus(* mbox_sync)(struct Mailbox *m)
Definition: mxapi.h:207
No changes.
Definition: mxapi.h:78
static void unlock_realpath(struct Mailbox *m)
Unlock the mailbox->realpath.
Definition: compress.c:124
Private data for compress.
Definition: lib.h:46
static int execute_command(struct Mailbox *m, const char *command, const char *progress)
Run a system command.
Definition: compress.c:319
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:124
static bool lock_realpath(struct Mailbox *m, bool excl)
Try to lock the ctx->realpath.
Definition: compress.c:85
const struct MxOps * child_ops
callbacks of de-compressed file
Definition: lib.h:52
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
Definition: mxapi.h:103
An error occurred.
Definition: mxapi.h:77
+ Here is the call graph for this function:

◆ maildir_mbox_sync()

enum MxStatus maildir_mbox_sync ( struct Mailbox m)

Save changes to the Mailbox - Implements MxOps::mbox_sync() -.

Return values
enumMxStatus
Note
The flag retvals come from a call to a backend sync function

Definition at line 1373 of file maildir.c.

1374 {
1375  enum MxStatus check = maildir_mbox_check(m);
1376  if (check == MX_STATUS_ERROR)
1377  return check;
1378 
1379  struct HeaderCache *hc = NULL;
1380 #ifdef USE_HCACHE
1381  const char *const c_header_cache =
1382  cs_subset_path(NeoMutt->sub, "header_cache");
1383  if (m->type == MUTT_MAILDIR)
1384  hc = mutt_hcache_open(c_header_cache, mailbox_path(m), NULL);
1385 #endif
1386 
1387  struct Progress *progress = NULL;
1388  if (m->verbose)
1389  {
1390  char msg[PATH_MAX];
1391  snprintf(msg, sizeof(msg), _("Writing %s..."), mailbox_path(m));
1392  progress = progress_new(msg, MUTT_PROGRESS_WRITE, m->msg_count);
1393  }
1394 
1395  for (int i = 0; i < m->msg_count; i++)
1396  {
1397  if (m->verbose)
1398  progress_update(progress, i, -1);
1399 
1400  if (!maildir_sync_mailbox_message(m, i, hc))
1401  {
1402  progress_free(&progress);
1403  goto err;
1404  }
1405  }
1406  progress_free(&progress);
1407 
1408 #ifdef USE_HCACHE
1409  if (m->type == MUTT_MAILDIR)
1410  mutt_hcache_close(hc);
1411 #endif
1412 
1413  /* XXX race condition? */
1414 
1416 
1417  /* adjust indices */
1418 
1419  if (m->msg_deleted)
1420  {
1421  for (int i = 0, j = 0; i < m->msg_count; i++)
1422  {
1423  struct Email *e = m->emails[i];
1424  if (!e)
1425  break;
1426 
1427  const bool c_maildir_trash =
1428  cs_subset_bool(NeoMutt->sub, "maildir_trash");
1429  if (!e->deleted || c_maildir_trash)
1430  e->index = j++;
1431  }
1432  }
1433 
1434  return check;
1435 
1436 err:
1437 #ifdef USE_HCACHE
1438  if (m->type == MUTT_MAILDIR)
1439  mutt_hcache_close(hc);
1440 #endif
1441  return MX_STATUS_ERROR;
1442 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:91
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
The envelope/body of an email.
Definition: email.h:37
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
enum MxStatus maildir_mbox_check(struct Mailbox *m)
Check for new mail - Implements MxOps::mbox_check() -This function handles arrival of new mail and re...
Definition: maildir.c:1166
void maildir_update_mtime(struct Mailbox *m)
Update our record of the Maildir modification time.
Definition: maildir.c:477
header cache structure
Definition: lib.h:84
#define _(a)
Definition: message.h:28
struct HeaderCache * mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
Multiplexor for StoreOps::open.
Definition: hcache.c:332
Container for Accounts, Notifications.
Definition: neomutt.h:36
A Progress Bar.
Definition: progress.c:47
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
#define PATH_MAX
Definition: mutt.h:40
char msg[1024]
Message to display.
Definition: progress.c:50
bool verbose
Display status messages?
Definition: mailbox.h:118
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:435
Progress tracks elements, according to $write_inc
Definition: lib.h:47
bool deleted
Email is deleted.
Definition: email.h:45
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
int index
The absolute (unsorted) message number.
Definition: email.h:86
bool maildir_sync_mailbox_message(struct Mailbox *m, int msgno, struct HeaderCache *hc)
Save changes to the mailbox.
Definition: maildir.c:946
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
An error occurred.
Definition: mxapi.h:77
+ Here is the call graph for this function:

◆ mh_mbox_sync()

enum MxStatus mh_mbox_sync ( struct Mailbox m)

Save changes to the Mailbox - Implements MxOps::mbox_sync() -.

Return values
MX_STATUS_REOPENEDmailbox has been externally modified
MX_STATUS_NEW_MAILnew mail has arrived
0Success
-1Error
Note
The flag retvals come from a call to a backend sync function

Definition at line 1029 of file mh.c.

1030 {
1031  enum MxStatus check = mh_mbox_check(m);
1032  if (check == MX_STATUS_ERROR)
1033  return check;
1034 
1035  struct HeaderCache *hc = NULL;
1036 #ifdef USE_HCACHE
1037  const char *const c_header_cache =
1038  cs_subset_path(NeoMutt->sub, "header_cache");
1039  if (m->type == MUTT_MH)
1040  hc = mutt_hcache_open(c_header_cache, mailbox_path(m), NULL);
1041 #endif
1042 
1043  struct Progress *progress = NULL;
1044  if (m->verbose)
1045  {
1046  char msg[PATH_MAX];
1047  snprintf(msg, sizeof(msg), _("Writing %s..."), mailbox_path(m));
1048  progress = progress_new(msg, MUTT_PROGRESS_WRITE, m->msg_count);
1049  }
1050 
1051  for (int i = 0; i < m->msg_count; i++)
1052  {
1053  if (m->verbose)
1054  progress_update(progress, i, -1);
1055 
1056  if (mh_sync_mailbox_message(m, i, hc) == -1)
1057  {
1058  progress_free(&progress);
1059  goto err;
1060  }
1061  }
1062  progress_free(&progress);
1063 
1064 #ifdef USE_HCACHE
1065  if (m->type == MUTT_MH)
1066  mutt_hcache_close(hc);
1067 #endif
1068 
1069  mh_seq_update(m);
1070 
1071  /* XXX race condition? */
1072 
1073  mh_update_mtime(m);
1074 
1075  /* adjust indices */
1076 
1077  if (m->msg_deleted)
1078  {
1079  for (int i = 0, j = 0; i < m->msg_count; i++)
1080  {
1081  struct Email *e = m->emails[i];
1082  if (!e)
1083  break;
1084 
1085  if (!e->deleted)
1086  e->index = j++;
1087  }
1088  }
1089 
1090  return check;
1091 
1092 err:
1093 #ifdef USE_HCACHE
1094  if (m->type == MUTT_MH)
1095  mutt_hcache_close(hc);
1096 #endif
1097  return MX_STATUS_ERROR;
1098 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
header cache structure
Definition: lib.h:84
#define _(a)
Definition: message.h:28
struct HeaderCache * mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
Multiplexor for StoreOps::open.
Definition: hcache.c:332
Container for Accounts, Notifications.
Definition: neomutt.h:36
A Progress Bar.
Definition: progress.c:47
void mh_update_mtime(struct Mailbox *m)
Update our record of the Maildir modification time.
Definition: mh.c:476
#define PATH_MAX
Definition: mutt.h:40
enum MxStatus mh_mbox_check(struct Mailbox *m)
Check for new mail - Implements MxOps::mbox_check() -This function handles arrival of new mail and re...
Definition: mh.c:885
char msg[1024]
Message to display.
Definition: progress.c:50
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
bool verbose
Display status messages?
Definition: mailbox.h:118
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:435
int mh_sync_mailbox_message(struct Mailbox *m, int msgno, struct HeaderCache *hc)
Save changes to the mailbox.
Definition: mh.c:751
void mh_seq_update(struct Mailbox *m)
Update sequence numbers.
Definition: sequence.c:234
Progress tracks elements, according to $write_inc
Definition: lib.h:47
bool deleted
Email is deleted.
Definition: email.h:45
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
int index
The absolute (unsorted) message number.
Definition: email.h:86
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
An error occurred.
Definition: mxapi.h:77
+ Here is the call graph for this function:

◆ mbox_mbox_sync()

static enum MxStatus mbox_mbox_sync ( struct Mailbox m)
static

Save changes to the Mailbox - Implements MxOps::mbox_sync() -.

Definition at line 1146 of file mbox.c.

1147 {
1148  struct MboxAccountData *adata = mbox_adata_get(m);
1149  if (!adata)
1150  return MX_STATUS_ERROR;
1151 
1152  struct Buffer *tempfile = NULL;
1153  char buf[32];
1154  int j;
1155  bool unlink_tempfile = false;
1156  int need_sort = 0; /* flag to resort mailbox if new mail arrives */
1157  int first = -1; /* first message to be written */
1158  LOFF_T offset; /* location in mailbox to write changed messages */
1159  struct stat statbuf;
1160  struct MUpdate *new_offset = NULL;
1161  struct MUpdate *old_offset = NULL;
1162  FILE *fp = NULL;
1163  struct Progress *progress = NULL;
1164  enum MxStatus rc = MX_STATUS_ERROR;
1165 
1166  /* sort message by their position in the mailbox on disk */
1167  const short c_sort = cs_subset_sort(NeoMutt->sub, "sort");
1168  if (c_sort != SORT_ORDER)
1169  {
1172  cs_subset_str_native_set(NeoMutt->sub, "sort", c_sort, NULL);
1173  need_sort = 1;
1174  }
1175 
1176  /* need to open the file for writing in such a way that it does not truncate
1177  * the file, so use read-write mode. */
1178  adata->fp = freopen(mailbox_path(m), "r+", adata->fp);
1179  if (!adata->fp)
1180  {
1182  mutt_error(_("Fatal error! Could not reopen mailbox!"));
1183  goto fatal;
1184  }
1185 
1186  mutt_sig_block();
1187 
1188  if (mbox_lock_mailbox(m, true, true) == -1)
1189  {
1190  mutt_sig_unblock();
1191  mutt_error(_("Unable to lock mailbox"));
1192  goto bail;
1193  }
1194 
1195  /* Check to make sure that the file hasn't changed on disk */
1196  enum MxStatus check = mbox_mbox_check(m);
1197  if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED))
1198  {
1199  /* new mail arrived, or mailbox reopened */
1200  rc = check;
1201  goto bail;
1202  }
1203  else if (check < 0)
1204  {
1205  goto fatal;
1206  }
1207 
1208  /* Create a temporary file to write the new version of the mailbox in. */
1209  tempfile = mutt_buffer_pool_get();
1210  mutt_buffer_mktemp(tempfile);
1211  int fd = open(mutt_buffer_string(tempfile), O_WRONLY | O_EXCL | O_CREAT, 0600);
1212  if ((fd == -1) || !(fp = fdopen(fd, "w")))
1213  {
1214  if (fd != -1)
1215  {
1216  close(fd);
1217  unlink_tempfile = true;
1218  }
1219  mutt_error(_("Could not create temporary file"));
1220  goto bail;
1221  }
1222  unlink_tempfile = true;
1223 
1224  /* find the first deleted/changed message. we save a lot of time by only
1225  * rewriting the mailbox from the point where it has actually changed. */
1226  int i = 0;
1227  for (; (i < m->msg_count) && !m->emails[i]->deleted &&
1228  !m->emails[i]->changed && !m->emails[i]->attach_del;
1229  i++)
1230  {
1231  }
1232  if (i == m->msg_count)
1233  {
1234  /* this means ctx->changed or m->msg_deleted was set, but no
1235  * messages were found to be changed or deleted. This should
1236  * never happen, is we presume it is a bug in neomutt. */
1237  mutt_error(
1238  _("sync: mbox modified, but no modified messages (report this bug)"));
1239  mutt_debug(LL_DEBUG1, "no modified messages\n");
1240  goto bail;
1241  }
1242 
1243  /* save the index of the first changed/deleted message */
1244  first = i;
1245  /* where to start overwriting */
1246  offset = m->emails[i]->offset;
1247 
1248  /* the offset stored in the header does not include the MMDF_SEP, so make
1249  * sure we seek to the correct location */
1250  if (m->type == MUTT_MMDF)
1251  offset -= (sizeof(MMDF_SEP) - 1);
1252 
1253  /* allocate space for the new offsets */
1254  new_offset = mutt_mem_calloc(m->msg_count - first, sizeof(struct MUpdate));
1255  old_offset = mutt_mem_calloc(m->msg_count - first, sizeof(struct MUpdate));
1256 
1257  if (m->verbose)
1258  {
1259  char msg[PATH_MAX];
1260  snprintf(msg, sizeof(msg), _("Writing %s..."), mailbox_path(m));
1261  progress = progress_new(msg, MUTT_PROGRESS_WRITE, m->msg_count);
1262  }
1263 
1264  for (i = first, j = 0; i < m->msg_count; i++)
1265  {
1266  if (m->verbose)
1267  progress_update(progress, i, i / (m->msg_count / 100 + 1));
1268  /* back up some information which is needed to restore offsets when
1269  * something fails. */
1270 
1271  old_offset[i - first].valid = true;
1272  old_offset[i - first].hdr = m->emails[i]->offset;
1273  old_offset[i - first].body = m->emails[i]->body->offset;
1274  old_offset[i - first].lines = m->emails[i]->lines;
1275  old_offset[i - first].length = m->emails[i]->body->length;
1276 
1277  if (!m->emails[i]->deleted)
1278  {
1279  j++;
1280 
1281  if (m->type == MUTT_MMDF)
1282  {
1283  if (fputs(MMDF_SEP, fp) == EOF)
1284  {
1285  mutt_perror(mutt_buffer_string(tempfile));
1286  goto bail;
1287  }
1288  }
1289 
1290  /* save the new offset for this message. we add 'offset' because the
1291  * temporary file only contains saved message which are located after
1292  * 'offset' in the real mailbox */
1293  new_offset[i - first].hdr = ftello(fp) + offset;
1294 
1295  struct Message *msg = mx_msg_open(m, m->emails[i]->msgno);
1296  const int rc2 = mutt_copy_message(fp, m, m->emails[i], msg, MUTT_CM_UPDATE,
1298  mx_msg_close(m, &msg);
1299  if (rc2 != 0)
1300  {
1301  mutt_perror(mutt_buffer_string(tempfile));
1302  goto bail;
1303  }
1304 
1305  /* Since messages could have been deleted, the offsets stored in memory
1306  * will be wrong, so update what we can, which is the offset of this
1307  * message, and the offset of the body. If this is a multipart message,
1308  * we just flush the in memory cache so that the message will be reparsed
1309  * if the user accesses it later. */
1310  new_offset[i - first].body = ftello(fp) - m->emails[i]->body->length + offset;
1311  mutt_body_free(&m->emails[i]->body->parts);
1312 
1313  switch (m->type)
1314  {
1315  case MUTT_MMDF:
1316  if (fputs(MMDF_SEP, fp) == EOF)
1317  {
1318  mutt_perror(mutt_buffer_string(tempfile));
1319  goto bail;
1320  }
1321  break;
1322  default:
1323  if (fputs("\n", fp) == EOF)
1324  {
1325  mutt_perror(mutt_buffer_string(tempfile));
1326  goto bail;
1327  }
1328  }
1329  }
1330  }
1331 
1332  if (mutt_file_fclose(&fp) != 0)
1333  {
1334  mutt_debug(LL_DEBUG1, "mutt_file_fclose (&) returned non-zero\n");
1335  mutt_perror(mutt_buffer_string(tempfile));
1336  goto bail;
1337  }
1338 
1339  /* Save the state of this folder. */
1340  if (stat(mailbox_path(m), &statbuf) == -1)
1341  {
1343  goto bail;
1344  }
1345 
1346  unlink_tempfile = false;
1347 
1348  fp = fopen(mutt_buffer_string(tempfile), "r");
1349  if (!fp)
1350  {
1351  mutt_sig_unblock();
1353  mutt_debug(LL_DEBUG1, "unable to reopen temp copy of mailbox!\n");
1354  mutt_perror(mutt_buffer_string(tempfile));
1355  FREE(&new_offset);
1356  FREE(&old_offset);
1357  goto fatal;
1358  }
1359 
1360  if ((fseeko(adata->fp, offset, SEEK_SET) != 0) || /* seek the append location */
1361  /* do a sanity check to make sure the mailbox looks ok */
1362  !fgets(buf, sizeof(buf), adata->fp) ||
1363  ((m->type == MUTT_MBOX) && !mutt_str_startswith(buf, "From ")) ||
1364  ((m->type == MUTT_MMDF) && !mutt_str_equal(MMDF_SEP, buf)))
1365  {
1366  mutt_debug(LL_DEBUG1, "message not in expected position\n");
1367  mutt_debug(LL_DEBUG1, " LINE: %s\n", buf);
1368  i = -1;
1369  }
1370  else
1371  {
1372  if (fseeko(adata->fp, offset, SEEK_SET) != 0) /* return to proper offset */
1373  {
1374  i = -1;
1375  mutt_debug(LL_DEBUG1, "fseek() failed\n");
1376  }
1377  else
1378  {
1379  /* copy the temp mailbox back into place starting at the first
1380  * change/deleted message */
1381  if (m->verbose)
1382  mutt_message(_("Committing changes..."));
1383  i = mutt_file_copy_stream(fp, adata->fp);
1384 
1385  if (ferror(adata->fp))
1386  i = -1;
1387  }
1388  if (i >= 0)
1389  {
1390  m->size = ftello(adata->fp); /* update the mailbox->size of the mailbox */
1391  if ((m->size < 0) || (ftruncate(fileno(adata->fp), m->size) != 0))
1392  {
1393  i = -1;
1394  mutt_debug(LL_DEBUG1, "ftruncate() failed\n");
1395  }
1396  }
1397  }
1398 
1399  mutt_file_fclose(&fp);
1400  fp = NULL;
1402 
1403  if ((mutt_file_fclose(&adata->fp) != 0) || (i == -1))
1404  {
1405  /* error occurred while writing the mailbox back, so keep the temp copy around */
1406 
1407  struct Buffer *savefile = mutt_buffer_pool_get();
1408 
1409  const char *const c_tmpdir = cs_subset_path(NeoMutt->sub, "tmpdir");
1410  mutt_buffer_printf(savefile, "%s/neomutt.%s-%s-%u", NONULL(c_tmpdir), NONULL(Username),
1411  NONULL(ShortHostname), (unsigned int) getpid());
1412  rename(mutt_buffer_string(tempfile), mutt_buffer_string(savefile));
1413  mutt_sig_unblock();
1415  mutt_buffer_pretty_mailbox(savefile);
1416  mutt_error(_("Write failed! Saved partial mailbox to %s"), mutt_buffer_string(savefile));
1417  mutt_buffer_pool_release(&savefile);
1418  FREE(&new_offset);
1419  FREE(&old_offset);
1420  goto fatal;
1421  }
1422 
1423  /* Restore the previous access/modification times */
1424  mbox_reset_atime(m, &statbuf);
1425 
1426  /* reopen the mailbox in read-only mode */
1427  adata->fp = mbox_open_readwrite(m);
1428  if (!adata->fp)
1429  {
1430  adata->fp = mbox_open_readonly(m);
1431  }
1432  if (!adata->fp)
1433  {
1434  unlink(mutt_buffer_string(tempfile));
1435  mutt_sig_unblock();
1437  mutt_error(_("Fatal error! Could not reopen mailbox!"));
1438  FREE(&new_offset);
1439  FREE(&old_offset);
1440  goto fatal;
1441  }
1442 
1443  /* update the offsets of the rewritten messages */
1444  for (i = first, j = first; i < m->msg_count; i++)
1445  {
1446  if (!m->emails[i]->deleted)
1447  {
1448  m->emails[i]->offset = new_offset[i - first].hdr;
1449  m->emails[i]->body->hdr_offset = new_offset[i - first].hdr;
1450  m->emails[i]->body->offset = new_offset[i - first].body;
1451  m->emails[i]->index = j++;
1452  }
1453  }
1454  FREE(&new_offset);
1455  FREE(&old_offset);
1456  unlink(mutt_buffer_string(tempfile)); /* remove partial copy of the mailbox */
1457  mutt_buffer_pool_release(&tempfile);
1458  mutt_sig_unblock();
1459 
1460  const bool c_check_mbox_size =
1461  cs_subset_bool(NeoMutt->sub, "check_mbox_size");
1462  if (c_check_mbox_size)
1463  {
1464  struct Mailbox *m_tmp = mailbox_find(mailbox_path(m));
1465  if (m_tmp && !m_tmp->has_new)
1466  mailbox_update(m_tmp);
1467  }
1468 
1469  progress_free(&progress);
1470  return 0; /* signal success */
1471 
1472 bail: /* Come here in case of disaster */
1473 
1474  mutt_file_fclose(&fp);
1475 
1476  if (tempfile && unlink_tempfile)
1477  unlink(mutt_buffer_string(tempfile));
1478 
1479  /* restore offsets, as far as they are valid */
1480  if ((first >= 0) && old_offset)
1481  {
1482  for (i = first; (i < m->msg_count) && old_offset[i - first].valid; i++)
1483  {
1484  m->emails[i]->offset = old_offset[i - first].hdr;
1485  m->emails[i]->body->hdr_offset = old_offset[i - first].hdr;
1486  m->emails[i]->body->offset = old_offset[i - first].body;
1487  m->emails[i]->lines = old_offset[i - first].lines;
1488  m->emails[i]->body->length = old_offset[i - first].length;
1489  }
1490  }
1491 
1492  /* this is ok to call even if we haven't locked anything */
1494 
1495  mutt_sig_unblock();
1496  FREE(&new_offset);
1497  FREE(&old_offset);
1498 
1499  adata->fp = freopen(mailbox_path(m), "r", adata->fp);
1500  if (!adata->fp)
1501  {
1502  mutt_error(_("Could not reopen mailbox"));
1504  goto fatal;
1505  }
1506 
1508  if (need_sort)
1509  {
1510  /* if the mailbox was reopened, the thread tree will be invalid so make
1511  * sure to start threading from scratch. */
1513  }
1514 
1515 fatal:
1516  mutt_buffer_pool_release(&tempfile);
1517  progress_free(&progress);
1518  return rc;
1519 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
LOFF_T body
Definition: mbox.c:70
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:74
void mutt_sig_unblock(void)
Restore previously blocked signals.
Definition: signal.c:168
int lines
How many lines in the body of this message?
Definition: email.h:85
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
int msg_count
Total number of messages.
Definition: mailbox.h:91
off_t size
Size of the Mailbox.
Definition: mailbox.h:87
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
static FILE * mbox_open_readonly(struct Mailbox *m)
Open an mbox read-only.
Definition: mbox.c:914
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
struct Body * body
List of MIME parts.
Definition: email.h:91
Update internal tables.
Definition: mailbox.h:183
#define mutt_error(...)
Definition: logging.h:88
#define MUTT_CM_UPDATE
Update structs on sync.
Definition: copy.h:40
Mbox-specific Account data -.
Definition: lib.h:48
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:125
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
New mail received in Mailbox.
Definition: mxapi.h:79
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define CH_FROM
Retain the "From " message separator?
Definition: copy.h:56
#define _(a)
Definition: message.h:28
bool changed
Email has been edited.
Definition: email.h:48
#define CH_UPDATE
Update the status and x-status fields?
Definition: copy.h:52
Store of new offsets, used by mutt_sync_mailbox()
Definition: mbox.c:66
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
static FILE * mbox_open_readwrite(struct Mailbox *m)
Open an mbox read-write.
Definition: mbox.c:899
#define mutt_perror(...)
Definition: logging.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:36
A Progress Bar.
Definition: progress.c:47
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:603
Mailbox was reopened.
Definition: mxapi.h:81
static int mbox_lock_mailbox(struct Mailbox *m, bool excl, bool retry)
Lock a mailbox.
Definition: mbox.c:140
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
WHERE char * Username
User&#39;s login name.
Definition: mutt_globals.h:48
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:305
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1186
LOFF_T hdr
Definition: mbox.c:69
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:48
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
LOFF_T length
Definition: mbox.c:72
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:429
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Email list needs resorting.
Definition: mailbox.h:181
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
A local copy of an email.
Definition: mxapi.h:41
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
A mailbox.
Definition: mailbox.h:81
#define PATH_MAX
Definition: mutt.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
WHERE char * ShortHostname
Short version of the hostname.
Definition: mutt_globals.h:46
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
char msg[1024]
Message to display.
Definition: progress.c:50
bool verbose
Display status messages?
Definition: mailbox.h:118
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Definition: copy.h:62
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
static struct MboxAccountData * mbox_adata_get(struct Mailbox *m)
Get the private data associated with a Mailbox.
Definition: mbox.c:100
void mailbox_update(struct Mailbox *m)
Get the mailbox&#39;s current size.
Definition: mailbox.c:190
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
#define MMDF_SEP
Definition: lib.h:60
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:84
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
static enum MxStatus mbox_mbox_check(struct Mailbox *m)
Check for new mail - Implements MxOps::mbox_check() -.
Definition: mbox.c:1023
Log at debug level 1.
Definition: logging.h:40
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
Progress tracks elements, according to $write_inc
Definition: lib.h:47
bool deleted
Email is deleted.
Definition: email.h:45
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
void mbox_reset_atime(struct Mailbox *m, struct stat *st)
Reset the access time on the mailbox file.
Definition: mbox.c:842
int index
The absolute (unsorted) message number.
Definition: email.h:86
int mutt_copy_message(FILE *fp_out, struct Mailbox *m, struct Email *e, struct Message *msg, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition: copy.c:853
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
bool valid
Definition: mbox.c:68
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:42
static void mbox_unlock_mailbox(struct Mailbox *m)
Unlock a mailbox.
Definition: mbox.c:162
long lines
Definition: mbox.c:71
FILE * fp
Mailbox file.
Definition: lib.h:50
void mutt_sig_block(void)
Block signals during critical operations.
Definition: signal.c:150
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:208
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1140
int msgno
Number displayed to the user.
Definition: email.h:87
An error occurred.
Definition: mxapi.h:77
+ Here is the call graph for this function:

◆ nntp_mbox_sync()

static enum MxStatus nntp_mbox_sync ( struct Mailbox m)
static

Save changes to the Mailbox - Implements MxOps::mbox_sync() -.

Note
May also return values from check_mailbox()

Definition at line 2489 of file nntp.c.

2490 {
2491  struct NntpMboxData *mdata = m->mdata;
2492 
2493  /* check for new articles */
2494  mdata->adata->check_time = 0;
2495  enum MxStatus check = check_mailbox(m);
2496  if (check != MX_STATUS_OK)
2497  return check;
2498 
2499 #ifdef USE_HCACHE
2500  mdata->last_cached = 0;
2501  struct HeaderCache *hc = nntp_hcache_open(mdata);
2502 #endif
2503 
2504  for (int i = 0; i < m->msg_count; i++)
2505  {
2506  struct Email *e = m->emails[i];
2507  if (!e)
2508  break;
2509 
2510  char buf[16];
2511 
2512  snprintf(buf, sizeof(buf), ANUM, nntp_edata_get(e)->article_num);
2513  if (mdata->bcache && e->deleted)
2514  {
2515  mutt_debug(LL_DEBUG2, "mutt_bcache_del %s\n", buf);
2516  mutt_bcache_del(mdata->bcache, buf);
2517  }
2518 
2519 #ifdef USE_HCACHE
2520  if (hc && (e->changed || e->deleted))
2521  {
2522  if (e->deleted && !e->read)
2523  mdata->unread--;
2524  mutt_debug(LL_DEBUG2, "mutt_hcache_store %s\n", buf);
2525  mutt_hcache_store(hc, buf, strlen(buf), e, 0);
2526  }
2527 #endif
2528  }
2529 
2530 #ifdef USE_HCACHE
2531  if (hc)
2532  {
2533  mutt_hcache_close(hc);
2534  mdata->last_cached = mdata->last_loaded;
2535  }
2536 #endif
2537 
2538  /* save .newsrc entries */
2540  nntp_newsrc_update(mdata->adata);
2541  nntp_newsrc_close(mdata->adata);
2542  return MX_STATUS_OK;
2543 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
void nntp_newsrc_gen_entries(struct Mailbox *m)
Generate array of .newsrc entries.
Definition: newsrc.c:296
struct NntpAccountData * adata
Definition: mdata.h:47
header cache structure
Definition: lib.h:84
bool changed
Email has been edited.
Definition: email.h:48
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:118
anum_t last_cached
Definition: mdata.h:39
bool read
Email is read.
Definition: email.h:51
Log at debug level 2.
Definition: logging.h:41
anum_t last_loaded
Definition: mdata.h:38
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define ANUM
Definition: lib.h:61
struct BodyCache * bcache
Definition: mdata.h:49
struct HeaderCache * nntp_hcache_open(struct NntpMboxData *mdata)
Open newsgroup hcache.
Definition: newsrc.c:709
No changes.
Definition: mxapi.h:78
int mutt_hcache_store(struct HeaderCache *hc, const char *key, size_t keylen, struct Email *e, uint32_t uidvalidity)
Multiplexor for StoreOps::store.
Definition: hcache.c:556
int mutt_bcache_del(struct BodyCache *bcache, const char *id)
Delete a file from the Body Cache.
Definition: bcache.c:264
static enum MxStatus check_mailbox(struct Mailbox *m)
Check current newsgroup for new articles.
Definition: nntp.c:1433
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
struct NntpEmailData * nntp_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:58
NNTP-specific Mailbox data -.
Definition: mdata.h:32
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:435
time_t check_time
Definition: adata.h:58
bool deleted
Email is deleted.
Definition: email.h:45
anum_t unread
Definition: mdata.h:40
int nntp_newsrc_update(struct NntpAccountData *adata)
Update .newsrc file.
Definition: newsrc.c:439
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
+ Here is the call graph for this function:

◆ nm_mbox_sync()

static enum MxStatus nm_mbox_sync ( struct Mailbox m)
static

Save changes to the Mailbox - Implements MxOps::mbox_sync() -.

Definition at line 2228 of file notmuch.c.

2229 {
2230  struct NmMboxData *mdata = nm_mdata_get(m);
2231  if (!mdata)
2232  return MX_STATUS_ERROR;
2233 
2234  enum MxStatus rc = MX_STATUS_OK;
2235  struct Progress *progress = NULL;
2236  char *url = mutt_str_dup(mailbox_path(m));
2237  bool changed = false;
2238 
2239  mutt_debug(LL_DEBUG1, "nm: sync start\n");
2240 
2241  if (m->verbose)
2242  {
2243  /* all is in this function so we don't use data->progress here */
2244  char msg[PATH_MAX];
2245  snprintf(msg, sizeof(msg), _("Writing %s..."), mailbox_path(m));
2246  progress = progress_new(msg, MUTT_PROGRESS_WRITE, m->msg_count);
2247  }
2248 
2249  struct HeaderCache *h = nm_hcache_open(m);
2250 
2251  int mh_sync_errors = 0;
2252  for (int i = 0; i < m->msg_count; i++)
2253  {
2254  char old_file[PATH_MAX], new_file[PATH_MAX];
2255  struct Email *e = m->emails[i];
2256  if (!e)
2257  break;
2258 
2259  struct NmEmailData *edata = nm_edata_get(e);
2260 
2261  if (m->verbose)
2262  progress_update(progress, i, -1);
2263 
2264  *old_file = '\0';
2265  *new_file = '\0';
2266 
2267  if (edata->oldpath)
2268  {
2269  mutt_str_copy(old_file, edata->oldpath, sizeof(old_file));
2270  old_file[sizeof(old_file) - 1] = '\0';
2271  mutt_debug(LL_DEBUG2, "nm: fixing obsolete path '%s'\n", old_file);
2272  }
2273  else
2274  email_get_fullpath(e, old_file, sizeof(old_file));
2275 
2276  mutt_buffer_strcpy(&m->pathbuf, edata->folder);
2277  m->type = edata->type;
2278 
2279  bool ok = maildir_sync_mailbox_message(m, i, h);
2280  if (!ok)
2281  {
2282  // Syncing file failed, query notmuch for new filepath.
2283  m->type = MUTT_NOTMUCH;
2284  notmuch_database_t *db = nm_db_get(m, true);
2285  if (db)
2286  {
2287  notmuch_message_t *msg = get_nm_message(db, e);
2288 
2289  sync_email_path_with_nm(e, msg);
2290 
2291  mutt_buffer_strcpy(&m->pathbuf, edata->folder);
2292  m->type = edata->type;
2293  ok = maildir_sync_mailbox_message(m, i, h);
2294  m->type = MUTT_NOTMUCH;
2295  }
2296  nm_db_release(m);
2297  m->type = edata->type;
2298  }
2299 
2300  mutt_buffer_strcpy(&m->pathbuf, url);
2301  m->type = MUTT_NOTMUCH;
2302 
2303  if (!ok)
2304  {
2305  mh_sync_errors += 1;
2306  continue;
2307  }
2308 
2309  if (!e->deleted)
2310  email_get_fullpath(e, new_file, sizeof(new_file));
2311 
2312  if (e->deleted || (strcmp(old_file, new_file) != 0))
2313  {
2314  if (e->deleted && (remove_filename(m, old_file) == 0))
2315  changed = true;
2316  else if (*new_file && *old_file && (rename_filename(m, old_file, new_file, e) == 0))
2317  changed = true;
2318  }
2319 
2320  FREE(&edata->oldpath);
2321  }
2322 
2323  if (mh_sync_errors > 0)
2324  {
2325  mutt_error(
2326  ngettext(
2327  "Unable to sync %d message due to external mailbox modification",
2328  "Unable to sync %d messages due to external mailbox modification", mh_sync_errors),
2329  mh_sync_errors);
2330  }
2331 
2332  mutt_buffer_strcpy(&m->pathbuf, url);
2333  m->type = MUTT_NOTMUCH;
2334 
2335  nm_db_release(m);
2336 
2337  if (changed)
2338  {
2339  m->mtime.tv_sec = mutt_date_epoch();
2340  m->mtime.tv_nsec = 0;
2341  }
2342 
2343  nm_hcache_close(h);
2344 
2345  progress_free(&progress);
2346  FREE(&url);
2347  mutt_debug(LL_DEBUG1, "nm: .... sync done [rc=%d]\n", rc);
2348  return rc;
2349 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
enum MailboxType type
Type of Mailbox the Email is in.
Definition: edata.h:38
#define mutt_error(...)
Definition: logging.h:88
char * oldpath
Definition: edata.h:36
bool maildir_sync_mailbox_message(struct Mailbox *m, int msgno, struct HeaderCache *hc)
Save changes to the mailbox.
Definition: maildir.c:946
header cache structure
Definition: lib.h:84
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:107
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
A Progress Bar.
Definition: progress.c:47
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: db.c:172
time_t tv_sec
Definition: file.h:50
struct NmEmailData * nm_edata_get(struct Email *e)
Get the Notmuch Email data.
Definition: edata.c:72
Log at debug level 2.
Definition: logging.h:41
Notmuch-specific Mailbox data -.
Definition: mdata.h:33
char * folder
Location of the Email.
Definition: edata.h:35
long tv_nsec
Definition: file.h:51
void * mdata
Driver specific data.
Definition: mailbox.h:136
static int rename_filename(struct Mailbox *m, const char *old_file, const char *new_file, struct Email *e)
Rename the file.
Definition: notmuch.c:1321
static notmuch_message_t * get_nm_message(notmuch_database_t *db, struct Email *e)
Find a Notmuch message.
Definition: notmuch.c:1037
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mdata.c:98
#define PATH_MAX
Definition: mutt.h:40
Notmuch-specific Email data -.
Definition: edata.h:33
static struct HeaderCache * nm_hcache_open(struct Mailbox *m)
Open a header cache.
Definition: notmuch.c:109
No changes.
Definition: mxapi.h:78
char msg[1024]
Message to display.
Definition: progress.c:50
bool verbose
Display status messages?
Definition: mailbox.h:118
static void sync_email_path_with_nm(struct Email *e, notmuch_message_t *msg)
Synchronize Neomutt&#39;s Email path with notmuch.
Definition: notmuch.c:1078
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
static void nm_hcache_close(struct HeaderCache *h)
Close the header cache.
Definition: notmuch.c:124
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
Log at debug level 1.
Definition: logging.h:40
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
Progress tracks elements, according to $write_inc
Definition: lib.h:47
bool deleted
Email is deleted.
Definition: email.h:45
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: db.c:196
void * edata
Driver-specific data.
Definition: email.h:111
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
static char * email_get_fullpath(struct Email *e, char *buf, size_t buflen)
Get the full path of an email.
Definition: notmuch.c:226
#define FREE(x)
Definition: memory.h:40
static int remove_filename(struct Mailbox *m, const char *path)
Delete a file.
Definition: notmuch.c:1257
struct Buffer pathbuf
Definition: mailbox.h:83
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
An error occurred.
Definition: mxapi.h:77
+ Here is the call graph for this function:

◆ pop_mbox_sync()

static enum MxStatus pop_mbox_sync ( struct Mailbox m)
static

Save changes to the Mailbox - Implements MxOps::mbox_sync() -Update POP mailbox, delete messages from server.

Definition at line 865 of file pop.c.

866 {
867  int i, j, rc = 0;
868  char buf[1024];
869  struct PopAccountData *adata = pop_adata_get(m);
870 #ifdef USE_HCACHE
871  struct HeaderCache *hc = NULL;
872 #endif
873 
874  adata->check_time = 0;
875 
876  int num_deleted = 0;
877  for (i = 0; i < m->msg_count; i++)
878  {
879  if (m->emails[i]->deleted)
880  num_deleted++;
881  }
882 
883  while (true)
884  {
885  if (pop_reconnect(m) < 0)
886  return MX_STATUS_ERROR;
887 
888 #ifdef USE_HCACHE
889  hc = pop_hcache_open(adata, mailbox_path(m));
890 #endif
891 
892  struct Progress *progress = NULL;
893  if (m->verbose)
894  {
895  progress = progress_new(_("Marking messages deleted..."),
896  MUTT_PROGRESS_WRITE, num_deleted);
897  }
898 
899  for (i = 0, j = 0, rc = 0; (rc == 0) && (i < m->msg_count); i++)
900  {
901  struct PopEmailData *edata = pop_edata_get(m->emails[i]);
902  if (m->emails[i]->deleted && (edata->refno != -1))
903  {
904  j++;
905  if (m->verbose)
906  progress_update(progress, j, -1);
907  snprintf(buf, sizeof(buf), "DELE %d\r\n", edata->refno);
908  rc = pop_query(adata, buf, sizeof(buf));
909  if (rc == 0)
910  {
911  mutt_bcache_del(adata->bcache, cache_id(edata->uid));
912 #ifdef USE_HCACHE
913  mutt_hcache_delete_record(hc, edata->uid, strlen(edata->uid));
914 #endif
915  }
916  }
917 
918 #ifdef USE_HCACHE
919  if (m->emails[i]->changed)
920  {
921  mutt_hcache_store(hc, edata->uid, strlen(edata->uid), m->emails[i], 0);
922  }
923 #endif
924  }
925  progress_free(&progress);
926 
927 #ifdef USE_HCACHE
928  mutt_hcache_close(hc);
929 #endif
930 
931  if (rc == 0)
932  {
933  mutt_str_copy(buf, "QUIT\r\n", sizeof(buf));
934  rc = pop_query(adata, buf, sizeof(buf));
935  }
936 
937  if (rc == 0)
938  {
939  adata->clear_cache = true;
940  pop_clear_cache(adata);
941  adata->status = POP_DISCONNECTED;
942  return MX_STATUS_OK;
943  }
944 
945  if (rc == -2)
946  {
947  mutt_error("%s", adata->err_msg);
948  return MX_STATUS_ERROR;
949  }
950  }
951 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
#define pop_query(adata, buf, buflen)
Definition: private.h:106
int msg_count
Total number of messages.
Definition: mailbox.h:91
char err_msg[POP_CMD_RESPONSE]
Definition: adata.h:56
#define mutt_error(...)
Definition: logging.h:88
struct BodyCache * bcache
body cache
Definition: adata.h:55
header cache structure
Definition: lib.h:84
#define _(a)
Definition: message.h:28
bool changed
Email has been edited.
Definition: email.h:48
static const char * cache_id(const char *id)
Make a message-cache-compatible id.
Definition: pop.c:83
int refno
Message number on server.
Definition: edata.h:34
Disconnected from server.
Definition: private.h:51
struct PopAccountData * pop_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:64
A Progress Bar.
Definition: progress.c:47
static void pop_clear_cache(struct PopAccountData *adata)
delete all cached messages
Definition: pop.c:495
static struct HeaderCache * pop_hcache_open(struct PopAccountData *adata, const char *path)
Open the header cache.
Definition: pop.c:297
const char * uid
Definition: edata.h:33
time_t check_time
Definition: adata.h:51
int pop_reconnect(struct Mailbox *m)
reconnect and verify indexes if connection was lost
Definition: lib.c:604
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
bool clear_cache
Definition: adata.h:49
No changes.
Definition: mxapi.h:78
int mutt_hcache_delete_record(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition: hcache.c:637
bool verbose
Display status messages?
Definition: mailbox.h:118
int mutt_hcache_store(struct HeaderCache *hc, const char *key, size_t keylen, struct Email *e, uint32_t uidvalidity)
Multiplexor for StoreOps::store.
Definition: hcache.c:556
int mutt_bcache_del(struct BodyCache *bcache, const char *id)
Delete a file from the Body Cache.
Definition: bcache.c:264
unsigned int status
Definition: adata.h:39
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
POP-specific Email data -.
Definition: edata.h:31
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:435
struct PopEmailData * pop_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:65
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
Progress tracks elements, according to $write_inc
Definition: lib.h:47
bool deleted
Email is deleted.
Definition: email.h:45
void * edata
Driver-specific data.
Definition: email.h:111
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
POP-specific Account data -.
Definition: adata.h:36
An error occurred.
Definition: mxapi.h:77
+ Here is the call graph for this function: