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

📄 mime.c

📁 一个功能全面的电子邮件客户端
💻 C
📖 第 1 页 / 共 4 页
字号:
/* TradeClient <http://tradeclient.sourceforge.net> * $Id: mime.c,v 1.52 2001/03/20 22:19:33 ttabner Exp $ * * Copyright (C) 1999-2000 Bynari Inc. * Copyright (C) 2001 Project TradeClient * * LGPL * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Library 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 Library * General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "puma.h"#undef writeLlist *mimetypes;#define NA 127/*   These functions are crazy in size but seem to be pretty solid. If you   notice me doing something weird tell me.*//*   pretty standard tatic tables for base64, quoted printable, encoding,   decoding, et cetera, et cetera.*/static char index_qp[256] = {	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	 0, 1, 2, 3,  4, 5, 6, 7,  8, 9,NA,NA, NA,NA,NA,NA,	NA,10,11,12, 13,14,15,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,10,11,12, 13,14,15,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA};static char index_b64[256] = {	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,62, NA,NA,NA,63,	52,53,54,55, 56,57,58,59, 60,61,NA,NA, NA,NA,NA,NA,	NA, 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,NA, NA,NA,NA,NA,	NA,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,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA};static char index_no_enc[256] = {	NA,NA,NA,NA, NA,NA,NA,NA, NA,00,NA,NA, NA,NA,NA,NA,//16	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,00,//32	00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,//48	00,00,00,00, 00,00,00,00, 00,00,00,00, NA,00,00,00,//64	00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,//80	00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,//96	00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,//112	00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,NA,NA,//128	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA,	NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA, NA,NA,NA,NA};static char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";static char hextable[16] = "0123456789ABCDEF";char gethex (int num) {	return hextable[num];}void attachments_destroy (Attachment *att) {	Attachment *tmpatt;	while (att) {		if (att->name) free (att->name);		if (att->fname) free (att->fname);		if (att->mtype) free (att->mtype);		tmpatt=att->next;		free (att);		att=tmpatt;	}}/*   check the first 4096 chars to determine how we should encode if 10% or   less need encoding we will just user qp if more then base64 here we come   :)*/int encode_with (char *string, unsigned long len) {	int i, numtoenc, len2=len;	if (!string) return FALSE;	numtoenc=0;	if (len2>4096) len2=4096;	for (i=0; i<len2; i++) {		if (index_no_enc[((int)string[i])]==NA)			numtoenc++;	}	if (numtoenc>0) {		if (numtoenc>(len2*0.1))			return ENC_BASE64;		else			return ENC_QP;	}	return ENC_NONE;}unsigned long hash_string (char *str) {	int len=strlen(str);	int i;	unsigned long sum=0;	if (!str) return 1;	if (str[0]=='\0') return (unsigned long)str;	for (i=0; i<len; i++) {		sum+=str[i];	}	sum=sum/(len/2);	return sum;}/*   a suggested seed should be something like a hash of the subject + a hash   of the recipients address + a hash of the timeofday*/char *generate_boundary (unsigned int seed, int length) {	char *ret=(char *)calloc(length+14, sizeof(char));	int i=0;	if (!length) {		free (ret);		return NULL;	}	srandom (seed);	memmove (ret, "------------", 12);	for (i=0; i<length; i++) {		ret[i+12]=hextable[(int)(random()%16)];	}	return ret;}MimeType *mime_type_add (char *type, char *handle, char *ext) {	MimeType *mtype=(MimeType *)calloc (1, sizeof (MimeType));	if (mime_type_search_type (type)!=NULL) {		return NULL;	}	if (type) mtype->type=strdup (type);	if (handle) mtype->handle=strdup (handle);	if (ext) mtype->ext=strdup (ext);	if (mimetypes) {		llist_append (mimetypes, mtype);	} else {		mimetypes=llist_append (NULL, mtype);	}	mime_types_rehash_clist ();	return mtype;}MimeType *mime_type_search_type (char *type) {	Llist *seek=mimetypes;	MimeType *mtype = NULL;	if (type) {		while (seek) {			mtype=(MimeType *)seek->data;			if (!mtype) return NULL;			if (strncasecmp (type, mtype->type, strlen (mtype->type))==0) return mtype;			seek=seek->next;		}	} else {#if DEBUG > 2		printf ("mime_type_search_type: argument 1 'type' == NULL\n");#endif	}	return NULL;}MimeType *mime_type_search_ext (char *ext) {	Llist *seek=mimetypes;	MimeType *mtype;	if (ext) {		while (seek) {			mtype=(MimeType *)seek->data;			if (strstr (mtype->ext, ext)!=NULL) return mtype;			seek=seek->next;		}	} else {#if DEBUG > 1		printf ("mime_type_search_ext: ext is null\n");#endif	}	return NULL;}void mime_type_delete (char *type) {	MimeType *mtype;	if (type) {		mtype=mime_type_search_type (type);		if (mtype) {			mimetypes=llist_detach (mimetypes, (void *)mtype);			if (mtype->type) free (mtype->type);			if (mtype->handle) free (mtype->handle);			if (mtype->ext) free (mtype->ext);			free (mtype);		}	}	mime_types_rehash_clist ();}Llist *mime_type_first () {	return mimetypes;}/*   I found these on most linux systems installed by default, seems to work   fine for most standard thing.*/void mime_type_add_defaults () {	if (mimetypes==NULL) {		mime_type_add ("text/plain", "Internal", "txt,text");		mime_type_add ("text/html", "netscape '%f'", "htm,html");		mime_type_add ("message/rfc822", "Internal", "eml");		mime_type_add ("application/octet-stream", "Save", "");		mime_type_add ("application/java-archive", "Save", "jar");		mime_type_add ("application/mac-binhex40", "Save", "hqx");		mime_type_add ("application/pdf", "xpdf '%f'", "pdf");		mime_type_add ("application/rtf", "Save", "rtf");		mime_type_add ("application/x-gzip", "Save", "gz");		mime_type_add ("application/x-cpio", "Save", "cpio");		mime_type_add ("application/x-gtar", "Save", "tar");		mime_type_add ("application/x-tar", "Save", "tar");		mime_type_add ("application/x-zip-compressed", "Save", "zip");		mime_type_add ("application/x-stuffit", "Save", "sit");		mime_type_add ("application/x-tex", "Save", "tex");		mime_type_add ("application/x-texinfo", "Save", "texi,texinfo");		mime_type_add ("application/x-latex", "Save", "latex");		mime_type_add ("application/x-dvi", "Save", "dvi");		mime_type_add ("video/mpeg", "xanim '%f'", "mpeg,mpg,mpv,mpe,vbs,mpegv");		mime_type_add ("video/quicktime", "xanim '%f'", "qt,mov,moov");		mime_type_add ("video/x-msvideo", "xanim '%f'", "avi");		mime_type_add ("video/x-mpeg2", "xanim '%f'", "mpv2,mp2v");		mime_type_add ("audio/x-mpeg", "xterm -e mpg123 '%f'", "mp3,mp2,mpa,abs,mpega");		mime_type_add ("audio/x-wav", "xterm -e play '%f'", "wav");		mime_type_add ("audio/x-aiff", "xterm -e play '%f'", "aif,aiff,aifc");		mime_type_add ("image/jpeg", "xv '%f'", "jpg,jpeg");		mime_type_add ("image/gif", "xv '%f'", "gif");		mime_type_add ("image/targa", "xv '%f'", "tga");		mime_type_add ("image/tiff", "xv '%f'", "tiff,tif");		mime_type_add ("image/png", "xv '%f'", "png");		mime_type_add ("image/x-MS-bmp", "xv '%f'", "bmp");		mime_type_add ("image/x-portable-pixmap", "xv '%f'", "ppm");		mime_type_add ("image/x-portable-graymap", "xv '%f'", "pgm");		mime_type_add ("image/x-portable-bitmap", "xv '%f'", "pbm");		mime_type_add ("image/x-xpixmap", "xv '%f'", "xpm");		mime_type_add ("image/x-xbitmap", "xv '%f'", "xbm");		mime_type_add ("image/x-rgb", "xv '%f'", "rgb");	}}int mime_handle (char *ttype) {	MimeType *mtype=mime_type_search_type (ttype);	if (mtype==NULL)		return MIMEHANDLE_NONE;	if (strncasecmp (mtype->handle, "Internal", 8)==0)		return MIMEHANDLE_INT;	if (strncasecmp (mtype->handle, "Save", 4)==0)		return MIMEHANDLE_SAVE;	if (strncasecmp (mtype->handle, "Prompt", 4)==0)		return MIMEHANDLE_PROMPT;	return MIMEHANDLE_EXT;}char *get_boundary (char *content_type) {  char *boundary;  char *tmp=NULL, *tmp2=NULL;  if (content_type!=NULL) {    tmp=strpbrk(content_type, "Bb");    while (tmp!=NULL) {      tmp++;      if (strncasecmp (tmp, "oundary=", 8)==0) {	tmp+=8;	if (*tmp=='"') {	  tmp++;	  tmp2=strchr (tmp, '"');	} else {	  tmp2=strpbrk(tmp, "\f\t\r\n ");	  /*	   * Let's see if the quotes where simply left off.	   * If tmp2 is still null, let's assume that the quotes were	   * left off of the boundary declaration and use what was	   * left since we DID find a boundary statement!!!!	   */	  if( !tmp2 ) {	    return strdup( tmp ) ;	  }	}	if (tmp2!=NULL) {	  boundary=(char *)calloc((tmp2-tmp)+1, sizeof(char));	  memmove (boundary, tmp, tmp2-tmp);	  return boundary;	}      }      tmp=strpbrk(tmp, "Ff");    }  }  return NULL;}char *get_name (char *content_type) {	char *name;	char *tmp=NULL, *tmp2=NULL;	if (content_type!=NULL) {		tmp=strpbrk(content_type, "Nn");		while (tmp!=NULL) {			tmp++;			if (strncasecmp (tmp, "ame=", 4)==0) {				tmp+=8;				if (*tmp=='"') {					tmp++;					tmp2=strchr (tmp, '"');				} else {					tmp2=strpbrk(tmp, "\f\t\r\n ");				}				if (tmp2!=NULL) {					name=(char *)calloc((tmp2-tmp)+1, sizeof(char));					memmove (name, tmp, tmp2-tmp);					return name;				}			}			tmp=strpbrk(tmp, "Ff");		}	}	return NULL;}char *get_filename (char *content_d) {	char *filename;	char *tmp=NULL, *tmp2=NULL;	char *maybe=NULL;	if (content_d!=NULL) {		tmp=strpbrk(content_d, "Ff");		while (tmp!=NULL) {			tmp++;			if (strncasecmp (tmp, "ilename=", 8)==0) {				tmp+=8;				maybe = tmp;				if (*tmp=='"') {					tmp++;					tmp2=strchr (tmp, '"');				} else {					tmp2=strpbrk(tmp, "\f\t\r\n ");				}				if (tmp2!=NULL) {					filename=(char *)calloc((tmp2-tmp)+1, sizeof(char));					memmove (filename, tmp, tmp2-tmp);					return filename;				}			}			tmp=strpbrk(tmp, "Ff");		}#if 1		if (tmp == NULL) {			if (maybe != NULL) {				filename = strdup (maybe);				return filename;			}		}#endif	}	return NULL;}/* TODO: verify this function */int mime_enc_type (char *content_t_e) {	if (content_t_e!=NULL) {		switch (content_t_e[0]) {			case 'q':			case 'Q':				if (strncasecmp(content_t_e+1, "uoted-printable", 15)==0)					return ENC_QP;				break;			case '7':			case '8':				if (strncasecmp(content_t_e+1, "bit", 3)==0)					return ENC_NONE;				break;			case 'b':			case 'B':				if (strncasecmp(content_t_e+1, "ase64", 5)==0)					return ENC_BASE64;				if (strncasecmp(content_t_e+1, "inary", 5)==0)					return ENC_NONE;			default:				printf (_("Unknown content encoding '%s'\n"), content_t_e);		}	}	return ENC_NONE;}char *mime_dec_base64 (char *data, unsigned long *bpos) {	int len=strlen(data);	int i,c1,c2,c3,c4;	int Done=FALSE;	char *tmpret=(char *)calloc(len+2, sizeof(char));	char *ret;#define getnc(p)	p[i];i++;	*bpos=0;	for (i=0; i<len;) {		c1=getnc(data);		if ( (c1!='=') && (index_b64[(unsigned char)c1]==NA) ) continue;		if (Done==TRUE) continue;		c2=getnc(data);		while ( (i<len) && (c2!='=') && (index_b64[(unsigned char)c2]==NA) ) {			c2=getnc(data);		}		c3=getnc(data);		while ( (i<len) && (c3!='=') && (index_b64[(unsigned char)c3]==NA) ) {			c3=getnc(data);		}		c4=getnc(data);		while ( (i<len) && (c4!='=') && (index_b64[(unsigned char)c4]==NA) ) {			c4=getnc(data);		}		if (i>len) {			free (tmpret);			return NULL;		}		if ((c1=='=')&&(c2=='=')) {			Done=TRUE;			continue;		}		c1=index_b64[(unsigned char)c1];		c2=index_b64[(unsigned char)c2];		tmpret[*bpos]=( (c1<<2) | ((c2&0x30)>>4) );		*bpos+=1;		if (c3=='=') {			Done=TRUE;		} else {			c3=index_b64[(unsigned char)c3];			tmpret[*bpos]=( ((c2&0x0F)<<4) | ((c3&0x3C)>>2) );			*bpos+=1;			if (c4=='=') {				Done=TRUE;			} else {				c4=index_b64[(unsigned char)c4];				tmpret[*bpos]=( ((c3&0x03)<<6) | c4);				*bpos+=1;			}

⌨️ 快捷键说明

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