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

📄 handler.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1996-2000 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 <stdlib.h>#include <string.h>#include <unistd.h>#include <ctype.h>#include <sys/wait.h>#include <sys/stat.h>#include "mutt.h"#include "mutt_curses.h"#include "rfc1524.h"#include "keymap.h"#include "mime.h"#include "copy.h"#include "charset.h"#include "mutt_crypt.h"#define BUFI_SIZE 1000#define BUFO_SIZE 2000typedef int (*handler_t) (BODY *, STATE *);int Index_hex[128] = {    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,     0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,    -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,    -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1};int Index_64[128] = {    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,    52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,    -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,    15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,    -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,    41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1};static void state_prefix_put (const char *d, size_t dlen, STATE *s){  if (s->prefix)    while (dlen--)      state_prefix_putc (*d++, s);  else    fwrite (d, dlen, 1, s->fpout);}void mutt_convert_to_state(iconv_t cd, char *bufi, size_t *l, STATE *s){  char bufo[BUFO_SIZE];  ICONV_CONST char *ib;  char *ob;  size_t ibl, obl;  if (!bufi)  {    if (cd != (iconv_t)(-1))    {      ob = bufo, obl = sizeof (bufo);      iconv (cd, 0, 0, &ob, &obl);      if (ob != bufo)	state_prefix_put (bufo, ob - bufo, s);    }    return;  }  if (cd == (iconv_t)(-1))  {    state_prefix_put (bufi, *l, s);    *l = 0;    return;  }  ib = bufi, ibl = *l;  for (;;)  {    ob = bufo, obl = sizeof (bufo);    mutt_iconv (cd, &ib, &ibl, &ob, &obl, 0, "?");    if (ob == bufo)      break;    state_prefix_put (bufo, ob - bufo, s);  }  memmove (bufi, ib, ibl);  *l = ibl;}void mutt_decode_xbit (STATE *s, long len, int istext, iconv_t cd){  int c, ch;  char bufi[BUFI_SIZE];  size_t l = 0;  if (istext)  {    state_set_prefix(s);    while ((c = fgetc(s->fpin)) != EOF && len--)    {      if(c == '\r' && len)      {	if((ch = fgetc(s->fpin)) == '\n')	{	  c = ch;	  len--;	}	else 	  ungetc(ch, s->fpin);      }      bufi[l++] = c;      if (l == sizeof (bufi))	mutt_convert_to_state (cd, bufi, &l, s);    }    mutt_convert_to_state (cd, bufi, &l, s);    mutt_convert_to_state (cd, 0, 0, s);    state_reset_prefix (s);  }  else    mutt_copy_bytes (s->fpin, s->fpout, len);}static int qp_decode_triple (char *s, char *d){  /* soft line break */  if (*s == '=' && !(*(s+1)))    return 1;    /* quoted-printable triple */  if (*s == '=' &&      isxdigit ((unsigned char) *(s+1)) &&      isxdigit ((unsigned char) *(s+2)))  {    *d = (hexval (*(s+1)) << 4) | hexval (*(s+2));    return 0;  }    /* something else */  return -1;}static void qp_decode_line (char *dest, char *src, size_t *l,			    int last){  char *d, *s;  char c;  int kind;  int soft = 0;  /* decode the line */    for (d = dest, s = src; *s;)  {    switch ((kind = qp_decode_triple (s, &c)))    {      case  0: *d++ = c; s += 3; break;	/* qp triple */      case -1: *d++ = *s++;      break; /* single character */      case  1: soft = 1; s++;	 break; /* soft line break */    }  }  if (!soft && last == '\n')    *d++ = '\n';    *d = '\0';  *l = d - dest;}/*  * Decode an attachment encoded with quoted-printable. *  * Why doesn't this overflow any buffers?  First, it's guaranteed * that the length of a line grows when you _en_-code it to * quoted-printable.  That means that we always can store the * result in a buffer of at most the _same_ size. *  * Now, we don't special-case if the line we read with fgets() * isn't terminated.  We don't care about this, since STRING > 78, * so corrupted input will just be corrupted a bit more.  That * implies that STRING+1 bytes are always sufficient to store the * result of qp_decode_line. *  * Finally, at soft line breaks, some part of a multibyte character * may have been left over by mutt_convert_to_state().  This shouldn't * be more than 6 characters, so STRING + 7 should be sufficient * memory to store the decoded data. *  * Just to make sure that I didn't make some off-by-one error * above, we just use STRING*2 for the target buffer's size. *  */void mutt_decode_quoted (STATE *s, long len, int istext, iconv_t cd){  char line[STRING];  char decline[2*STRING];  size_t l = 0;  size_t linelen;      /* number of input bytes in `line' */  size_t l3;    int last;    /* store the last character in the input line */    if (istext)    state_set_prefix(s);  while (len > 0)  {    last = 0;        /*     * It's ok to use a fixed size buffer for input, even if the line turns     * out to be longer than this.  Just process the line in chunks.  This     * really shouldn't happen according the MIME spec, since Q-P encoded     * lines are at most 76 characters, but we should be liberal about what     * we accept.     */    if (fgets (line, MIN ((ssize_t)sizeof (line), len + 1), s->fpin) == NULL)      break;    linelen = strlen(line);    len -= linelen;    /*     * inspect the last character we read so we can tell if we got the     * entire line.     */    last = linelen ? line[linelen - 1] : 0;    /* chop trailing whitespace if we got the full line */    if (last == '\n')    {      while (linelen > 0 && ISSPACE (line[linelen-1]))       linelen--;      line[linelen]=0;    }    /* decode and do character set conversion */    qp_decode_line (decline + l, line, &l3, last);    l += l3;    mutt_convert_to_state (cd, decline, &l, s);  }  mutt_convert_to_state (cd, 0, 0, s);  state_reset_prefix(s);}void mutt_decode_base64 (STATE *s, long len, int istext, iconv_t cd){  char buf[5];  int c1, c2, c3, c4, ch, cr = 0, i;  char bufi[BUFI_SIZE];  size_t l = 0;  buf[4] = 0;  if (istext)     state_set_prefix(s);  while (len > 0)  {    for (i = 0 ; i < 4 && len > 0 ; len--)    {      if ((ch = fgetc (s->fpin)) == EOF)	break;      if (ch >= 0 && ch < 128 && (base64val(ch) != -1 || ch == '='))	buf[i++] = ch;    }    if (i != 4)    {      dprint (2, (debugfile, "%s:%d [mutt_decode_base64()]: "		  "didn't get a multiple of 4 chars.\n", __FILE__, __LINE__));      break;    }    c1 = base64val (buf[0]);    c2 = base64val (buf[1]);    ch = (c1 << 2) | (c2 >> 4);    if (cr && ch != '\n')       bufi[l++] = '\r';    cr = 0;          if (istext && ch == '\r')      cr = 1;    else      bufi[l++] = ch;    if (buf[2] == '=')      break;    c3 = base64val (buf[2]);    ch = ((c2 & 0xf) << 4) | (c3 >> 2);    if (cr && ch != '\n')      bufi[l++] = '\r';    cr = 0;    if (istext && ch == '\r')      cr = 1;    else      bufi[l++] = ch;    if (buf[3] == '=') break;    c4 = base64val (buf[3]);    ch = ((c3 & 0x3) << 6) | c4;    if (cr && ch != '\n')      bufi[l++] = '\r';    cr = 0;    if (istext && ch == '\r')      cr = 1;    else      bufi[l++] = ch;        if (l + 8 >= sizeof (bufi))      mutt_convert_to_state (cd, bufi, &l, s);  }  if (cr) bufi[l++] = '\r';  mutt_convert_to_state (cd, bufi, &l, s);  mutt_convert_to_state (cd, 0, 0, s);  state_reset_prefix(s);}unsigned char decode_byte (char ch){  if (ch == 96)    return 0;  return ch - 32;}void mutt_decode_uuencoded (STATE *s, long len, int istext, iconv_t cd){  char tmps[SHORT_STRING];  char linelen, c, l, out;  char *pt;  char bufi[BUFI_SIZE];  size_t k = 0;  if(istext)    state_set_prefix(s);    while(len > 0)  {    if ((fgets(tmps, sizeof(tmps), s->fpin)) == NULL)      return;    len -= mutt_strlen(tmps);    if ((!mutt_strncmp (tmps, "begin", 5)) && ISSPACE (tmps[5]))      break;  }  while(len > 0)  {    if ((fgets(tmps, sizeof(tmps), s->fpin)) == NULL)      return;    len -= mutt_strlen(tmps);    if (!mutt_strncmp (tmps, "end", 3))      break;    pt = tmps;    linelen = decode_byte (*pt);    pt++;    for (c = 0; c < linelen;)    {      for (l = 2; l <= 6; l += 2)      {	out = decode_byte (*pt) << l;	pt++;	out |= (decode_byte (*pt) >> (6 - l));	bufi[k++] = out;	c++;	if (c == linelen)	  break;      }      mutt_convert_to_state (cd, bufi, &k, s);      pt++;    }  }  mutt_convert_to_state (cd, bufi, &k, s);  mutt_convert_to_state (cd, 0, 0, s);    state_reset_prefix(s);}/* ---------------------------------------------------------------------------- * A (not so) minimal implementation of RFC1563. */#define IndentSize (4)    enum { RICH_PARAM=0, RICH_BOLD, RICH_UNDERLINE, RICH_ITALIC, RICH_NOFILL,   RICH_INDENT, RICH_INDENT_RIGHT, RICH_EXCERPT, RICH_CENTER, RICH_FLUSHLEFT,  RICH_FLUSHRIGHT, RICH_COLOR, RICH_LAST_TAG };static struct {  const char *tag_name;  int index;} EnrichedTags[] = {  { "param",		RICH_PARAM },  { "bold",		RICH_BOLD },  { "italic",		RICH_ITALIC },  { "underline",	RICH_UNDERLINE },  { "nofill",		RICH_NOFILL },  { "excerpt",		RICH_EXCERPT },  { "indent",		RICH_INDENT },  { "indentright",	RICH_INDENT_RIGHT },  { "center",		RICH_CENTER },  { "flushleft",	RICH_FLUSHLEFT },  { "flushright",	RICH_FLUSHRIGHT },  { "flushboth",	RICH_FLUSHLEFT },  { "color",		RICH_COLOR },  { "x-color",		RICH_COLOR },  { NULL,		-1 }};struct enriched_state{  char *buffer;  char *line;  char *param;  size_t buff_len;  size_t line_len;  size_t line_used;  size_t line_max;  size_t indent_len;  size_t word_len;  size_t buff_used;  size_t param_used;  size_t param_len;  int tag_level[RICH_LAST_TAG];  int WrapMargin;  STATE *s;};static void enriched_wrap (struct enriched_state *stte){  int x;  int extra;  if (stte->line_len)  {    if (stte->tag_level[RICH_CENTER] || stte->tag_level[RICH_FLUSHRIGHT])    {      /* Strip trailing white space */      size_t y = stte->line_used - 1;      while (y && ISSPACE (stte->line[y]))      {	stte->line[y] = '\0';	y--;	stte->line_used--;	stte->line_len--;      }      if (stte->tag_level[RICH_CENTER])      {	/* Strip leading whitespace */	y = 0;	while (stte->line[y] && ISSPACE (stte->line[y]))	  y++;	if (y)	{	  size_t z;	  for (z = y ; z <= stte->line_used; z++)	  {	    stte->line[z - y] = stte->line[z];	  }	  stte->line_len -= y;	  stte->line_used -= y;	}      }    }    extra = stte->WrapMargin - stte->line_len - stte->indent_len -      (stte->tag_level[RICH_INDENT_RIGHT] * IndentSize);    if (extra > 0)     {      if (stte->tag_level[RICH_CENTER])       {	x = extra / 2;	while (x)	{	  state_putc (' ', stte->s);	  x--;	}      }       else if (stte->tag_level[RICH_FLUSHRIGHT])      {	x = extra-1;	while (x)	{	  state_putc (' ', stte->s);	  x--;	}      }    }    state_puts (stte->line, stte->s);  }  state_putc ('\n', stte->s);  stte->line[0] = '\0';  stte->line_len = 0;  stte->line_used = 0;  stte->indent_len = 0;  if (stte->s->prefix)  {    state_puts (stte->s->prefix, stte->s);    stte->indent_len += mutt_strlen (stte->s->prefix);  }  if (stte->tag_level[RICH_EXCERPT])  {    x = stte->tag_level[RICH_EXCERPT];    while (x)     {      if (stte->s->prefix)      {	state_puts (stte->s->prefix, stte->s);	    stte->indent_len += mutt_strlen (stte->s->prefix);      }      else      {	state_puts ("> ", stte->s);	stte->indent_len += mutt_strlen ("> ");      }      x--;    }  }  else    stte->indent_len = 0;  if (stte->tag_level[RICH_INDENT])  {    x = stte->tag_level[RICH_INDENT] * IndentSize;    stte->indent_len += x;    while (x)     {      state_putc (' ', stte->s);      x--;    }  }}static void enriched_flush (struct enriched_state *stte, int wrap){  if (!stte->tag_level[RICH_NOFILL] && (stte->line_len + stte->word_len >       (stte->WrapMargin - (stte->tag_level[RICH_INDENT_RIGHT] * IndentSize) -        stte->indent_len)))    enriched_wrap (stte);  if (stte->buff_used)  {    stte->buffer[stte->buff_used] = '\0';    stte->line_used += stte->buff_used;    if (stte->line_used > stte->line_max)    {      stte->line_max = stte->line_used;      safe_realloc (&stte->line, stte->line_max + 1);    }    strcat (stte->line, stte->buffer);	/* __STRCAT_CHECKED__ */    stte->line_len += stte->word_len;    stte->word_len = 0;    stte->buff_used = 0;  }  if (wrap)     enriched_wrap(stte);}static void enriched_putc (int c, struct enriched_state *stte){  if (stte->tag_level[RICH_PARAM])   {    if (stte->tag_level[RICH_COLOR])     {      if (stte->param_used + 1 >= stte->param_len)	safe_realloc (&stte->param, (stte->param_len += STRING));      stte->param[stte->param_used++] = c;    }    return; /* nothing to do */  }  /* see if more space is needed (plus extra for possible rich characters) */  if (stte->buff_len < stte->buff_used + 3)  {    stte->buff_len += LONG_STRING;    safe_realloc (&stte->buffer, stte->buff_len + 1);  }  if ((!stte->tag_level[RICH_NOFILL] && ISSPACE (c)) || c == '\0' )  {    if (c == '\t')      stte->word_len += 8 - (stte->line_len + stte->word_len) % 8;    else      stte->word_len++;        stte->buffer[stte->buff_used++] = c;    enriched_flush (stte, 0);  }  else  {    if (stte->s->flags & M_DISPLAY)    {      if (stte->tag_level[RICH_BOLD])      {	stte->buffer[stte->buff_used++] = c;	stte->buffer[stte->buff_used++] = '\010';	stte->buffer[stte->buff_used++] = c;      }      else if (stte->tag_level[RICH_UNDERLINE])      {	stte->buffer[stte->buff_used++] = '_';	stte->buffer[stte->buff_used++] = '\010';	stte->buffer[stte->buff_used++] = c;      }      else if (stte->tag_level[RICH_ITALIC])      {	stte->buffer[stte->buff_used++] = c;	stte->buffer[stte->buff_used++] = '\010';	stte->buffer[stte->buff_used++] = '_';

⌨️ 快捷键说明

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