📄 commands.c
字号:
int method = Sort; /* save the current method in case of abort */ switch (mutt_multi_choice (reverse ? _("Rev-Sort (d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/(u)nsort/si(z)e/s(c)ore/s(p)am?: ") : _("Sort (d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/(u)nsort/si(z)e/s(c)ore/s(p)am?: "), _("dfrsotuzcp"))) { case -1: /* abort - don't resort */ return -1; case 1: /* (d)ate */ Sort = SORT_DATE; break; case 2: /* (f)rm */ Sort = SORT_FROM; break; case 3: /* (r)ecv */ Sort = SORT_RECEIVED; break; case 4: /* (s)ubj */ Sort = SORT_SUBJECT; break; case 5: /* t(o) */ Sort = SORT_TO; break; case 6: /* (t)hread */ Sort = SORT_THREADS; break; case 7: /* (u)nsort */ Sort = SORT_ORDER; break; case 8: /* si(z)e */ Sort = SORT_SIZE; break; case 9: /* s(c)ore */ Sort = SORT_SCORE; break; case 10: /* s(p)am */ Sort = SORT_SPAM; break; } if (reverse) Sort |= SORT_REVERSE; return (Sort != method ? 0 : -1); /* no need to resort if it's the same */}/* invoke a command in a subshell */void mutt_shell_escape (void){ char buf[LONG_STRING]; buf[0] = 0; if (mutt_get_field (_("Shell command: "), buf, sizeof (buf), M_CMD) == 0) { if (!buf[0] && Shell) strfcpy (buf, Shell, sizeof (buf)); if(buf[0]) { CLEARLINE (LINES-1); mutt_endwin (NULL); fflush (stdout); if (mutt_system (buf) != 0 || option (OPTWAITKEY)) mutt_any_key_to_continue (NULL); } }}/* enter a mutt command */void mutt_enter_command (void){ BUFFER err, token; char buffer[LONG_STRING], errbuf[SHORT_STRING]; int r; buffer[0] = 0; if (mutt_get_field (":", buffer, sizeof (buffer), M_COMMAND) != 0 || !buffer[0]) return; err.data = errbuf; err.dsize = sizeof (errbuf); memset (&token, 0, sizeof (token)); r = mutt_parse_rc_line (buffer, &token, &err); FREE (&token.data); if (errbuf[0]) { /* since errbuf could potentially contain printf() sequences in it, we must call mutt_error() in this fashion so that vsprintf() doesn't expect more arguments that we passed */ if (r == 0) mutt_message ("%s", errbuf); else mutt_error ("%s", errbuf); }}void mutt_display_address (ENVELOPE *env){ char *pfx = NULL; char buf[SHORT_STRING]; ADDRESS *adr = NULL; adr = mutt_get_address (env, &pfx); if (!adr) return; /* * Note: We don't convert IDNA to local representation this time. * That is intentional, so the user has an opportunity to copy & * paste the on-the-wire form of the address to other, IDN-unable * software. */ buf[0] = 0; rfc822_write_address (buf, sizeof (buf), adr, 0); mutt_message ("%s: %s", pfx, buf);}static void set_copy_flags (HEADER *hdr, int decode, int decrypt, int *cmflags, int *chflags){ *cmflags = 0; *chflags = CH_UPDATE_LEN; if (WithCrypto && !decode && decrypt && (hdr->security & ENCRYPT)) { if ((WithCrypto & APPLICATION_PGP) && mutt_is_multipart_encrypted(hdr->content)) { *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME; *cmflags = M_CM_DECODE_PGP; } else if ((WithCrypto & APPLICATION_PGP) && mutt_is_application_pgp (hdr->content) & ENCRYPT) decode = 1; else if ((WithCrypto & APPLICATION_SMIME) && mutt_is_application_smime(hdr->content) & ENCRYPT) { *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME; *cmflags = M_CM_DECODE_SMIME; } } if (decode) { *chflags = CH_XMIT | CH_MIME | CH_TXTPLAIN; *cmflags = M_CM_DECODE | M_CM_CHARCONV; if (!decrypt) /* If decode doesn't kick in for decrypt, */ { *chflags |= CH_DECODE; /* then decode RFC 2047 headers, */ if (option (OPTWEED)) { *chflags |= CH_WEED; /* and respect $weed. */ *cmflags |= M_CM_WEED; } } }}int _mutt_save_message (HEADER *h, CONTEXT *ctx, int delete, int decode, int decrypt){ int cmflags, chflags; int rc; set_copy_flags (h, decode, decrypt, &cmflags, &chflags); if (decode || decrypt) mutt_parse_mime_message (Context, h); if ((rc = mutt_append_message (ctx, Context, h, cmflags, chflags)) != 0) return rc; if (delete) { mutt_set_flag (Context, h, M_DELETE, 1); if (option (OPTDELETEUNTAG)) mutt_set_flag (Context, h, M_TAG, 0); } return 0;}/* returns 0 if the copy/save was successful, or -1 on error/abort */int mutt_save_message (HEADER *h, int delete, int decode, int decrypt, int *redraw){ int i, need_buffy_cleanup; int need_passphrase = 0, app=0; char prompt[SHORT_STRING], buf[_POSIX_PATH_MAX]; CONTEXT ctx; struct stat st;#ifdef BUFFY_SIZE BUFFY *tmp = NULL;#else struct utimbuf ut;#endif *redraw = 0; snprintf (prompt, sizeof (prompt), decode ? (delete ? _("Decode-save%s to mailbox") : _("Decode-copy%s to mailbox")) : (decrypt ? (delete ? _("Decrypt-save%s to mailbox") : _("Decrypt-copy%s to mailbox")) : (delete ? _("Save%s to mailbox") : _("Copy%s to mailbox"))), h ? "" : _(" tagged")); if (h) { if (WithCrypto) { need_passphrase = h->security & ENCRYPT; app = h->security; } mutt_message_hook (Context, h, M_MESSAGEHOOK); mutt_default_save (buf, sizeof (buf), h); } else { /* look for the first tagged message */ for (i = 0; i < Context->vcount; i++) { if (Context->hdrs[Context->v2r[i]]->tagged) { h = Context->hdrs[Context->v2r[i]]; break; } } if (h) { mutt_message_hook (Context, h, M_MESSAGEHOOK); mutt_default_save (buf, sizeof (buf), h); if (WithCrypto) { need_passphrase = h->security & ENCRYPT; app = h->security; } h = NULL; } } mutt_pretty_mailbox (buf); if (mutt_enter_fname (prompt, buf, sizeof (buf), redraw, 0) == -1) return (-1); if (*redraw != REDRAW_FULL) { if (!h) *redraw = REDRAW_INDEX | REDRAW_STATUS; else *redraw = REDRAW_STATUS; } if (!buf[0]) return (-1); /* This is an undocumented feature of ELM pointed out to me by Felix von * Leitner <leitner@prz.fu-berlin.de> */ if (mutt_strcmp (buf, ".") == 0) strfcpy (buf, LastSaveFolder, sizeof (buf)); else strfcpy (LastSaveFolder, buf, sizeof (LastSaveFolder)); mutt_expand_path (buf, sizeof (buf)); /* check to make sure that this file is really the one the user wants */ if (mutt_save_confirm (buf, &st) != 0) return -1; if (WithCrypto && need_passphrase && (decode || decrypt) && !crypt_valid_passphrase(app)) return -1; mutt_message (_("Copying to %s..."), buf); #ifdef USE_IMAP if (Context->magic == M_IMAP && !(decode || decrypt) && mx_is_imap (buf)) { switch (imap_copy_messages (Context, h, buf, delete)) { /* success */ case 0: mutt_clear_error (); return 0; /* non-fatal error: fall through to fetch/append */ case 1: break; /* fatal error, abort */ case -1: return -1; } }#endif if (mx_open_mailbox (buf, M_APPEND, &ctx) != NULL) { if (h) { if (_mutt_save_message(h, &ctx, delete, decode, decrypt) != 0) { mx_close_mailbox (&ctx, NULL); return -1; } } else { for (i = 0; i < Context->vcount; i++) { if (Context->hdrs[Context->v2r[i]]->tagged) { mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], M_MESSAGEHOOK); if (_mutt_save_message(Context->hdrs[Context->v2r[i]], &ctx, delete, decode, decrypt) != 0) { mx_close_mailbox (&ctx, NULL); return -1; } } } } need_buffy_cleanup = (ctx.magic == M_MBOX || ctx.magic == M_MMDF); mx_close_mailbox (&ctx, NULL); if (need_buffy_cleanup) {#ifdef BUFFY_SIZE tmp = mutt_find_mailbox (buf); if (tmp && !tmp->new) mutt_update_mailbox (tmp);#else /* fix up the times so buffy won't get confused */ if (st.st_mtime > st.st_atime) { ut.actime = st.st_atime; ut.modtime = time (NULL); utime (buf, &ut); } else utime (buf, NULL);#endif } mutt_clear_error (); return (0); } return -1;}void mutt_version (void){ mutt_message ("Mutt %s (%s)", MUTT_VERSION, ReleaseDate);}void mutt_edit_content_type (HEADER *h, BODY *b, FILE *fp){ char buf[LONG_STRING]; char obuf[LONG_STRING]; char tmp[STRING]; PARAMETER *p; char charset[STRING]; char *cp; short charset_changed = 0; short type_changed = 0; cp = mutt_get_parameter ("charset", b->parameter); strfcpy (charset, NONULL (cp), sizeof (charset)); snprintf (buf, sizeof (buf), "%s/%s", TYPE (b), b->subtype); strfcpy (obuf, buf, sizeof (obuf)); if (b->parameter) { size_t l; for (p = b->parameter; p; p = p->next) { l = strlen (buf); rfc822_cat (tmp, sizeof (tmp), p->value, MimeSpecials); snprintf (buf + l, sizeof (buf) - l, "; %s=%s", p->attribute, tmp); } } if (mutt_get_field ("Content-Type: ", buf, sizeof (buf), 0) != 0 || buf[0] == 0) return; /* clean up previous junk */ mutt_free_parameter (&b->parameter); FREE (&b->subtype); mutt_parse_content_type (buf, b); snprintf (tmp, sizeof (tmp), "%s/%s", TYPE (b), NONULL (b->subtype)); type_changed = ascii_strcasecmp (tmp, obuf); charset_changed = ascii_strcasecmp (charset, mutt_get_parameter ("charset", b->parameter)); /* if in send mode, check for conversion - current setting is default. */ if (!h && b->type == TYPETEXT && charset_changed) { int r; snprintf (tmp, sizeof (tmp), _("Convert to %s upon sending?"), mutt_get_parameter ("charset", b->parameter)); if ((r = mutt_yesorno (tmp, !b->noconv)) != -1) b->noconv = (r == M_NO); } /* inform the user */ snprintf (tmp, sizeof (tmp), "%s/%s", TYPE (b), NONULL (b->subtype)); if (type_changed) mutt_message (_("Content-Type changed to %s."), tmp); if (b->type == TYPETEXT && charset_changed) { if (type_changed) mutt_sleep (1); mutt_message (_("Character set changed to %s; %s."), mutt_get_parameter ("charset", b->parameter), b->noconv ? _("not converting") : _("converting")); } b->force_charset |= charset_changed ? 1 : 0; if (!is_multipart (b) && b->parts) mutt_free_body (&b->parts); if (!mutt_is_message_type (b->type, b->subtype) && b->hdr) { b->hdr->content = NULL; mutt_free_header (&b->hdr); } if (fp && (is_multipart (b) || mutt_is_message_type (b->type, b->subtype))) mutt_parse_part (fp, b); if (WithCrypto && h) { if (h->content == b) h->security = 0; h->security |= crypt_query (b); }}static int _mutt_check_traditional_pgp (HEADER *h, int *redraw){ MESSAGE *msg; int rv = 0; h->security |= PGP_TRADITIONAL_CHECKED; mutt_parse_mime_message (Context, h); if ((msg = mx_open_message (Context, h->msgno)) == NULL) return 0; if (crypt_pgp_check_traditional (msg->fp, h->content, 0)) { h->security = crypt_query (h->content); *redraw |= REDRAW_FULL; rv = 1; } h->security |= PGP_TRADITIONAL_CHECKED; mx_close_message (&msg); return rv;}int mutt_check_traditional_pgp (HEADER *h, int *redraw){ int i; int rv = 0; if (h && !(h->security & PGP_TRADITIONAL_CHECKED)) rv = _mutt_check_traditional_pgp (h, redraw); else { for (i = 0; i < Context->vcount; i++) if (Context->hdrs[Context->v2r[i]]->tagged && !(Context->hdrs[Context->v2r[i]]->security & PGP_TRADITIONAL_CHECKED)) rv = _mutt_check_traditional_pgp (Context->hdrs[Context->v2r[i]], redraw) || rv; } return rv;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -