⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recvattach.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org> * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org> *  *     This program is free software; you can redistribute it and/or modify *     it under the terms of the GNU General Public License as published by *     the Free Software Foundation; either version 2 of the License, or *     (at your option) any later version. *  *     This program is distributed in the hope that it will be useful, *     but WITHOUT ANY WARRANTY; without even the implied warranty of *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *     GNU General Public License for more details. *  *     You should have received a copy of the GNU General Public License *     along with this program; if not, write to the Free Software *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. */ #if HAVE_CONFIG_H# include "config.h"#endif#include "mutt.h"#include "mutt_curses.h"#include "mutt_menu.h"#include "rfc1524.h"#include "mime.h"#include "mailbox.h"#include "attach.h"#include "mapping.h"#include "mx.h"#include "copy.h"#include "mutt_crypt.h"#include <ctype.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#include <sys/stat.h>#include <string.h>#include <errno.h>static const char *Mailbox_is_read_only = N_("Mailbox is read-only.");#define CHECK_READONLY if (Context->readonly) \{\    mutt_flushinp (); \    mutt_error _(Mailbox_is_read_only); \    break; \}static struct mapping_t AttachHelp[] = {  { N_("Exit"),  OP_EXIT },  { N_("Save"),  OP_SAVE },  { N_("Pipe"),  OP_PIPE },  { N_("Print"), OP_PRINT },  { N_("Help"),  OP_HELP },  { NULL }};void mutt_update_tree (ATTACHPTR **idx, short idxlen){  char buf[STRING];  char *s;  int x;  for (x = 0; x < idxlen; x++)  {    idx[x]->num = x;    if (2 * (idx[x]->level + 2) < sizeof (buf))    {      if (idx[x]->level)      {	s = buf + 2 * (idx[x]->level - 1);	*s++ = (idx[x]->content->next) ? M_TREE_LTEE : M_TREE_LLCORNER;	*s++ = M_TREE_HLINE;	*s++ = M_TREE_RARROW;      }      else	s = buf;      *s = 0;    }    if (idx[x]->tree)    {      if (mutt_strcmp (idx[x]->tree, buf) != 0)	mutt_str_replace (&idx[x]->tree, buf);    }    else      idx[x]->tree = safe_strdup (buf);    if (2 * (idx[x]->level + 2) < sizeof (buf) && idx[x]->level)    {      s = buf + 2 * (idx[x]->level - 1);      *s++ = (idx[x]->content->next) ? '\005' : '\006';      *s++ = '\006';    }  }}ATTACHPTR **mutt_gen_attach_list (BODY *m,				  int parent_type,				  ATTACHPTR **idx,				  short *idxlen,				  short *idxmax,				  int level,				  int compose){  ATTACHPTR *new;  int i;    for (; m; m = m->next)  {    if (*idxlen == *idxmax)    {      safe_realloc (&idx, sizeof (ATTACHPTR *) * ((*idxmax) += 5));      for (i = *idxlen; i < *idxmax; i++)	idx[i] = NULL;    }    if (m->type == TYPEMULTIPART && m->parts	&& (compose || (parent_type == -1 && ascii_strcasecmp ("alternative", m->subtype)))        && (!(WithCrypto & APPLICATION_PGP) || !mutt_is_multipart_encrypted(m))	)    {      idx = mutt_gen_attach_list (m->parts, m->type, idx, idxlen, idxmax, level, compose);    }    else    {      if (!idx[*idxlen])	idx[*idxlen] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR));      new = idx[(*idxlen)++];      new->content = m;      m->aptr = new;      new->parent_type = parent_type;      new->level = level;      /* We don't support multipart messages in the compose menu yet */      if (!compose && !m->collapsed && 	  ((m->type == TYPEMULTIPART            && (!(WithCrypto & APPLICATION_PGP)                || !mutt_is_multipart_encrypted (m))	    )	   || mutt_is_message_type(m->type, m->subtype)))      {	idx = mutt_gen_attach_list (m->parts, m->type, idx, idxlen, idxmax, level + 1, compose);      }    }  }  if (level == 0)    mutt_update_tree (idx, *idxlen);  return (idx);}/* %c = character set: convert? * %C = character set * %D = deleted flag * %d = description * %e = MIME content-transfer-encoding * %f = filename * %I = content-disposition, either I (inline) or A (attachment) * %t = tagged flag * %T = tree chars * %m = major MIME type * %M = MIME subtype * %n = attachment number * %s = size * %u = unlink  */const char *mutt_attach_fmt (char *dest,    size_t destlen,    char op,    const char *src,    const char *prefix,    const char *ifstring,    const char *elsestring,    unsigned long data,    format_flag flags){  char fmt[16];  char tmp[SHORT_STRING];  char charset[SHORT_STRING];  ATTACHPTR *aptr = (ATTACHPTR *) data;  int optional = (flags & M_FORMAT_OPTIONAL);  size_t l;    switch (op)  {    case 'C':      if (!optional)      {	if (mutt_is_text_part (aptr->content) &&	    mutt_get_body_charset (charset, sizeof (charset), aptr->content))	  mutt_format_s (dest, destlen, prefix, charset);	else	  mutt_format_s (dest, destlen, prefix, "");      }      else if (!mutt_is_text_part (aptr->content) ||	       !mutt_get_body_charset (charset, sizeof (charset), aptr->content))        optional = 0;      break;    case 'c':      /* XXX */      if (!optional)      {	snprintf (fmt, sizeof (fmt), "%%%sc", prefix);	snprintf (dest, destlen, fmt, aptr->content->type != TYPETEXT ||		  aptr->content->noconv ? 'n' : 'c');      }      else if (aptr->content->type != TYPETEXT || aptr->content->noconv)        optional = 0;      break;    case 'd':      if(!optional)      {	if (aptr->content->description)	{	  mutt_format_s (dest, destlen, prefix, aptr->content->description);	  break;	}	if (mutt_is_message_type(aptr->content->type, aptr->content->subtype) &&	    MsgFmt && aptr->content->hdr)	{	  char s[SHORT_STRING];	  _mutt_make_string (s, sizeof (s), MsgFmt, NULL, aptr->content->hdr,			     M_FORMAT_FORCESUBJ | M_FORMAT_MAKEPRINT | M_FORMAT_ARROWCURSOR);	  if (*s)	  {	    mutt_format_s (dest, destlen, prefix, s);	    break;	  }	}	if (!aptr->content->filename)	{	  mutt_format_s (dest, destlen, prefix, "<no description>");	  break;	}      }      else if(aptr->content->description || 	      (mutt_is_message_type (aptr->content->type, aptr->content->subtype)	      && MsgFmt && aptr->content->hdr))        break;    /* FALLS THROUGH TO 'f' */    case 'f':      if(!optional)      {	if (aptr->content->filename && *aptr->content->filename == '/')	{	  char path[_POSIX_PATH_MAX];	  	  strfcpy (path, aptr->content->filename, sizeof (path));	  mutt_pretty_mailbox (path);	  mutt_format_s (dest, destlen, prefix, path);	}	else	  mutt_format_s (dest, destlen, prefix, NONULL (aptr->content->filename));      }      else if(!aptr->content->filename)        optional = 0;      break;    case 'D':      if(!optional)	snprintf (dest, destlen, "%c", aptr->content->deleted ? 'D' : ' ');      else if(!aptr->content->deleted)        optional = 0;      break;    case 'e':      if(!optional)	mutt_format_s (dest, destlen, prefix,		      ENCODING (aptr->content->encoding));      break;    case 'I':      if (!optional)      {	  snprintf (dest, destlen, "%c",		  (aptr->content->disposition == DISPINLINE) ? 'I' : 'A');      }      break;    case 'm':      if(!optional)	mutt_format_s (dest, destlen, prefix, TYPE (aptr->content));      break;    case 'M':      if(!optional)	mutt_format_s (dest, destlen, prefix, aptr->content->subtype);      else if(!aptr->content->subtype)        optional = 0;      break;    case 'n':      if(!optional)      {	snprintf (fmt, sizeof (fmt), "%%%sd", prefix);	snprintf (dest, destlen, fmt, aptr->num + 1);      }      break;    case 'Q':      if (optional)        optional = aptr->content->attach_qualifies;      else {	    snprintf (fmt, sizeof (fmt), "%%%sc", prefix);        mutt_format_s (dest, destlen, fmt, "Q");      }      break;    case 's':      if (flags & M_FORMAT_STAT_FILE)      {	struct stat st;	stat (aptr->content->filename, &st);	l = st.st_size;      }      else        l = aptr->content->length;            if(!optional)      {	mutt_pretty_size (tmp, sizeof(tmp), l);	mutt_format_s (dest, destlen, prefix, tmp);      }      else if (l == 0)        optional = 0;      break;    case 't':      if(!optional)        snprintf (dest, destlen, "%c", aptr->content->tagged ? '*' : ' ');      else if(!aptr->content->tagged)        optional = 0;      break;    case 'T':      if(!optional)	mutt_format_s_tree (dest, destlen, prefix, NONULL (aptr->tree));      else if (!aptr->tree)        optional = 0;      break;    case 'u':      if(!optional)        snprintf (dest, destlen, "%c", aptr->content->unlink ? '-' : ' ');      else if (!aptr->content->unlink)        optional = 0;      break;    case 'X':      if (optional)        optional = (aptr->content->attach_count + aptr->content->attach_qualifies) != 0;      else      {        snprintf (fmt, sizeof (fmt), "%%%sd", prefix);        snprintf (dest, destlen, fmt, aptr->content->attach_count + aptr->content->attach_qualifies);      }      break;    default:      *dest = 0;  }    if (optional)    mutt_FormatString (dest, destlen, ifstring, mutt_attach_fmt, data, 0);  else if (flags & M_FORMAT_OPTIONAL)    mutt_FormatString (dest, destlen, elsestring, mutt_attach_fmt, data, 0);  return (src);}void attach_entry (char *b, size_t blen, MUTTMENU *menu, int num){  mutt_FormatString (b, blen, NONULL (AttachFormat), mutt_attach_fmt, (unsigned long) (((ATTACHPTR **)menu->data)[num]), M_FORMAT_ARROWCURSOR);}int mutt_tag_attach (MUTTMENU *menu, int n, int m){  BODY *cur = ((ATTACHPTR **) menu->data)[n]->content;  int ot = cur->tagged;    cur->tagged = (m >= 0 ? m : !cur->tagged);  return cur->tagged - ot;}int mutt_is_message_type (int type, const char *subtype){  if (type != TYPEMESSAGE)    return 0;  subtype = NONULL(subtype);  return (ascii_strcasecmp (subtype, "rfc822") == 0 || ascii_strcasecmp (subtype, "news") == 0);}static int mutt_query_save_attachment (FILE *fp, BODY *body, HEADER *hdr, char **directory){  char *prompt;  char buf[_POSIX_PATH_MAX], tfile[_POSIX_PATH_MAX];  int is_message;  int append = 0;  int rc;    if (body->filename)   {    if (directory && *directory)      mutt_concat_path (buf, *directory, mutt_basename (body->filename), sizeof (buf));    else      strfcpy (buf, body->filename, sizeof (buf));  }  else if(body->hdr &&	  body->encoding != ENCBASE64 &&	  body->encoding != ENCQUOTEDPRINTABLE &&	  mutt_is_message_type(body->type, body->subtype))    mutt_default_save(buf, sizeof(buf), body->hdr);  else    buf[0] = 0;  prompt = _("Save to file: ");  while (prompt)  {    if (mutt_get_field (prompt, buf, sizeof (buf), M_FILE | M_CLEAR) != 0	|| !buf[0])      return -1;        prompt = NULL;    mutt_expand_path (buf, sizeof (buf));        is_message = (fp && 		  body->hdr && 		  body->encoding != ENCBASE64 && 		  body->encoding != ENCQUOTEDPRINTABLE && 		  mutt_is_message_type (body->type, body->subtype));        if (is_message)    {      struct stat st;            /* check to make sure that this file is really the one the user wants */      if ((rc = mutt_save_confirm (buf, &st)) == 1)      {	prompt = _("Save to file: ");	continue;      }       else if (rc == -1)	return -1;      strfcpy(tfile, buf, sizeof(tfile));    }    else    {      if ((rc = mutt_check_overwrite (body->filename, buf, tfile, sizeof (tfile), &append, directory)) == -1)	return -1;      else if (rc == 1)      {	prompt = _("Save to file: ");	continue;      }    }        mutt_message _("Saving...");    if (mutt_save_attachment (fp, body, tfile, append, (hdr || !is_message) ? hdr : body->hdr) == 0)    {      mutt_message _("Attachment saved.");      return 0;    }    else    {      prompt = _("Save to file: ");      continue;    }  }  return 0;}    void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr, MUTTMENU *menu){  char buf[_POSIX_PATH_MAX], tfile[_POSIX_PATH_MAX];  char *directory = NULL;  int rc = 1;  int last = menu ? menu->current : -1;  FILE *fpout;  buf[0] = 0;  for (; top; top = top->next)  {    if (!tag || top->tagged)    {      if (!option (OPTATTACHSPLIT))      {	if (!buf[0])	{	  int append = 0;	  strfcpy (buf, mutt_basename (NONULL (top->filename)), sizeof (buf));	  if (mutt_get_field (_("Save to file: "), buf, sizeof (buf),				    M_FILE | M_CLEAR) != 0 || !buf[0])	    return;	  mutt_expand_path (buf, sizeof (buf));	  if (mutt_check_overwrite (top->filename, buf, tfile,				    sizeof (tfile), &append, NULL))	    return;	  rc = mutt_save_attachment (fp, top, tfile, append, hdr);	  if (rc == 0 && AttachSep && (fpout = fopen (tfile,"a")) != NULL)	  {	    fprintf(fpout, "%s", AttachSep);	    fclose (fpout);	  }	}	else	{	  rc = mutt_save_attachment (fp, top, tfile, M_SAVE_APPEND, hdr);	  if (rc == 0 && AttachSep && (fpout = fopen (tfile,"a")) != NULL)	  {	    fprintf(fpout, "%s", AttachSep);	    fclose (fpout);	  }	}      }      else       {	if (tag && menu && top->aptr)	{	  menu->oldcurrent = menu->current;	  menu->current = top->aptr->num;	  menu_check_recenter (menu);	  menu->redraw |= REDRAW_MOTION;	  menu_redraw (menu);	}	if (mutt_query_save_attachment (fp, top, hdr, &directory) == -1)	  break;      }    }    else if (top->parts)      mutt_save_attachment_list (fp, 1, top->parts, hdr, menu);    if (!tag)      break;  }  FREE (&directory);  if (tag && menu)  {    menu->oldcurrent = menu->current;    menu->current = last;    menu_check_recenter (menu);    menu->redraw |= REDRAW_MOTION;  }    if (!option (OPTATTACHSPLIT) && (rc == 0))    mutt_message _("Attachment saved.");}static voidmutt_query_pipe_attachment (char *command, FILE *fp, BODY *body, int filter){  char tfile[_POSIX_PATH_MAX];  char warning[STRING+_POSIX_PATH_MAX];  if (filter)  {    snprintf (warning, sizeof (warning),	      _("WARNING!  You are about to overwrite %s, continue?"),	      body->filename);    if (mutt_yesorno (warning, M_NO) != M_YES) {      CLEARLINE (LINES-1);      return;    }    mutt_mktemp (tfile);  }  else    tfile[0] = 0;  if (mutt_pipe_attachment (fp, body, command, tfile))  {    if (filter)    {      mutt_unlink (body->filename);      mutt_rename_file (tfile, body->filename);      mutt_update_encoding (body);      mutt_message _("Attachment filtered.");    }  }  else  {    if (filter && tfile[0])      mutt_unlink (tfile);  }}static void pipe_attachment (FILE *fp, BODY *b, STATE *state){  FILE *ifp;  if (fp)  {    state->fpin = fp;    mutt_decode_attachment (b, state);    if (AttachSep)      state_puts (AttachSep, state);  }  else  {    if ((ifp = fopen (b->filename, "r")) == NULL)    {      mutt_perror ("fopen");      return;    }    mutt_copy_stream (ifp, state->fpout);    fclose (ifp);    if (AttachSep)      state_puts (AttachSep, state);  }}static voidpipe_attachment_list (char *command, FILE *fp, int tag, BODY *top, int filter,		      STATE *state){  for (; top; top = top->next)  {    if (!tag || top->tagged)    {      if (!filter && !option (OPTATTACHSPLIT))	pipe_attachment (fp, top, state);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -