Exemple #1
0
void mutt_set_followup_to (ENVELOPE *e)
{
  ADDRESS *t = NULL;
  ADDRESS *from;

  /* 
   * Only generate the Mail-Followup-To if the user has requested it, and
   * it hasn't already been set
   */

  if (option (OPTFOLLOWUPTO) && !e->mail_followup_to)
  {
    if (mutt_is_list_cc (0, e->to, e->cc))
    {
      /* 
       * this message goes to known mailing lists, so create a proper
       * mail-followup-to header
       */

      t = rfc822_append (&e->mail_followup_to, e->to, 0);
      rfc822_append (&t, e->cc, 1);
    }

    /* remove ourselves from the mail-followup-to header */
    e->mail_followup_to = remove_user (e->mail_followup_to, 0);

    /*
     * If we are not subscribed to any of the lists in question,
     * re-add ourselves to the mail-followup-to header.  The 
     * mail-followup-to header generated is a no-op with group-reply,
     * but makes sure list-reply has the desired effect.
     */

    if (e->mail_followup_to && !mutt_is_list_recipient (0, e->to, e->cc))
    {
      if (e->reply_to)
	from = rfc822_cpy_adr (e->reply_to, 0);
      else if (e->from)
	from = rfc822_cpy_adr (e->from, 0);
      else
	from = mutt_default_from ();
      
      if (from)
      {
	/* Normally, this loop will not even be entered. */
	for (t = from; t && t->next; t = t->next)
	  ;
	
	t->next = e->mail_followup_to; 	/* t cannot be NULL at this point. */
	e->mail_followup_to = from;
      }
    }
    
    e->mail_followup_to = mutt_remove_duplicates (e->mail_followup_to);
    
  }
}
Exemple #2
0
/* append list 'b' to list 'a' and return the last element in the new list */
ADDRESS *rfc822_append (ADDRESS **a, ADDRESS *b, int prune)
{
  ADDRESS *tmp = *a;

  while (tmp && tmp->next)
    tmp = tmp->next;
  if (!b)
    return tmp;
  if (tmp)
    tmp->next = rfc822_cpy_adr (b, prune);
  else
    tmp = *a = rfc822_cpy_adr (b, prune);
  while (tmp && tmp->next)
    tmp = tmp->next;
  return tmp;
}
Exemple #3
0
static ADDRESS *result_to_addr (QUERY *r)
{
        static ADDRESS *tmp;

        if (!(tmp = rfc822_cpy_adr (r->addr, 0)))
                return NULL;

        if(!tmp->next && !tmp->personal)
                tmp->personal = safe_strdup (r->name);

        mutt_addrlist_to_idna (tmp, NULL);
        return tmp;
}
Exemple #4
0
void mutt_group_add_adrlist (group_t *g, ADDRESS *a)
{
  ADDRESS **p, *q;

  if (!g)
    return;
  if (!a)
    return;

  for (p = &g->as; *p; p = &((*p)->next))
    ;

  q = rfc822_cpy_adr (a, 0);
  q = mutt_remove_xrefs (g->as, q);
  *p = q;
}
Exemple #5
0
static ADDRESS *mutt_expand_aliases_r (ADDRESS *a, LIST **expn)
{
  ADDRESS *head = NULL, *last = NULL, *t, *w;
  LIST *u;
  char i;
  const char *fqdn;
  
  while (a)
  {
    if (!a->group && !a->personal && a->mailbox && strchr (a->mailbox, '@') == NULL)
    {
      t = mutt_lookup_alias (a->mailbox);

      if (t)
      {	
        i = 0;
        for (u = *expn; u; u = u->next)
	{
	  if (mutt_strcmp (a->mailbox, u->data) == 0) /* alias already found */
	  {
	    dprint (1, (debugfile, "mutt_expand_aliases_r(): loop in alias found for '%s'\n", a->mailbox));
	    i = 1;
	    break;
	  }
	}

        if (!i)
	{
          u = safe_malloc (sizeof (LIST));
          u->data = safe_strdup (a->mailbox);
          u->next = *expn;
          *expn = u;
	  w = rfc822_cpy_adr (t, 0);
	  w = mutt_expand_aliases_r (w, expn);
	  if (head)
	    last->next = w;
	  else
	    head = last = w;
	  while (last && last->next)
	    last = last->next;
        }
	t = a;
	a = a->next;
	t->next = NULL;
	rfc822_free_address (&t);
	continue;
      }
      else
      {
	struct passwd *pw = getpwnam (a->mailbox);

	if (pw)
	{
	  char namebuf[STRING];
	  
	  mutt_gecos_name (namebuf, sizeof (namebuf), pw);
	  mutt_str_replace (&a->personal, namebuf);
	  
#ifdef EXACT_ADDRESS
	  FREE (&a->val);
#endif
	}
      }
    }

    if (head)
    {
      last->next = a;
      last = last->next;
    }
    else
      head = last = a;
    a = a->next;
    last->next = NULL;
  }

  if (option (OPTUSEDOMAIN) && (fqdn = mutt_fqdn(1)))
  {
    /* now qualify all local addresses */
    rfc822_qualify (head, fqdn);
  }

  return (head);
}
Exemple #6
0
int mmdf_parse_mailbox(CONTEXT *ctx)
{
    char buf[HUGE_STRING];
    char return_path[LONG_STRING];
    int count = 0, oldmsgcount = ctx->msgcount;
    int lines;
    time_t t;
    LOFF_T loc, tmploc;
    HEADER *hdr;
    struct stat sb;

#ifdef NFS_ATTRIBUTE_HACK
    struct utimbuf newtime;
#endif /* ifdef NFS_ATTRIBUTE_HACK */
    progress_t progress;
    char msgbuf[STRING];

    if (stat(ctx->path, &sb) == -1) {
        mutt_perror(ctx->path);
        return -1;
    }
    ctx->atime = sb.st_atime;
    ctx->mtime = sb.st_mtime;
    ctx->size = sb.st_size;

#ifdef NFS_ATTRIBUTE_HACK

    if (sb.st_mtime > sb.st_atime) {
        newtime.modtime = sb.st_mtime;
        newtime.actime = time(NULL);
        utime(ctx->path, &newtime);
    }
#endif /* ifdef NFS_ATTRIBUTE_HACK */

    buf[sizeof(buf) - 1] = 0;

    if (!ctx->quiet) {
        snprintf(msgbuf, sizeof(msgbuf), _("Reading %s..."), ctx->path);
        mutt_progress_init(&progress, msgbuf, M_PROGRESS_MSG, ReadInc, 0);
    }

    FOREVER
    {
        if (fgets(buf, sizeof(buf) - 1, ctx->fp) == NULL)
            break;

        if (mutt_strcmp(buf, MMDF_SEP) == 0) {
            loc = ftello(ctx->fp);

            count++;

            if (!ctx->quiet)
                mutt_progress_update(&progress, count,
                                     (int)(loc / (ctx->size / 100 + 1)));

            if (ctx->msgcount == ctx->hdrmax)
                mx_alloc_memory(ctx);
            ctx->hdrs[ctx->msgcount] = hdr = mutt_new_header();
            hdr->offset = loc;
            hdr->index = ctx->msgcount;

            if (fgets(buf, sizeof(buf) - 1, ctx->fp) == NULL) {
                /* TODO: memory leak??? */
                dprint(1, "mmdf_parse_mailbox: unexpected EOF\n");
                break;
            }

            return_path[0] = 0;

            if (!is_from(buf, return_path, sizeof(return_path), &t)) {
                if (fseeko(ctx->fp, loc, SEEK_SET) != 0) {
                    dprint(1, "mmdf_parse_mailbox: fseek() failed\n");
                    mutt_error _("Mailbox is corrupt!");
                    return -1;
                }
            } else
                hdr->received = t - mutt_local_tz(t);

            hdr->env = mutt_read_rfc822_header(ctx->fp, hdr, 0, 0);

            loc = ftello(ctx->fp);

            if ((hdr->content->length > 0)
                && (hdr->lines > 0)) {
                tmploc = loc + hdr->content->length;

                if ((0 < tmploc)
                    && (tmploc < ctx->size)) {
                    if ((fseeko(ctx->fp, tmploc, SEEK_SET) != 0)
                        || (fgets(buf, sizeof(buf) - 1, ctx->fp) == NULL)
                        || (mutt_strcmp(MMDF_SEP, buf) != 0)) {
                        if (fseeko(ctx->fp, loc, SEEK_SET) != 0)
                            dprint(1, "mmdf_parse_mailbox: fseek() failed\n");
                        hdr->content->length = -1;
                    }
                } else
                    hdr->content->length = -1;
            } else
                hdr->content->length = -1;

            if (hdr->content->length < 0) {
                lines = -1;

                do {
                    loc = ftello(ctx->fp);

                    if (fgets(buf, sizeof(buf) - 1, ctx->fp) == NULL)
                        break;
                    lines++;
                } while (mutt_strcmp(buf, MMDF_SEP) != 0);

                hdr->lines = lines;
                hdr->content->length = loc - hdr->content->offset;
            }

            if (!hdr->env->return_path
                && return_path[0])
                hdr->env->return_path = rfc822_parse_adrlist(
                    hdr->env->return_path,
                    return_path);

            if (!hdr->env->from)
                hdr->env->from = rfc822_cpy_adr(hdr->env->return_path, 0);

            ctx->msgcount++;
        } else {
            dprint(1, "mmdf_parse_mailbox: corrupt mailbox!\n");
            mutt_error _("Mailbox is corrupt!");
            return -1;
        }
    }

    if (ctx->msgcount > oldmsgcount)
        mx_update_context(ctx, ctx->msgcount - oldmsgcount);

    return 0;
}
Exemple #7
0
/* Note that this function is also called when new mail is appended to the
 * currently open folder, and NOT just when the mailbox is initially read.
 *
 * NOTE: it is assumed that the mailbox being read has been locked before
 * this routine gets called.  Strange things could happen if it's not!
 */
int mbox_parse_mailbox(CONTEXT *ctx)
{
    struct stat sb;
    char buf[HUGE_STRING], return_path[STRING];
    HEADER *curhdr;
    time_t t;
    int count = 0, lines = 0;
    LOFF_T loc;

#ifdef NFS_ATTRIBUTE_HACK
    struct utimbuf newtime;
#endif /* ifdef NFS_ATTRIBUTE_HACK */
    progress_t progress;
    char msgbuf[STRING];

    /* Save information about the folder at the time we opened it. */
    if (stat(ctx->path, &sb) == -1) {
        mutt_perror(ctx->path);
        return -1;
    }

    ctx->size = sb.st_size;
    ctx->mtime = sb.st_mtime;
    ctx->atime = sb.st_atime;

#ifdef NFS_ATTRIBUTE_HACK

    if (sb.st_mtime > sb.st_atime) {
        newtime.modtime = sb.st_mtime;
        newtime.actime = time(NULL);
        utime(ctx->path, &newtime);
    }
#endif /* ifdef NFS_ATTRIBUTE_HACK */

    if (!ctx->readonly)
        ctx->readonly = access(ctx->path, W_OK) ? 1 : 0;

    if (!ctx->quiet) {
        snprintf(msgbuf, sizeof(msgbuf), _("Reading %s..."), ctx->path);
        mutt_progress_init(&progress, msgbuf, M_PROGRESS_MSG, ReadInc, 0);
    }

    loc = ftello(ctx->fp);

    while (fgets(buf, sizeof(buf), ctx->fp) != NULL) {
        if (is_from(buf, return_path, sizeof(return_path), &t)) {
            /* Save the Content-Length of the previous message */
            if (count > 0) {
#define PREV ctx->hdrs[ctx->msgcount - 1]

                if (PREV->content->length < 0) {
                    PREV->content->length = loc - PREV->content->offset - 1;

                    if (PREV->content->length < 0)
                        PREV->content->length = 0;
                }

                if (!PREV->lines)
                    PREV->lines = lines ? lines - 1 : 0;
            }

            count++;

            if (!ctx->quiet)
                mutt_progress_update(&progress, count,
                                     (int)(ftello(ctx->fp) /
                                           (ctx->size / 100 + 1)));

            if (ctx->msgcount == ctx->hdrmax)
                mx_alloc_memory(ctx);

            curhdr = ctx->hdrs[ctx->msgcount] = mutt_new_header();
            curhdr->received = t - mutt_local_tz(t);
            curhdr->offset = loc;
            curhdr->index = ctx->msgcount;

            curhdr->env = mutt_read_rfc822_header(ctx->fp, curhdr, 0, 0);

            /* if we know how long this message is, either just skip over the
               body,
             * or if we don't know how many lines there are, count them now
             *(this will
             * save time by not having to search for the next message marker).
             */
            if (curhdr->content->length > 0) {
                LOFF_T tmploc;

                loc = ftello(ctx->fp);
                tmploc = loc + curhdr->content->length + 1;

                if ((0 < tmploc)
                    && (tmploc < ctx->size)) {
                    /*
                     * check to see if the content-length looks valid.  we
                     *expect to
                     * to see a valid message separator at this point in the
                     *stream
                     */
                    if ((fseeko(ctx->fp, tmploc, SEEK_SET) != 0)
                        || (fgets(buf, sizeof(buf), ctx->fp) == NULL)
                        || (mutt_strncmp("From ", buf, 5) != 0)) {
                        dprint(1, "mbox_parse_mailbox: bad content-length in message %d (cl="
                                OFF_T_FMT ")\n", curhdr->index, curhdr->content->length);
                        dprint(1, "\tLINE: %s", buf);

                        if (fseeko(ctx->fp, loc, SEEK_SET) != 0) { /* nope,
                                                                      return the
                                                                      previous
                                                                      position
                                                                      */
                            dprint(1, "mbox_parse_mailbox: fseek() failed\n");
                        }
                        curhdr->content->length = -1;
                    }
                } else if (tmploc != ctx->size) {
                    /* content-length would put us past the end of the file, so
                       it
                     * must be wrong
                     */
                    curhdr->content->length = -1;
                }

                if (curhdr->content->length != -1) {
                    /* good content-length.  check to see if we know how many
                       lines
                     * are in this message.
                     */
                    if (curhdr->lines == 0) {
                        int cl = curhdr->content->length;

                        /* count the number of lines in this message */
                        if (fseeko(ctx->fp, loc, SEEK_SET) != 0)
                            dprint(1, "mbox_parse_mailbox: fseek() failed\n");

                        while (cl-- > 0) {
                            if (fgetc(ctx->fp) == '\n')
                                curhdr->lines++;
                        }
                    }

                    /* return to the offset of the next message separator */
                    if (fseeko(ctx->fp, tmploc, SEEK_SET) != 0)
                        dprint(1, "mbox_parse_mailbox: fseek() failed\n");
                }
            }

            ctx->msgcount++;

            if (!curhdr->env->return_path
                && return_path[0])
                curhdr->env->return_path = rfc822_parse_adrlist(
                    curhdr->env->return_path,
                    return_path);

            if (!curhdr->env->from)
                curhdr->env->from = rfc822_cpy_adr(curhdr->env->return_path, 0);


            lines = 0;
        } else
            lines++;

        loc = ftello(ctx->fp);
    }

    /*
     * Only set the content-length of the previous message if we have read more
     * than one message during _this_ invocation.  If this routine is called
     * when new mail is received, we need to make sure not to clobber what
     * previously was the last message since the headers may be sorted.
     */
    if (count > 0) {
        if (PREV->content->length < 0) {
            PREV->content->length = ftello(ctx->fp) - PREV->content->offset - 1;

            if (PREV->content->length < 0)
                PREV->content->length = 0;
        }

        if (!PREV->lines)
            PREV->lines = lines ? lines - 1 : 0;

        mx_update_context(ctx, count);
    }

    return 0;
}