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

📄 sendlib.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 4 页
字号:
 * We assume that the output from iconv is never more than 4 times as * long as the input for any pair of charsets we might be interested * in. */static size_t convert_file_to (FILE *file, const char *fromcode,			       int ncodes, const char **tocodes,			       int *tocode, CONTENT *info){#ifdef HAVE_ICONV  iconv_t cd1, *cd;  char bufi[256], bufu[512], bufo[4 * sizeof (bufi)];  ICONV_CONST char *ib, *ub;  char *ob;  size_t ibl, obl, ubl, ubl1, n, ret;  int i;  CONTENT *infos;  CONTENT_STATE *states;  size_t *score;  cd1 = mutt_iconv_open ("UTF-8", fromcode, 0);  if (cd1 == (iconv_t)(-1))    return -1;  cd     = safe_calloc (ncodes, sizeof (iconv_t));  score  = safe_calloc (ncodes, sizeof (size_t));  states = safe_calloc (ncodes, sizeof (CONTENT_STATE));  infos  = safe_calloc (ncodes, sizeof (CONTENT));  for (i = 0; i < ncodes; i++)    if (ascii_strcasecmp (tocodes[i], "UTF-8"))      cd[i] = mutt_iconv_open (tocodes[i], "UTF-8", 0);    else      /* Special case for conversion to UTF-8 */      cd[i] = (iconv_t)(-1), score[i] = (size_t)(-1);  rewind (file);  ibl = 0;  for (;;)  {    /* Try to fill input buffer */    n = fread (bufi + ibl, 1, sizeof (bufi) - ibl, file);    ibl += n;    /* Convert to UTF-8 */    ib = bufi;    ob = bufu, obl = sizeof (bufu);    n = iconv (cd1, ibl ? &ib : 0, &ibl, &ob, &obl);    assert (n == (size_t)(-1) || !n || ICONV_NONTRANS);    if (n == (size_t)(-1) &&	((errno != EINVAL && errno != E2BIG) || ib == bufi))    {      assert (errno == EILSEQ ||	      (errno == EINVAL && ib == bufi && ibl < sizeof (bufi)));      ret = (size_t)(-1);      break;    }    ubl1 = ob - bufu;    /* Convert from UTF-8 */    for (i = 0; i < ncodes; i++)      if (cd[i] != (iconv_t)(-1) && score[i] != (size_t)(-1))      {	ub = bufu, ubl = ubl1;	ob = bufo, obl = sizeof (bufo);	n = iconv (cd[i], (ibl || ubl) ? &ub : 0, &ubl, &ob, &obl);	if (n == (size_t)(-1))	{	  assert (errno == E2BIG ||		  (BUGGY_ICONV && (errno == EILSEQ || errno == ENOENT)));	  score[i] = (size_t)(-1);	}	else	{	  score[i] += n;	  update_content_info (&infos[i], &states[i], bufo, ob - bufo);	}      }      else if (cd[i] == (iconv_t)(-1) && score[i] == (size_t)(-1))	/* Special case for conversion to UTF-8 */	update_content_info (&infos[i], &states[i], bufu, ubl1);    if (ibl)      /* Save unused input */      memmove (bufi, ib, ibl);    else if (!ubl1 && ib < bufi + sizeof (bufi))    {      ret = 0;      break;    }  }  if (!ret)  {    /* Find best score */    ret = (size_t)(-1);    for (i = 0; i < ncodes; i++)    {      if (cd[i] == (iconv_t)(-1) && score[i] == (size_t)(-1))      {	/* Special case for conversion to UTF-8 */	*tocode = i;	ret = 0;	break;      }      else if (cd[i] == (iconv_t)(-1) || score[i] == (size_t)(-1))	continue;      else if (ret == (size_t)(-1) || score[i] < ret)      {	*tocode = i;	ret = score[i];	if (!ret)	  break;      }    }    if (ret != (size_t)(-1))    {      memcpy (info, &infos[*tocode], sizeof(CONTENT));      update_content_info (info, &states[*tocode], 0, 0); /* EOF */    }  }  for (i = 0; i < ncodes; i++)    if (cd[i] != (iconv_t)(-1))      iconv_close (cd[i]);  iconv_close (cd1);  FREE (&cd);  FREE (&infos);  FREE (&score);  FREE (&states);  return ret;#else  return -1;#endif /* !HAVE_ICONV */}/* * Find the first of the fromcodes that gives a valid conversion and * the best charset conversion of the file into one of the tocodes. If * successful, set *fromcode and *tocode to dynamically allocated * strings, set CONTENT *info, and return the number of characters * converted inexactly. If no conversion was possible, return -1. * * Both fromcodes and tocodes may be colon-separated lists of charsets. * However, if fromcode is zero then fromcodes is assumed to be the * name of a single charset even if it contains a colon. */static size_t convert_file_from_to (FILE *file,				    const char *fromcodes, const char *tocodes,				    char **fromcode, char **tocode, CONTENT *info){  char *fcode;  char **tcode;  const char *c, *c1;  size_t ret;  int ncodes, i, cn;  /* Count the tocodes */  ncodes = 0;  for (c = tocodes; c; c = c1 ? c1 + 1 : 0)  {    if ((c1 = strchr (c, ':')) == c)      continue;    ++ncodes;  }  /* Copy them */  tcode = safe_malloc (ncodes * sizeof (char *));  for (c = tocodes, i = 0; c; c = c1 ? c1 + 1 : 0, i++)  {    if ((c1 = strchr (c, ':')) == c)      continue;    tcode[i] = mutt_substrdup (c, c1);  }  ret = (size_t)(-1);  if (fromcode)  {    /* Try each fromcode in turn */    for (c = fromcodes; c; c = c1 ? c1 + 1 : 0)    {      if ((c1 = strchr (c, ':')) == c)	continue;      fcode = mutt_substrdup (c, c1);            ret = convert_file_to (file, fcode, ncodes, (const char **)tcode,			     &cn, info);      if (ret != (size_t)(-1))      {	*fromcode = fcode;	*tocode = tcode[cn];	tcode[cn] = 0;	break;      }      FREE (&fcode);    }  }  else  {    /* There is only one fromcode */    ret = convert_file_to (file, fromcodes, ncodes, (const char **)tcode,			   &cn, info);    if (ret != (size_t)(-1))    {      *tocode = tcode[cn];      tcode[cn] = 0;    }  }  /* Free memory */  for (i = 0; i < ncodes; i++)    FREE (&tcode[i]);  FREE (tcode);		/* __FREE_CHECKED__ */    return ret;}/*  * Analyze the contents of a file to determine which MIME encoding to use. * Also set the body charset, sometimes, or not. */CONTENT *mutt_get_content_info (const char *fname, BODY *b){  CONTENT *info;  CONTENT_STATE state;  FILE *fp = NULL;  char *tocode;  char buffer[100];  char chsbuf[STRING];  size_t r;  struct stat sb;    if(b && !fname) fname = b->filename;  if (stat (fname, &sb) == -1)  {    mutt_error (_("Can't stat %s: %s"), fname, strerror (errno));    return NULL;  }    if (!S_ISREG(sb.st_mode))  {    mutt_error (_("%s isn't a regular file."), fname);    return NULL;  }    if ((fp = fopen (fname, "r")) == NULL)  {    dprint (1, (debugfile, "mutt_get_content_info: %s: %s (errno %d).\n",		fname, strerror (errno), errno));    return (NULL);  }  info = safe_calloc (1, sizeof (CONTENT));  memset (&state, 0, sizeof (state));    if (b != NULL && b->type == TYPETEXT && (!b->noconv && !b->force_charset))  {    char *chs = mutt_get_parameter ("charset", b->parameter);    if (Charset && (chs || SendCharset) &&	convert_file_from_to (fp, Charset, chs ? chs : SendCharset,			      0, &tocode, info) != (size_t)(-1))    {      if (!chs)      {	mutt_canonical_charset (chsbuf, sizeof (chsbuf), tocode);	mutt_set_parameter ("charset", chsbuf, &b->parameter);      }      FREE (&tocode);      safe_fclose (&fp);      return info;    }  }  rewind (fp);  while ((r = fread (buffer, 1, sizeof(buffer), fp)))    update_content_info (info, &state, buffer, r);  update_content_info (info, &state, 0, 0);  safe_fclose (&fp);    if (b != NULL && b->type == TYPETEXT && (!b->noconv && !b->force_charset))    mutt_set_parameter ("charset", (!info->hibin ? "us-ascii" :				    Charset  && !mutt_is_us_ascii (Charset) ? Charset : "unknown-8bit"),			&b->parameter);  return info;}/* Given a file with path ``s'', see if there is a registered MIME type. * returns the major MIME type, and copies the subtype to ``d''.  First look * for ~/.mime.types, then look in a system mime.types if we can find one. * The longest match is used so that we can match `ps.gz' when `gz' also * exists. */int mutt_lookup_mime_type (BODY *att, const char *path){  FILE *f;  char *p, *q, *ct;  char buf[LONG_STRING];  char subtype[STRING], xtype[STRING];  int count;  int szf, sze, cur_sze;  int type;  *subtype = '\0';  *xtype   = '\0';  type     = TYPEOTHER;  cur_sze  = 0;  szf      = mutt_strlen (path);  for (count = 0 ; count < 3 ; count++)  {    /*     * can't use strtok() because we use it in an inner loop below, so use     * a switch statement here instead.     */    switch (count)    {      case 0:	snprintf (buf, sizeof (buf), "%s/.mime.types", NONULL(Homedir));	break;      case 1:	strfcpy (buf, SYSCONFDIR"/mime.types", sizeof(buf));	break;      case 2:	strfcpy (buf, PKGDATADIR"/mime.types", sizeof (buf));	break;      default:        dprint (1, (debugfile, "mutt_lookup_mime_type: Internal error, count = %d.\n", count));	goto bye;	/* shouldn't happen */    }    if ((f = fopen (buf, "r")) != NULL)    {      while (fgets (buf, sizeof (buf) - 1, f) != NULL)      {	/* weed out any comments */	if ((p = strchr (buf, '#')))	  *p = 0;	/* remove any leading space. */	ct = buf;	SKIPWS (ct);	/* position on the next field in this line */	if ((p = strpbrk (ct, " \t")) == NULL)	  continue;	*p++ = 0;	SKIPWS (p);	/* cycle through the file extensions */	while ((p = strtok (p, " \t\n")))	{	  sze = mutt_strlen (p);	  if ((sze > cur_sze) && (szf >= sze) &&	      (mutt_strcasecmp (path + szf - sze, p) == 0 || ascii_strcasecmp (path + szf - sze, p) == 0) &&	      (szf == sze || path[szf - sze - 1] == '.'))	  {	    /* get the content-type */	    if ((p = strchr (ct, '/')) == NULL)	    {	      /* malformed line, just skip it. */	      break;	    }	    *p++ = 0;	    for (q = p; *q && !ISSPACE (*q); q++)	      ;	    	    mutt_substrcpy (subtype, p, q, sizeof (subtype));	    if ((type = mutt_check_mime_type (ct)) == TYPEOTHER)	      strfcpy (xtype, ct, sizeof (xtype));	    cur_sze = sze;	  }	  p = NULL;	}      }      fclose (f);    }  }   bye:  if (type != TYPEOTHER || *xtype != '\0')  {    att->type = type;    mutt_str_replace (&att->subtype, subtype);    mutt_str_replace (&att->xtype, xtype);  }    return (type);}void mutt_message_to_7bit (BODY *a, FILE *fp){  char temp[_POSIX_PATH_MAX];  char *line = NULL;  FILE *fpin = NULL;  FILE *fpout = NULL;  struct stat sb;  if (!a->filename && fp)    fpin = fp;  else if (!a->filename || !(fpin = fopen (a->filename, "r")))  {    mutt_error (_("Could not open %s"), a->filename ? a->filename : "(null)");    return;  }   else  {    a->offset = 0;    if (stat (a->filename, &sb) == -1)    {      mutt_perror ("stat");      fclose (fpin);    }    a->length = sb.st_size;  }  mutt_mktemp (temp);  if (!(fpout = safe_fopen (temp, "w+")))  {    mutt_perror ("fopen");    goto cleanup;  }  fseeko (fpin, a->offset, 0);  a->parts = mutt_parse_messageRFC822 (fpin, a);  transform_to_7bit (a->parts, fpin);    mutt_copy_hdr (fpin, fpout, a->offset, a->offset + a->length, 		 CH_MIME | CH_NONEWLINE | CH_XMIT, NULL);  fputs ("MIME-Version: 1.0\n", fpout);  mutt_write_mime_header (a->parts, fpout);  fputc ('\n', fpout);  mutt_write_mime_body (a->parts, fpout);   cleanup:  FREE (&line);  if (fpin && !fp)    fclose (fpin);  if (fpout)    fclose (fpout);  else    return;    a->encoding = ENC7BIT;  a->d_filename = a->filename;  if (a->filename && a->unlink)    unlink (a->filename);  a->filename = safe_strdup (temp);  a->unlink = 1;  if(stat (a->filename, &sb) == -1)   {    mutt_perror ("stat");    return;  }  a->length = sb.st_size;  mutt_free_body (&a->parts);  a->hdr->content = NULL;}static void transform_to_7bit (BODY *a, FILE *fpin){  char buff[_POSIX_PATH_MAX];  STATE s;  struct stat sb;  memset (&s, 0, sizeof (s));  for (; a; a = a->next)  {    if (a->type == TYPEMULTIPART)    {      if (a->encoding != ENC7BIT)	a->encoding = ENC7BIT;      transform_to_7bit (a->parts, fpin);    }     else if (mutt_is_message_type(a->type, a->subtype))    {      mutt_message_to_7bit (a, fpin);    }    else     {      a->noconv = 1;      a->force_charset = 1;            mutt_mktemp (buff);      if ((s.fpout = safe_fopen (buff, "w")) == NULL)       {	mutt_perror ("fopen");	return;      }      s.fpin = fpin;      mutt_decode_attachment (a, &s);      fclose (s.fpout);      a->d_filename = a->filename;      a->filename = safe_strdup (buff);      a->unlink = 1;      if (stat (a->filename, &sb) == -1)       {	mutt_perror ("stat");	return;      }      a->length = sb.st_size;      mutt_update_encoding (a);      if (a->encoding == ENC8BIT)	a->encoding = ENCQUOTEDPRINTABLE;      else if(a->encoding == ENCBINARY)	a->encoding = ENCBASE64;    }  }}/* determine which Content-Transfer-Encoding to use */static void mutt_set_encoding (BODY *b, CONTENT *info){  char send_charset[SHORT_STRING];  if (b->type == TYPETEXT)  {    char *chsname = mutt_get_body_charset (send_charset, sizeof (send_charset), b);    if ((info->lobin && ascii_strncasecmp (chsname, "iso-2022", 8)) || info->linemax > 990 || (info->from && option (OPTENCODEFROM)))      b->encoding = ENCQUOTEDPRINTABLE;    else if (info->hibin)      b->encoding = option (OPTALLOW8BIT) ? ENC8BIT : ENCQUOTEDPRINTABLE;    else      b->encoding = ENC7BIT;  }  else if (b->type == TYPEMESSAGE || b->type == TYPEMULTIPART)  {    if (info->lobin || info->hibin)    {      if (option (OPTALLOW8BIT) && !info->lobin)	b->encoding = ENC8BIT;       else	mutt_message_to_7bit (b, NULL);    }    else      b->encoding = ENC7BIT;  }  else if (b->type == TYPEAPPLICATION && ascii_strcasecmp (b->subtype, "pgp-keys") == 0)    b->encoding = ENC7BIT;  else#if 0    if (info->lobin || info->hibin || info->binary || info->linemax > 990	   || info->cr || (/* option (OPTENCODEFROM) && */ info->from))#endif  {    /* Determine which encoding is smaller  */    if (1.33 * (float)(info->lobin+info->hibin+info->ascii) < 	 3.0 * (float)(info->lobin + info->hibin) + (float)info->ascii)      b->encoding = ENCBASE64;    else      b->encoding = ENCQUOTEDPRINTABLE;  }#if 0  else    b->encoding = ENC7BIT;#endif}void mutt_stamp_attachment(BODY *a){  a->stamp = time(NULL);}/* Get a body's character set */char *mutt_get_body_charset (char *d, size_t dlen, BODY *b){  char *p = NULL;  if (b && b->type != TYPETEXT)    return NULL;  if (b)     p = mutt_get_parameter ("charset", b->parameter);  if (p)    mutt_canonical_charset (d, dlen, NONULL(p));  else    strfcpy (d, "us-ascii", dlen);  return d;}/* Assumes called from send mode where BODY->filename points to actual file */void mutt_update_encoding (BODY *a){  CONTENT *info;  char chsbuff[STRING];  /* override noconv when it's us-ascii */  if (mutt_is_us_ascii (mutt_get_body_charset (chsbuff, sizeof (chsbuff), a)))    a->noconv = 0;  if (!a->force_charset && !a->noconv)    mutt_delete_parameter ("charset", &a->parameter);

⌨️ 快捷键说明

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