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); } }
/* 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; }
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; }
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; }
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); }
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; }
/* 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; }