Example #1
0
File: set.c Project: kdave/neomutt
/**
 * 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);
}
Example #2
0
File: set.c Project: darnir/neomutt
/**
 * 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);
}
Example #3
0
File: mh.c Project: kdave/neomutt
/**
 * 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;
}