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

📄 mimedecode.c

📁 一个UTF的源代码,可以提供参考
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * This program comes with absolutely no guarantees and may * be used for whatever purpose, * *      Frederik H. Andersen - 1996 *      Dansk Data Elektronik A/S * *      fha@dde.dk * *//* * This program performs the decoding of transfer encoded text type * mime messages. The message in its entirety is read from stdin. * The decoded message is written to stdout; hence, this program * behaves as a filter which may be placed wherever convenient. * I particular like it in front of my slocal command in my .forward * file. * * It is assumed that the message has reached its point of final * delivery and at that point 8-bit text types can be handled * natively. Hence, the need for transfer-encodings is not present * any more. * * Only some cases are handled: *      - encoded header fields are decoded from QP or B encoding. *        The charset is assumed to be iso-8859-1 *      - part or subparts of content-type text only are decoded *      - all other content-types are passed transparently *      *//* extensive changes by Ričardas Čepas <rch@richard.eu.org> *        All charsets are converted to UTF-8 */#define _POSIX_C_SOURCE 2#include <stdio.h>#include <string.h>#include <ctype.h>#include <stdlib.h>#include <unistd.h>/* Some defines. Should have gone into a file by itself. */#define MIMED_VERSION "mimedecode version 1.8"#define lower(c)        ( isupper(c) ? tolower(c) : (c) )#include "2UTF.h"/* content types: */#define UNDEF		0#define TEXT		1#define MULT    	2#define MULT_DIGEST    	3#define MULT_PGP    	4#define MESG    	5/* transfer encodings: */#define QP	1#define B64	2#define BIT7	3#define BIT8	4#define BINARY	5#define UN 255#define LWSP " \t\n"unsigned char b64_map[256] ={  UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN,	/* 0x00 - 0x0f, NUL - SI */  UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN,	/* 0x10 - 0x1f, DLE - US */  UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, 62, UN, UN, UN, 63,	/* 0x20 - 0x2f, SP  - / */  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, UN, UN, UN, 0x3d, UN, UN,	/* 0x30 - 0x3f, 0   - ? */  UN, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,		/* 0x40 - 0x4f, @   - O */  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, UN, UN, UN, UN, UN,	/* 0x50 - 0x5f, P   - _ */  UN, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,	/* 0x60 - 0x6f, `   - o */  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, UN, UN, UN, UN, UN,	/* 0x70 - 0x7f, p   - DEL */  UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN,	/* 0x80 - 0x8f */  UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN,	/* 0x90 - 0x9f */  UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN,	/* 0xA0 - 0xAf */  UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN,	/* 0xB0 - 0xBf */  UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN,	/* 0xC0 - 0xCf */  UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN,	/* 0xD0 - 0xDf */  UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN,	/* 0xE0 - 0xEf */  UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN, UN,	/* 0xF0 - 0xFf */};char *especials = "()<>@,;:\\\"/[]?.=";int reserve = 100;/*******************************************************************/intparse_message (boundary)/*******************************************************************/     char *boundary;{  int c, saved_content_type;  struct mime_header_type mhead =  {0, 0, "\0", "\0", "\0"};  int ret;  if (Debug)    if (boundary)      fprintf (stderr, " - Entry parse_message with boundary=\"%s\" \n", boundary);    else      fprintf (stderr, " - Entry parse_message without boundary \n");  /* parse header */  if (!(ret = parse_header (&mhead)))    {      if (Debug)	fprintf (stderr, "parse of message header failed: %d\n", ret);      return (FALSE);    }  if (mhead.content_type == MULT || mhead.content_type == MULT_DIGEST)    {      if (Debug >= 2)	{	  fprintf (stderr, "message is multipart\n");	  fprintf (stderr, "search header boundary line: %s\n", mhead.boundary);	}      /* search for the boundary line before parsing further */      if ((ret = Seek_boundary (stdin, mhead.boundary, PUSH_BOUNDARY)) == TRUE)	/* When the message is of type multipart we have to handle each	 * part as an individual message.	 * We use the boundary to identify the beginning of each part	 */	do	  /* Check if part's own headers are missing */	  if ((c = getc (stdin)) == '\n')	    {	      putc (c, charset_p->pipe);	      if (mhead.content_type == MULT_DIGEST)		/* default is message/rfc */		ret = parse_message (mhead.boundary);	      else		{		/* default is text/plain; charset=us-ascii */		  saved_content_type = mhead.content_type;		  mhead.content_type = TEXT;		  if (charset_p->USASCII_is_subset == NO)		    Validate_charset ("us-ascii", 0);		  ret = parse_body (&mhead, mhead.boundary);		  mhead.content_type = saved_content_type;		}	    }	  else	    {	      ungetc (c, stdin);	      ret = parse_message (mhead.boundary);	    }	while (ret == TRUE);      if (boundary)		/* && ret == END_BOUNDARY) */	/* skip stuff after the last part of inner multipart message */	ret = Seek_boundary (ret < OUTER_BOUNDARY ? stdin : NULL, boundary, 0);    }  else if (mhead.content_type == MESG)    {      /* When message is type message we have to handle the body as       * an individual message.       */      ret = parse_message (boundary);    }  else    /* plain message */    {      ret = parse_body (&mhead, boundary);    }  if (Debug)    if (boundary)      fprintf (stderr, " - parse_message with boundary=\"%s\" returned %i - \n", boundary, ret);    else      fprintf (stderr, " - parse_message without boundary returned %i - \n", ret);  return (ret);}/*******************************************************************/intparse_body (mime_header_p, boundary)/*******************************************************************//*     int type, encoding; */     struct mime_header_type *mime_header_p;     char *boundary;{  int c;  int ret = FALSE;		/* ??? */  /*struct charset_type *old_charset_p; */  if (Debug)    fprintf (stderr, " -- Entry parse_body -- \n");  if (Debug >= 2)    fprintf (stderr, " -- type: %d, enc: %d\n", mime_header_p->content_type, mime_header_p->transfer_encoding);  if ((mime_header_p->content_type == TEXT) && \      ((mime_header_p->transfer_encoding == QP) \       ||(mime_header_p->transfer_encoding == B64) \       ||(mime_header_p->transfer_encoding == BIT8) \       ||(mime_header_p->transfer_encoding == BIT7) \      ))    {      if (boundary)	{	  if (Debug >= 2)	    fprintf (stderr, " -- with boundary: %s\n -- decoding -- \n", boundary);	  if (mime_header_p->transfer_encoding == QP)	    ret = decode_quoted_printable (stdin, charset_p->pipe, boundary);	  else if (mime_header_p->transfer_encoding == B64)	    ret = decode_base64 (stdin, charset_p->pipe, boundary);	  if (ret == FALSE)	    ret = Seek_boundary (stdin, boundary, 0);	}      else	/* no boundary */	{	  if (Debug >= 2)	    fprintf (stderr, " -- decoding -- \n");	  if (mime_header_p->transfer_encoding == QP)	    ret = decode_quoted_printable (stdin, charset_p->pipe, 0);	  else if (mime_header_p->transfer_encoding == B64)	    ret = decode_base64 (stdin, charset_p->pipe, 0);	  else			/*if (mime_header_p->transfer_encoding == BIT8 || mime_header_p->transfer_encoding == BIT7) */	    ret = 2, Pipe_to_UTF8 (stdin);	}    }  else if (boundary)    {      if (Debug >= 2)	fprintf (stderr, " -- with boundary: %s\n", boundary);      if (Debug >= 2)	fprintf (stderr, " -- skipping -- \n");      /*  old_charset_p = charset_p;         charset_p = &unknown_charset; */      Validate_charset ("'unknown'", 0);      ret = Seek_boundary (stdin, boundary, 0);      Validate_charset (NULL, 0);/*      charset_p = old_charset_p; */    }  else    {      if (Debug >= 2)	fprintf (stderr, " -- skipping -- \n");      Validate_charset ("'unknown'", 0);      ret = 2;      while ((c = getc (stdin)) != EOF)	putc (c, charset_p->pipe);    }  return (ret);}char *Add_to_buffer (struct buffer_type *buffer_p, char *string){/*  size_t old_size = buffer_p->end - buffer_p->start + 1;   if (Debug >= 9)   fprintf (stderr, "2UTF: realloc %i += %i \n", old_size, strlen (string));   buffer_p->start = xrealloc (buffer_p->start, (old_size + strlen (string)));   *//* buffer_p->start changes *//*     return (buffer_p->end = Stpcpy (buffer_p->start + old_size - 1, string));   */  size_t length;  length = strlen (string);  if (buffer_p->next + length - buffer_p->end > reserve)    {      fprintf (stderr, "2UTF: %s %li\n", buffer_overflow, (long)(buffer_p->next + length - buffer_p->end - reserve));      length = buffer_p->end - buffer_p->next - reserve;    }  memcpy (buffer_p->next, string, length);  return (buffer_p->next += length);}/*******************************************************************/intparse_header (mhp)/*******************************************************************/     struct mime_header_type *mhp;{  unsigned char *cp;  unsigned char *nlbp;  int c;  int ct_charset_unknown = FALSE;	/* Warning about unknown charset in ct */  size_t ct_header_charset_name_begin = 0, ct_header_charset_name_end = 0;  int ct_is_changing = FALSE;	/* Content charset parameter needs change */  int ct_read = FALSE;		/* Content-type field read */  int ct_written = FALSE;	/* Content-type written */  int cte_read = FALSE;		/* Content-transfer-encoding read */  int cte_written = FALSE;	/* Content-transfer-encoding written */  int headers_8bit = FALSE;	/* non-MIME-encrypted headers */  int quoted;  struct buffer_type headers_buffer =  {NULL, NULL, NULL, NULL};#define REALLOC_CHUNK 4000  line.buf = headers_buffer.next = headers_buffer.start = headers_buffer.header_start = xrealloc (line.buf, line.length += reserve);  headers_buffer.end = headers_buffer.start + line.length - reserve;/*    = xmalloc (REALLOC_CHUNK * 2 + reserve);   headers_buffer.end = headers_buffer.start + REALLOC_CHUNK * 2; */  if (Debug)    fprintf (stderr, " -- Entry parse_header - pass 1 -- \n");  mhp->boundary[0] = '\001';  mhp->content_type = UNDEF;  mhp->transfer_encoding = BIT8;  mhp->headers_charset[0] = '\0';  mhp->content_charset[0] = '\0';  /* first pass */  while (TRUE)    {      if ((c = getc (stdin)) == EOF)	{	  Validate_charset ("us-ascii", 0);	  fwrite (headers_buffer.start, 1, headers_buffer.next - headers_buffer.start, charset_p->pipe);	  return (FALSE);	}    again:      *headers_buffer.next++ = c;      while (headers_buffer.next >= headers_buffer.end)	{			/* realloc more memory */	  size_t old_size = headers_buffer.end - headers_buffer.start;	  size_t next_offset = headers_buffer.next - headers_buffer.start;	  size_t header_start_offset = headers_buffer.header_start - headers_buffer.start;	  if (Debug >= 9)	    fprintf (stderr, "2UTF: realloc %li += %i \n", (long)old_size + reserve, REALLOC_CHUNK);	  line.buf = headers_buffer.start = xrealloc (headers_buffer.start, old_size + reserve + REALLOC_CHUNK);	  line.length += REALLOC_CHUNK;	  headers_buffer.end = headers_buffer.start + old_size + REALLOC_CHUNK;	  headers_buffer.next = headers_buffer.start + next_offset;	  headers_buffer.header_start = headers_buffer.start + header_start_offset;	  if (line.length != old_size + reserve + REALLOC_CHUNK && Debug)	    fprintf (stderr, "2UTF: memory allocation error: \n  %li != %li \n", (long)line.length, (long)old_size + reserve + REALLOC_CHUNK);	}      if ((c > 0x7F || (c != '\n' && c != '\t' && iscntrl (c))) &&headers_8bit == FALSE)	{	  headers_8bit = TRUE;	  if (Debug >= 2)	    fprintf (stderr, " -- 8 bit bytes or control codes in headers detected \n");	}      if (c == '\n')		/* end of line reached */	{	  if ((c = getc (stdin)) == EOF)	    {	      Add_to_buffer (&headers_buffer, "\n");	      Validate_charset ("us-ascii", 0);	      fwrite (headers_buffer.start, 1, headers_buffer.next - headers_buffer.start, charset_p->pipe);	      break;	    }	  else if (c == ' ' || c == '\t')	    /* if next line begins with space 	     * it is continuation of the same header	     */	    goto again;	  else	    ungetc (c, stdin);	  *headers_buffer.next = '\0';	/* zero terminate the line buf *//*        headers_buffer.header_start = headers_buffer.next; */	  if (Debug >= 4)	    fprintf (stderr, "headers_buffer: %s\n", headers_buffer.header_start);	  if (!Strcase_has_prefix (headers_buffer.header_start, "content-type:"))	    {	      ct_read = TRUE;	      cp = headers_buffer.header_start + strlen ("Content-Type:");	      cp += strspn (cp, LWSP);	      /* we are only doing decoding of text types */	      if (Strcase_has_prefix (cp, "text/") == 0)		{		  if (Debug >= 3)		    fprintf (stderr, "Content IS text\n");		  mhp->content_type = TEXT;		  if ((cp = strchr (cp, ';')))		    while ((cp = strchr (cp, ';')))		      if (Strcase_has_prefix (cp += strspn (cp, "; \t\n"), "charset=") == 0)			{			  ct_header_charset_name_begin = (cp += 8) - headers_buffer.header_start;			  cp += strspn (cp, "'\"");			  if ((cp[0] == 'x' || cp[0] == 'X') &&cp[1] == '-')			    cp += 2;			  ct_header_charset_name_end = cp + strcspn (cp, ";\n\r") - headers_buffer.header_start;			  strncpy (mhp->content_charset, cp, MIN (79, strcspn (cp, "*'\"; \t\n\r")));			  mhp->content_charset[ MIN (79, strcspn (cp, "*'\"; \t\n\r"))] = '\0';			  if (Debug)			    fprintf (stderr, " -- Content charset: %s\n", mhp->content_charset);			  break;			}		}	      else if (Strcase_has_prefix (cp, "multipart/") == 0)		{		  if (Strcase_has_prefix (cp += strlen ("multipart/"), "digest") == 0)		    mhp->content_type = MULT_DIGEST;		  else if (Strcase_has_prefix (cp, "pgp") == 0 ||Strcase_has_prefix (cp, "signed") == 0)		    mhp->content_type = MULT_PGP;		  else		    mhp->content_type = MULT;		  /* search for the boundary parameter */		  while ((cp = strchr (cp, ';')))		    if (Strcase_has_prefix (cp += 1 + strspn (1 + cp, LWSP), "boundary=") == 0)		      /* skip ; and remove white space */		      {			cp += strlen ("boundary=");			if (*cp == '"')			  {			    quoted = TRUE;			    cp++;			  }			else			  quoted = FALSE;			*(cp = Stpncpy (mhp->boundary, cp, 78)) = '"';			*++cp = '\0';			*(cp = mhp->boundary + strcspn (mhp->boundary, quoted ? "\"\n" : "\"" LWSP)) = '\0';			/* remove trailing white space */			cp--;			while ((char *) cp >= mhp->boundary &&(*cp == ' ' || *cp == '\t'))			  *cp-- = '\0';			if ((char *) cp <= mhp->boundary ||mhp->boundary[0] == '\0')			  {			    mhp->boundary[0] = '\0';			    mhp->content_type = UNDEF;			  }			break;		      }		  if (cp == NULL)		    {		      if (Debug)			fprintf (stderr, "boundary parameter missing ! \n");		      mhp->content_type = UNDEF;		      mhp->boundary[0] = '\0';		    }		}	      else if (Strcase_has_prefix (cp, "message/") == 0)		{		  mhp->content_type = MESG;		}	      nlbp = headers_buffer.header_start;	    }	  else if (!Strcase_has_prefix (headers_buffer.header_start, "content-transfer-encoding:"))	    {	      cte_read = TRUE;	      /* Remember the encoding in mhp! */	      cp = headers_buffer.header_start + strlen ("content-transfer-encoding:");	      cp += strspn (cp, LWSP);	/* remove white space */	      {		if (!Strcase_has_prefix (cp, "quoted-printable"))		  {		    if (Debug >= 3)		      fprintf (stderr, "Transfer-encoding IS QP\n");		    mhp->transfer_encoding = QP;		  }		else if (!Strcase_has_prefix (cp, "base64"))		  {		    if (Debug >= 3)		      fprintf (stderr, "Transfer-encoding IS B64\n");		    mhp->transfer_encoding = B64;		  }		else if (!Strcase_has_prefix (cp, "7bit"))		  {		    if (Debug >= 3)		      fprintf (stderr, "Transfer-encoding IS 7bit\n");		    mhp->transfer_encoding = BIT7;		  }		else if (!Strcase_has_prefix (cp, "8bit"))		  {		    if (Debug >= 3)		      fprintf (stderr, "Transfer-encoding IS 8bit\n");		    mhp->transfer_encoding = BIT8;		  }		else if (!Strcase_has_prefix (cp, "binary"))		  {		    if (Debug >= 3)		      fprintf (stderr, "Transfer-encoding IS BINARY\n");		    mhp->transfer_encoding = BINARY;		  }		else		  {

⌨️ 快捷键说明

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