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

📄 attach.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_menu.h"#include "attach.h"#include "mutt_curses.h"#include "keymap.h"#include "rfc1524.h"#include "mime.h"#include "pager.h"#include "mailbox.h"#include "copy.h"#include "mx.h"#include "mutt_crypt.h"#include <ctype.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <errno.h>int mutt_get_tmp_attachment (BODY *a){  char type[STRING];  char tempfile[_POSIX_PATH_MAX];  rfc1524_entry *entry = rfc1524_new_entry();  FILE *fpin = NULL, *fpout = NULL;  struct stat st;    if(a->unlink)    return 0;  snprintf(type, sizeof(type), "%s/%s", TYPE(a), a->subtype);  rfc1524_mailcap_lookup(a, type, entry, 0);  rfc1524_expand_filename(entry->nametemplate, a->filename, 			  tempfile, sizeof(tempfile));    rfc1524_free_entry(&entry);  if(stat(a->filename, &st) == -1)    return -1;  if((fpin = fopen(a->filename, "r")) && (fpout = safe_fopen(tempfile, "w")))  /* __FOPEN_CHECKED__ */  {    mutt_copy_stream (fpin, fpout);    mutt_str_replace (&a->filename, tempfile);    a->unlink = 1;    if(a->stamp >= st.st_mtime)      mutt_stamp_attachment(a);  }  else    mutt_perror(fpin ? tempfile : a->filename);    if(fpin)  fclose(fpin);  if(fpout) fclose(fpout);    return a->unlink ? 0 : -1;}/* return 1 if require full screen redraw, 0 otherwise */int mutt_compose_attachment (BODY *a){  char type[STRING];  char command[STRING];  char newfile[_POSIX_PATH_MAX] = "";  rfc1524_entry *entry = rfc1524_new_entry ();  short unlink_newfile = 0;  int rc = 0;    snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);  if (rfc1524_mailcap_lookup (a, type, entry, M_COMPOSE))  {    if (entry->composecommand || entry->composetypecommand)    {      if (entry->composetypecommand)	strfcpy (command, entry->composetypecommand, sizeof (command));      else 	strfcpy (command, entry->composecommand, sizeof (command));      if (rfc1524_expand_filename (entry->nametemplate,				      a->filename, newfile, sizeof (newfile)))      {	dprint(1, (debugfile, "oldfile: %s\t newfile: %s\n",				  a->filename, newfile));	if (safe_symlink (a->filename, newfile) == -1)	{	  if (mutt_yesorno (_("Can't match nametemplate, continue?"), M_YES) != M_YES)	    goto bailout;	}	else	  unlink_newfile = 1;      }      else	strfcpy(newfile, a->filename, sizeof(newfile));            if (rfc1524_expand_command (a, newfile, type,				      command, sizeof (command)))      {	/* For now, editing requires a file, no piping */	mutt_error _("Mailcap compose entry requires %%s");      }      else      {	int r;	mutt_endwin (NULL);	if ((r = mutt_system (command)) == -1)	  mutt_error (_("Error running \"%s\"!"), command);		if (r != -1 && entry->composetypecommand)	{	  BODY *b;	  FILE *fp, *tfp;	  char tempfile[_POSIX_PATH_MAX];	  if ((fp = safe_fopen (a->filename, "r")) == NULL)	  {	    mutt_perror _("Failure to open file to parse headers.");	    goto bailout;	  }	  b = mutt_read_mime_header (fp, 0);	  if (b)	  {	    if (b->parameter)	    {	      mutt_free_parameter (&a->parameter);	      a->parameter = b->parameter;	      b->parameter = NULL;	    }	    if (b->description) {	      FREE (&a->description);	      a->description = b->description;	      b->description = NULL;	    }	    if (b->form_name)	    {	      FREE (&a->form_name);	      a->form_name = b->form_name;	      b->form_name = NULL;	    }	    /* Remove headers by copying out data to another file, then 	     * copying the file back */	    fseeko (fp, b->offset, 0);	    mutt_mktemp (tempfile);	    if ((tfp = safe_fopen (tempfile, "w")) == NULL)	    {	      mutt_perror _("Failure to open file to strip headers.");	      goto bailout;	    }	    mutt_copy_stream (fp, tfp);	    fclose (fp);	    fclose (tfp);	    mutt_unlink (a->filename);  	    if (mutt_rename_file (tempfile, a->filename) != 0) 	    {	      mutt_perror _("Failure to rename file.");	      goto bailout;	    }	    mutt_free_body (&b);	  }	}      }    }  }  else  {    rfc1524_free_entry (&entry);    mutt_message (_("No mailcap compose entry for %s, creating empty file."),		   type);    return 1;  }  rc = 1;    bailout:    if(unlink_newfile)    unlink(newfile);  rfc1524_free_entry (&entry);  return rc;}/*  * Currently, this only works for send mode, as it assumes that the  * BODY->filename actually contains the information.  I'm not sure * we want to deal with editing attachments we've already received, * so this should be ok. * * Returns 1 if editor found, 0 if not (useful to tell calling menu to * redraw) */int mutt_edit_attachment (BODY *a){  char type[STRING];  char command[STRING];  char newfile[_POSIX_PATH_MAX] = "";  rfc1524_entry *entry = rfc1524_new_entry ();  short unlink_newfile = 0;  int rc = 0;    snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);  if (rfc1524_mailcap_lookup (a, type, entry, M_EDIT))  {    if (entry->editcommand)    {      strfcpy (command, entry->editcommand, sizeof (command));      if (rfc1524_expand_filename (entry->nametemplate,				      a->filename, newfile, sizeof (newfile)))      {	dprint(1, (debugfile, "oldfile: %s\t newfile: %s\n",				  a->filename, newfile));	if (safe_symlink (a->filename, newfile) == -1)	{	  if (mutt_yesorno (_("Can't match nametemplate, continue?"), M_YES) != M_YES)	    goto bailout;	}	else	  unlink_newfile = 1;      }      else	strfcpy(newfile, a->filename, sizeof(newfile));      if (rfc1524_expand_command (a, newfile, type,				      command, sizeof (command)))      {	/* For now, editing requires a file, no piping */	mutt_error _("Mailcap Edit entry requires %%s");        goto bailout;      }      else      {	mutt_endwin (NULL);	if (mutt_system (command) == -1)        {	  mutt_error (_("Error running \"%s\"!"), command);          goto bailout;        }      }    }  }  else if (a->type == TYPETEXT)  {    /* On text, default to editor */    mutt_edit_file (NONULL (Editor), a->filename);  }  else  {    rfc1524_free_entry (&entry);    mutt_error (_("No mailcap edit entry for %s"),type);    return 0;  }  rc = 1;    bailout:    if(unlink_newfile)    unlink(newfile);    rfc1524_free_entry (&entry);  return rc;}/* for compatibility with metamail */static int is_mmnoask (const char *buf){  char tmp[LONG_STRING], *p, *q;  int lng;  if ((p = getenv ("MM_NOASK")) != NULL && *p)  {    if (mutt_strcmp (p, "1") == 0)      return (1);    strfcpy (tmp, p, sizeof (tmp));    p = tmp;    while ((p = strtok (p, ",")) != NULL)    {      if ((q = strrchr (p, '/')) != NULL)      {	if (*(q+1) == '*')	{	  if (ascii_strncasecmp (buf, p, q-p) == 0)	    return (1);	}	else	{	  if (ascii_strcasecmp (buf, p) == 0)	    return (1);	}      }      else      {	lng = mutt_strlen (p);	if (buf[lng] == '/' && mutt_strncasecmp (buf, p, lng) == 0)	  return (1);      }      p = NULL;    }  }  return (0);}void mutt_check_lookup_list (BODY *b, char *type, int len){  LIST *t = MimeLookupList;  int i;  for (; t; t = t->next) {    i = mutt_strlen (t->data) - 1;    if ((i > 0 && t->data[i-1] == '/' && t->data[i] == '*' && 	 ascii_strncasecmp (type, t->data, i) == 0) ||	ascii_strcasecmp (type, t->data) == 0) {    BODY tmp = {0};    int n;    if ((n = mutt_lookup_mime_type (&tmp, b->filename)) != TYPEOTHER) {      snprintf (type, len, "%s/%s",                n == TYPEAUDIO ? "audio" :                n == TYPEAPPLICATION ? "application" :                n == TYPEIMAGE ? "image" :                n == TYPEMESSAGE ? "message" :                n == TYPEMODEL ? "model" :                n == TYPEMULTIPART ? "multipart" :                n == TYPETEXT ? "text" :                n == TYPEVIDEO ? "video" : "other",                tmp.subtype);      dprint(1, (debugfile, "mutt_check_lookup_list: \"%s\" -> %s\n",         b->filename, type));    }    if (tmp.subtype)       FREE (&tmp.subtype);    if (tmp.xtype)       FREE (&tmp.xtype);    }  }}int mutt_is_autoview (BODY *b, const char *type){  LIST *t = AutoViewList;  char _type[SHORT_STRING];  int i;  if (!type)    snprintf (_type, sizeof (_type), "%s/%s", TYPE (b), b->subtype);  else    strncpy (_type, type, sizeof(_type));  mutt_check_lookup_list (b, _type, sizeof(_type));  type = _type;  if (mutt_needs_mailcap (b))  {    if (option (OPTIMPLICITAUTOVIEW))      return 1;        if (is_mmnoask (type))      return 1;  }  for (; t; t = t->next) {    i = mutt_strlen (t->data) - 1;    if ((i > 0 && t->data[i-1] == '/' && t->data[i] == '*' && 	 ascii_strncasecmp (type, t->data, i) == 0) ||	ascii_strcasecmp (type, t->data) == 0)      return 1;  }  return 0;}/* returns -1 on error, 0 or the return code from mutt_do_pager() on success */int mutt_view_attachment (FILE *fp, BODY *a, int flag, HEADER *hdr,			  ATTACHPTR **idx, short idxlen){  char tempfile[_POSIX_PATH_MAX] = "";  char pagerfile[_POSIX_PATH_MAX] = "";  int is_message;  int use_mailcap;  int use_pipe = 0;  int use_pager = 1;  char type[STRING];  char command[STRING];  char descrip[STRING];  char *fname;  rfc1524_entry *entry = NULL;  int rc = -1;  int unlink_tempfile = 0;    is_message = mutt_is_message_type(a->type, a->subtype);  if (WithCrypto && is_message && a->hdr && (a->hdr->security & ENCRYPT) &&      !crypt_valid_passphrase(a->hdr->security))    return (rc);  use_mailcap = (flag == M_MAILCAP ||		(flag == M_REGULAR && mutt_needs_mailcap (a)));  snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);    if (use_mailcap)  {    entry = rfc1524_new_entry ();     if (!rfc1524_mailcap_lookup (a, type, entry, 0))    {      if (flag == M_REGULAR)      {	/* fallback to view as text */	rfc1524_free_entry (&entry);	mutt_error _("No matching mailcap entry found.  Viewing as text.");	flag = M_AS_TEXT;	use_mailcap = 0;      }      else	goto return_error;    }  }    if (use_mailcap)  {    if (!entry->command)    {      mutt_error _("MIME type not defined.  Cannot view attachment.");      goto return_error;    }    strfcpy (command, entry->command, sizeof (command));        if (fp)    {      fname = safe_strdup (a->filename);      mutt_sanitize_filename (fname, 1);    }    else      fname = a->filename;    if (rfc1524_expand_filename (entry->nametemplate, fname,				 tempfile, sizeof (tempfile)))    {      if (fp == NULL && mutt_strcmp(tempfile, a->filename))      {	/* send case: the file is already there */	if (safe_symlink (a->filename, tempfile) == -1)	{	  if (mutt_yesorno (_("Can't match nametemplate, continue?"), M_YES) == M_YES)	    strfcpy (tempfile, a->filename, sizeof (tempfile));	  else	    goto return_error;	}	else	  unlink_tempfile = 1;      }    }    else if (fp == NULL) /* send case */      strfcpy (tempfile, a->filename, sizeof (tempfile));        if (fp)    {      /* recv case: we need to save the attachment to a file */      FREE (&fname);      if (mutt_save_attachment (fp, a, tempfile, 0, NULL) == -1)	goto return_error;    }    use_pipe = rfc1524_expand_command (a, tempfile, type,				       command, sizeof (command));    use_pager = entry->copiousoutput;  }    if (use_pager)  {    if (fp && !use_mailcap && a->filename)    {      /* recv case */      strfcpy (pagerfile, a->filename, sizeof (pagerfile));      mutt_adv_mktemp (pagerfile, sizeof(pagerfile));    }    else      mutt_mktemp (pagerfile);  }      if (use_mailcap)  {    pid_t thepid = 0;    int tempfd = -1, pagerfd = -1;        if (!use_pager)      mutt_endwin (NULL);    if (use_pager || use_pipe)    {      if (use_pager && ((pagerfd = safe_open (pagerfile, O_CREAT | O_EXCL | O_WRONLY)) == -1))      {	mutt_perror ("open");	goto return_error;      }      if (use_pipe && ((tempfd = open (tempfile, 0)) == -1))      {	if(pagerfd != -1)	  close(pagerfd);	mutt_perror ("open");	goto return_error;      }      if ((thepid = mutt_create_filter_fd (command, NULL, NULL, NULL,					   use_pipe ? tempfd : -1, use_pager ? pagerfd : -1, -1)) == -1)      {	if(pagerfd != -1)	  close(pagerfd);		if(tempfd != -1)

⌨️ 快捷键说明

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