Ejemplo n.º 1
0
Archivo: mh.c Proyecto: kdave/neomutt
/**
 * mh_read_sequences - Read a set of MH sequences
 * @param mhs  Existing sequences
 * @param path File to read from
 * @retval  0 Success
 * @retval -1 Error
 */
int mh_read_sequences(struct MhSequences *mhs, const char *path)
{
  int line = 1;
  char *buf = NULL;
  size_t sz = 0;

  MhSeqFlags flags;
  int first, last, rc = 0;

  char pathname[PATH_MAX];
  snprintf(pathname, sizeof(pathname), "%s/.mh_sequences", path);

  FILE *fp = fopen(pathname, "r");
  if (!fp)
    return 0; /* yes, ask callers to silently ignore the error */

  while ((buf = mutt_file_read_line(buf, &sz, fp, &line, 0)))
  {
    char *t = strtok(buf, " \t:");
    if (!t)
      continue;

    if (mutt_str_strcmp(t, C_MhSeqUnseen) == 0)
      flags = MH_SEQ_UNSEEN;
    else if (mutt_str_strcmp(t, C_MhSeqFlagged) == 0)
      flags = MH_SEQ_FLAGGED;
    else if (mutt_str_strcmp(t, C_MhSeqReplied) == 0)
      flags = MH_SEQ_REPLIED;
    else /* unknown sequence */
      continue;

    while ((t = strtok(NULL, " \t:")))
    {
      if (mh_read_token(t, &first, &last) < 0)
      {
        mhs_free_sequences(mhs);
        rc = -1;
        goto out;
      }
      for (; first <= last; first++)
        mhs_set(mhs, first, flags);
    }
  }

  rc = 0;

out:
  FREE(&buf);
  mutt_file_fclose(&fp);
  return rc;
}
Ejemplo n.º 2
0
/**
 * tls_check_stored_hostname - Does the hostname match a stored certificate?
 * @param cert     Certificate
 * @param hostname Hostname
 * @retval 1 Hostname match found
 * @retval 0 Error, or no match
 */
static int tls_check_stored_hostname(const gnutls_datum_t *cert, const char *hostname)
{
  char *linestr = NULL;
  size_t linestrsize = 0;
  int linenum = 0;
  regex_t preg;
  regmatch_t pmatch[3];

  /* try checking against names stored in stored certs file */
  FILE *fp = fopen(C_CertificateFile, "r");
  if (fp)
  {
    if (REGCOMP(&preg, "^#H ([a-zA-Z0-9_\\.-]+) ([0-9A-F]{4}( [0-9A-F]{4}){7})[ \t]*$",
                REG_ICASE) != 0)
    {
      mutt_file_fclose(&fp);
      return 0;
    }

    char buf[80];
    buf[0] = '\0';
    tls_fingerprint(GNUTLS_DIG_MD5, buf, sizeof(buf), cert);
    while ((linestr = mutt_file_read_line(linestr, &linestrsize, fp, &linenum, 0)))
    {
      if ((linestr[0] == '#') && (linestr[1] == 'H'))
      {
        if (regexec(&preg, linestr, 3, pmatch, 0) == 0)
        {
          linestr[pmatch[1].rm_eo] = '\0';
          linestr[pmatch[2].rm_eo] = '\0';
          if ((strcmp(linestr + pmatch[1].rm_so, hostname) == 0) &&
              (strcmp(linestr + pmatch[2].rm_so, buf) == 0))
          {
            regfree(&preg);
            FREE(&linestr);
            mutt_file_fclose(&fp);
            return 1;
          }
        }
      }
    }

    regfree(&preg);
    mutt_file_fclose(&fp);
  }

  /* not found a matching name */
  return 0;
}
Ejemplo n.º 3
0
Archivo: mh.c Proyecto: kdave/neomutt
/**
 * mh_update_sequences - Update sequence numbers
 * @param m Mailbox
 *
 * XXX we don't currently remove deleted messages from sequences we don't know.
 * Should we?
 */
void mh_update_sequences(struct Mailbox *m)
{
  char sequences[PATH_MAX];
  char *tmpfname = NULL;
  char *buf = NULL;
  char *p = NULL;
  size_t s;
  int l = 0;
  int i;

  int unseen = 0;
  int flagged = 0;
  int replied = 0;

  char seq_unseen[256];
  char seq_replied[256];
  char seq_flagged[256];

  struct MhSequences mhs = { 0 };

  snprintf(seq_unseen, sizeof(seq_unseen), "%s:", NONULL(C_MhSeqUnseen));
  snprintf(seq_replied, sizeof(seq_replied), "%s:", NONULL(C_MhSeqReplied));
  snprintf(seq_flagged, sizeof(seq_flagged), "%s:", NONULL(C_MhSeqFlagged));

  FILE *fp_new = NULL;
  if (mh_mkstemp(m, &fp_new, &tmpfname) != 0)
  {
    /* error message? */
    return;
  }

  snprintf(sequences, sizeof(sequences), "%s/.mh_sequences", m->path);

  /* first, copy unknown sequences */
  FILE *fp_old = fopen(sequences, "r");
  if (fp_old)
  {
    while ((buf = mutt_file_read_line(buf, &s, fp_old, &l, 0)))
    {
      if (mutt_str_startswith(buf, seq_unseen, CASE_MATCH) ||
          mutt_str_startswith(buf, seq_flagged, CASE_MATCH) ||
          mutt_str_startswith(buf, seq_replied, CASE_MATCH))
        continue;

      fprintf(fp_new, "%s\n", buf);
    }
  }
  mutt_file_fclose(&fp_old);

  /* now, update our unseen, flagged, and replied sequences */
  for (l = 0; l < m->msg_count; l++)
  {
    if (m->emails[l]->deleted)
      continue;

    p = strrchr(m->emails[l]->path, '/');
    if (p)
      p++;
    else
      p = m->emails[l]->path;

    if (mutt_str_atoi(p, &i) < 0)
      continue;

    if (!m->emails[l]->read)
    {
      mhs_set(&mhs, i, MH_SEQ_UNSEEN);
      unseen++;
    }
    if (m->emails[l]->flagged)
    {
      mhs_set(&mhs, i, MH_SEQ_FLAGGED);
      flagged++;
    }
    if (m->emails[l]->replied)
    {
      mhs_set(&mhs, i, MH_SEQ_REPLIED);
      replied++;
    }
  }

  /* write out the new sequences */
  if (unseen)
    mhs_write_one_sequence(fp_new, &mhs, MH_SEQ_UNSEEN, NONULL(C_MhSeqUnseen));
  if (flagged)
    mhs_write_one_sequence(fp_new, &mhs, MH_SEQ_FLAGGED, NONULL(C_MhSeqFlagged));
  if (replied)
    mhs_write_one_sequence(fp_new, &mhs, MH_SEQ_REPLIED, NONULL(C_MhSeqReplied));

  mhs_free_sequences(&mhs);

  /* try to commit the changes - no guarantee here */
  mutt_file_fclose(&fp_new);

  unlink(sequences);
  if (mutt_file_safe_rename(tmpfname, sequences) != 0)
  {
    /* report an error? */
    unlink(tmpfname);
  }

  FREE(&tmpfname);
}