static LIST *_mutt_list_hook (const char *match, int hook) { HOOK *tmp = Hooks; LIST *matches = NULL; for (; tmp; tmp = tmp->next) { if ((tmp->type & hook) && ((match && regexec (tmp->rx.rx, match, 0, NULL, 0) == 0) ^ tmp->rx.not)) matches = mutt_add_list (matches, tmp->command); } return (matches); }
static LIST *pgp_add_string_to_hints (LIST *hints, const char *str) { char *scratch; char *t; if ((scratch = safe_strdup (str)) == NULL) return hints; for (t = strtok (scratch, " ,.:\"()<>\n"); t; t = strtok (NULL, " ,.:\"()<>\n")) { if (strlen (t) > 3) hints = mutt_add_list (hints, t); } FREE (&scratch); return hints; }
/* args: * ctx Context info, used when recalling a message to which * we reply. * hdr envelope/attachment info for recalled message * cur if message was a reply, `cur' is set to the message which * `hdr' is in reply to * fcc fcc for the recalled message * fcclen max length of fcc * * return vals: * -1 error/no messages * 0 normal exit * SENDREPLY recalled message is a reply */ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, char *fcc, size_t fcclen) { HEADER *h; int code = SENDPOSTPONED; LIST *tmp; LIST *last = NULL; LIST *next; const char *p; int opt_delete; if (!Postponed) return (-1); if ((PostContext = mx_open_mailbox (Postponed, M_NOSORT, NULL)) == NULL) { PostCount = 0; mutt_error _("No postponed messages."); return (-1); } if (! PostContext->msgcount) { PostCount = 0; mx_close_mailbox (PostContext, NULL); FREE (&PostContext); mutt_error _("No postponed messages."); return (-1); } if (PostContext->msgcount == 1) { /* only one message, so just use that one. */ h = PostContext->hdrs[0]; } else if ((h = select_msg ()) == NULL) { mx_close_mailbox (PostContext, NULL); FREE (&PostContext); return (-1); } if (mutt_prepare_template (NULL, PostContext, hdr, h, 0) < 0) { mx_fastclose_mailbox (PostContext); FREE (&PostContext); return (-1); } /* finished with this message, so delete it. */ mutt_set_flag (PostContext, h, M_DELETE, 1); /* update the count for the status display */ PostCount = PostContext->msgcount - PostContext->deleted; /* avoid the "purge deleted messages" prompt */ opt_delete = quadoption (OPT_DELETE); set_quadoption (OPT_DELETE, M_YES); mx_close_mailbox (PostContext, NULL); set_quadoption (OPT_DELETE, opt_delete); FREE (&PostContext); for (tmp = hdr->env->userhdrs; tmp; ) { if (ascii_strncasecmp ("X-Mutt-References:", tmp->data, 18) == 0) { if (ctx) { /* if a mailbox is currently open, look to see if the orignal message the user attempted to reply to is in this mailbox */ p = skip_email_wsp(tmp->data + 18); if (!ctx->id_hash) ctx->id_hash = mutt_make_id_hash (ctx); *cur = hash_find (ctx->id_hash, p); } /* Remove the X-Mutt-References: header field. */ next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; if (*cur) code |= SENDREPLY; } else if (ascii_strncasecmp ("X-Mutt-Fcc:", tmp->data, 11) == 0) { p = skip_email_wsp(tmp->data + 11); strfcpy (fcc, p, fcclen); mutt_pretty_mailbox (fcc, fcclen); /* remove the X-Mutt-Fcc: header field */ next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; /* note that x-mutt-fcc was present. we do this because we want to add a * default fcc if the header was missing, but preserve the request of the * user to not make a copy if the header field is present, but empty. * see http://dev.mutt.org/trac/ticket/3653 */ code |= SENDPOSTPONEDFCC; } else if ((WithCrypto & APPLICATION_PGP) && (mutt_strncmp ("Pgp:", tmp->data, 4) == 0 /* this is generated * by old mutt versions */ || mutt_strncmp ("X-Mutt-PGP:", tmp->data, 11) == 0)) { hdr->security = mutt_parse_crypt_hdr (strchr (tmp->data, ':') + 1, 1, APPLICATION_PGP); hdr->security |= APPLICATION_PGP; /* remove the pgp field */ next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; } else if ((WithCrypto & APPLICATION_SMIME) && mutt_strncmp ("X-Mutt-SMIME:", tmp->data, 13) == 0) { hdr->security = mutt_parse_crypt_hdr (strchr (tmp->data, ':') + 1, 1, APPLICATION_SMIME); hdr->security |= APPLICATION_SMIME; /* remove the smime field */ next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; } #ifdef MIXMASTER else if (mutt_strncmp ("X-Mutt-Mix:", tmp->data, 11) == 0) { char *t; mutt_free_list (&hdr->chain); t = strtok (tmp->data + 11, " \t\n"); while (t) { hdr->chain = mutt_add_list (hdr->chain, t); t = strtok (NULL, " \t\n"); } next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; } #endif else { last = tmp; tmp = tmp->next; } } if (option (OPTCRYPTOPPORTUNISTICENCRYPT)) crypt_opportunistic_encrypt (hdr); return (code); }
/* args: * ctx Context info, used when recalling a message to which * we reply. * hdr envelope/attachment info for recalled message * cur if message was a reply, `cur' is set to the message which * `hdr' is in reply to * fcc fcc for the recalled message * fcclen max length of fcc * * return vals: * -1 error/no messages * 0 normal exit * SENDREPLY recalled message is a reply */ int mutt_get_postponed (CONTEXT * ctx, HEADER * hdr, HEADER ** cur, char *fcc, size_t fcclen) { HEADER *h; int code = SENDPOSTPONED; LIST *tmp; LIST *last = NULL; LIST *next; char *p; int opt_delete; if (!Postponed) return (-1); if ((PostContext = mx_open_mailbox (Postponed, M_NOSORT, NULL)) == NULL) { PostCount = 0; mutt_error _("No postponed messages."); return (-1); } if (!PostContext->msgcount) { PostCount = 0; mx_close_mailbox (PostContext, NULL); mem_free (&PostContext); mutt_error _("No postponed messages."); return (-1); } if (PostContext->msgcount == 1) { /* only one message, so just use that one. */ h = PostContext->hdrs[0]; } else if ((h = select_msg ()) == NULL) { mx_close_mailbox (PostContext, NULL); mem_free (&PostContext); return (-1); } if (mutt_prepare_template (NULL, PostContext, hdr, h, 0) < 0) { mx_fastclose_mailbox (PostContext); mem_free (&PostContext); return (-1); } /* finished with this message, so delete it. */ mutt_set_flag (PostContext, h, M_DELETE, 1); /* and consider it saved, so that it won't be moved to the trash folder */ mutt_set_flag (PostContext, h, M_APPENDED, 1); /* update the count for the status display */ PostCount = PostContext->msgcount - PostContext->deleted; /* avoid the "purge deleted messages" prompt */ opt_delete = quadoption (OPT_DELETE); set_quadoption (OPT_DELETE, M_YES); mx_close_mailbox (PostContext, NULL); set_quadoption (OPT_DELETE, opt_delete); mem_free (&PostContext); for (tmp = hdr->env->userhdrs; tmp;) { if (ascii_strncasecmp ("X-Mutt-References:", tmp->data, 18) == 0) { if (ctx) { /* if a mailbox is currently open, look to see if the orignal message the user attempted to reply to is in this mailbox */ p = tmp->data + 18; SKIPWS (p); if (!ctx->id_hash) ctx->id_hash = mutt_make_id_hash (ctx); *cur = hash_find (ctx->id_hash, p); } /* Remove the X-Mutt-References: header field. */ next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; if (*cur) code |= SENDREPLY; } else if (ascii_strncasecmp ("X-Mutt-Fcc:", tmp->data, 11) == 0) { p = tmp->data + 11; SKIPWS (p); strfcpy (fcc, p, fcclen); mutt_pretty_mailbox (fcc); /* remove the X-Mutt-Fcc: header field */ next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; } else if ((WithCrypto & APPLICATION_PGP) && (str_ncmp ("Pgp:", tmp->data, 4) == 0 /* this is generated * by old mutt versions */ || str_ncmp ("X-Mutt-PGP:", tmp->data, 11) == 0)) { hdr->security = mutt_parse_crypt_hdr (strchr (tmp->data, ':') + 1, 1); hdr->security |= APPLICATION_PGP; /* remove the pgp field */ next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; } else if ((WithCrypto & APPLICATION_SMIME) && str_ncmp ("X-Mutt-SMIME:", tmp->data, 13) == 0) { hdr->security = mutt_parse_crypt_hdr (strchr (tmp->data, ':') + 1, 1); hdr->security |= APPLICATION_SMIME; /* remove the smime field */ next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; } #ifdef MIXMASTER else if (str_ncmp ("X-Mutt-Mix:", tmp->data, 11) == 0) { char *t; mutt_free_list (&hdr->chain); t = strtok (tmp->data + 11, " \t\n"); while (t) { hdr->chain = mutt_add_list (hdr->chain, t); t = strtok (NULL, " \t\n"); } next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; } #endif else { last = tmp; tmp = tmp->next; } } return (code); }
void mix_make_chain (LIST **chainp, int *redraw) { LIST *p; MIXCHAIN *chain; int c_cur = 0, c_old = 0; short c_redraw = 1; REMAILER **type2_list = NULL; size_t ttll = 0; struct coord *coords = NULL; MUTTMENU *menu; char helpstr[LONG_STRING]; short loop = 1; int op; int i, j; char *t; if (!(type2_list = mix_type2_list (&ttll))) { mutt_error _("Can't get mixmaster's type2.list!"); return; } *redraw = REDRAW_FULL; chain = safe_calloc (sizeof (MIXCHAIN), 1); for (p = *chainp; p; p = p->next) mix_chain_add (chain, (char *) p->data, type2_list); mutt_free_list (chainp); /* safety check */ for (i = 0; i < chain->cl; i++) { if (chain->ch[i] >= ttll) chain->ch[i] = 0; } mix_screen_coordinates (type2_list, &coords, chain, 0); menu = mutt_new_menu (MENU_MIX); menu->max = ttll; menu->make_entry = mix_entry; menu->tag = NULL; menu->title = _("Select a remailer chain."); menu->data = type2_list; menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_MIX, RemailerHelp); menu->pagelen = MIX_VOFFSET - 1; while (loop) { if (menu->pagelen != MIX_VOFFSET - 1) { menu->pagelen = MIX_VOFFSET - 1; menu->redraw = REDRAW_FULL; } if (c_redraw) { mix_redraw_head (chain); mix_redraw_chain (type2_list, coords, chain, c_cur); c_redraw = 0; } else if (c_cur != c_old) { mix_redraw_ce (type2_list, coords, chain, c_old, 0); mix_redraw_ce (type2_list, coords, chain, c_cur, 1); } c_old = c_cur; switch ((op = mutt_menuLoop (menu))) { case OP_REDRAW: { menu_redraw_status (menu); mix_redraw_head (chain); mix_screen_coordinates (type2_list, &coords, chain, 0); mix_redraw_chain (type2_list, coords, chain, c_cur); menu->pagelen = MIX_VOFFSET - 1; break; } case OP_EXIT: { chain->cl = 0; loop = 0; break; } case OP_MIX_USE: { if (!chain->cl) { chain->cl++; chain->ch[0] = menu->current; mix_screen_coordinates (type2_list, &coords, chain, c_cur); c_redraw = 1; } if (chain->cl && chain->ch[chain->cl - 1] && (type2_list[chain->ch[chain->cl-1]]->caps & MIX_CAP_MIDDLEMAN)) { mutt_error ( _("Error: %s can't be used as the final remailer of a chain."), type2_list[chain->ch[chain->cl - 1]]->shortname); } else { loop = 0; } break; } case OP_GENERIC_SELECT_ENTRY: case OP_MIX_APPEND: { if (chain->cl < MAXMIXES && c_cur < chain->cl) c_cur++; } /* fallthrough */ case OP_MIX_INSERT: { if (chain->cl < MAXMIXES) { chain->cl++; for (i = chain->cl - 1; i > c_cur; i--) chain->ch[i] = chain->ch[i-1]; chain->ch[c_cur] = menu->current; mix_screen_coordinates (type2_list, &coords, chain, c_cur); c_redraw = 1; } else mutt_error ( _("Mixmaster chains are limited to %d elements."), MAXMIXES); break; } case OP_MIX_DELETE: { if (chain->cl) { chain->cl--; for (i = c_cur; i < chain->cl; i++) chain->ch[i] = chain->ch[i+1]; if (c_cur == chain->cl && c_cur) c_cur--; mix_screen_coordinates (type2_list, &coords, chain, c_cur); c_redraw = 1; } else { mutt_error _("The remailer chain is already empty."); } break; } case OP_MIX_CHAIN_PREV: { if (c_cur) c_cur--; else mutt_error _("You already have the first chain element selected."); break; } case OP_MIX_CHAIN_NEXT: { if (chain->cl && c_cur < chain->cl - 1) c_cur++; else mutt_error _("You already have the last chain element selected."); break; } } } mutt_menuDestroy (&menu); /* construct the remailer list */ if (chain->cl) { for (i = 0; i < chain->cl; i++) { if ((j = chain->ch[i])) t = type2_list[j]->shortname; else t = "*"; *chainp = mutt_add_list (*chainp, t); } } mix_free_type2_list (&type2_list); FREE (&coords); FREE (&chain); }
/* args: * ctx Context info, used when recalling a message to which * we reply. * hdr envelope/attachment info for recalled message * cur if message was a reply, `cur' is set to the message which * `hdr' is in reply to * fcc fcc for the recalled message * fcclen max length of fcc * * return vals: * -1 error/no messages * 0 normal exit * SENDREPLY recalled message is a reply */ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, char *fcc, size_t fcclen) { HEADER *h; int code = SENDPOSTPONED; LIST *tmp; LIST *last = NULL; LIST *next; char *p; int opt_delete; #ifdef USE_IMAP char curpath[LONG_STRING]; int need_reopen = 0; #endif if (!Postponed) return (-1); #ifdef USE_IMAP /* if we're in an IMAP folder and the postponed folder is also IMAP, we may * need to take steps to avoid opening an additional connection to the same * server. */ if ((ctx && ctx->magic == M_IMAP) && mx_is_imap (Postponed)) { strfcpy (curpath, ctx->path, sizeof (curpath)); if (imap_select_mailbox (ctx, Postponed) < 0) return -1; need_reopen = 1; PostContext = ctx; } else #endif if ((PostContext = mx_open_mailbox (Postponed, M_NOSORT, NULL)) == NULL) { PostCount = 0; mutt_error _("No postponed messages."); return (-1); } if (! PostContext->msgcount) { PostCount = 0; mx_close_mailbox (PostContext, NULL); #ifdef USE_IMAP if (need_reopen) ctx = mx_open_mailbox (curpath, 0, PostContext); else #endif safe_free ((void **) &PostContext); mutt_error _("No postponed messages."); return (-1); } if (PostContext->msgcount == 1) { /* only one message, so just use that one. */ h = PostContext->hdrs[0]; } else if ((h = select_msg ()) == NULL) { mx_close_mailbox (PostContext, NULL); #ifdef USE_IMAP if (need_reopen) ctx = mx_open_mailbox (curpath, 0, PostContext); else #endif safe_free ((void **) &PostContext); return (-1); } if (mutt_prepare_template (NULL, PostContext, hdr, h, 0) < 0) { mx_fastclose_mailbox (PostContext); #ifdef USE_IMAP if (need_reopen) ctx = mx_open_mailbox (curpath, 0, NULL); else #endif safe_free ((void **) &PostContext); return (-1); } /* finished with this message, so delete it. */ mutt_set_flag (PostContext, h, M_DELETE, 1); /* update the count for the status display */ PostCount = PostContext->msgcount - PostContext->deleted; /* avoid the "purge deleted messages" prompt */ opt_delete = quadoption (OPT_DELETE); set_quadoption (OPT_DELETE, M_YES); mx_close_mailbox (PostContext, NULL); set_quadoption (OPT_DELETE, opt_delete); #ifdef USE_IMAP if (need_reopen) ctx = mx_open_mailbox (curpath, 0, PostContext); else #endif safe_free ((void **) &PostContext); for (tmp = hdr->env->userhdrs; tmp; ) { if (mutt_strncasecmp ("X-Mutt-References:", tmp->data, 18) == 0) { if (ctx) { /* if a mailbox is currently open, look to see if the orignal message the user attempted to reply to is in this mailbox */ p = tmp->data + 18; SKIPWS (p); *cur = hash_find (ctx->id_hash, p); } /* Remove the X-Mutt-References: header field. */ next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; if (*cur) code |= SENDREPLY; } else if (mutt_strncasecmp ("X-Mutt-Fcc:", tmp->data, 11) == 0) { p = tmp->data + 11; SKIPWS (p); strfcpy (fcc, p, fcclen); mutt_pretty_mailbox (fcc); /* remove the X-Mutt-Fcc: header field */ next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; } #ifdef HAVE_PGP else if (mutt_strncmp ("Pgp:", tmp->data, 4) == 0 /* this is generated * by old mutt versions */ || mutt_strncmp ("X-Mutt-PGP:", tmp->data, 11) == 0) { hdr->pgp = mutt_parse_pgp_hdr (strchr (tmp->data, ':') + 1, 1); /* remove the pgp field */ next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; } #endif /* HAVE_PGP */ #ifdef MIXMASTER else if (mutt_strncmp ("X-Mutt-Mix:", tmp->data, 11) == 0) { char *t; mutt_free_list (&hdr->chain); t = strtok (tmp->data + 11, " \t\n"); while (t) { hdr->chain = mutt_add_list (hdr->chain, t); t = strtok (NULL, " \t\n"); } next = tmp->next; if (last) last->next = tmp->next; else hdr->env->userhdrs = tmp->next; tmp->next = NULL; mutt_free_list (&tmp); tmp = next; } #endif else { last = tmp; tmp = tmp->next; } } return (code); }
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; } } }