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

📄 copy.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1996-2000,2002 Michael R. Elkins <me@mutt.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 "mailbox.h"#include "mx.h"#include "copy.h"#include "rfc2047.h"#include "mime.h"#include "mutt_crypt.h"#include "mutt_idna.h"#include <string.h>#include <stdlib.h>#include <ctype.h>#include <unistd.h> /* needed for SEEK_SET under SunOS 4.1.4 */static int address_header_decode (char **str);static int copy_delete_attach (BODY *b, FILE *fpin, FILE *fpout, char *date);/* Ok, the only reason for not merging this with mutt_copy_header() * below is to avoid creating a HEADER structure in message_handler(). */intmutt_copy_hdr (FILE *in, FILE *out, LOFF_T off_start, LOFF_T off_end, int flags,	       const char *prefix){  int from = 0;  int this_is_from;  int ignore = 0;  char buf[STRING]; /* should be long enough to get most fields in one pass */  char *nl;  LIST *t;  char **headers;  int hdr_count;  int x;  char *this_one = NULL;  int error;  if (ftello (in) != off_start)    fseeko (in, off_start, 0);  buf[0] = '\n';  buf[1] = 0;  if ((flags & (CH_REORDER | CH_WEED | CH_MIME | CH_DECODE | CH_PREFIX | CH_WEED_DELIVERED)) == 0)  {    /* Without these flags to complicate things     * we can do a more efficient line to line copying     */    while (ftello (in) < off_end)    {      nl = strchr (buf, '\n');      if ((fgets (buf, sizeof (buf), in)) == NULL)	break;      /* Is it the begining of a header? */      if (nl && buf[0] != ' ' && buf[0] != '\t')      {	ignore = 1;	if (!from && mutt_strncmp ("From ", buf, 5) == 0)	{	  if ((flags & CH_FROM) == 0)	    continue;	  from = 1;	}	else if (flags & (CH_NOQFROM) &&			ascii_strncasecmp (">From ", buf, 6) == 0)		continue;	else if (buf[0] == '\n' || (buf[0] == '\r' && buf[1] == '\n'))	  break; /* end of header */	if ((flags & (CH_UPDATE | CH_XMIT | CH_NOSTATUS)) &&	    (ascii_strncasecmp ("Status:", buf, 7) == 0 ||	     ascii_strncasecmp ("X-Status:", buf, 9) == 0))	  continue;	if ((flags & (CH_UPDATE_LEN | CH_XMIT | CH_NOLEN)) &&	    (ascii_strncasecmp ("Content-Length:", buf, 15) == 0 ||	     ascii_strncasecmp ("Lines:", buf, 6) == 0))	  continue;	if ((flags & CH_UPDATE_REFS) &&	    ascii_strncasecmp ("References:", buf, 11) == 0)	  continue;	if ((flags & CH_UPDATE_IRT) &&	    ascii_strncasecmp ("In-Reply-To:", buf, 12) == 0)	  continue;	ignore = 0;      }      if (!ignore && fputs (buf, out) == EOF)	return (-1);    }    return 0;  }  hdr_count = 1;  x = 0;  error = FALSE;  /* We are going to read and collect the headers in an array   * so we are able to do re-ordering.   * First count the number of entries in the array   */  if (flags & CH_REORDER)  {    for (t = HeaderOrderList; t; t = t->next)    {      dprint(1, (debugfile, "Reorder list: %s\n", t->data));      hdr_count++;    }  }  dprint (1, (debugfile, "WEED is %s\n", (flags & CH_WEED) ? "Set" : "Not"));  headers = safe_calloc (hdr_count, sizeof (char *));  /* Read all the headers into the array */  while (ftello (in) < off_end)  {    nl = strchr (buf, '\n');    /* Read a line */    if ((fgets (buf, sizeof (buf), in)) == NULL)      break;    /* Is it the begining of a header? */    if (nl && buf[0] != ' ' && buf[0] != '\t')    {      /* Do we have anything pending? */      if (this_one)      {	if (flags & CH_DECODE) 	{	  if (!address_header_decode (&this_one))	    rfc2047_decode (&this_one);	}		if (!headers[x])	  headers[x] = this_one;	else 	{	  safe_realloc (&headers[x], mutt_strlen (headers[x]) + 			mutt_strlen (this_one) + sizeof (char));	  strcat (headers[x], this_one); /* __STRCAT_CHECKED__ */	  FREE (&this_one);	}	this_one = NULL;      }      ignore = 1;      this_is_from = 0;      if (!from && mutt_strncmp ("From ", buf, 5) == 0)      {	if ((flags & CH_FROM) == 0)	  continue;	this_is_from = from = 1;      }      else if (buf[0] == '\n' || (buf[0] == '\r' && buf[1] == '\n'))	break; /* end of header */      /* note: CH_FROM takes precedence over header weeding. */      if (!((flags & CH_FROM) && (flags & CH_FORCE_FROM) && this_is_from) &&	  (flags & CH_WEED) &&	  mutt_matches_ignore (buf, Ignore) &&	  !mutt_matches_ignore (buf, UnIgnore))	continue;      if ((flags & CH_WEED_DELIVERED) &&	  ascii_strncasecmp ("Delivered-To:", buf, 13) == 0)	continue;      if ((flags & (CH_UPDATE | CH_XMIT | CH_NOSTATUS)) &&	  (ascii_strncasecmp ("Status:", buf, 7) == 0 ||	   ascii_strncasecmp ("X-Status:", buf, 9) == 0))	continue;      if ((flags & (CH_UPDATE_LEN | CH_XMIT | CH_NOLEN)) &&	  (ascii_strncasecmp ("Content-Length:", buf, 15) == 0 ||	   ascii_strncasecmp ("Lines:", buf, 6) == 0))	continue;      if ((flags & CH_MIME) &&	  ((ascii_strncasecmp ("content-", buf, 8) == 0 &&	    (ascii_strncasecmp ("transfer-encoding:", buf + 8, 18) == 0 ||	     ascii_strncasecmp ("type:", buf + 8, 5) == 0)) ||	   ascii_strncasecmp ("mime-version:", buf, 13) == 0))	continue;      if ((flags & CH_UPDATE_REFS) &&	  ascii_strncasecmp ("References:", buf, 11) == 0)	continue;      if ((flags & CH_UPDATE_IRT) &&	  ascii_strncasecmp ("In-Reply-To:", buf, 12) == 0)	continue;      /* Find x -- the array entry where this header is to be saved */      if (flags & CH_REORDER)      {	for (t = HeaderOrderList, x = 0 ; (t) ; t = t->next, x++)	{	  if (!ascii_strncasecmp (buf, t->data, mutt_strlen (t->data)))	  {	    dprint(2, (debugfile, "Reorder: %s matches %s\n", t->data, buf));	    break;	  }	}      }      ignore = 0;    } /* If beginning of header */    if (!ignore)    {      dprint (2, (debugfile, "Reorder: x = %d; hdr_count = %d\n", x, hdr_count));      if (!this_one)	this_one = safe_strdup (buf);      else      {	safe_realloc (&this_one,		      mutt_strlen (this_one) + mutt_strlen (buf) + sizeof (char));	strcat (this_one, buf); /* __STRCAT_CHECKED__ */      }    }  } /* while (ftello (in) < off_end) */  /* Do we have anything pending?  -- XXX, same code as in above in the loop. */  if (this_one)  {    if (flags & CH_DECODE)     {      if (!address_header_decode (&this_one))	rfc2047_decode (&this_one);    }        if (!headers[x])      headers[x] = this_one;    else     {      safe_realloc (&headers[x], mutt_strlen (headers[x]) + 		    mutt_strlen (this_one) + sizeof (char));      strcat (headers[x], this_one); /* __STRCAT_CHECKED__ */      FREE (&this_one);    }    this_one = NULL;  }  /* Now output the headers in order */  for (x = 0; x < hdr_count; x++)  {    if (headers[x])    {#if 0      if (flags & CH_DECODE)	rfc2047_decode (&headers[x]);#endif      /* We couldn't do the prefixing when reading because RFC 2047       * decoding may have concatenated lines.       */      if (flags & CH_PREFIX)      {	char *ch = headers[x];	int print_prefix = 1;	while (*ch)	{ 	  if (print_prefix)	  {	    if (fputs (prefix, out) == EOF)	    {	      error = TRUE;	      break;	    }	    print_prefix = 0;	  }	  if (*ch == '\n' && ch[1])	    print_prefix = 1;	  if (putc (*ch++, out) == EOF)	  {	    error = TRUE;	    break;	  }	}	if (error)	  break;      }      else      {      	if (fputs (headers[x], out) == EOF)	{	  error = TRUE;	  break;	}      }    }  }  /* Free in a separate loop to be sure that all headers are freed   * in case of error. */  for (x = 0; x < hdr_count; x++)    FREE (&headers[x]);  FREE (&headers);  if (error)    return (-1);  return (0);}/* flags 	CH_DECODE	RFC2047 header decoding 	CH_FROM		retain the "From " message separator        CH_FORCE_FROM	give CH_FROM precedence over CH_WEED 	CH_MIME		ignore MIME fields	CH_NOLEN	don't write Content-Length: and Lines: 	CH_NONEWLINE	don't output a newline after the header 	CH_NOSTATUS	ignore the Status: and X-Status: 	CH_PREFIX	quote header with $indent_str 	CH_REORDER	output header in order specified by `hdr_order'  	CH_TXTPLAIN	generate text/plain MIME headers [hack alert.] 	CH_UPDATE	write new Status: and X-Status: 	CH_UPDATE_LEN	write new Content-Length: and Lines: 	CH_XMIT		ignore Lines: and Content-Length: 	CH_WEED		do header weeding	CH_NOQFROM      ignore ">From " line	CH_UPDATE_IRT	update the In-Reply-To: header	CH_UPDATE_REFS	update the References: header   prefix   	string to use if CH_PREFIX is set */intmutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix){  char buffer[SHORT_STRING];  if (h->env)    flags |= (h->env->irt_changed ? CH_UPDATE_IRT : 0)      | (h->env->refs_changed ? CH_UPDATE_REFS : 0);    if (mutt_copy_hdr (in, out, h->offset, h->content->offset, flags, prefix) == -1)    return (-1);  if (flags & CH_TXTPLAIN)  {    char chsbuf[SHORT_STRING];    fputs ("MIME-Version: 1.0\n", out);    fputs ("Content-Transfer-Encoding: 8bit\n", out);    fputs ("Content-Type: text/plain; charset=", out);    mutt_canonical_charset (chsbuf, sizeof (chsbuf), Charset ? Charset : "us-ascii");    rfc822_cat(buffer, sizeof(buffer), chsbuf, MimeSpecials);    fputs(buffer, out);    fputc('\n', out);        if (ferror (out) != 0 || feof (out) != 0)      return -1;      }  if (flags & CH_UPDATE)  {    if ((flags & CH_NOSTATUS) == 0)    {      if (h->env->irt_changed && h->env->in_reply_to)      {	LIST *listp = h->env->in_reply_to;	if (fputs ("In-Reply-To: ", out) == EOF)	  return (-1);	for (; listp; listp = listp->next)	  if ((fputs (listp->data, out) == EOF) || (fputc (' ', out) == EOF))	    return (-1);	if (fputc ('\n', out) == EOF)	  return (-1);      }      if (h->env->refs_changed && h->env->references)      {	LIST *listp = h->env->references, *refs = NULL, *t;	if (fputs ("References: ", out) == EOF)	  return (-1);	/* Mutt stores references in reverse order, thus we create	 * a reordered refs list that we can put in the headers */	for (; listp; listp = listp->next, refs = t)	{	  t = (LIST *)safe_malloc (sizeof (LIST));	  t->data = listp->data;	  t->next = refs;	}	for (; refs; refs = refs->next)	  if ((fputs (refs->data, out) == EOF) || (fputc (' ', out) == EOF))	    return (-1);	/* clearing refs from memory */	for (t = refs; refs; refs = t->next, t = refs)	  FREE (&refs);	if (fputc ('\n', out) == EOF)	  return (-1);      }      if (h->old || h->read)      {	if (fputs ("Status: ", out) == EOF)	  return (-1);	if (h->read)	{	  if (fputs ("RO", out) == EOF)	    return (-1);	}	else if (h->old)	{	  if (fputc ('O', out) == EOF)	    return (-1);	}	if (fputc ('\n', out) == EOF)	  return (-1);      }      if (h->flagged || h->replied)      {	if (fputs ("X-Status: ", out) == EOF)	  return (-1);	if (h->replied)	{	  if (fputc ('A', out) == EOF)	    return (-1);	}	if (h->flagged)	{	  if (fputc ('F', out) == EOF)	    return (-1);	}		if (fputc ('\n', out) == EOF)	  return (-1);      }    }  }  if (flags & CH_UPDATE_LEN &&      (flags & CH_NOLEN) == 0)  {    fprintf (out, "Content-Length: " OFF_T_FMT "\n", h->content->length);    if (h->lines != 0 || h->content->length == 0)      fprintf (out, "Lines: %d\n", h->lines);  }  if ((flags & CH_NONEWLINE) == 0)  {    if (flags & CH_PREFIX)      fputs(prefix, out);    if (fputc ('\n', out) == EOF) /* add header terminator */      return (-1);  }  if (ferror (out) || feof (out))    return -1;    return (0);}/* Count the number of lines and bytes to be deleted in this body*/static int count_delete_lines (FILE *fp, BODY *b, LOFF_T *length, size_t datelen){  int dellines = 0;  long l;  int ch;  if (b->deleted)  {

⌨️ 快捷键说明

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