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

📄 rfc2047.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* Find earliest and latest things we must encode. */  s0 = s1 = t0 = t1 = 0;  for (t = u; t < u + ulen; t++)  {    if ((*t & 0x80) || 	(*t == '=' && t[1] == '?' && (t == u || HSPACE(*(t-1)))))    {      if (!t0) t0 = t;      t1 = t;    }    else if (specials && strchr (specials, *t))    {      if (!s0) s0 = t;      s1 = t;    }  }  /* If we have something to encode, include RFC822 specials */  if (t0 && s0 && s0 < t0)    t0 = s0;  if (t1 && s1 && s1 > t1)    t1 = s1;  if (!t0)  {    /* No encoding is required. */    *e = u;    *elen = ulen;    return ret;  }  /* Choose target charset. */  tocode = fromcode;  if (icode)  {    if ((tocode1 = mutt_choose_charset (icode, charsets, u, ulen, 0, 0)))      tocode = tocode1;    else      ret = 2, icode = 0;  }  /* Hack to avoid labelling 8-bit data as us-ascii. */  if (!icode && mutt_is_us_ascii (tocode))    tocode = "unknown-8bit";    /* Adjust t0 for maximum length of line. */  t = u + (ENCWORD_LEN_MAX + 1) - col - ENCWORD_LEN_MIN;  if (t < u)  t = u;  if (t < t0) t0 = t;    /* Adjust t0 until we can encode a character after a space. */  for (; t0 > u; t0--)  {    if (!HSPACE(*(t0-1)))      continue;    t = t0 + 1;    if (icode)      while (t < u + ulen && CONTINUATION_BYTE(*t))	++t;    if (!try_block (t0, t - t0, icode, tocode, &encoder, &wlen) &&	col + (t0 - u) + wlen <= ENCWORD_LEN_MAX + 1)      break;  }  /* Adjust t1 until we can encode a character before a space. */  for (; t1 < u + ulen; t1++)  {    if (!HSPACE(*t1))      continue;    t = t1 - 1;    if (icode)      while (CONTINUATION_BYTE(*t))	--t;    if (!try_block (t, t1 - t, icode, tocode, &encoder, &wlen) &&	1 + wlen + (u + ulen - t1) <= ENCWORD_LEN_MAX + 1)      break;  }  /* We shall encode the region [t0,t1). */  /* Initialise the output buffer with the us-ascii prefix. */  buflen = 2 * ulen;  buf = safe_malloc (buflen);  bufpos = t0 - u;  memcpy (buf, u, t0 - u);  col += t0 - u;  t = t0;  for (;;)  {    /* Find how much we can encode. */    n = choose_block (t, t1 - t, col, icode, tocode, &encoder, &wlen);    if (n == t1 - t)    {      /* See if we can fit the us-ascii suffix, too. */      if (col + wlen + (u + ulen - t1) <= ENCWORD_LEN_MAX + 1)	break;      n = t1 - t - 1;      if (icode)	while (CONTINUATION_BYTE(t[n]))	  --n;      assert (t + n >= t);      if (!n)      {	/* This should only happen in the really stupid case where the	   only word that needs encoding is one character long, but	   there is too much us-ascii stuff after it to use a single	   encoded word. We add the next word to the encoded region	   and try again. */	assert (t1 < u + ulen);	for (t1++; t1 < u + ulen && !HSPACE(*t1); t1++)	  ;	continue;      }      n = choose_block (t, n, col, icode, tocode, &encoder, &wlen);    }    /* Add to output buffer. */#define LINEBREAK "\n\t"    if (bufpos + wlen + strlen (LINEBREAK) > buflen)    {      buflen = bufpos + wlen + strlen (LINEBREAK);      safe_realloc (&buf, buflen);    }    r = encode_block (buf + bufpos, t, n, icode, tocode, encoder);    assert (r == wlen);    bufpos += wlen;    memcpy (buf + bufpos, LINEBREAK, strlen (LINEBREAK));    bufpos += strlen (LINEBREAK);#undef LINEBREAK    col = 1;    t += n;  }  /* Add last encoded word and us-ascii suffix to buffer. */  buflen = bufpos + wlen + (u + ulen - t1);  safe_realloc (&buf, buflen + 1);  r = encode_block (buf + bufpos, t, t1 - t, icode, tocode, encoder);  assert (r == wlen);  bufpos += wlen;  memcpy (buf + bufpos, t1, u + ulen - t1);  FREE (&tocode1);  FREE (&u);  buf[buflen] = '\0';    *e = buf;  *elen = buflen + 1;  return ret;}void _rfc2047_encode_string (char **pd, int encode_specials, int col){  char *e;  size_t elen;  char *charsets;  if (!Charset || !*pd)    return;  charsets = SendCharset;  if (!charsets || !*charsets)    charsets = "UTF-8";  rfc2047_encode (*pd, strlen (*pd), col,		  Charset, charsets, &e, &elen,		  encode_specials ? RFC822Specials : NULL);  FREE (pd);		/* __FREE_CHECKED__ */  *pd = e;}void rfc2047_encode_adrlist (ADDRESS *addr, const char *tag){  ADDRESS *ptr = addr;  int col = tag ? strlen (tag) + 2 : 32;    while (ptr)  {    if (ptr->personal)      _rfc2047_encode_string (&ptr->personal, 1, col);#ifdef EXACT_ADDRESS    if (ptr->val)      _rfc2047_encode_string (&ptr->val, 1, col);#endif    ptr = ptr->next;  }}static int rfc2047_decode_word (char *d, const char *s, size_t len){  const char *pp, *pp1;  char *pd, *d0;  const char *t, *t1;  int enc = 0, count = 0;  char *charset = NULL;  pd = d0 = safe_malloc (strlen (s));  for (pp = s; (pp1 = strchr (pp, '?')); pp = pp1 + 1)  {    count++;    switch (count)    {      case 2:	/* ignore language specification a la RFC 2231 */        	t = pp1;        if ((t1 = memchr (pp, '*', t - pp)))	  t = t1;	charset = safe_malloc (t - pp + 1);	memcpy (charset, pp, t - pp);	charset[t-pp] = '\0';	break;      case 3:	if (toupper ((unsigned char) *pp) == 'Q')	  enc = ENCQUOTEDPRINTABLE;	else if (toupper ((unsigned char) *pp) == 'B')	  enc = ENCBASE64;	else	{	  FREE (&charset);	  FREE (&d0);	  return (-1);	}	break;      case 4:	if (enc == ENCQUOTEDPRINTABLE)	{	  for (; pp < pp1; pp++)	  {	    if (*pp == '_')	      *pd++ = ' ';	    else if (*pp == '=' &&		     (!(pp[1] & ~127) && hexval(pp[1]) != -1) &&		     (!(pp[2] & ~127) && hexval(pp[2]) != -1))	    {	      *pd++ = (hexval(pp[1]) << 4) | hexval(pp[2]);	      pp += 2;	    }	    else	      *pd++ = *pp;	  }	  *pd = 0;	}	else if (enc == ENCBASE64)	{	  int c, b = 0, k = 0;	  for (; pp < pp1; pp++)	  {	    if (*pp == '=')	      break;	    if ((*pp & ~127) || (c = base64val(*pp)) == -1)	      continue;	    if (k + 6 >= 8)	    {	      k -= 2;	      *pd++ = b | (c >> k);	      b = c << (8 - k);	    }	    else	    {	      b |= c << (k + 2);	      k += 6;	    }	  }	  *pd = 0;	}	break;    }  }    if (charset)    mutt_convert_string (&d0, charset, Charset, M_ICONV_HOOK_FROM);  mutt_filter_unprintable (&d0);  strfcpy (d, d0, len);  FREE (&charset);  FREE (&d0);  return (0);}/* * Find the start and end of the first encoded word in the string. * We use the grammar in section 2 of RFC 2047, but the "encoding" * must be B or Q. Also, we don't require the encoded word to be * separated by linear-white-space (section 5(1)). */static const char *find_encoded_word (const char *s, const char **x){  const char *p, *q;  q = s;  while ((p = strstr (q, "=?")))  {    for (q = p + 2;	 0x20 < *q && *q < 0x7f && !strchr ("()<>@,;:\"/[]?.=", *q);	 q++)      ;    if (q[0] != '?' || !strchr ("BbQq", q[1]) || q[2] != '?')      continue;    for (q = q + 3; 0x20 < *q && *q < 0x7f && *q != '?'; q++)      ;    if (q[0] != '?' || q[1] != '=')    {      --q;      continue;    }    *x = q + 2;    return p;  }  return 0;}/* try to decode anything that looks like a valid RFC2047 encoded * header field, ignoring RFC822 parsing rules */void rfc2047_decode (char **pd){  const char *p, *q;  size_t n;  int found_encoded = 0;  char *d0, *d;  const char *s = *pd;  size_t dlen;  if (!s || !*s)    return;  dlen = 4 * strlen (s); /* should be enough */  d = d0 = safe_malloc (dlen + 1);  while (*s && dlen > 0)  {    if (!(p = find_encoded_word (s, &q)))    {      /* no encoded words */      strncpy (d, s, dlen);      d += dlen;      break;    }    if (p != s)    {      n = (size_t) (p - s);      /* ignore spaces between encoded words */      if (!found_encoded || strspn (s, " \t\r\n") != n)      {	if (n > dlen)	  n = dlen;	memcpy (d, s, n);	d += n;	dlen -= n;      }    }    rfc2047_decode_word (d, p, dlen);    found_encoded = 1;    s = q;    n = mutt_strlen (d);    dlen -= n;    d += n;  }  *d = 0;  FREE (pd);		/* __FREE_CHECKED__ */  *pd = d0;  mutt_str_adjust (pd);}void rfc2047_decode_adrlist (ADDRESS *a){  while (a)  {    if (a->personal && strstr (a->personal, "=?") != NULL)      rfc2047_decode (&a->personal);#ifdef EXACT_ADDRESS    if (a->val && strstr (a->val, "=?") != NULL)      rfc2047_decode (&a->val);#endif    a = a->next;  }}

⌨️ 快捷键说明

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