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

📄 handler.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 3 页
字号:
      }      else      {	stte->buffer[stte->buff_used++] = c;      }    }    else    {      stte->buffer[stte->buff_used++] = c;    }    stte->word_len++;  }}static void enriched_puts (char *s, struct enriched_state *stte){  char *c;  if (stte->buff_len < stte->buff_used + mutt_strlen(s))  {    stte->buff_len += LONG_STRING;    safe_realloc (&stte->buffer, stte->buff_len + 1);  }  c = s;  while (*c)  {    stte->buffer[stte->buff_used++] = *c;    c++;  }}static void enriched_set_flags (const char *tag, struct enriched_state *stte){  const char *tagptr = tag;  int i, j;  if (*tagptr == '/')    tagptr++;    for (i = 0, j = -1; EnrichedTags[i].tag_name; i++)    if (ascii_strcasecmp (EnrichedTags[i].tag_name,tagptr) == 0)    {      j = EnrichedTags[i].index;      break;    }  if (j != -1)  {    if (j == RICH_CENTER || j == RICH_FLUSHLEFT || j == RICH_FLUSHRIGHT)      enriched_flush (stte, 1);    if (*tag == '/')    {      if (stte->tag_level[j]) /* make sure not to go negative */	stte->tag_level[j]--;      if ((stte->s->flags & M_DISPLAY) && j == RICH_PARAM && stte->tag_level[RICH_COLOR])      {	stte->param[stte->param_used] = '\0';	if (!ascii_strcasecmp(stte->param, "black"))	{	  enriched_puts("\033[30m", stte);	}	else if (!ascii_strcasecmp(stte->param, "red"))	{	  enriched_puts("\033[31m", stte);	}	else if (!ascii_strcasecmp(stte->param, "green"))	{	  enriched_puts("\033[32m", stte);	}	else if (!ascii_strcasecmp(stte->param, "yellow"))	{	  enriched_puts("\033[33m", stte);	}	else if (!ascii_strcasecmp(stte->param, "blue"))	{	  enriched_puts("\033[34m", stte);	}	else if (!ascii_strcasecmp(stte->param, "magenta"))	{	  enriched_puts("\033[35m", stte);	}	else if (!ascii_strcasecmp(stte->param, "cyan"))	{	  enriched_puts("\033[36m", stte);	}	else if (!ascii_strcasecmp(stte->param, "white"))	{	  enriched_puts("\033[37m", stte);	}      }      if ((stte->s->flags & M_DISPLAY) && j == RICH_COLOR)      {	enriched_puts("\033[0m", stte);      }      /* flush parameter buffer when closing the tag */      if (j == RICH_PARAM)      {	stte->param_used = 0;	stte->param[0] = '\0';      }    }    else      stte->tag_level[j]++;    if (j == RICH_EXCERPT)      enriched_flush(stte, 1);  }}int text_enriched_handler (BODY *a, STATE *s){  enum {    TEXT, LANGLE, TAG, BOGUS_TAG, NEWLINE, ST_EOF, DONE  } state = TEXT;  long bytes = a->length;  struct enriched_state stte;  int c = 0;  int tag_len = 0;  char tag[LONG_STRING + 1];  memset (&stte, 0, sizeof (stte));  stte.s = s;  stte.WrapMargin = ((s->flags & M_DISPLAY) ? (COLS-4) : ((COLS-4)<72)?(COLS-4):72);  stte.line_max = stte.WrapMargin * 4;  stte.line = (char *) safe_calloc (1, stte.line_max + 1);  stte.param = (char *) safe_calloc (1, STRING);  stte.param_len = STRING;  stte.param_used = 0;  if (s->prefix)  {    state_puts (s->prefix, s);    stte.indent_len += mutt_strlen (s->prefix);  }  while (state != DONE)  {    if (state != ST_EOF)    {      if (!bytes || (c = fgetc (s->fpin)) == EOF)	state = ST_EOF;      else	bytes--;    }    switch (state)    {      case TEXT :	switch (c)	{	  case '<' :	    state = LANGLE;	    break;	  case '\n' :	    if (stte.tag_level[RICH_NOFILL])	    {	      enriched_flush (&stte, 1);	    }	    else 	    {	      enriched_putc (' ', &stte);	      state = NEWLINE;	    }	    break;	  default:	    enriched_putc (c, &stte);	}	break;      case LANGLE :	if (c == '<')	{	  enriched_putc (c, &stte);	  state = TEXT;	  break;	}	else	{	  tag_len = 0;	  state = TAG;	}	/* Yes, fall through (it wasn't a <<, so this char is first in TAG) */      case TAG :	if (c == '>')	{	  tag[tag_len] = '\0';	  enriched_set_flags (tag, &stte);	  state = TEXT;	}	else if (tag_len < LONG_STRING)  /* ignore overly long tags */	  tag[tag_len++] = c;	else	  state = BOGUS_TAG;	break;      case BOGUS_TAG :	if (c == '>')	  state = TEXT;	break;      case NEWLINE :	if (c == '\n')	  enriched_flush (&stte, 1);	else	{	  ungetc (c, s->fpin);	  bytes++;	  state = TEXT;	}	break;      case ST_EOF :	enriched_putc ('\0', &stte);        enriched_flush (&stte, 1);	state = DONE;	break;      case DONE: /* not reached, but gcc complains if this is absent */	break;    }  }  state_putc ('\n', s); /* add a final newline */  FREE (&(stte.buffer));  FREE (&(stte.line));  FREE (&(stte.param));  return 0;}                                                                              /* * An implementation of RFC 2646. * * NOTE: This still has to be made UTF-8 aware. * */#define FLOWED_MAX 77static void flowed_quote (STATE *s, int level){  int i;    if (s->prefix)  {    if (option (OPTTEXTFLOWED))      level++;    else      state_puts (s->prefix, s);  }    for (i = 0; i < level; i++)    state_putc ('>', s);}static int flowed_maybe_quoted (char *cont){  return regexec ((regex_t *) QuoteRegexp.rx, cont, 0, NULL, 0) == 0;}static void flowed_stuff (STATE *s, char *cont, int level){  if (!option (OPTTEXTFLOWED) && !(s->flags & M_DISPLAY))    return;  if (s->flags & M_DISPLAY)  {    /*      * Hack: If we are in the beginning of the line and there is      * some text on the line which looks like it's quoted, turn off      * ANSI colors, so quote coloring doesn't affect this line.      */    if (*cont && !level && !mutt_strcmp (Pager, "builtin") && flowed_maybe_quoted (cont))      state_puts ("\033[0m",s);  }  else if ((!(s->flags & M_PRINTING)) && 	   ((*cont == ' ') || (*cont == '>') || (!level && !mutt_strncmp (cont, "From ", 5))))    state_putc (' ', s);}static char *flowed_skip_indent (char *prefix, char *cont){  for (; *cont == ' ' || *cont == '\t'; cont++)    *prefix++ = *cont;  *prefix = '\0';  return cont;}static int flowed_visual_strlen (char *l, int i){  int j;  for (j = 0; *l; l++)  {    if (*l == '\t')      j += 8 - ((i + j) % 8);    else      j++;  }    return j;}static int text_plain_flowed_handler (BODY *a, STATE *s){  char line[LONG_STRING];  char indent[LONG_STRING];  int  quoted = -1;  int  last_quoted;  int  full = 1;  int  last_full;  int  col = 0, tmpcol;  int  i_add = 0;  int  add = 0;  int  soft = 0;  int  l, rl;    int  flowed_max;  int  bytes = a->length;  int  actually_wrap = 0;    char *cont = NULL;  char *tail = NULL;  char *lc = NULL;  char *t;    *indent = '\0';    if (s->prefix)    add = 1;    if ((flowed_max = FLOWED_MAX) > COLS - 3)    flowed_max = COLS - 3;  if (flowed_max > COLS - WrapMargin)    flowed_max = COLS - WrapMargin;  if (flowed_max <= 0)    flowed_max = COLS;      while (bytes > 0 && fgets (line, sizeof (line), s->fpin))  {    bytes        -= strlen (line);    tail          = NULL;    last_full     = full;        /*      * If the last line wasn't fully read, this is the     * tail of some line.      */    actually_wrap = !last_full;         if ((t = strrchr (line, '\r')) || (t = strrchr (line, '\n')))    {      *t   = '\0';      full = 1;    }    else if ((t = strrchr (line, ' ')) || (t = strrchr (line, '\t')))    {      /*        * Bad: We have a line of more than LONG_STRING characters.       * (Which SHOULD NOT happen, since lines SHOULD be <= 79       * characters long.)       *        * Try to simulate a soft line break at a word boundary.       * Handle the rest of the line next time.       *        * Give up when we have a single word which is longer than       * LONG_STRING characters.  It will just be split into parts,       * with a hard line break in between.        */      full = 0;      l    = strlen (t + 1);      t[0] = ' ';      t[1] = '\0';      if (l)      {	fseek (s->fpin, -l, SEEK_CUR);	bytes += l;      }    }    else      full = 0;    last_quoted = quoted;    if (last_full)    {      /*        * We are in the beginning of a new line. Determine quote level       * and indentation prefix        */      for (quoted = 0; line[quoted] == '>'; quoted++)	;            cont = line + quoted;            /* undo space stuffing */      if (*cont == ' ')	cont++;      /* If there is an indentation, record it. */      cont  = flowed_skip_indent (indent, cont);      i_add = flowed_visual_strlen (indent, quoted + add);    }    else    {      /*        * This is just the tail of some over-long line. Keep       * indentation and quote levels.  Don't unstuff.       */      cont = line;    }    /* If we have a change in quoting depth, wrap. */    if (col && last_quoted != quoted && last_quoted >= 0)    {      state_putc ('\n', s);      col = 0;    }        do     {      if (tail)	cont = tail;      SKIPWS (cont);            tail = NULL;      soft = 0;            /* try to find a point for word wrapping */    retry_wrap:      l  = flowed_visual_strlen (cont, quoted + i_add + add + col);      rl = mutt_strlen (cont);      if (quoted + i_add + add + col + l > flowed_max)      {	actually_wrap = 1;	for (tmpcol = quoted + i_add + add + col, t = cont;	     *t && tmpcol < flowed_max; t++)	{	  if (*t == ' ' || *t == '\t')	    tail = t;	  if (*t == '\t')	    tmpcol = (tmpcol & ~7) + 8;	  else	    tmpcol++;	}		if (tail)	{	  *tail++ = '\0';	  soft = 2;	}      }      /* We seem to be desperate.  Get me a new line, and retry. */      if (!tail && (quoted + add + col + i_add + l > flowed_max) && col)      {	state_putc ('\n', s);	col = 0;	goto retry_wrap;      }      /* Detect soft line breaks. */      if (!soft && ascii_strcmp (cont, "-- "))      {	lc = strrchr (cont, ' ');	if (lc && lc[1] == '\0')	  soft = 1;      }      /*        * If we are in the beginning of an output line, do quoting       * and stuffing.        *        * We have to temporarily assemble the line since display       * stuffing (i.e., turning off quote coloring) may depend on       * the line's actual content.  You never know what people put       * into their regular expressions.        */      if (!col)      {	char tmp[LONG_STRING];	snprintf (tmp, sizeof (tmp), "%s%s", indent, cont);	flowed_quote (s, quoted);	flowed_stuff (s, tmp, quoted + add);	state_puts (indent, s);      }      /* output the text */      state_puts (cont, s);      col += flowed_visual_strlen (cont, quoted + i_add + add + col);            /* possibly indicate a soft line break */      if (soft == 2)      {	state_putc (' ', s);	col++;      }            /*        * Wrap if this display line corresponds to a        * text line. Don't wrap if we changed the line.       */      if (!soft || (!actually_wrap && full))      {	state_putc ('\n', s);	col = 0;      }    }    while (tail);  }  if (col)    state_putc ('\n', s);  return 0;}#define TXTHTML     1#define TXTPLAIN    2#define TXTENRICHED 3static int alternative_handler (BODY *a, STATE *s){  BODY *choice = NULL;  BODY *b;  LIST *t;  char buf[STRING];  int type = 0;  int mustfree = 0;  int rc = 0;  if (a->encoding == ENCBASE64 || a->encoding == ENCQUOTEDPRINTABLE ||      a->encoding == ENCUUENCODED)  {    struct stat st;    mustfree = 1;    fstat (fileno (s->fpin), &st);    b = mutt_new_body ();    b->length = (long) st.st_size;    b->parts = mutt_parse_multipart (s->fpin,		  mutt_get_parameter ("boundary", a->parameter),		  (long) st.st_size, ascii_strcasecmp ("digest", a->subtype) == 0);  }  else    b = a;  a = b;  /* First, search list of prefered types */  t = AlternativeOrderList;  while (t && !choice)  {    char *c;    int btlen;  /* length of basetype */    int wild;	/* do we have a wildcard to match all subtypes? */    c = strchr (t->data, '/');    if (c)    {      wild = (c[1] == '*' && c[2] == 0);      btlen = c - t->data;    }    else    {      wild = 1;      btlen = mutt_strlen (t->data);    }    if (a && a->parts)       b = a->parts;    else      b = a;    while (b)    {      const char *bt = TYPE(b);      if (!ascii_strncasecmp (bt, t->data, btlen) && bt[btlen] == 0)      {	/* the basetype matches */	if (wild || !ascii_strcasecmp (t->data + btlen + 1, b->subtype))	{	  choice = b;	}      }      b = b->next;    }    t = t->next;  }  /* Next, look for an autoviewable type */  if (!choice)  {    if (a && a->parts)       b = a->parts;    else      b = a;    while (b)    {      snprintf (buf, sizeof (buf), "%s/%s", TYPE (b), b->subtype);      if (mutt_is_autoview (b, buf))      {	rfc1524_entry *entry = rfc1524_new_entry ();	if (rfc1524_mailcap_lookup (b, buf, entry, M_AUTOVIEW))	{	  choice = b;	}	rfc1524_free_entry (&entry);      }      b = b->next;    }  }  /* Then, look for a text entry */  if (!choice)  {    if (a && a->parts)       b = a->parts;    else      b = a;    while (b)    {      if (b->type == TYPETEXT)      {	if (! ascii_strcasecmp ("plain", b->subtype) && type <= TXTPLAIN)	{	  choice = b;	  type = TXTPLAIN;	}	else if (! ascii_strcasecmp ("enriched", b->subtype) && type <= TXTENRICHED)	{	  choice = b;	  type = TXTENRICHED;	}	else if (! ascii_strcasecmp ("html", b->subtype) && type <= TXTHTML)

⌨️ 快捷键说明

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