/** * cs_init - Initialise a Config Set * @param cs Config items * @param size Number of expected config items */ void cs_init(struct ConfigSet *cs, size_t size) { if (!cs) return; memset(cs, 0, sizeof(*cs)); cs->hash = mutt_hash_new(size, MUTT_HASH_NO_FLAGS); mutt_hash_set_destructor(cs->hash, destroy, (intptr_t) cs); }
/** * cs_init - Initialise a Config Set * @param cs Config items * @param size Number of expected config items */ void cs_init(struct ConfigSet *cs, size_t size) { if (!cs) return; /* LCOV_EXCL_LINE */ memset(cs, 0, sizeof(*cs)); cs->hash = mutt_hash_new(size, 0); mutt_hash_set_destructor(cs->hash, destroy, (intptr_t) cs); }
/** * mh_mbox_check - Implements MxOps::mbox_check() * * This function handles arrival of new mail and reopening of mh/maildir * folders. Things are getting rather complex because we don't have a * well-defined "mailbox order", so the tricks from mbox.c and mx.c won't work * here. * * Don't change this code unless you _really_ understand what happens. */ int mh_mbox_check(struct Mailbox *m, int *index_hint) { if (!m) return -1; char buf[PATH_MAX]; struct stat st, st_cur; bool modified = false, occult = false, flags_changed = false; int num_new = 0; struct Maildir *md = NULL, *p = NULL; struct Maildir **last = NULL; struct MhSequences mhs = { 0 }; int count = 0; struct Hash *fnames = NULL; struct MaildirMboxData *mdata = maildir_mdata_get(m); if (!C_CheckNew) return 0; mutt_str_strfcpy(buf, m->path, sizeof(buf)); if (stat(buf, &st) == -1) return -1; /* create .mh_sequences when there isn't one. */ snprintf(buf, sizeof(buf), "%s/.mh_sequences", m->path); int i = stat(buf, &st_cur); if ((i == -1) && (errno == ENOENT)) { char *tmp = NULL; FILE *fp = NULL; if (mh_mkstemp(m, &fp, &tmp) == 0) { mutt_file_fclose(&fp); if (mutt_file_safe_rename(tmp, buf) == -1) unlink(tmp); FREE(&tmp); } } if ((i == -1) && (stat(buf, &st_cur) == -1)) modified = true; if ((mutt_file_stat_timespec_compare(&st, MUTT_STAT_MTIME, &m->mtime) > 0) || (mutt_file_stat_timespec_compare(&st_cur, MUTT_STAT_MTIME, &mdata->mtime_cur) > 0)) { modified = true; } if (!modified) return 0; /* Update the modification times on the mailbox. * * The monitor code notices changes in the open mailbox too quickly. * In practice, this sometimes leads to all the new messages not being * noticed during the SAME group of mtime stat updates. To work around * the problem, don't update the stat times for a monitor caused check. */ #ifdef USE_INOTIFY if (MonitorContextChanged) MonitorContextChanged = 0; else #endif { mutt_file_get_stat_timespec(&mdata->mtime_cur, &st_cur, MUTT_STAT_MTIME); mutt_file_get_stat_timespec(&m->mtime, &st, MUTT_STAT_MTIME); } md = NULL; last = &md; maildir_parse_dir(m, &last, NULL, &count, NULL); maildir_delayed_parsing(m, &md, NULL); if (mh_read_sequences(&mhs, m->path) < 0) return -1; mh_update_maildir(md, &mhs); mhs_free_sequences(&mhs); /* check for modifications and adjust flags */ fnames = mutt_hash_new(count, MUTT_HASH_NO_FLAGS); for (p = md; p; p = p->next) { /* the hash key must survive past the header, which is freed below. */ p->canon_fname = mutt_str_strdup(p->email->path); mutt_hash_insert(fnames, p->canon_fname, p); } for (i = 0; i < m->msg_count; i++) { m->emails[i]->active = false; p = mutt_hash_find(fnames, m->emails[i]->path); if (p && p->email && mutt_email_cmp_strict(m->emails[i], p->email)) { m->emails[i]->active = true; /* found the right message */ if (!m->emails[i]->changed) if (maildir_update_flags(m, m->emails[i], p->email)) flags_changed = true; mutt_email_free(&p->email); } else /* message has disappeared */ occult = true; } /* destroy the file name hash */ mutt_hash_free(&fnames); /* If we didn't just get new mail, update the tables. */ if (occult) mutt_mailbox_changed(m, MBN_RESORT); /* Incorporate new messages */ num_new = maildir_move_to_mailbox(m, &md); if (num_new > 0) { mutt_mailbox_changed(m, MBN_INVALID); m->changed = true; } if (occult) return MUTT_REOPENED; if (num_new > 0) return MUTT_NEW_MAIL; if (flags_changed) return MUTT_FLAGS; return 0; }