static void process_user_recips (ENVELOPE *env) { LIST *uh = UserHeader; for (; uh; uh = uh->next) { if (ascii_strncasecmp ("to:", uh->data, 3) == 0) env->to = rfc822_parse_adrlist (env->to, uh->data + 3); else if (ascii_strncasecmp ("cc:", uh->data, 3) == 0) env->cc = rfc822_parse_adrlist (env->cc, uh->data + 3); else if (ascii_strncasecmp ("bcc:", uh->data, 4) == 0) env->bcc = rfc822_parse_adrlist (env->bcc, uh->data + 4); } }
static void process_user_header (ENVELOPE *env) { LIST *uh = UserHeader; LIST *last = env->userhdrs; if (last) while (last->next) last = last->next; for (; uh; uh = uh->next) { if (ascii_strncasecmp ("from:", uh->data, 5) == 0) { /* User has specified a default From: address. Remove default address */ rfc822_free_address (&env->from); env->from = rfc822_parse_adrlist (env->from, uh->data + 5); } else if (ascii_strncasecmp ("reply-to:", uh->data, 9) == 0) { rfc822_free_address (&env->reply_to); env->reply_to = rfc822_parse_adrlist (env->reply_to, uh->data + 9); } else if (ascii_strncasecmp ("message-id:", uh->data, 11) == 0) { char *tmp = mutt_extract_message_id (uh->data + 11, NULL); if (rfc822_valid_msgid (tmp) >= 0) { FREE(&env->message_id); env->message_id = tmp; } else FREE(&tmp); } else if (ascii_strncasecmp ("to:", uh->data, 3) != 0 && ascii_strncasecmp ("cc:", uh->data, 3) != 0 && ascii_strncasecmp ("bcc:", uh->data, 4) != 0 && ascii_strncasecmp ("subject:", uh->data, 8) != 0 && ascii_strncasecmp ("return-path:", uh->data, 12) != 0) { if (last) { last->next = mutt_new_list (); last = last->next; } else last = env->userhdrs = mutt_new_list (); last->data = safe_strdup (uh->data); } } }
static QUERY *run_query (char *s, int quiet) { FILE *fp; QUERY *first = NULL; QUERY *cur = NULL; char cmd[_POSIX_PATH_MAX]; char *buf = NULL; size_t buflen; int dummy = 0; char msg[STRING]; char *p; pid_t thepid; mutt_expand_file_fmt (cmd, sizeof(cmd), QueryCmd, s); if ((thepid = mutt_create_filter (cmd, NULL, &fp, NULL)) < 0) { dprint (1, (debugfile, "unable to fork command: %s", cmd)); return 0; } if (!quiet) mutt_message _("Waiting for response..."); fgets (msg, sizeof (msg), fp); if ((p = strrchr (msg, '\n'))) *p = '\0'; while ((buf = mutt_read_line (buf, &buflen, fp, &dummy, 0)) != NULL) { if ((p = strtok(buf, "\t\n"))) { if (first == NULL) { first = (QUERY *) safe_calloc (1, sizeof (QUERY)); cur = first; } else { cur->next = (QUERY *) safe_calloc (1, sizeof (QUERY)); cur = cur->next; } cur->addr = rfc822_parse_adrlist (cur->addr, p); p = strtok(NULL, "\t\n"); if (p) { cur->name = safe_strdup (p); p = strtok(NULL, "\t\n"); if (p) cur->other = safe_strdup (p); } } } FREE (&buf); safe_fclose (&fp); if (mutt_wait_filter (thepid)) { dprint (1, (debugfile, "Error: %s\n", msg)); if (!quiet) mutt_error ("%s", msg); } else { if (!quiet) mutt_message ("%s", msg); } return first; }
int writeout(struct header *h, const char *datefmt, unsigned char create_real_name) { int rv = 0; ADDRESS *addr, *p; time_t timep; char timebuf[256]; char *c; if(!h->value) return 0; addr = rfc822_parse_adrlist(NULL, h->value); time(&timep); rfc2047_decode_adrlist(addr); for(p = addr; p; p = p->next) { if(create_real_name == 1 && (!p->personal || !*p->personal) && p->mailbox) { if(p->personal) FREE(p->personal); p->personal = safe_strdup(p->mailbox); c=strchr(p->personal, '@'); if (c) *c='\0'; } if(!p->group && p->mailbox && *p->mailbox && p->personal) { if(p->personal && strlen(p->personal) > 30) strcpy(p->personal + 27, "..."); if ((c=strchr(p->mailbox,'@'))) for(c++; *c; c++) *c=tolower(*c); strftime(timebuf, sizeof(timebuf), datefmt, localtime(&timep)); if(print_email_only == 1) { printf("%s\n", p->mailbox); } else { printf("%s,%s\n", p->mailbox, p->personal && *p->personal ? p->personal : " "); } rv = 1; } } rfc822_free_address(&addr); return rv; }
int main (int argc, char **argv) { ADDRESS *list; char buf[256]; char *str = "michael, Michael Elkins <*****@*****.**>, testing a really complex address: this example <@[email protected]:[email protected]>;, [email protected] (lothar)"; list = rfc822_parse_adrlist (NULL, str); buf[0] = 0; rfc822_write_address (buf, sizeof (buf), list); rfc822_free_address (&list); puts (buf); exit (0); }
/* * 1522 decode the personal name portion of addr and return an allocated * copy of the resulting address string. */ char * decode_fullname_of_addrstring(char *addr, int verbose) { char *pers_decoded, *tmp_a_string, *ret = NULL; ADDRESS *adr; static char *fakedomain = "@"; RFC822BUFFER rbuf; size_t len; tmp_a_string = cpystr(addr ? addr : ""); adr = NULL; rfc822_parse_adrlist(&adr, tmp_a_string, fakedomain); fs_give((void **)&tmp_a_string); if(!adr) return(cpystr("")); if(adr->personal && adr->personal[0]){ pers_decoded = cpystr((char *)rfc1522_decode_to_utf8((unsigned char *)tmp_20k_buf, SIZEOF_20KBUF, adr->personal)); fs_give((void **)&adr->personal); adr->personal = pers_decoded; } len = est_size(adr); ret = (char *) fs_get(len * sizeof(char)); ret[0] = '\0'; rbuf.f = dummy_soutr; rbuf.s = NULL; rbuf.beg = ret; rbuf.cur = ret; rbuf.end = ret+len-1; rfc822_output_address_list(&rbuf, adr, 0L, NULL); *rbuf.cur = '\0'; mail_free_address(&adr); return(ret); }
PPerson CPerson::Create( LPCSTR AddrList ) { return rfc822_parse_adrlist( NULL, AddrList ); }
void mutt_attach_bounce (FILE * fp, struct header * hdr, ATTACHPTR ** idx, short idxlen, struct body * cur) { short i; char prompt[STRING]; char buf[HUGE_STRING]; struct address *adr = NULL; int ret = 0; int p = 0; if (check_all_msg (idx, idxlen, cur, 1) == -1) return; /* one or more messages? */ p = (cur || count_tagged (idx, idxlen) == 1); /* RfC 5322 mandates a From: header, so warn before bouncing * messages without one */ if (cur) { if (!cur->hdr->env->from) { mutt_error("Warning: message contains no From: header"); mutt_sleep(2); mutt_clear_error(); } } else { for (i = 0; i < idxlen; i++) { if (idx[i]->content->tagged) { if (!idx[i]->content->hdr->env->from) { mutt_error("Warning: message contains no From: header"); mutt_sleep (2); mutt_clear_error (); break; } } } } if (p) strfcpy (prompt, ("Bounce message to: "), sizeof (prompt)); else strfcpy (prompt, ("Bounce tagged messages to: "), sizeof (prompt)); buf[0] = '\0'; if (mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS) || buf[0] == '\0') return; if (!(adr = rfc822_parse_adrlist (adr, buf))) { mutt_error("Error parsing address!"); return; } adr = mutt_expand_aliases (adr); buf[0] = 0; rfc822_write_address (buf, sizeof (buf), adr, 1); #define extra_space (15+7+2) /* * See commands.c. */ snprintf (prompt, sizeof (prompt) - 4, (p ? ("Bounce message to %s") : ("Bounce messages to %s")), buf); if (mutt_strwidth (prompt) > COLS - extra_space) { mutt_format_string (prompt, sizeof (prompt) - 4, 0, COLS-extra_space, FMT_LEFT, 0, prompt, sizeof (prompt), 0); safe_strcat (prompt, sizeof (prompt), "...?"); } else safe_strcat (prompt, sizeof (prompt), "?"); if (query_quadoption (OPT_BOUNCE, prompt) != M_YES) { rfc822_free_address (&adr); CLEARLINE (LINES - 1); mutt_message (p ? ("Message not bounced.") : ("Messages not bounced.")); return; } CLEARLINE (LINES - 1); if (cur) ret = mutt_bounce_message (fp, cur->hdr, adr); else { for (i = 0; i < idxlen; i++) { if (idx[i]->content->tagged) if (mutt_bounce_message (fp, idx[i]->content->hdr, adr)) ret = 1; } } if (!ret) mutt_message (p ? ("Message bounced.") : ("Messages bounced.")); else mutt_error (p ? ("Error bouncing message!") : ("Error bouncing messages!")); }
/* * This function does white pages lookups. * * Args string -- the string to use in the lookup * * Returns NULL -- lookup failed * Address -- A single address is returned if lookup was successfull. */ ADDRESS * wp_lookups(char *string, WP_ERR_S *wp_err, int recursing) { ADDRESS *ret_a = NULL; char ebuf[200]; #ifdef ENABLE_LDAP LDAP_SERV_RES_S *free_when_done = NULL; LDAPLookupStyle style; LDAP_CHOOSE_S *winning_e = NULL; LDAP_SERV_S *info = NULL; static char *fakedomain = "@"; char *tmp_a_string; int auwe_rv = 0; /* * Runtime ldap lookup of addrbook entry. */ if(!strncmp(string, RUN_LDAP, LEN_RL)){ LDAP_SERV_RES_S *head_of_result_list; info = break_up_ldap_server(string+LEN_RL); head_of_result_list = ldap_lookup(info, "", NULL, wp_err, 1); if(head_of_result_list){ if(!wp_exit) auwe_rv = ask_user_which_entry(head_of_result_list, string, &winning_e, wp_err, wp_err->wp_err_occurred ? DisplayIfOne : DisplayIfTwo); if(auwe_rv != -5) free_when_done = head_of_result_list; } else{ wp_err->wp_err_occurred = 1; if(wp_err->error){ q_status_message(SM_ORDER, 3, 5, wp_err->error); display_message('x'); fs_give((void **)&wp_err->error); } /* try using backup email address */ if(info && info->mail && *info->mail){ tmp_a_string = cpystr(info->mail); rfc822_parse_adrlist(&ret_a, tmp_a_string, fakedomain); fs_give((void **)&tmp_a_string); wp_err->error = cpystr(_("Directory lookup failed, using backup email address")); } else{ /* * Do this so the awful LDAP: ... string won't show up * in the composer. This shouldn't actually happen in * real life, so we're not too concerned about it. If we * were we'd want to recover the nickname we started with * somehow, or something like that. */ ret_a = mail_newaddr(); ret_a->mailbox = cpystr("missing-username"); wp_err->error = cpystr(_("Directory lookup failed, no backup email address available")); } q_status_message(SM_ORDER, 3, 5, wp_err->error); display_message('x'); } } else{ style = F_ON(F_COMPOSE_REJECTS_UNQUAL, ps_global) ? DisplayIfOne : DisplayIfTwo; auwe_rv = ldap_lookup_all(string, as.n_serv, recursing, style, NULL, &winning_e, wp_err, &free_when_done); } if(winning_e && auwe_rv != -5){ ret_a = address_from_ldap(winning_e); if(pith_opt_save_ldap_entry && ret_a && F_ON(F_ADD_LDAP_TO_ABOOK, ps_global) && !info) (*pith_opt_save_ldap_entry)(ps_global, winning_e, 1); fs_give((void **)&winning_e); } /* Info's only set in the RUN_LDAP case */ if(info){ if(ret_a && ret_a->host){ ADDRESS *backup = NULL; if(info->mail && *info->mail) rfc822_parse_adrlist(&backup, info->mail, fakedomain); if(!backup || !address_is_same(ret_a, backup)){ if(wp_err->error){ q_status_message(SM_ORDER, 3, 5, wp_err->error); display_message('x'); fs_give((void **)&wp_err->error); } snprintf(ebuf, sizeof(ebuf), _("Warning: current address different from saved address (%s)"), info->mail); wp_err->error = cpystr(ebuf); q_status_message(SM_ORDER, 3, 5, wp_err->error); display_message('x'); } if(backup) mail_free_address(&backup); } free_ldap_server_info(&info); } if(free_when_done) free_ldap_result_list(&free_when_done); #endif /* ENABLE_LDAP */ if(ret_a){ if(ret_a->mailbox){ /* indicates there was a MAIL attribute */ if(!ret_a->host || !ret_a->host[0]){ if(ret_a->host) fs_give((void **)&ret_a->host); ret_a->host = cpystr("missing-hostname"); wp_err->wp_err_occurred = 1; if(wp_err->error) fs_give((void **)&wp_err->error); wp_err->error = cpystr(_("Missing hostname in LDAP address")); q_status_message(SM_ORDER, 3, 5, wp_err->error); display_message('x'); } if(!ret_a->mailbox[0]){ if(ret_a->mailbox) fs_give((void **)&ret_a->mailbox); ret_a->mailbox = cpystr("missing-username"); wp_err->wp_err_occurred = 1; if(wp_err->error) fs_give((void **)&wp_err->error); wp_err->error = cpystr(_("Missing username in LDAP address")); q_status_message(SM_ORDER, 3, 5, wp_err->error); display_message('x'); } } else{ wp_err->wp_err_occurred = 1; if(wp_err->error) fs_give((void **)&wp_err->error); snprintf(ebuf, sizeof(ebuf), _("No email address available for \"%s\""), (ret_a->personal && *ret_a->personal) ? ret_a->personal : "selected entry"); wp_err->error = cpystr(ebuf); q_status_message(SM_ORDER, 3, 5, wp_err->error); display_message('x'); mail_free_address(&ret_a); ret_a = NULL; } } return(ret_a); }
void ci_bounce_message (HEADER *h, int *redraw) { char prompt[SHORT_STRING]; char scratch[SHORT_STRING]; char buf[HUGE_STRING] = { 0 }; ADDRESS *adr = NULL; char *err = NULL; int rc; /* RfC 5322 mandates a From: header, so warn before bouncing * messages without one */ if (h) { if (!h->env->from) { mutt_error _("Warning: message has no From: header"); mutt_sleep (2); } } else if (Context) { for (rc = 0; rc < Context->msgcount; rc++) { if (Context->hdrs[rc]->tagged && !Context->hdrs[rc]->env->from) { mutt_error ("Warning: message has no From: header"); mutt_sleep (2); break; } } } if(h) strfcpy(prompt, _("Bounce message to: "), sizeof(prompt)); else strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt)); rc = mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS); if (option (OPTNEEDREDRAW)) { unset_option (OPTNEEDREDRAW); *redraw = REDRAW_FULL; } if (rc || !buf[0]) return; if (!(adr = rfc822_parse_adrlist (adr, buf))) { mutt_error _("Error parsing address!"); return; } adr = mutt_expand_aliases (adr); if (mutt_addrlist_to_idna (adr, &err) < 0) { mutt_error (_("Bad IDN: '%s'"), err); FREE (&err); rfc822_free_address (&adr); return; } buf[0] = 0; rfc822_write_address (buf, sizeof (buf), adr, 1); #define extra_space (15 + 7 + 2) snprintf (scratch, sizeof (scratch), (h ? _("Bounce message to %s") : _("Bounce messages to %s")), buf); if (mutt_strwidth (prompt) > COLS - extra_space) { mutt_format_string (prompt, sizeof (prompt), 0, COLS-extra_space, FMT_LEFT, 0, scratch, sizeof (scratch), 0); safe_strcat (prompt, sizeof (prompt), "...?"); } else snprintf (prompt, sizeof (prompt), "%s?", scratch); if (query_quadoption (OPT_BOUNCE, prompt) != M_YES) { rfc822_free_address (&adr); CLEARLINE (LINES - 1); mutt_message (h ? _("Message not bounced.") : _("Messages not bounced.")); return; } CLEARLINE (LINES - 1); rc = mutt_bounce_message (NULL, h, adr); rfc822_free_address (&adr); /* If no error, or background, display message. */ if ((rc == 0) || (rc == S_BKG)) mutt_message (h ? _("Message bounced.") : _("Messages bounced.")); }
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; }
static void parse_argv(int argc, char *argv[]) { int ret = 0; struct option options[] = { {"help", no_argument, &arg_help, 'h'}, {"version", no_argument, &arg_version, 'v'}, {"dump-config-items", no_argument, &arg_dump_config, 'D'}, {"alias-expand", required_argument, &arg_expand_alias, 'A'}, {"query-config-item", required_argument, NULL, 'Q'}, {"subject", required_argument, NULL, 's'}, {"emulate-mailx", no_argument, &arg_emulate_mailx, 'x'}, {"config-file", required_argument, NULL, 'F'}, {"mailbox", required_argument, NULL, 'm'}, {"attach", required_argument, NULL, 'a'}, {"execute", required_argument, &arg_execute, 'e'}, {"include", required_argument, NULL, 'i'}, {"mailbox_type", required_argument, NULL, 't'}, {"postponed", no_argument, &arg_resume_postponed, 'p'}, {"bcc", required_argument, NULL, 'b'}, {"cc", required_argument, NULL, 'c'}, {"to", required_argument, NULL, 'r'}, {0,0,0,0} }; while ((ret = getopt_long(argc, argv, "hvA:DQ:s:xF:m:a:e:i:t:b:c:r:", options, NULL)) != -1) { switch (ret) { case 'h': mutt_usage(); exit(RETURN_SUCCESS); case 'v': /* we don't exit because we support verbose option */ arg_version++; break; case 's': arg_subject = optarg; break; case 'x': arg_emulate_mailx = 1; break; case 'a': if (optarg == NULL) { mutt_usage(); exit(-1); } attach = mutt_add_list(attach, optarg); arg_attach = 1; break; case 'b': if (!msg) msg = mutt_new_header(); if (!msg->env) msg->env = mutt_new_envelope(); msg->env->bcc = rfc822_parse_adrlist(msg->env->bcc, optarg); break; case 'c': if (!msg) msg = mutt_new_header(); if (!msg->env) msg->env = mutt_new_envelope(); msg->env->cc = rfc822_parse_adrlist(msg->env->cc, optarg); break; case 'e': if (arg_expand_alias || arg_query_conf || optarg == NULL) { mutt_usage(); exit(-1); } commands = mutt_add_list(commands, optarg); arg_execute = 1; break; case 'i': if (optarg == NULL) { mutt_usage(); exit(-1); } arg_include = optarg; break; case 'm': if (optarg == NULL) { mutt_usage(); exit(-1); } arg_mailbox = optarg; break; case 'p': arg_resume_postponed = 1; break; case 'r': addr_to = mutt_add_list(addr_to, optarg); break; case 't': if (optarg == NULL) { mutt_usage(); exit(-1); } arg_mailbox_type = optarg; break; case 'D': if (!is_mutt_init) init(commands); exit(mutt_dump_variables()); case 'A': if (optarg == NULL) { mutt_usage(); exit(-1); } optind--; while (optind < argc) { aliases = mutt_add_list(aliases, argv[optind]); optind++; } arg_expand_alias = 1; break; case 'F': if (optarg == NULL) { mutt_usage(); exit(-1); } mutt_str_replace(&Muttrc, optarg); break; case 'Q': if (optarg == NULL) { mutt_usage(); exit(-1); } optind--; while (optind < argc) { queries = mutt_add_list(queries, argv[optind]); optind++; } arg_query_conf = 1; break; } } }
int main(int argc, char **argv) { char folder[_POSIX_PATH_MAX] = ""; int flags = 0; /* set default locale */ setlocale(LC_ALL, ""); /* initialization of main output routines with default values */ mutt_error = mutt_message = mutt_nocurses_error; /* parse command line options */ parse_argv(argc, argv); if (arg_version == 1) { show_version(); exit(RETURN_SUCCESS); } else if (arg_version == 2) { show_version_verbose(); exit(RETURN_SUCCESS); } if (arg_execute) { init(commands); is_mutt_init = true; } if (arg_expand_alias) { struct list_t *alias; if (!is_mutt_init) init(commands); for(alias = aliases; alias; alias = alias->next) { struct address *a = mutt_lookup_alias(alias->data); if (a) { printf("alias->data %s\n", alias->data); mutt_write_address_list(a, stdout, 0, 0); } } exit(RETURN_SUCCESS); } if (arg_query_conf) { if (!is_mutt_init) init(commands); if (queries) return mutt_query_variables(queries); exit(RETURN_SUCCESS); } if (arg_emulate_mailx) { sendflags |= SENDMAILX; } if (arg_mailbox) strfcpy(folder, arg_mailbox, sizeof(folder)); if (arg_mailbox_type) mx_set_magic(arg_mailbox_type); if (arg_resume_postponed) sendflags |= SENDPOSTPONED; /* no-curses for non-terminal session */ if (!isatty(STDIN_FILENO)) { set_bit(options, OPTNOCURSES); sendflags = SENDBATCH; } else { /* * This must come before mutt_init() because curses needs to be started * before calling the init_pair() function to set the color scheme. */ start_curses(); /* check whether terminal status is supported */ term_status = mutt_ts_capability(); } /* Initialize crypto backends. */ crypt_init(); if (!is_mutt_init) init(commands); if (!bit_val(options, OPTNOCURSES)) { SETCOLOR(MT_COLOR_NORMAL); clear(); mutt_error = mutt_curses_error; mutt_message = mutt_curses_message; } /* Create the Maildir directory if it doesn't exist */ if (!bit_val(options, OPTNOCURSES) && Maildir) { struct stat sb; char fpath[_POSIX_PATH_MAX]; char msg[STRING]; strfcpy(fpath, Maildir, sizeof(fpath)); mutt_expand_path(fpath, sizeof(fpath)); #if USE_IMAP /* we're not connected yet - skip mail folder creation */ if (!mx_is_imap(fpath)) #endif if (stat(fpath, &sb) == -1 && errno == ENOENT) { snprintf(msg, sizeof(msg), ("%s does not exist. Create it?"), Maildir); if (mutt_yesorno(msg, M_YES) == M_YES) if (mkdir(fpath, 0700) == -1 && errno != EEXIST) mutt_error( ("Can't create %s: %s."), Maildir, strerror(errno)); } } if (sendflags & SENDPOSTPONED) { if (!bit_val(options, OPTNOCURSES)) mutt_flushinp(); ci_send_message(SENDPOSTPONED, NULL, NULL, NULL, NULL); mutt_endwin(NULL); } else if (arg_subject || msg || sendflags || arg_include || attach) { FILE *fin = NULL; char buf[LONG_STRING]; char *tempfile = NULL, *infile = NULL; char *bodytext = NULL; int rv = 0; if (!bit_val(options, OPTNOCURSES)) mutt_flushinp(); if (!msg) msg = mutt_new_header(); if (!msg->env) msg->env = mutt_new_envelope(); for(; addr_to; addr_to = addr_to->next) { if (url_check_scheme(addr_to->data) == U_MAILTO) { if (url_parse_mailto(msg->env, &bodytext, addr_to->data) < 0) { if (!bit_val(options, OPTNOCURSES)) mutt_endwin(NULL); fputs(("Failed to parse mailto: link\n"), stderr); exit(RETURN_WRONG_ADDR); } } else msg->env->to = rfc822_parse_adrlist(msg->env->to, addr_to->data); } if (bit_val(options, OPTAUTOEDIT) && !msg->env->to && !msg->env->cc) { if (!bit_val(options, OPTNOCURSES)) mutt_endwin(NULL); fputs(("No recipients specified.\n"), stderr); exit(RETURN_ERR_ARG); } if (arg_subject) msg->env->subject = safe_strdup(arg_subject); if (arg_include) infile = arg_include; if (infile || bodytext) { if (infile) { if (mutt_strcmp("-", infile) == 0) fin = stdin; else { char path[_POSIX_PATH_MAX]; strfcpy(path, infile, sizeof(path)); mutt_expand_path(path, sizeof(path)); if ((fin = fopen(path, "r")) == NULL) { if (!bit_val(options, OPTNOCURSES)) mutt_endwin(NULL); perror(path); exit(RETURN_ERR_ARG); } } } mutt_mktemp(buf, sizeof(buf)); tempfile = safe_strdup(buf); /* TODO: is the following if still needed? */ if (tempfile) { FILE *fout; if ((fout = safe_fopen(tempfile, "w")) == NULL) { if (!bit_val(options, OPTNOCURSES)) mutt_endwin(NULL); perror(tempfile); safe_fclose(&fin); safe_free(&tempfile); exit(RETURN_ERR_ARG); } if (fin) mutt_copy_stream(fin, fout); else if (bodytext) fputs(bodytext, fout); safe_fclose(&fout); } if (fin && fin != stdin) safe_fclose(&fin); } safe_free(&bodytext); if (attach) { struct list_t *t = attach; struct body *a = NULL; while(t) { if (a) { a->next = mutt_make_file_attach(t->data); a = a->next; } else msg->content = a = mutt_make_file_attach(t->data); if (!a) { if (!bit_val(options, OPTNOCURSES)) mutt_endwin(NULL); fprintf(stderr, ("%s: unable to attach file.\n"), t->data); mutt_free_list(&attach); exit(RETURN_ERR_ARG); } t = t->next; } mutt_free_list(&attach); } rv = ci_send_message(sendflags, msg, tempfile, NULL, NULL); if (!bit_val(options, OPTNOCURSES)) mutt_endwin(NULL); if (rv) exit(RETURN_ERR_ARG); } else { if (!folder[0]) strfcpy(folder, NONULL(Spoolfile), sizeof(folder)); mutt_expand_path(folder, sizeof(folder)); mutt_str_replace(&CurrentFolder, folder); mutt_str_replace(&LastFolder, folder); mutt_folder_hook(folder); if ((Context = mx_open_mailbox(folder, flags, NULL)) || !arg_mailbox) { mutt_index_menu(); if (Context) safe_free(&Context); } #if USE_IMAP imap_logout_all(); #endif #if USE_SASL mutt_sasl_done(); #endif mutt_free_opts(); mutt_endwin(Errorbuf); } exit(RETURN_SUCCESS); }
static int address_header_decode (char **h) { char *s = *h; int l, rp = 0; ADDRESS *a = NULL; ADDRESS *cur = NULL; switch (tolower ((unsigned char) *s)) { case 'r': { if (ascii_strncasecmp (s, "return-path:", 12) == 0) { l = 12; rp = 1; break; } else if (ascii_strncasecmp (s, "reply-to:", 9) == 0) { l = 9; break; } return 0; } case 'f': { if (ascii_strncasecmp (s, "from:", 5)) return 0; l = 5; break; } case 'c': { if (ascii_strncasecmp (s, "cc:", 3)) return 0; l = 3; break; } case 'b': { if (ascii_strncasecmp (s, "bcc:", 4)) return 0; l = 4; break; } case 's': { if (ascii_strncasecmp (s, "sender:", 7)) return 0; l = 7; break; } case 't': { if (ascii_strncasecmp (s, "to:", 3)) return 0; l = 3; break; } case 'm': { if (ascii_strncasecmp (s, "mail-followup-to:", 17)) return 0; l = 17; break; } default: return 0; } if ((a = rfc822_parse_adrlist (a, s + l)) == NULL) return 0; mutt_addrlist_to_local (a); rfc2047_decode_adrlist (a); for (cur = a; cur; cur = cur->next) if (cur->personal) rfc822_dequote_comment (cur->personal); /* angle brackets for return path are mandated by RfC5322, * so leave Return-Path as-is */ if (rp) *h = safe_strdup (s); else { *h = safe_calloc (1, l + 2); strfcpy (*h, s, l + 1); format_address_header (h, a); } rfc822_free_address (&a); FREE (&s); return 1; }
pgp_key_t pgp_getkeybyaddr (ADDRESS * a, short abilities, pgp_ring_t keyring, int oppenc_mode) { ADDRESS *r, *p; LIST *hints = NULL; int multi = 0; int match; pgp_key_t keys, k, kn; pgp_key_t the_strong_valid_key = NULL; pgp_key_t a_valid_addrmatch_key = NULL; pgp_key_t matches = NULL; pgp_key_t *last = &matches; pgp_uid_t *q; if (a && a->mailbox) hints = pgp_add_string_to_hints (hints, a->mailbox); if (a && a->personal) hints = pgp_add_string_to_hints (hints, a->personal); if (! oppenc_mode ) mutt_message (_("Looking for keys matching \"%s\"..."), a->mailbox); keys = pgp_get_candidates (keyring, hints); mutt_free_list (&hints); if (!keys) return NULL; dprint (5, (debugfile, "pgp_getkeybyaddr: looking for %s <%s>.", a->personal, a->mailbox)); for (k = keys; k; k = kn) { kn = k->next; dprint (5, (debugfile, " looking at key: %s\n", pgp_keyid (k))); if (abilities && !(k->flags & abilities)) { dprint (5, (debugfile, " insufficient abilities: Has %x, want %x\n", k->flags, abilities)); continue; } match = 0; /* any match */ for (q = k->address; q; q = q->next) { r = rfc822_parse_adrlist (NULL, NONULL (q->addr)); for (p = r; p; p = p->next) { int validity = pgp_id_matches_addr (a, p, q); if (validity & PGP_KV_MATCH) /* something matches */ match = 1; if ((validity & PGP_KV_VALID) && (validity & PGP_KV_ADDR)) { if (validity & PGP_KV_STRONGID) { if (the_strong_valid_key && the_strong_valid_key != k) multi = 1; the_strong_valid_key = k; } else { a_valid_addrmatch_key = k; } } } rfc822_free_address (&r); } if (match) { *last = pgp_principal_key (k); kn = pgp_remove_key (&keys, *last); last = pgp_get_lastp (k); } } pgp_free_key (&keys); if (matches) { if (oppenc_mode) { if (the_strong_valid_key) { pgp_remove_key (&matches, the_strong_valid_key); k = the_strong_valid_key; } else if (a_valid_addrmatch_key) { pgp_remove_key (&matches, a_valid_addrmatch_key); k = a_valid_addrmatch_key; } else k = NULL; } else if (the_strong_valid_key && !multi) { /* * There was precisely one strong match on a valid ID. * * Proceed without asking the user. */ pgp_remove_key (&matches, the_strong_valid_key); k = the_strong_valid_key; } else { /* * Else: Ask the user. */ if ((k = pgp_select_key (matches, a, NULL))) pgp_remove_key (&matches, k); } pgp_free_key (&matches); return k; } return NULL; }
void mutt_attach_bounce (FILE * fp, HEADER * hdr, ATTACHPTR ** idx, short idxlen, BODY * cur) { short i; char prompt[STRING]; char buf[HUGE_STRING]; char *err = NULL; ADDRESS *adr = NULL; int ret = 0; int p = 0; if (check_all_msg (idx, idxlen, cur, 1) == -1) return; /* one or more messages? */ p = (cur || count_tagged (idx, idxlen) == 1); if (p) strfcpy (prompt, _("Bounce message to: "), sizeof (prompt)); else strfcpy (prompt, _("Bounce tagged messages to: "), sizeof (prompt)); buf[0] = '\0'; if (mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS) || buf[0] == '\0') return; if (!(adr = rfc822_parse_adrlist (adr, buf))) { mutt_error _("Error parsing address!"); return; } adr = mutt_expand_aliases (adr); if (mutt_addrlist_to_idna (adr, &err) < 0) { mutt_error (_("Bad IDN: '%s'"), err); mem_free (&err); rfc822_free_address (&adr); return; } buf[0] = 0; rfc822_write_address (buf, sizeof (buf), adr, 1); #define extra_space (15+7+2) /* * See commands.c. */ snprintf (prompt, sizeof (prompt) - 4, (p ? _("Bounce message to %s") : _("Bounce messages to %s")), buf); if (mutt_strwidth (prompt) > COLS - extra_space) { mutt_format_string (prompt, sizeof (prompt) - 4, 0, COLS - extra_space, 0, 0, prompt, sizeof (prompt), 0); str_cat (prompt, sizeof (prompt), "...?"); } else str_cat (prompt, sizeof (prompt), "?"); if (query_quadoption (OPT_BOUNCE, prompt) != M_YES) { rfc822_free_address (&adr); CLEARLINE (LINES - 1); mutt_message (p ? _("Message not bounced.") : _("Messages not bounced.")); return; } CLEARLINE (LINES - 1); if (cur) ret = mutt_bounce_message (fp, cur->hdr, adr); else { for (i = 0; i < idxlen; i++) { if (idx[i]->content->tagged) if (mutt_bounce_message (fp, idx[i]->content->hdr, adr)) ret = 1; } } if (!ret) mutt_message (p ? _("Message bounced.") : _("Messages bounced.")); else mutt_error (p ? _("Error bouncing message!") : _("Error bouncing messages!")); }