📄 recvattach.c
字号:
else mutt_query_pipe_attachment (command, fp, top, filter); } else if (top->parts) pipe_attachment_list (command, fp, tag, top->parts, filter, state); if (!tag) break; }}void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter){ STATE state; char buf[SHORT_STRING]; pid_t thepid; if (fp) filter = 0; /* sanity check: we can't filter in the recv case yet */ buf[0] = 0; memset (&state, 0, sizeof (STATE)); if (mutt_get_field ((filter ? _("Filter through: ") : _("Pipe to: ")), buf, sizeof (buf), M_CMD) != 0 || !buf[0]) return; mutt_expand_path (buf, sizeof (buf)); if (!filter && !option (OPTATTACHSPLIT)) { mutt_endwin (NULL); thepid = mutt_create_filter (buf, &state.fpout, NULL, NULL); pipe_attachment_list (buf, fp, tag, top, filter, &state); fclose (state.fpout); if (mutt_wait_filter (thepid) != 0 || option (OPTWAITKEY)) mutt_any_key_to_continue (NULL); } else pipe_attachment_list (buf, fp, tag, top, filter, &state);}static int can_print (BODY *top, int tag){ char type [STRING]; for (; top; top = top->next) { snprintf (type, sizeof (type), "%s/%s", TYPE (top), top->subtype); if (!tag || top->tagged) { if (!rfc1524_mailcap_lookup (top, type, NULL, M_PRINT)) { if (ascii_strcasecmp ("text/plain", top->subtype) && ascii_strcasecmp ("application/postscript", top->subtype)) { if (!mutt_can_decode (top)) { mutt_error (_("I dont know how to print %s attachments!"), type); return (0); } } } } else if (top->parts) return (can_print (top->parts, tag)); if (!tag) break; } return (1);}static void print_attachment_list (FILE *fp, int tag, BODY *top, STATE *state){ char type [STRING]; for (; top; top = top->next) { if (!tag || top->tagged) { snprintf (type, sizeof (type), "%s/%s", TYPE (top), top->subtype); if (!option (OPTATTACHSPLIT) && !rfc1524_mailcap_lookup (top, type, NULL, M_PRINT)) { if (!ascii_strcasecmp ("text/plain", top->subtype) || !ascii_strcasecmp ("application/postscript", top->subtype)) pipe_attachment (fp, top, state); else if (mutt_can_decode (top)) { /* decode and print */ char newfile[_POSIX_PATH_MAX] = ""; FILE *ifp; mutt_mktemp (newfile); if (mutt_decode_save_attachment (fp, top, newfile, M_PRINTING, 0) == 0) { if ((ifp = fopen (newfile, "r")) != NULL) { mutt_copy_stream (ifp, state->fpout); fclose (ifp); if (AttachSep) state_puts (AttachSep, state); } } mutt_unlink (newfile); } } else mutt_print_attachment (fp, top); } else if (top->parts) print_attachment_list (fp, tag, top->parts, state); if (!tag) return; }}void mutt_print_attachment_list (FILE *fp, int tag, BODY *top){ STATE state; pid_t thepid; if (query_quadoption (OPT_PRINT, tag ? _("Print tagged attachment(s)?") : _("Print attachment?")) != M_YES) return; if (!option (OPTATTACHSPLIT)) { if (!can_print (top, tag)) return; mutt_endwin (NULL); memset (&state, 0, sizeof (STATE)); thepid = mutt_create_filter (NONULL (PrintCmd), &state.fpout, NULL, NULL); print_attachment_list (fp, tag, top, &state); fclose (state.fpout); if (mutt_wait_filter (thepid) != 0 || option (OPTWAITKEY)) mutt_any_key_to_continue (NULL); } else print_attachment_list (fp, tag, top, &state);}voidmutt_update_attach_index (BODY *cur, ATTACHPTR ***idxp, short *idxlen, short *idxmax, MUTTMENU *menu){ ATTACHPTR **idx = *idxp; while (--(*idxlen) >= 0) idx[(*idxlen)]->content = NULL; *idxlen = 0; idx = *idxp = mutt_gen_attach_list (cur, -1, idx, idxlen, idxmax, 0, 0); menu->max = *idxlen; menu->data = *idxp; if (menu->current >= menu->max) menu->current = menu->max - 1; menu_check_recenter (menu); menu->redraw |= REDRAW_INDEX; }intmutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr, BODY *cur, ATTACHPTR ***idxp, short *idxlen, short *idxmax, int recv){ ATTACHPTR **idx = *idxp;#if 0 int old_optweed = option (OPTWEED); set_option (OPTWEED);#endif do { switch (op) { case OP_DISPLAY_HEADERS: toggle_option (OPTWEED); /* fall through */ case OP_VIEW_ATTACH: op = mutt_view_attachment (fp, idx[menu->current]->content, M_REGULAR, hdr, idx, *idxlen); break; case OP_NEXT_ENTRY: case OP_MAIN_NEXT_UNDELETED: /* hack */ if (menu->current < menu->max - 1) { menu->current++; op = OP_VIEW_ATTACH; } else op = OP_NULL; break; case OP_PREV_ENTRY: case OP_MAIN_PREV_UNDELETED: /* hack */ if (menu->current > 0) { menu->current--; op = OP_VIEW_ATTACH; } else op = OP_NULL; break; case OP_EDIT_TYPE: /* when we edit the content-type, we should redisplay the attachment immediately */ mutt_edit_content_type (hdr, idx[menu->current]->content, fp); if (idxmax) { mutt_update_attach_index (cur, idxp, idxlen, idxmax, menu); idx = *idxp; } op = OP_VIEW_ATTACH; break; /* functions which are passed through from the pager */ case OP_CHECK_TRADITIONAL: if (!(WithCrypto & APPLICATION_PGP) || (hdr && hdr->security & PGP_TRADITIONAL_CHECKED)) { op = OP_NULL; break; } /* fall through */ case OP_ATTACH_COLLAPSE: if (recv) return op; default: op = OP_NULL; } } while (op != OP_NULL);#if 0 if (option (OPTWEED) != old_optweed) toggle_option (OPTWEED);#endif return op;}static void attach_collapse (BODY *b, short collapse, short init, short just_one){ short i; for (; b; b = b->next) { i = init || b->collapsed; if (i && option (OPTDIGESTCOLLAPSE) && b->type == TYPEMULTIPART && !ascii_strcasecmp (b->subtype, "digest")) attach_collapse (b->parts, 1, 1, 0); else if (b->type == TYPEMULTIPART || mutt_is_message_type (b->type, b->subtype)) attach_collapse (b->parts, collapse, i, 0); b->collapsed = collapse; if (just_one) return; }}void mutt_attach_init (BODY *b){ for (; b; b = b->next) { b->tagged = 0; b->collapsed = 0; if (b->parts) mutt_attach_init (b->parts); }}static const char *Function_not_permitted = N_("Function not permitted in attach-message mode.");#define CHECK_ATTACH if(option(OPTATTACHMSG)) \ {\ mutt_flushinp (); \ mutt_error _(Function_not_permitted); \ break; \ }void mutt_view_attachments (HEADER *hdr){ int secured = 0; int need_secured = 0; char helpstr[SHORT_STRING]; MUTTMENU *menu; BODY *cur = NULL; MESSAGE *msg; FILE *fp; ATTACHPTR **idx = NULL; short idxlen = 0; short idxmax = 0; int flags = 0; int op = OP_NULL; /* make sure we have parsed this message */ mutt_parse_mime_message (Context, hdr); mutt_message_hook (Context, hdr, M_MESSAGEHOOK); if ((msg = mx_open_message (Context, hdr->msgno)) == NULL) return; if (WithCrypto && ((hdr->security & ENCRYPT) || (mutt_is_application_smime(hdr->content) & SMIMEOPAQUE))) { need_secured = 1; if ((hdr->security & ENCRYPT) && !crypt_valid_passphrase(hdr->security)) { mx_close_message (&msg); return; } if ((WithCrypto & APPLICATION_SMIME) && (hdr->security & APPLICATION_SMIME)) { if (hdr->env) crypt_smime_getkeys (hdr->env); if (mutt_is_application_smime(hdr->content)) { secured = ! crypt_smime_decrypt_mime (msg->fp, &fp, hdr->content, &cur); /* S/MIME nesting */ if ((mutt_is_application_smime (cur) & SMIMEOPAQUE)) { BODY *_cur = cur; FILE *_fp = fp; fp = NULL; cur = NULL; secured = !crypt_smime_decrypt_mime (_fp, &fp, _cur, &cur); mutt_free_body (&_cur); safe_fclose (&_fp); } } else need_secured = 0; } if ((WithCrypto & APPLICATION_PGP) && (hdr->security & APPLICATION_PGP)) { if (mutt_is_multipart_encrypted(hdr->content)) secured = !crypt_pgp_decrypt_mime (msg->fp, &fp, hdr->content, &cur); else need_secured = 0; } if (need_secured && !secured) { mx_close_message (&msg); mutt_error _("Can't decrypt encrypted message!"); return; } } if (!WithCrypto || !need_secured) { fp = msg->fp; cur = hdr->content; } menu = mutt_new_menu (); menu->menu = MENU_ATTACH; menu->title = _("Attachments"); menu->make_entry = attach_entry; menu->tag = mutt_tag_attach; menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_ATTACH, AttachHelp); mutt_attach_init (cur); attach_collapse (cur, 0, 1, 0); mutt_update_attach_index (cur, &idx, &idxlen, &idxmax, menu); FOREVER { if (op == OP_NULL) op = mutt_menuLoop (menu); switch (op) { case OP_ATTACH_VIEW_MAILCAP: mutt_view_attachment (fp, idx[menu->current]->content, M_MAILCAP, hdr, idx, idxlen); menu->redraw = REDRAW_FULL; break; case OP_ATTACH_VIEW_TEXT: mutt_view_attachment (fp, idx[menu->current]->content, M_AS_TEXT, hdr, idx, idxlen); menu->redraw = REDRAW_FULL; break; case OP_DISPLAY_HEADERS: case OP_VIEW_ATTACH: op = mutt_attach_display_loop (menu, op, fp, hdr, cur, &idx, &idxlen, &idxmax, 1); menu->redraw = REDRAW_FULL; continue; case OP_ATTACH_COLLAPSE: if (!idx[menu->current]->content->parts) { mutt_error _("There are no subparts to show!"); break; } if (!idx[menu->current]->content->collapsed) attach_collapse (idx[menu->current]->content, 1, 0, 1); else attach_collapse (idx[menu->current]->content, 0, 1, 1); mutt_update_attach_index (cur, &idx, &idxlen, &idxmax, menu); break; case OP_FORGET_PASSPHRASE: crypt_forget_passphrase (); break; case OP_EXTRACT_KEYS: if ((WithCrypto & APPLICATION_PGP)) { crypt_pgp_extract_keys_from_attachment_list (fp, menu->tagprefix, menu->tagprefix ? cur : idx[menu->current]->content); menu->redraw = REDRAW_FULL; } break; case OP_CHECK_TRADITIONAL: if ((WithCrypto & APPLICATION_PGP) && crypt_pgp_check_traditional (fp, menu->tagprefix ? cur : idx[menu->current]->content, menu->tagprefix)) { hdr->security = crypt_query (cur); menu->redraw = REDRAW_FULL; } break; case OP_PRINT: mutt_print_attachment_list (fp, menu->tagprefix, menu->tagprefix ? cur : idx[menu->current]->content); break; case OP_PIPE: mutt_pipe_attachment_list (fp, menu->tagprefix, menu->tagprefix ? cur : idx[menu->current]->content, 0); break; case OP_SAVE: mutt_save_attachment_list (fp, menu->tagprefix, menu->tagprefix ? cur : idx[menu->current]->content, hdr, menu); if (!menu->tagprefix && option (OPTRESOLVE) && menu->current < menu->max - 1) menu->current++; menu->redraw = REDRAW_MOTION_RESYNCH | REDRAW_FULL; break; case OP_DELETE: CHECK_READONLY;#ifdef USE_POP if (Context->magic == M_POP) { mutt_flushinp (); mutt_error _("Can't delete attachment from POP server."); break; }#endif if (WithCrypto && hdr->security & ~PGP_TRADITIONAL_CHECKED) { mutt_message _( "Deletion of attachments from encrypted messages is unsupported."); } else { if (!menu->tagprefix) { if (idx[menu->current]->parent_type == TYPEMULTIPART) { idx[menu->current]->content->deleted = 1; if (option (OPTRESOLVE) && menu->current < menu->max - 1) { menu->current++; menu->redraw = REDRAW_MOTION_RESYNCH; } else menu->redraw = REDRAW_CURRENT; } else mutt_message _( "Only deletion of multipart attachments is supported."); } else { int x; for (x = 0; x < menu->max; x++) { if (idx[x]->content->tagged) { if (idx[x]->parent_type == TYPEMULTIPART) { idx[x]->content->deleted = 1; menu->redraw = REDRAW_INDEX; } else mutt_message _( "Only deletion of multipart attachments is supported."); } } } } break; case OP_UNDELETE: CHECK_READONLY; if (!menu->tagprefix) { idx[menu->current]->content->deleted = 0; if (option (OPTRESOLVE) && menu->current < menu->max - 1) { menu->current++; menu->redraw = REDRAW_MOTION_RESYNCH; } else menu->redraw = REDRAW_CURRENT; } else { int x; for (x = 0; x < menu->max; x++) { if (idx[x]->content->tagged) { idx[x]->content->deleted = 0; menu->redraw = REDRAW_INDEX; } } } break; case OP_RESEND: CHECK_ATTACH; mutt_attach_resend (fp, hdr, idx, idxlen, menu->tagprefix ? NULL : idx[menu->current]->content); menu->redraw = REDRAW_FULL; break; case OP_BOUNCE_MESSAGE: CHECK_ATTACH; mutt_attach_bounce (fp, hdr, idx, idxlen, menu->tagprefix ? NULL : idx[menu->current]->content); menu->redraw = REDRAW_FULL; break; case OP_FORWARD_MESSAGE: CHECK_ATTACH; mutt_attach_forward (fp, hdr, idx, idxlen, menu->tagprefix ? NULL : idx[menu->current]->content); menu->redraw = REDRAW_FULL; break; case OP_REPLY: case OP_GROUP_REPLY: case OP_LIST_REPLY: CHECK_ATTACH; flags = SENDREPLY | (op == OP_GROUP_REPLY ? SENDGROUPREPLY : 0) | (op == OP_LIST_REPLY ? SENDLISTREPLY : 0); mutt_attach_reply (fp, hdr, idx, idxlen, menu->tagprefix ? NULL : idx[menu->current]->content, flags); menu->redraw = REDRAW_FULL; break; case OP_EDIT_TYPE: mutt_edit_content_type (hdr, idx[menu->current]->content, fp); mutt_update_attach_index (cur, &idx, &idxlen, &idxmax, menu); break; case OP_EXIT: mx_close_message (&msg); hdr->attach_del = 0; while (idxmax-- > 0) { if (!idx[idxmax]) continue; if (idx[idxmax]->content && idx[idxmax]->content->deleted) hdr->attach_del = 1; if (idx[idxmax]->content) idx[idxmax]->content->aptr = NULL; FREE (&idx[idxmax]->tree); FREE (&idx[idxmax]); } if (hdr->attach_del) hdr->changed = 1; FREE (&idx); idxmax = 0; if (WithCrypto && need_secured && secured) { fclose (fp); mutt_free_body (&cur); } mutt_menuDestroy (&menu); return; } op = OP_NULL; } /* not reached */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -